Skip to main content

Milestone

Milestone allows for the selection of a specific event date with a label. The shape of the options being passed in will determine whether a PlusMinus control appears to specify a duration, age, or some other value.

Options can also specify a milestoneDate which will be used to calculate a date based on the selected duration.

The Milestone component supports minimal schema validation with yup & Formik. It is recommended to perform complex validation with the validate callback.

Result
Loading...
Live Editor
const options = [
	{
		id: 'Start',
		defaultValue: '01/01/2000',
		label: 'Start (01/01/2000)',
	},
	{
		id: 'ClientDeath',
		defaultValue: '05/01/2055',
		label: 'Death of client (05/01/2055)',
	},
	{
		id: 'CalendarYear',
		defaultValue: 2050,
		label: 'Calendar Year',
	},
	{
		id: 'ClientIs',
		defaultValue: 50,
		label: 'When client is',
		milestoneDate: '05/30/1980',
	},
];

function Example() {
	const [value, setValue] = useState();

	const handleChange = (payload) => {
		console.log('change', payload);
		setValue(payload);
	};

	return <div data-testid="pw-milestone-1"><Milestone label="Milestone" onChange={handleChange} options={options} value={value} /></div>;
}

render(<Example />);

With specific date ranges on a NumberField

You can also specify a custom description prefix to individual options.

Result
Loading...
Live Editor
const options = [
	{
		id: 'ClientIs',
		defaultValue: 21,
		label: 'When client is',
		milestoneDate: '05/30/1980',
		descriptionPrefix: 'Actual year:',
	},
];

function Example() {
	const [value, setValue] = useState();

	return (
		<Milestone
			label="Milestone"
			onChange={setValue}
			options={options}
			value={value}
			numberFieldProps={{ minValue: 18, maxValue: 65 }}
		/>
	);
}

render(<Example />);

Or within the option itself if the props should be different. NumberField props defined in the option will always override over NumberField props.

Result
Loading...
Live Editor
const options = [
	{
		id: 'ClientIs',
		defaultValue: 21,
		label: 'When client is',
		milestoneDate: '05/30/1980',
		descriptionPrefix: 'Actual year:',
		numberFieldProps: { minValue: 18, maxValue: 65 },
	},
	{
		id: 'CalendarYear',
		defaultValue: 2050,
		label: 'When client retires',
		numberFieldProps: { minValue: 2045, maxValue: 2055 },
	},
];

function Example() {
	const [value, setValue] = useState();

	return <Milestone label="Milestone" onChange={setValue} options={options} value={value} />;
}

render(<Example />);

Validation

The Milestone component supports minimal schema validation with yup & Formik. It is recommended to perform complex validation with the validate callback.

Result
Loading...
Live Editor
const options = [
	{
		id: 'ClientIs',
		defaultValue: 50,
		label: 'When client is',
		milestoneDate: '05/30/1980',
	},
];

function Example() {
	return (
		<div data-testid="within-form">
			<Form
				initialValues={{}}
				onSubmit={(values, { setSubmitting }) => {
					console.log(values);
					setSubmitting(false);
				}}
				validationSchema={object().shape({
					milestone: object().shape({
						type: string(),
						value: mixed()
							.label('Age')
							.when('type', {
								is: 'ClientIs',
								then: number().min(25, '${path} must be at least 25').max(65, '${path} must be at most 65'),
							}),
					}),
				})}
			>
				<FormField>
					<Milestone label="Milestone" name="milestone" options={options} />
				</FormField>
			</Form>
		</div>
	);
}

render(<Example />);

Select and NumberField Props

The selectProps and numberFieldProps pass additional props to the underlying Select and NumberField components.

Additionally, each option in the options array can also include a selectProps and the numberFieldProps object.

Note: Props defined in the option will always override over props defined in selectProps and numberFieldProps, with the exception of description which will be combined together.

Result
Loading...
Live Editor
const options = [
	{
		id: 'ClientIs',
		defaultValue: 50,
		label: 'When client is',
		milestoneDate: '05/30/1980',
		descriptionPrefix: 'Actual year:',
		selectProps: { description: 'Option 1 description from selectProps.' },
		numberFieldProps: { minValue: 18, maxValue: 65, description: 'Option 1 description from numberFieldProps' },
	},
	{
		id: 'CalendarYear',
		defaultValue: 2050,
		label: 'Calendar Year',
		selectProps: { description: 'Option 2 description from selectProps.' },
		numberFieldProps: { minValue: 2045, maxValue: 2055, description: 'Option 2 description from numberFieldProps' },
	},
];

function Example() {
	const [value, setValue] = useState();

	return (
		<Milestone 
			label="Milestone" 
			onChange={setValue} 
			options={options} 
			value={value} 
			selectProps={{ description: "Description from selectProps" }}
			numberFieldProps={{ description: "Description from numberFieldProps" }}
		/>
	);
}

render(<Example />);

Analytics

The Milestone component is trackable through Kyber Analytics. This is the default analytics config.

export default {
value: 'Start',
actions: {
onChange: { type: 'START_CHANGE', payload: 'Change' },
},
};

Props