<State initial={undefined}>
{([date, setDate]) => (
<Form>
<DateRangePicker
open
disableCloseOnClickOutside
value={date}
onChange={(v) => setDate(v)}
/>
</Form>
)}
</State>
States
Default
<State initial={{ start: new Date('02/09/21'), end: new Date('02/16/21') }}>
{([date, setDate]) => (
<Form>
<Form.DateRangePicker
label='Default Value'
description="Description goes here..."
value={date}
onChange={(v) => setDate(v)}
/>
<Form.DateRangePicker
label='Min and Max Date'
minDate={new Date('02/01/21')}
maxDate={new Date('02/20/21')}
value={date}
onChange={(v) => setDate(v)}
open
disableCloseOnClickOutside
/>
</Form>
)}
</State>
Placeholder
<State initial={{}}>
{([date, setDate]) => (
<Form>
<Form.DateRangePicker
label="With Placeholder"
value={date}
input={{ placeholder: "Select the event's date range" }}
onChange={(v) => setDate(v)}
/>
</Form>
)}
</State>
Error
For each input, errors for exceeding min or max date is handled internally using a tooltip. For errors that are external, use Form.DateRangePicker
's error
prop to pass in error and the message.
<State initial={{ start: new Date('02/09/21'), end: new Date('02/16/21') }}>
{([date, setDate]) => (
<>
<Form style={{ height: 540 }}>
<Form.DateRangePicker
label='Exceed Min and Max Date'
minDate={new Date('02/10/21')}
maxDate={new Date('02/12/21')}
value={date}
onChange={(v) => setDate(v)}
open
disableCloseOnClickOutside
/>
</Form>
<Form>
<Form.DateRangePicker
label='Externally Triggered'
value={date}
onChange={(v) => setDate(v)}
error
open
disableCloseOnClickOutside
/>
</Form>
</>
)}
</State>
Required
<State initial={{ start: new Date('02/09/21'), end: new Date('02/16/21') }}>
{([date, setDate]) => (
<Form>
<Form.DateRangePicker
label="Date Label"
value={date}
onChange={(v) => setDate(v)}
required
/>
</Form>
)}
</State>
Disabled
<State initial={{ start: new Date('02/09/21'), end: new Date('02/16/21') }}>
{([date, setDate]) => (
<Form>
<Form.DateRangePicker
label="Date Label"
onChange={(v) => setDate(v)}
disabled
/>
<Form.DateRangePicker
label="Date Label"
value={date}
onChange={(v) => setDate(v)}
disabled
/>
</Form>
)}
</State>
Options
In the use cases where frequently used ranges are determined, preset options can be used to speed up selection for the users.
Default
<State initial={{}}>
{([date, setDate]) => (
<Form>
<Form.DateRangePicker
label='Date Label'
onChange={(v) => setDate(v)}
value={date}
open
disableCloseOnClickOutside
dropdown={{
options: [
{
value: {
start: new Date(new Date().setDate(new Date().getDate() - 7)),
end: new Date(),
},
text: 'Last 7 Days',
},
{
value: {
start: new Date(new Date().setDate(new Date().getDate() - 30)),
end: new Date(),
},
text: 'Last 30 Days',
},
{
value: {
start: new Date(new Date().setDate(new Date().getDate() - 90)),
end: new Date(),
},
text: 'Last 90 Days',
},
{
value: {
start: new Date(new Date().setDate(new Date().getDate() - 365)),
end: new Date(),
},
text: 'Last 365 Days',
}
]
}}
/>
</Form>
)}
</State>
Options that are out of range
The options that are out of min max range will be disabled. This example has the same options with min and max date set to only make first option - Last 7 Days
- in range.
<State initial={{}}>
{([date, setDate]) => (
<Form>
<Form.DateRangePicker
label='Date Label'
onChange={(v) => setDate(v)}
open
value={date}
focusTrapOptions={{
disabled: true,
autoFocus: false
}}
disableCloseOnClickOutside
minDate={new Date(new Date().setDate(new Date().getDate() - 7))}
maxDate={new Date()}
dropdown={{
options: [
{
value: {
start: new Date(new Date().setDate(new Date().getDate() - 7)),
end: new Date(),
},
text: 'Last 7 Days',
},
{
value: {
start: new Date(new Date().setDate(new Date().getDate() - 30)),
end: new Date(),
},
text: 'Last 30 Days',
},
{
value: {
start: new Date(new Date().setDate(new Date().getDate() - 90)),
end: new Date(),
},
text: 'Last 90 Days',
},
{
value: {
start: new Date(new Date().setDate(new Date().getDate() - 365)),
end: new Date(),
},
text: 'Last 365 Days',
}
]
}}
/>
</Form>
)}
</State>
Label
Labels can have a help icon with a tooltip to provide additional context to a label.
Help
<State initial={undefined}>
{([date, setDate]) => (
<Form>
<Form.DateRangePicker
label="Date Label"
value={date}
labelProps={{
help: 'This is help text',
direction: 'r',
}}
onChange={(v) => setDate(v)}
/>
</Form>
)}
</State>
Required and Optional
A visual indicator can be applied on a Date Picker's label.
<Form>
<State initial={undefined}>
{([date, setDate]) => (
<Form.DateRangePicker
label="Date Label"
value={date}
labelProps={{
required: true,
}}
onChange={(v) => setDate(v)}
/>
)}
</State>
<State initial={undefined}>
{([date, setDate]) => (
<Form.DateRangePicker
label="Date Label"
value={date}
labelProps={{
optional: true,
}}
onChange={(v) => setDate(v)}
/>
)}
</State>
</Form>
Multiple Calendar View
<State initial={undefined}>
{([date, setDate]) => (
<Form>
<DateRangePicker
open
disableCloseOnClickOutside
value={date}
onChange={(v) => setDate(v)}
dropdown={{ views: 2 }}
/>
</Form>
)}
</State>
Accessibility
The user should be able to choose a date by typing into the start and end date input or by selecting a date from the calendar. The user should be able to use either method.
Keyboard Support
- When focus is on the trigger, press
space
to open and escape
to close the calendar.
- When picker is open, use
tab
/ shift + tab
to change focus between inputs, calendar, and options.
- When focus is on the calendar:
- use the arrow keys to traverse through dates
- use
enter
to select a date
- use
space
to apply, when Apply
button is enabled
- use
page up
and page down
to change months
- use
cmd + page up
and cmd + page down
to change the view scope between month, year, and decade.
Content Guidelines
Most of the content guidelines from Forms applies to the Date Picker.
A label is a short, meaningful description that clearly indicates what the user is expected to enter. Labels should be 1 to 3 words and written in title case. Labels should primarily be nouns. Avoid using labels as CTAs. A label is not inline help and shouldn’t be used to provide instruction.
Follow capitalization rules
Input labels should be written in title case.
Inline help should explain the situation for needing a date range.
Best Practices
- Set minDate and maxDate to reduce user mistakes.
Components
Patterns
- Form design pattern for how related controls are ordered.
Importing
import { DateRangePicker } from '@servicetitan/design-system';