Import
import { Datepicker } from '@contentful/f36-components';// orimport { Datepicker } from '@contentful/f36-datepicker';
Examples
Basic
Display Datepicker component with text input
function BasicExample() { const [selectedDay, setSelectedDay] = useState(new Date()); return <Datepicker selected={selectedDay} onSelect={setSelectedDay} />; }
Date Formats
Datepicker supports printing out different formats to users, see https://date-fns.org/v2.16.1/docs/format
At Contentful we use dd LLL yyyy format to communicate date to users, example 31 Jan 2021
function FormatExample() { const [selectedDay, setSelectedDay] = useState(new Date()); return ( <Flex marginBottom="spacingM" flexDirection="column" fullWidth> <Box marginBottom="spacingM"> <Datepicker dateFormat="do LLL yyyy" selected={selectedDay} onSelect={setSelectedDay} /> </Box> <Box> <Datepicker dateFormat="dd.MM.yyyy" selected={selectedDay} onSelect={setSelectedDay} /> </Box> </Flex> ); }
Visual States
Visual states indicates to users certain messages through UI.
Communicate to the users in text why the Datepicker is in a specific state, example:
Disabled: "You don't have access to edit this field!" Invalid: "Please enter a valid date!"
function VisualStatesExample() { const [selectedDay, setSelectedDay] = useState(new Date()); return ( <> <SectionHeading>Disabled</SectionHeading> <Datepicker selected={selectedDay} onSelect={setSelectedDay} inputProps={{ isDisabled: true }} /> <br /> <SectionHeading>Invalid</SectionHeading> <Datepicker selected={selectedDay} onSelect={setSelectedDay} inputProps={{ isInvalid: true }} /> </> ); }
Wrapped in FormControl
You can use Datepicker with the FormControl in order to enhance layout with input label, help text or validation message.
function WithFormControlExample() { const [selectedDay, setSelectedDay] = useState(new Date()); return ( <FormControl id="date" isRequired> <FormControl.Label>Date</FormControl.Label> <Datepicker selected={selectedDay} onSelect={setSelectedDay} /> <FormControl.HelpText>Please enter a publish date</FormControl.HelpText> </FormControl> ); }
Limiting the date range
Set mininum and/or maximum dates to limit users to choose from a specific period in time.
Use the fromDate and toDate properties to control time frames.
function LimitingTheDateRangeExample() { const [selectedDay, setSelectedDay] = useState(new Date()); const fromDate = new Date(); const twoYearsFromNow = new Date( new Date(fromDate).setFullYear(fromDate.getFullYear() + 2), ); return ( <Datepicker fromDate={fromDate} toDate={twoYearsFromNow} selected={selectedDay} onSelect={setSelectedDay} /> ); }
Multiple months
If you need to show more than a month at once, use the numberOfMonths property.
function WithMultipleMonthsExample() { const [selectedDay, setSelectedDay] = useState(new Date()); return ( <Datepicker selected={selectedDay} onSelect={setSelectedDay} numberOfMonths={2} /> ); }
Custom placeholder
To replace default placeholder with your custom one, use the placeholder property.
function PlaceholderExample() { const [selectedDay, setSelectedDay] = useState(undefined); return ( <Datepicker selected={selectedDay} onSelect={setSelectedDay} placeholder="Select a date" /> ); }
Open by default
Use the defaultIsOpen property to open the dropdown and display the Calendar by default without user interaction.
Note: the Calendar closes by pressing the escape key or by clicking outside of the Datepicker.
function DefaultOpenExample() { const [selectedDay, setSelectedDay] = useState(new Date()); return ( <Datepicker defaultIsOpen selected={selectedDay} onSelect={setSelectedDay} /> ); }
Custom
If you need a custom solution, you can build it by leveraging our lower-level components, such as Calendar, Popover, and TextInput. For example, Datepicker that uses text input as a trigger without a button.
function CustomExample() { const DATE_FORMAT = 'yyyy-MM-dd'; // e.g. 2022-01-31 const [selected, setSelected] = useState(new Date('2022-04-15')); const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [inputValue, setInputValue] = useState(() => selected ? format(selected, DATE_FORMAT) : '', ); const [isInputInvalid, setIsInputInvalid] = useState(false); const popoverWasClosed = useRef(false); const closePopover = () => { popoverWasClosed.current = true; setIsPopoverOpen(false); }; const handleDaySelect = (date) => { if (date) { setSelected(date); setInputValue(format(date, DATE_FORMAT)); closePopover(); } }; const handleInputFocus = () => { // when popover gets closed focus returns to the input, // we want to prevent popover to be opened in this case if (popoverWasClosed.current) { popoverWasClosed.current = false; return; } setIsPopoverOpen((state) => !state); }; const hendleInputKeyDown = (event) => { if (event.key === 'Enter' && !isInputInvalid) { event.preventDefault(); setIsPopoverOpen(true); } }; const handleInputChange = (e) => { const value = e.currentTarget.value; setInputValue(value); const date = parse(value, DATE_FORMAT, new Date()); if (isValid(date)) { setIsInputInvalid(false); setSelected(date); } else { setIsInputInvalid(true); setSelected(undefined); } }; return ( <Popover isOpen={isPopoverOpen} onClose={closePopover}> <Popover.Trigger> <TextInput placeholder={format(new Date(), DATE_FORMAT)} value={inputValue} onChange={handleInputChange} onFocus={handleInputFocus} onKeyDown={hendleInputKeyDown} isInvalid={isInputInvalid} aria-label="Choose date" /> </Popover.Trigger> <Popover.Content> <FocusLock returnFocus={true}> <Calendar className={css({ padding: tokens.spacingM, })} mode="single" selected={selected} onSelect={handleDaySelect} initialFocus={false} defaultMonth={selected} /> </FocusLock> </Popover.Content> </Popover> ); }
Props (API reference)
Open in StorybookName | Type | Default |
|---|---|---|
| onSelect required | (day: Date) => void Callback fired when the day is selected | |
| captionLayout | "dropdown" "buttons" "dropdown-buttons" Change the layout of the caption: - `buttons`: display prev/right buttons - `dropdown`: display drop-downs to change the month and the year **Note:** the `dropdown` layout is available only when `fromDate`, `fromMonth` or`fromYear` and `toDate`, `toMonth` or `toYear` are set. | |
| className | string CSS class to be appended to the root element | |
| components | CustomComponents Map of components used to create the layout. Look at the [components source](https://github.com/gpbl/react-day-picker/tree/main/src/components) to understand how internal components are built and provide your custom components. | |
| dateFormat | string Format that is used to display date in the input, It is based on (Unicode Technical Standart #35)[https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table] | 'dd LLL yyyy' e.g. 31 Jan 2022 |
| defaultIsOpen | false true If `true`, the Datepicker will be initially opened. | |
| defaultMonth | Date The initial month to show in the calendar. Use this prop to let DayPicker control the current month. If you need to set the month programmatically, use {@link month]] and [[onMonthChange}. | |
| dir | string The text direction of the calendar. Use `ltr` for left-to-right (default) or `rtl` for right-to-left. | |
| disabled | false true Date (date: Date) => boolean Date[] DateRange DateBefore DateAfter DateInterval DayOfWeek Matcher[] Apply the `disabled` modifier to the matching days. | |
| disableNavigation | false true Disable the navigation between months. | |
| firstWeekContainsDate | 1 4 The day of January, which is always in the first week of the year. Can be either Monday (`1`) or Thursday (`4`). | |
| fixedWeeks | false true Display six weeks per months, regardless the month’s number of weeks. To use this prop, {@link showOutsideDays} must be set. | |
| footer | string number bigint false true ReactElement<unknown, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal Promise<AwaitedReactNode> Content to add to the table footer element. | |
| formatters | Partial<Formatters> A map of formatters. Use the formatters to override the default formatting functions. | |
| fromDate | Date The earliest day to start the month navigation. | |
| hidden | false true Date (date: Date) => boolean Date[] DateRange DateBefore DateAfter DateInterval DayOfWeek Matcher[] Apply the `hidden` modifier to the matching days. Will hide them from the calendar. | |
| hideHead | false true Hide the month’s head displaying the weekday names. | |
| id | string A unique id to replace the random generated id – used by DayPicker for accessibility. | |
| initialFocus | false true When a selection mode is set, DayPicker will focus the first selected day (if set) or the today's date (if not disabled). Use this prop when you need to focus DayPicker after a user actions, for improved accessibility. | |
| inputProps | Partial<TextInputProps> Props to pass to the TextInput component | |
| ISOWeek | false true Use ISO week dates instead of the locale setting. Setting this prop will ignore {@link weekStartsOn} and {@link firstWeekContainsDate}. | |
| labels | Partial<Labels> Labels creators to override the defaults. Use this prop to customize the ARIA labels attributes. | |
| lang | string Add the language tag to the container element. | |
| locale | Locale The date-fns locale object used to localize dates. | |
| modifiers | DayModifiers Add modifiers to the matching days. | |
| modifiersClassNames | ModifiersClassNames Change the class name for the day matching the {@link modifiers}. | |
| modifiersStyles | ModifiersStyles Change the inline style for the day matching the {@link modifiers}. | |
| month | Date The month displayed in the calendar. As opposed to {@link DayPickerBase.defaultMonth}, use this prop with {@link DayPickerBase.onMonthChange} to change the month programmatically. | |
| nonce | string A cryptographic nonce ("number used once") which can be used by Content Security Policy for the inline `style` attributes. | |
| numberOfMonths | number The number of displayed months. | |
| onDayBlur | DayFocusEventHandler Event callback fired when the user blurs from a day. | |
| onDayClick | DayClickEventHandler Event callback fired when the user clicks on a day. | |
| onDayFocus | DayFocusEventHandler Event callback fired when the user focuses on a day. | |
| onDayKeyDown | DayKeyboardEventHandler Event callback fired when the user presses a key on a day. | |
| onDayKeyPress | DayKeyboardEventHandler Event callback fired when the user presses a key on a day. | |
| onDayKeyUp | DayKeyboardEventHandler Event callback fired when the user presses a key on a day. | |
| onDayMouseEnter | DayMouseEventHandler Event callback fired when the user hovers on a day. | |
| onDayMouseLeave | DayMouseEventHandler Event callback fired when the user hovers away from a day. | |
| onDayPointerEnter | DayPointerEventHandler Event callback fired when the pointer enters a day. | |
| onDayPointerLeave | DayPointerEventHandler Event callback fired when the pointer leaves a day. | |
| onDayTouchCancel | DayTouchEventHandler Event callback when a day touch event is canceled. | |
| onDayTouchEnd | DayTouchEventHandler Event callback when a day touch event ends. | |
| onDayTouchMove | DayTouchEventHandler Event callback when a day touch event moves. | |
| onDayTouchStart | DayTouchEventHandler Event callback when a day touch event starts. | |
| onMonthChange | MonthChangeEventHandler Event fired when the user navigates between months. | |
| onNextClick | MonthChangeEventHandler Event callback fired when the next month button is clicked. | |
| onPrevClick | MonthChangeEventHandler Event callback fired when the previous month button is clicked. | |
| onWeekNumberClick | WeekNumberClickEventHandler Event callback fired when the week number is clicked. Requires `showWeekNumbers` set. | |
| pagedNavigation | false true Paginate the month navigation displaying the {@link numberOfMonths} at time. | |
| placeholder | string Custom placeholder for the input field | |
| popoverProps | Partial<PopoverProps> Props to pass to the Popover (Dropdown) component | |
| required | false true Make the selection required. | |
| reverseMonths | false true Render the months in reversed order (when {@link numberOfMonths} is greater than `1`) to display the most recent month first. | |
| selected | Date The selected day. | |
| showOutsideDays | false true Show the outside days. An outside day is a day falling in the next or the previous month. | |
| showWeekNumber | false true Show the week numbers column. Weeks are numbered according to the local week index. - to use ISO week numbering, use the {@link ISOWeek} prop. - to change how the week numbers are displayed, use the {@link Formatters} prop. | |
| size | "small" "medium" Size variations | |
| styles | Partial<Omit<StyledElement<CSSProperties>, InternalModifiersElement>> Change the inline styles of the HTML elements. | |
| testId | string A [data-test-id] attribute used for testing purposes | |
| title | string Add a `title` attribute to the container element. | |
| toDate | Date The latest day to end the month navigation. | |
| today | Date The today’s date. Default is the current date. This Date will get the `today` modifier to style the day. | |
| weekStartsOn | 0 1 2 3 4 5 6 The index of the first day of the week (0 - Sunday). Overrides the locale's one. |
Accessibility
- Keyboard navigation is supported
- Necessary aria roles are provided by default
- When providing a label, ensure it's linked to the text input