DatePicker
Button that becomes a removable chip once a date is chosen, with a calendar behind it. It is
Calendar wrapped in an AddButton and a
SelectedItem.
Use this when / not when
- Use for an optional date in a filter or a form, where "no date" is a normal state and the chosen date should read as a removable chip.
- Not for a date that is always present. The unchosen state is a "Select date" button, not an empty field, and there is no label or border.
- Not for a date and a time —
DateTimePickeris that. - Not when you want the grid on the page; use
Calendardirectly.
Import
import { DatePicker } from "@onlyoffice/apps-ui-kit/components/date-picker";
Also exported from the root barrel @onlyoffice/apps-ui-kit.
Needs ThemeProvider from @onlyoffice/apps-ui-kit/providers/theme.
Dates are Luxon DateTime objects.
Stories
Default
The picker as a form shows it before a date is chosen: click Select date to open the calendar, pick a day to turn the button into a chip, and change any other prop live in the Controls panel below.
With Initial Date
DatePicker initialized with the current date. The selected date appears as a chip that can be removed.
Future Dates Only
Restricts selection to future dates only by setting minDate to today. Past dates appear disabled in the calendar.
Specific Year Range
Constrains the calendar to a specific year (2023). Only dates within January 1 - December 31, 2023 are selectable.
Without Calendar Icon
The calendar icon in the selected date chip can be hidden with showCalendarIcon={false}.
Without Clear Button
For a date the form requires: the chip has no cross, so a date can be replaced by clicking the chip and picking another day, but not removed (hideCross).
Aligned To Right Edge
For a picker near the right edge of the window, such as the last column of a toolbar: click Select date and the calendar opens leftwards from the right edge of the nearest positioned container, here the window, instead of running off the screen (autoPosition).
End Of Day Value
For an inclusive end of a period, such as a "valid until" date: pick a day and the value above ends in 23:59:59.999, so the whole day is covered (useMaxTime). Without the prop the day is reported at the current time of day.
Right To Left
The picker under a right-to-left interface: the chip starts at the right edge, with the calendar icon on its right and the cross on its left, and the calendar opens under the right end of the picker. The direction comes from the theme's interfaceDirection (the Direction toolbar); the wrapper also carries dir="rtl" for the rules that read the DOM direction.
Css Customization
The variables are listed under CSS variables on this page. They are set on one wrapper around two pickers. The first holds the first day of this month, so it shows the chip; the second has no date, so it shows the Select date button. Open either calendar to see the calendar variables: both start at the first of this month (minDate), so the days of the previous month and the left arrow show their disabled colours, and the first picker's chosen day differs from today. Hover the chip, the button and a day to see the hover variables.
Minimal example
outerDate is what makes the chosen date stick. Hold the date yourself, set it from
onChange, and pass it back in.
import { useState } from "react";
import { DateTime } from "luxon";
import { DatePicker } from "@onlyoffice/apps-ui-kit/components/date-picker";
export function DueDateFilter() {
const [due, setDue] = useState<DateTime | null>(null);
return (
<DatePicker
locale="en"
openDate={DateTime.now()}
outerDate={due}
onChange={setDue}
selectDateText="Due date"
/>
);
}
Props
Recipes
Clearing, and a bounded range
onChange is called with null when the chip's cross is clicked; hideCross removes that
cross when the date must not be cleared.
import { useState } from "react";
import { DateTime } from "luxon";
import { DatePicker } from "@onlyoffice/apps-ui-kit/components/date-picker";
export function DeliveryDate() {
const [date, setDate] = useState<DateTime | null>(null);
return (
<div>
<DatePicker
locale="en"
openDate={DateTime.now()}
minDate={DateTime.now()}
maxDate={DateTime.now().plus({ months: 3 })}
outerDate={date}
onChange={setDate}
selectDateText="Choose a delivery date"
autoPosition
/>
{date ? <p>Delivering {date.toFormat("dd MMM yyyy")}</p> : null}
</div>
);
}
Behaviour the types don't state
outerDateis the real value prop, and it is optional in the type. An effect clears the component's own date wheneverouterDateis empty, so without it the chip never appears: you pick a day,onChangefires, and the control drops straight back to its button.initialDatealone does not survive that effect either.- The chosen date is formatted
dd MMM yyyyand that is fixed. There is no format prop; the month name followslocale. - The calendar closes on any pick. Choosing a day calls
onChangeand closes, so there is no way to change your mind inside the popup. - Outside clicks are caught in the capture phase on the document, with an exception for scrollbar thumbs so that dragging the calendar's scrollbar does not dismiss it.
autoPositionis measured once, as the calendar opens, against a fixed 340px of room to the right. Resizing the window while it is open does not move it.useMaxTimeonly applies while nothing is chosen — once a date is held, the flag is passed to the calendar asfalse, so re-picking keeps the existing time instead of the end of day.- The wrapper has
role="presentation", and the unchosen state is a<div role="button">around anAddButton, so the button is nested inside a second button role. - There is no disabled state and no error state; neither is a prop.
CSS variables
DatePicker's own stylesheet exposes nothing that reaches the rendered picker; its look comes from the three components inside it, so their variables, set on any ancestor, restyle it. The ones that show here:
The full lists, with the caveats, are in AddButton,
SelectedItem and
Calendar. The calendar glyph inside the chip is filled
with a fixed grey that no variable reaches.
Accessibility
- The "select date" control is a
<div role="button">withtabIndex={0}and anaria-label, so it is focusable — but it has no key handler, so Enter and Space do not open the calendar. - The calendar itself cannot be used from the keyboard at all — see
Calendar. Taken together, a keyboard-only user cannot choose a date. - The chip's clearing cross comes from
SelectedItemand inherits whatever name that gives it. aria-expandedis set on the select-date control, but not on the chip, so once a date is chosen nothing announces that the calendar can be reopened.
Test ids
| Element | data-testid |
|---|---|
| The wrapper | date-picker, or testId |
| The "select date" control | date-selector |
| The chip's label | selected-label |
| The calendar glyph | calendar-icon |
Related
Calendar— the grid this opens.DateTimePicker— this plus a time.SelectedItem— the chip the chosen date is drawn as.