@commercetools/nimbus-mcp 0.1.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -14
- package/data/docs/route-manifest.json +10913 -0
- package/data/docs/routes/components-accessibility-visually-hidden.json +388 -0
- package/data/docs/routes/components-accessibility.json +34 -0
- package/data/docs/routes/components-buttons-button.json +715 -0
- package/data/docs/routes/components-buttons-icon-button.json +852 -0
- package/data/docs/routes/components-buttons-icon-toggle-button.json +594 -0
- package/data/docs/routes/components-buttons-split-button.json +670 -0
- package/data/docs/routes/components-buttons-toggle-button-group.json +722 -0
- package/data/docs/routes/components-buttons-toggle-button.json +689 -0
- package/data/docs/routes/components-buttons.json +36 -0
- package/data/docs/routes/components-data-display-badge.json +555 -0
- package/data/docs/routes/components-data-display-card.json +338 -0
- package/data/docs/routes/components-data-display-data-table.json +855 -0
- package/data/docs/routes/components-data-display-draggable-list.json +596 -0
- package/data/docs/routes/components-data-display-table.json +472 -0
- package/data/docs/routes/components-data-display-tag-group.json +535 -0
- package/data/docs/routes/components-data-display.json +34 -0
- package/data/docs/routes/components-feedback-alert.json +696 -0
- package/data/docs/routes/components-feedback-dialog.json +682 -0
- package/data/docs/routes/components-feedback-drawer.json +600 -0
- package/data/docs/routes/components-feedback-loading-spinner.json +415 -0
- package/data/docs/routes/components-feedback-progress-bar.json +661 -0
- package/data/docs/routes/components-feedback-toast.json +1040 -0
- package/data/docs/routes/components-feedback-tooltip.json +510 -0
- package/data/docs/routes/components-feedback.json +34 -0
- package/data/docs/routes/components-forms-field-errors.json +557 -0
- package/data/docs/routes/components-forms-form-field.json +848 -0
- package/data/docs/routes/components-forms-group.json +427 -0
- package/data/docs/routes/components-forms-localized-field.json +770 -0
- package/data/docs/routes/components-forms.json +37 -0
- package/data/docs/routes/components-inputs-calendar.json +611 -0
- package/data/docs/routes/components-inputs-checkbox.json +774 -0
- package/data/docs/routes/components-inputs-combo-box.json +761 -0
- package/data/docs/routes/components-inputs-date-input.json +628 -0
- package/data/docs/routes/components-inputs-date-picker.json +709 -0
- package/data/docs/routes/components-inputs-date-range-picker.json +599 -0
- package/data/docs/routes/components-inputs-money-input.json +721 -0
- package/data/docs/routes/components-inputs-multiline-text-input.json +611 -0
- package/data/docs/routes/components-inputs-number-input.json +647 -0
- package/data/docs/routes/components-inputs-password-input.json +576 -0
- package/data/docs/routes/components-inputs-radio-input.json +583 -0
- package/data/docs/routes/components-inputs-range-calendar.json +607 -0
- package/data/docs/routes/components-inputs-rich-text-input.json +599 -0
- package/data/docs/routes/components-inputs-scoped-search-input.json +570 -0
- package/data/docs/routes/components-inputs-search-input.json +588 -0
- package/data/docs/routes/components-inputs-select-input.json +960 -0
- package/data/docs/routes/components-inputs-switch.json +720 -0
- package/data/docs/routes/components-inputs-text-input.json +566 -0
- package/data/docs/routes/components-inputs-time-input.json +775 -0
- package/data/docs/routes/components-inputs.json +34 -0
- package/data/docs/routes/components-layout-box.json +501 -0
- package/data/docs/routes/components-layout-defaultpage.json +748 -0
- package/data/docs/routes/components-layout-flex.json +587 -0
- package/data/docs/routes/components-layout-grid.json +393 -0
- package/data/docs/routes/components-layout-modalpage.json +716 -0
- package/data/docs/routes/components-layout-pagecontent.json +673 -0
- package/data/docs/routes/components-layout-separator.json +461 -0
- package/data/docs/routes/components-layout-simple-grid.json +519 -0
- package/data/docs/routes/components-layout-spacer.json +573 -0
- package/data/docs/routes/components-layout-stack.json +481 -0
- package/data/docs/routes/components-layout.json +34 -0
- package/data/docs/routes/components-media-avatar.json +427 -0
- package/data/docs/routes/components-media-icon.json +663 -0
- package/data/docs/routes/components-media-image.json +511 -0
- package/data/docs/routes/components-media-inline-svg.json +586 -0
- package/data/docs/routes/components-media.json +34 -0
- package/data/docs/routes/components-navigation-accordion.json +643 -0
- package/data/docs/routes/components-navigation-collapsible-motion.json +628 -0
- package/data/docs/routes/components-navigation-link.json +554 -0
- package/data/docs/routes/components-navigation-menu.json +546 -0
- package/data/docs/routes/components-navigation-pagination.json +502 -0
- package/data/docs/routes/components-navigation-steps.json +629 -0
- package/data/docs/routes/components-navigation-tabnav.json +546 -0
- package/data/docs/routes/components-navigation-tabs.json +635 -0
- package/data/docs/routes/components-navigation-toolbar.json +549 -0
- package/data/docs/routes/components-navigation.json +34 -0
- package/data/docs/routes/components-typography-code.json +39 -0
- package/data/docs/routes/components-typography-heading.json +402 -0
- package/data/docs/routes/components-typography-kbd.json +399 -0
- package/data/docs/routes/components-typography-list.json +593 -0
- package/data/docs/routes/components-typography-text.json +444 -0
- package/data/docs/routes/components-typography.json +34 -0
- package/data/docs/routes/components-utilities-nimbus-i18n-provider.json +295 -0
- package/data/docs/routes/components-utilities-nimbus-provider.json +663 -0
- package/data/docs/routes/components-utilities.json +34 -0
- package/data/docs/routes/components.json +33 -0
- package/data/docs/routes/home-contribute-adrs-adr0001-consumer-component-apis.json +314 -0
- package/data/docs/routes/home-contribute-adrs-adr0002-compound-component-extraction.json +160 -0
- package/data/docs/routes/home-contribute-adrs-adr0003-component-lifecycle-states.json +460 -0
- package/data/docs/routes/home-contribute-adrs.json +205 -0
- package/data/docs/routes/home-contribute-development-setup.json +213 -0
- package/data/docs/routes/home-contribute-stats.json +36 -0
- package/data/docs/routes/home-contribute.json +36 -0
- package/data/docs/routes/home-design-tokens-aspect-ratios.json +36 -0
- package/data/docs/routes/home-design-tokens-borders.json +35 -0
- package/data/docs/routes/home-design-tokens-colors.json +157 -0
- package/data/docs/routes/home-design-tokens-other-animations.json +119 -0
- package/data/docs/routes/home-design-tokens-other-blurs.json +36 -0
- package/data/docs/routes/home-design-tokens-other-breakpoints.json +61 -0
- package/data/docs/routes/home-design-tokens-other-cursors.json +36 -0
- package/data/docs/routes/home-design-tokens-other-z-indices.json +39 -0
- package/data/docs/routes/home-design-tokens-other.json +35 -0
- package/data/docs/routes/home-design-tokens-radii.json +59 -0
- package/data/docs/routes/home-design-tokens-shadows.json +57 -0
- package/data/docs/routes/home-design-tokens-sizes.json +137 -0
- package/data/docs/routes/home-design-tokens-spacing.json +36 -0
- package/data/docs/routes/home-design-tokens-typography.json +184 -0
- package/data/docs/routes/home-design-tokens.json +34 -0
- package/data/docs/routes/home-getting-started-core-concepts.json +301 -0
- package/data/docs/routes/home-getting-started-installation.json +621 -0
- package/data/docs/routes/home-getting-started-mcp-server-overview.json +139 -0
- package/data/docs/routes/home-getting-started-mcp-server-setup.json +316 -0
- package/data/docs/routes/home-getting-started-release-process.json +294 -0
- package/data/docs/routes/home-getting-started-testing-setup.json +296 -0
- package/data/docs/routes/home-playground-markdown.json +638 -0
- package/data/docs/routes/home-playground-toc.json +169 -0
- package/data/docs/routes/home-playground.json +34 -0
- package/data/docs/routes/home-style-props-background.json +236 -0
- package/data/docs/routes/home-style-props-border.json +310 -0
- package/data/docs/routes/home-style-props-display.json +120 -0
- package/data/docs/routes/home-style-props-effects.json +116 -0
- package/data/docs/routes/home-style-props-filters.json +396 -0
- package/data/docs/routes/home-style-props-flex-and-grid.json +496 -0
- package/data/docs/routes/home-style-props-interactivity.json +356 -0
- package/data/docs/routes/home-style-props-layout.json +422 -0
- package/data/docs/routes/home-style-props-list.json +116 -0
- package/data/docs/routes/home-style-props-sizing.json +244 -0
- package/data/docs/routes/home-style-props-spacing.json +228 -0
- package/data/docs/routes/home-style-props-svg.json +96 -0
- package/data/docs/routes/home-style-props-tables.json +116 -0
- package/data/docs/routes/home-style-props-transforms.json +216 -0
- package/data/docs/routes/home-style-props-transitions.json +216 -0
- package/data/docs/routes/home-style-props-typography.json +536 -0
- package/data/docs/routes/home-style-props.json +33 -0
- package/data/docs/routes/home.json +32 -0
- package/data/docs/routes/hooks-usecopytoclipboard.json +76 -0
- package/data/docs/routes/hooks-usehotkeys.json +117 -0
- package/data/docs/routes/hooks.json +33 -0
- package/data/docs/routes/icons.json +32 -0
- package/data/docs/routes/patterns-fields-date-range-picker-field.json +393 -0
- package/data/docs/routes/patterns-fields-money-input-field.json +415 -0
- package/data/docs/routes/patterns-fields-multiline-text-input-field.json +404 -0
- package/data/docs/routes/patterns-fields-number-input-field.json +470 -0
- package/data/docs/routes/patterns-fields-password-input-field.json +319 -0
- package/data/docs/routes/patterns-fields-search-input-field.json +382 -0
- package/data/docs/routes/patterns-fields-text-input-field.json +404 -0
- package/data/docs/routes/patterns-fields.json +78 -0
- package/data/docs/routes/patterns.json +34 -0
- package/data/docs/search-index.json +1 -0
- package/data/docs/types/Accordion.json +12 -0
- package/data/docs/types/AccordionContent.json +286 -0
- package/data/docs/types/AccordionHeader.json +891 -0
- package/data/docs/types/AccordionHeaderRightContent.json +27 -0
- package/data/docs/types/AccordionItem.json +242 -0
- package/data/docs/types/AccordionRoot.json +162 -0
- package/data/docs/types/Alert.json +12 -0
- package/data/docs/types/AlertActions.json +11 -0
- package/data/docs/types/AlertDescription.json +118 -0
- package/data/docs/types/AlertDismissButton.json +937 -0
- package/data/docs/types/AlertRoot.json +42 -0
- package/data/docs/types/AlertTitle.json +118 -0
- package/data/docs/types/Avatar.json +125 -0
- package/data/docs/types/Badge.json +64 -0
- package/data/docs/types/Body.json +67 -0
- package/data/docs/types/Box.json +85 -0
- package/data/docs/types/Button.json +1015 -0
- package/data/docs/types/Calendar.json +565 -0
- package/data/docs/types/Caption.json +67 -0
- package/data/docs/types/Card.json +12 -0
- package/data/docs/types/CardContent.json +27 -0
- package/data/docs/types/CardHeader.json +27 -0
- package/data/docs/types/CardRoot.json +106 -0
- package/data/docs/types/Cell.json +227 -0
- package/data/docs/types/Checkbox.json +897 -0
- package/data/docs/types/Code.json +112 -0
- package/data/docs/types/CollapsibleMotionContent.json +35 -0
- package/data/docs/types/CollapsibleMotionRoot.json +99 -0
- package/data/docs/types/CollapsibleMotionTrigger.json +71 -0
- package/data/docs/types/Column.json +101 -0
- package/data/docs/types/ColumnGroup.json +101 -0
- package/data/docs/types/ColumnHeader.json +193 -0
- package/data/docs/types/ComboBoxListBox.json +751 -0
- package/data/docs/types/ComboBoxOption.json +672 -0
- package/data/docs/types/ComboBoxPopover.json +786 -0
- package/data/docs/types/ComboBoxRoot.json +747 -0
- package/data/docs/types/ComboBoxSection.json +277 -0
- package/data/docs/types/ComboBoxTrigger.json +70 -0
- package/data/docs/types/Content.json +33 -0
- package/data/docs/types/DataTable.json +596 -0
- package/data/docs/types/DataTableBody.json +223 -0
- package/data/docs/types/DataTableFooter.json +27 -0
- package/data/docs/types/DataTableHeader.json +269 -0
- package/data/docs/types/DataTableManager.json +11 -0
- package/data/docs/types/DataTableRoot.json +590 -0
- package/data/docs/types/DataTableTable.json +271 -0
- package/data/docs/types/DateInput.json +792 -0
- package/data/docs/types/DatePicker.json +700 -0
- package/data/docs/types/DateRangePicker.json +936 -0
- package/data/docs/types/DateRangePickerField.json +1047 -0
- package/data/docs/types/DefaultPage.json +12 -0
- package/data/docs/types/DefaultPageActions.json +27 -0
- package/data/docs/types/DefaultPageBackLink.json +213 -0
- package/data/docs/types/DefaultPageContent.json +27 -0
- package/data/docs/types/DefaultPageFooter.json +27 -0
- package/data/docs/types/DefaultPageHeader.json +27 -0
- package/data/docs/types/DefaultPageRoot.json +106 -0
- package/data/docs/types/DefaultPageSubtitle.json +27 -0
- package/data/docs/types/DefaultPageTabNav.json +28 -0
- package/data/docs/types/DefaultPageTitle.json +27 -0
- package/data/docs/types/DialogBody.json +27 -0
- package/data/docs/types/DialogCloseTrigger.json +939 -0
- package/data/docs/types/DialogContent.json +27 -0
- package/data/docs/types/DialogFooter.json +27 -0
- package/data/docs/types/DialogHeader.json +27 -0
- package/data/docs/types/DialogRoot.json +138 -0
- package/data/docs/types/DialogTitle.json +27 -0
- package/data/docs/types/DialogTrigger.json +80 -0
- package/data/docs/types/DraggableList.json +12 -0
- package/data/docs/types/DraggableListField.json +894 -0
- package/data/docs/types/DraggableListItem.json +574 -0
- package/data/docs/types/DraggableListRoot.json +745 -0
- package/data/docs/types/Drawer.json +12 -0
- package/data/docs/types/DrawerBody.json +27 -0
- package/data/docs/types/DrawerCloseTrigger.json +939 -0
- package/data/docs/types/DrawerContent.json +27 -0
- package/data/docs/types/DrawerFooter.json +27 -0
- package/data/docs/types/DrawerHeader.json +27 -0
- package/data/docs/types/DrawerRoot.json +142 -0
- package/data/docs/types/DrawerTitle.json +27 -0
- package/data/docs/types/DrawerTrigger.json +80 -0
- package/data/docs/types/FieldErrors.getBuiltInMessage.json +11 -0
- package/data/docs/types/FieldErrors.getCustomMessage.json +9 -0
- package/data/docs/types/FieldErrors.json +109 -0
- package/data/docs/types/Flex.json +238 -0
- package/data/docs/types/Footer.json +67 -0
- package/data/docs/types/FormFieldDescription.json +11 -0
- package/data/docs/types/FormFieldError.json +11 -0
- package/data/docs/types/FormFieldInfoBox.json +27 -0
- package/data/docs/types/FormFieldInput.json +11 -0
- package/data/docs/types/FormFieldLabel.json +11 -0
- package/data/docs/types/FormFieldRoot.json +148 -0
- package/data/docs/types/Grid.json +253 -0
- package/data/docs/types/GridProps.json +11 -0
- package/data/docs/types/Group.json +143 -0
- package/data/docs/types/Header.json +67 -0
- package/data/docs/types/Heading.json +109 -0
- package/data/docs/types/Icon.json +112 -0
- package/data/docs/types/IconButton.json +1019 -0
- package/data/docs/types/IconToggleButton.json +787 -0
- package/data/docs/types/Image.json +373 -0
- package/data/docs/types/Indicator.json +67 -0
- package/data/docs/types/InlineSvg.json +98 -0
- package/data/docs/types/Item.json +67 -0
- package/data/docs/types/Kbd.json +118 -0
- package/data/docs/types/Link.json +380 -0
- package/data/docs/types/List.json +12 -0
- package/data/docs/types/ListIndicator.json +70 -0
- package/data/docs/types/ListItem.json +70 -0
- package/data/docs/types/ListRoot.json +124 -0
- package/data/docs/types/LoadingSpinner.json +87 -0
- package/data/docs/types/LocalizedField.json +460 -0
- package/data/docs/types/LocalizedStringFormatter.json +9 -0
- package/data/docs/types/MakeElementFocusable.json +196 -0
- package/data/docs/types/MenuContent.json +111 -0
- package/data/docs/types/MenuItem.json +671 -0
- package/data/docs/types/MenuRoot.json +670 -0
- package/data/docs/types/MenuSection.json +364 -0
- package/data/docs/types/MenuSubmenu.json +111 -0
- package/data/docs/types/MenuSubmenuTrigger.json +67 -0
- package/data/docs/types/MenuTrigger.json +906 -0
- package/data/docs/types/ModalPage.json +12 -0
- package/data/docs/types/ModalPageActions.json +27 -0
- package/data/docs/types/ModalPageContent.json +27 -0
- package/data/docs/types/ModalPageFooter.json +27 -0
- package/data/docs/types/ModalPageHeader.json +27 -0
- package/data/docs/types/ModalPageRoot.json +87 -0
- package/data/docs/types/ModalPageSubtitle.json +27 -0
- package/data/docs/types/ModalPageTabNav.json +28 -0
- package/data/docs/types/ModalPageTitle.json +27 -0
- package/data/docs/types/ModalPageTopBar.json +57 -0
- package/data/docs/types/MoneyInput.isEmpty.json +40 -0
- package/data/docs/types/MoneyInput.json +282 -0
- package/data/docs/types/MoneyInputField.json +379 -0
- package/data/docs/types/MoneyInputFieldProps.json +9 -0
- package/data/docs/types/MultilineTextInput.json +1194 -0
- package/data/docs/types/MultilineTextInputField.json +1269 -0
- package/data/docs/types/MultilineTextInputFieldProps.json +9 -0
- package/data/docs/types/NimbusI18nProvider.json +42 -0
- package/data/docs/types/NimbusI18nProviderProps.json +9 -0
- package/data/docs/types/NimbusProvider.json +270 -0
- package/data/docs/types/NumberInput.json +952 -0
- package/data/docs/types/NumberInputField.json +1004 -0
- package/data/docs/types/NumberInputFieldProps.json +9 -0
- package/data/docs/types/PageContent.json +11 -0
- package/data/docs/types/PageContentColumn.json +99 -0
- package/data/docs/types/PageContentRoot.json +114 -0
- package/data/docs/types/Pagination.json +159 -0
- package/data/docs/types/PasswordInput.json +1120 -0
- package/data/docs/types/PasswordInputField.json +1216 -0
- package/data/docs/types/PasswordInputFieldProps.json +9 -0
- package/data/docs/types/ProgressBar.json +280 -0
- package/data/docs/types/RadioInputOption.json +550 -0
- package/data/docs/types/RadioInputRoot.json +514 -0
- package/data/docs/types/RangeCalendar.json +618 -0
- package/data/docs/types/RichTextInput.json +134 -0
- package/data/docs/types/Root.json +122 -0
- package/data/docs/types/Row.json +67 -0
- package/data/docs/types/ScopedSearchInput.isEmpty.json +40 -0
- package/data/docs/types/ScopedSearchInput.json +253 -0
- package/data/docs/types/ScrollArea.json +82 -0
- package/data/docs/types/SearchInput.json +1165 -0
- package/data/docs/types/SearchInputField.json +1240 -0
- package/data/docs/types/Select.json +12 -0
- package/data/docs/types/SelectOption.json +572 -0
- package/data/docs/types/SelectOptionGroup.json +215 -0
- package/data/docs/types/SelectOptions.json +693 -0
- package/data/docs/types/SelectRoot.json +926 -0
- package/data/docs/types/Separator.json +65 -0
- package/data/docs/types/SimpleGrid.json +291 -0
- package/data/docs/types/Spacer.json +27 -0
- package/data/docs/types/SpacerProps.json +9 -0
- package/data/docs/types/SplitButton.json +203 -0
- package/data/docs/types/Stack.json +144 -0
- package/data/docs/types/Steps.json +12 -0
- package/data/docs/types/StepsChangeDetails.json +9 -0
- package/data/docs/types/StepsCompletedContent.json +28 -0
- package/data/docs/types/StepsCompletedContentProps.json +9 -0
- package/data/docs/types/StepsContent.json +43 -0
- package/data/docs/types/StepsContentProps.json +9 -0
- package/data/docs/types/StepsDescription.json +28 -0
- package/data/docs/types/StepsDescriptionProps.json +9 -0
- package/data/docs/types/StepsIndicator.json +28 -0
- package/data/docs/types/StepsIndicatorProps.json +9 -0
- package/data/docs/types/StepsItem.json +43 -0
- package/data/docs/types/StepsItemProps.json +9 -0
- package/data/docs/types/StepsList.json +28 -0
- package/data/docs/types/StepsListProps.json +9 -0
- package/data/docs/types/StepsNextTrigger.json +62 -0
- package/data/docs/types/StepsNextTriggerProps.json +9 -0
- package/data/docs/types/StepsNumber.json +28 -0
- package/data/docs/types/StepsNumberProps.json +9 -0
- package/data/docs/types/StepsPrevTrigger.json +62 -0
- package/data/docs/types/StepsPrevTriggerProps.json +9 -0
- package/data/docs/types/StepsRoot.json +183 -0
- package/data/docs/types/StepsRootProps.json +11 -0
- package/data/docs/types/StepsSeparator.json +28 -0
- package/data/docs/types/StepsSeparatorProps.json +9 -0
- package/data/docs/types/StepsStatus.json +57 -0
- package/data/docs/types/StepsStatusProps.json +9 -0
- package/data/docs/types/StepsTitle.json +28 -0
- package/data/docs/types/StepsTitleProps.json +9 -0
- package/data/docs/types/StepsTrigger.json +47 -0
- package/data/docs/types/StepsTriggerProps.json +9 -0
- package/data/docs/types/Switch.json +371 -0
- package/data/docs/types/TabListProps.json +9 -0
- package/data/docs/types/TabNav.json +12 -0
- package/data/docs/types/TabNavItem.json +300 -0
- package/data/docs/types/TabNavItemProps.json +9 -0
- package/data/docs/types/TabNavProps.json +9 -0
- package/data/docs/types/TabNavRoot.json +80 -0
- package/data/docs/types/TabPanelProps.json +9 -0
- package/data/docs/types/TabPanelsProps.json +9 -0
- package/data/docs/types/TabProps.json +9 -0
- package/data/docs/types/Table.json +9 -0
- package/data/docs/types/TableBody.json +67 -0
- package/data/docs/types/TableBodyProps.json +9 -0
- package/data/docs/types/TableCaption.json +67 -0
- package/data/docs/types/TableCaptionProps.json +9 -0
- package/data/docs/types/TableCell.json +227 -0
- package/data/docs/types/TableCellProps.json +9 -0
- package/data/docs/types/TableColumn.json +101 -0
- package/data/docs/types/TableColumnGroup.json +101 -0
- package/data/docs/types/TableColumnGroupProps.json +9 -0
- package/data/docs/types/TableColumnHeader.json +193 -0
- package/data/docs/types/TableColumnHeaderProps.json +9 -0
- package/data/docs/types/TableColumnProps.json +9 -0
- package/data/docs/types/TableFooter.json +67 -0
- package/data/docs/types/TableFooterProps.json +9 -0
- package/data/docs/types/TableHeader.json +67 -0
- package/data/docs/types/TableHeaderProps.json +9 -0
- package/data/docs/types/TableRoot.json +365 -0
- package/data/docs/types/TableRootProps.json +12 -0
- package/data/docs/types/TableRow.json +67 -0
- package/data/docs/types/TableRowProps.json +9 -0
- package/data/docs/types/TableScrollArea.json +82 -0
- package/data/docs/types/TableScrollAreaProps.json +9 -0
- package/data/docs/types/Tabs.json +12 -0
- package/data/docs/types/TabsList.json +110 -0
- package/data/docs/types/TabsPanel.json +112 -0
- package/data/docs/types/TabsPanels.json +108 -0
- package/data/docs/types/TabsRoot.json +211 -0
- package/data/docs/types/TabsTab.json +174 -0
- package/data/docs/types/TagGroup.json +12 -0
- package/data/docs/types/TagGroupRoot.json +306 -0
- package/data/docs/types/TagGroupTag.json +595 -0
- package/data/docs/types/TagGroupTagList.json +166 -0
- package/data/docs/types/Text.json +119 -0
- package/data/docs/types/TextInput.json +1156 -0
- package/data/docs/types/TextInputField.json +1263 -0
- package/data/docs/types/TimeInput.json +752 -0
- package/data/docs/types/ToastAction.json +9 -0
- package/data/docs/types/ToastManagerApi.json +9 -0
- package/data/docs/types/ToastOptions.json +9 -0
- package/data/docs/types/ToastOutlet.json +12 -0
- package/data/docs/types/ToastPlacement.json +9 -0
- package/data/docs/types/ToastPromiseOptions.json +9 -0
- package/data/docs/types/ToastType.json +9 -0
- package/data/docs/types/ToastVariant.json +9 -0
- package/data/docs/types/ToggleButton.json +789 -0
- package/data/docs/types/ToggleButtonGroup.json +9 -0
- package/data/docs/types/ToggleButtonGroupButton.json +331 -0
- package/data/docs/types/ToggleButtonGroupRoot.json +269 -0
- package/data/docs/types/Toolbar.json +176 -0
- package/data/docs/types/Tooltip.json +12 -0
- package/data/docs/types/TooltipContent.json +372 -0
- package/data/docs/types/TooltipRoot.json +179 -0
- package/data/docs/types/Trigger.json +69 -0
- package/data/docs/types/VisuallyHidden.json +93 -0
- package/data/docs/types/__object.json +12 -0
- package/data/docs/types/filters.json +11 -0
- package/data/docs/types/manifest.json +278 -0
- package/data/docs/types/toast.json +234 -0
- package/data/docs/types/useColorMode.json +13 -0
- package/data/docs/types/useColorModeValue.json +13 -0
- package/data/docs/types/useColorScheme.json +12 -0
- package/data/docs/types/useLocalizedStringFormatter.json +14 -0
- package/data/icons.json +21940 -0
- package/data/tokens.json +40061 -0
- package/dist/index.js +2516 -17
- package/package.json +25 -6
- package/dist/data-loader.d.ts +0 -102
- package/dist/data-loader.js +0 -104
- package/dist/index.d.ts +0 -13
- package/dist/server.d.ts +0 -9
- package/dist/server.js +0 -22
- package/dist/server.spec.d.ts +0 -1
- package/dist/server.spec.js +0 -69
- package/dist/tools/list-components.d.ts +0 -9
- package/dist/tools/list-components.js +0 -42
- package/dist/types.d.ts +0 -28
- package/dist/types.js +0 -4
- package/src/data-loader.ts +0 -226
- package/src/index.ts +0 -29
- package/src/server.spec.ts +0 -86
- package/src/server.ts +0 -28
- package/src/tools/list-components.ts +0 -49
- package/src/types.ts +0 -31
- package/tsconfig.json +0 -14
- package/vitest.config.ts +0 -9
|
@@ -0,0 +1,709 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"id": "Components-DatePicker",
|
|
4
|
+
"title": "Date picker",
|
|
5
|
+
"exportName": "DatePicker",
|
|
6
|
+
"description": "A date picker is a UI component for users to input or select a specific calendar date.",
|
|
7
|
+
"lifecycleState": "Stable",
|
|
8
|
+
"order": 999,
|
|
9
|
+
"repoPath": "packages/nimbus/src/components/date-picker/date-picker.mdx",
|
|
10
|
+
"menu": [
|
|
11
|
+
"Components",
|
|
12
|
+
"Inputs",
|
|
13
|
+
"Date picker"
|
|
14
|
+
],
|
|
15
|
+
"route": "components/inputs/date-picker",
|
|
16
|
+
"tags": [
|
|
17
|
+
"component",
|
|
18
|
+
"date",
|
|
19
|
+
"calendar"
|
|
20
|
+
],
|
|
21
|
+
"toc": [
|
|
22
|
+
{
|
|
23
|
+
"value": "Overview",
|
|
24
|
+
"href": "#overview",
|
|
25
|
+
"depth": 2,
|
|
26
|
+
"numbering": [
|
|
27
|
+
1,
|
|
28
|
+
1
|
|
29
|
+
],
|
|
30
|
+
"parent": "root"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"value": "Resources",
|
|
34
|
+
"href": "#resources",
|
|
35
|
+
"depth": 3,
|
|
36
|
+
"numbering": [
|
|
37
|
+
1,
|
|
38
|
+
1,
|
|
39
|
+
1
|
|
40
|
+
],
|
|
41
|
+
"parent": "root"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"value": "Variables",
|
|
45
|
+
"href": "#variables",
|
|
46
|
+
"depth": 2,
|
|
47
|
+
"numbering": [
|
|
48
|
+
1,
|
|
49
|
+
2
|
|
50
|
+
],
|
|
51
|
+
"parent": "root"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"value": "Visual options",
|
|
55
|
+
"href": "#visual-options",
|
|
56
|
+
"depth": 3,
|
|
57
|
+
"numbering": [
|
|
58
|
+
1,
|
|
59
|
+
2,
|
|
60
|
+
1
|
|
61
|
+
],
|
|
62
|
+
"parent": "root"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"value": "Medium",
|
|
66
|
+
"href": "#medium",
|
|
67
|
+
"depth": 4,
|
|
68
|
+
"numbering": [
|
|
69
|
+
1,
|
|
70
|
+
2,
|
|
71
|
+
1,
|
|
72
|
+
1
|
|
73
|
+
],
|
|
74
|
+
"parent": "root"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"value": "Small",
|
|
78
|
+
"href": "#small",
|
|
79
|
+
"depth": 4,
|
|
80
|
+
"numbering": [
|
|
81
|
+
1,
|
|
82
|
+
2,
|
|
83
|
+
1,
|
|
84
|
+
2
|
|
85
|
+
],
|
|
86
|
+
"parent": "root"
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"layout": "app-frame",
|
|
90
|
+
"tabs": [
|
|
91
|
+
{
|
|
92
|
+
"key": "overview",
|
|
93
|
+
"title": "Overview",
|
|
94
|
+
"order": 0
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"key": "guidelines",
|
|
98
|
+
"title": "Guidelines",
|
|
99
|
+
"order": 2
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"key": "dev",
|
|
103
|
+
"title": "Implementation",
|
|
104
|
+
"order": 3
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"key": "a11y",
|
|
108
|
+
"title": "Accessibility",
|
|
109
|
+
"order": 4
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
"mdx": "\n## Overview\n\nDate picker can be simple or complex, allowing users to select a single date and\nor specific times. There are two offered sizes, the default being medium for\nmost use cases.\n\n### Resources\n\nDeep dive into implementation details and access the Nimbus design library.\n\n[Figma library](https://www.figma.com/design/AvtPX6g7OGGCRvNlatGOIY/NIMBUS-design-system?node-id=2923-4379&m=dev)\n\n## Variables\n\nGet familiar with the features.\n\n### Visual options\n\n#### Medium\n\n```jsx live\n const App = () => <DatePicker size=\"md\" aria-label=\"Enter a date\" width=\"1/3\" />\n```\n\n#### Small\n\n```jsx live\n const App = () => <DatePicker size=\"sm\" aria-label=\"Enter a date\" width=\"1/3\" />\n```\n",
|
|
114
|
+
"views": {
|
|
115
|
+
"overview": {
|
|
116
|
+
"mdx": "\n## Overview\n\nDate picker can be simple or complex, allowing users to select a single date and\nor specific times. There are two offered sizes, the default being medium for\nmost use cases.\n\n### Resources\n\nDeep dive into implementation details and access the Nimbus design library.\n\n[Figma library](https://www.figma.com/design/AvtPX6g7OGGCRvNlatGOIY/NIMBUS-design-system?node-id=2923-4379&m=dev)\n\n## Variables\n\nGet familiar with the features.\n\n### Visual options\n\n#### Medium\n\n```jsx live\n const App = () => <DatePicker size=\"md\" aria-label=\"Enter a date\" width=\"1/3\" />\n```\n\n#### Small\n\n```jsx live\n const App = () => <DatePicker size=\"sm\" aria-label=\"Enter a date\" width=\"1/3\" />\n```\n",
|
|
117
|
+
"toc": [
|
|
118
|
+
{
|
|
119
|
+
"value": "Overview",
|
|
120
|
+
"href": "#overview",
|
|
121
|
+
"depth": 2,
|
|
122
|
+
"numbering": [
|
|
123
|
+
1,
|
|
124
|
+
1
|
|
125
|
+
],
|
|
126
|
+
"parent": "root"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"value": "Resources",
|
|
130
|
+
"href": "#resources",
|
|
131
|
+
"depth": 3,
|
|
132
|
+
"numbering": [
|
|
133
|
+
1,
|
|
134
|
+
1,
|
|
135
|
+
1
|
|
136
|
+
],
|
|
137
|
+
"parent": "root"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"value": "Variables",
|
|
141
|
+
"href": "#variables",
|
|
142
|
+
"depth": 2,
|
|
143
|
+
"numbering": [
|
|
144
|
+
1,
|
|
145
|
+
2
|
|
146
|
+
],
|
|
147
|
+
"parent": "root"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"value": "Visual options",
|
|
151
|
+
"href": "#visual-options",
|
|
152
|
+
"depth": 3,
|
|
153
|
+
"numbering": [
|
|
154
|
+
1,
|
|
155
|
+
2,
|
|
156
|
+
1
|
|
157
|
+
],
|
|
158
|
+
"parent": "root"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"value": "Medium",
|
|
162
|
+
"href": "#medium",
|
|
163
|
+
"depth": 4,
|
|
164
|
+
"numbering": [
|
|
165
|
+
1,
|
|
166
|
+
2,
|
|
167
|
+
1,
|
|
168
|
+
1
|
|
169
|
+
],
|
|
170
|
+
"parent": "root"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"value": "Small",
|
|
174
|
+
"href": "#small",
|
|
175
|
+
"depth": 4,
|
|
176
|
+
"numbering": [
|
|
177
|
+
1,
|
|
178
|
+
2,
|
|
179
|
+
1,
|
|
180
|
+
2
|
|
181
|
+
],
|
|
182
|
+
"parent": "root"
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
},
|
|
186
|
+
"a11y": {
|
|
187
|
+
"mdx": "\n## Accessibility\n\nAccessibility ensures that digital content and functionality are usable by\neveryone, including people with disabilities, by addressing visual, auditory,\ncognitive, and physical limitations.\n\n```jsx live\nconst App = () => <DatePicker aria-label=\"Enter a date\" />\n```\n\n### Accessibility standards\n\n- Always provide a visible label for the input.\n- Clearly associate the label with the input using the for attribute on the\n `<label>` and a matching id on the input element.\n- Ensure sufficient color contrast for all elements (text, borders, icons, focus\n indicators).\n- Clearly indicate the focused state.\n- Support keyboard navigation:\n- Use Tab to navigate to and from the date input.\n- Use Enter or Space to open/close the date picker (if applicable).\n- Use arrow keys to navigate within the calendar grid (if a date picker is\n provided).\n- Allow users to select dates using Enter or Space.\n- Communicate errors clearly, using both visual cues (e.g., color) and\n descriptive error messages.\n- Provide clear instructions on the expected date format (e.g., MM/DD/YYYY).\n- Ensure screen readers announce the selected date and any navigation changes\n within a date picker.\n- Provide an accessible way to clear the date input.\n\n### Resources\n\n- [React Spectrum](https://react-spectrum.adobe.com/react-spectrum/DatePicker.html)\n- [W3C ARIA Authoring Practices Guide (APG)](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/)\n",
|
|
188
|
+
"toc": [
|
|
189
|
+
{
|
|
190
|
+
"value": "Accessibility",
|
|
191
|
+
"href": "#accessibility",
|
|
192
|
+
"depth": 2,
|
|
193
|
+
"numbering": [
|
|
194
|
+
1,
|
|
195
|
+
1
|
|
196
|
+
],
|
|
197
|
+
"parent": "root"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"value": "Accessibility standards",
|
|
201
|
+
"href": "#accessibility-standards",
|
|
202
|
+
"depth": 3,
|
|
203
|
+
"numbering": [
|
|
204
|
+
1,
|
|
205
|
+
1,
|
|
206
|
+
1
|
|
207
|
+
],
|
|
208
|
+
"parent": "root"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"value": "Resources",
|
|
212
|
+
"href": "#resources",
|
|
213
|
+
"depth": 3,
|
|
214
|
+
"numbering": [
|
|
215
|
+
1,
|
|
216
|
+
1,
|
|
217
|
+
2
|
|
218
|
+
],
|
|
219
|
+
"parent": "root"
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
"dev": {
|
|
224
|
+
"mdx": "\n## Getting started\n\n### Import\n\n```tsx\nimport { DatePicker, type DatePickerProps } from '@commercetools/nimbus';\n```\n\n### Basic usage\n\nThe simplest implementation uses uncontrolled mode with an accessible label:\n\n```jsx live-dev\nconst App = () => (\n <DatePicker aria-label=\"Select a date\" />\n)\n```\n\n## Working with date values\n\nThe DatePicker component relies on [`@internationalized/date`](https://react-spectrum.adobe.com/internationalized/date/)'s date types for type-safe date handling. This library provides calendar-system-aware date representations that work correctly across different locales and time zones.\n\n### Date types\n\nThe library provides several date types, each with different levels of precision:\n\n```tsx\nimport { CalendarDate, CalendarDateTime, ZonedDateTime } from '@internationalized/date';\n\n// Date only (no time component)\nconst date = new CalendarDate(\n 2025, // year\n 6, // month (1-12)\n 15 // day\n);\n\n// Date and time (no timezone)\nconst dateTime = new CalendarDateTime(\n 2025, // year\n 6, // month (1-12)\n 15, // day\n 14, // hour (0-23)\n 30, // minute (0-59)\n 0 // second (0-59)\n);\n\n// Date, time, and timezone\nconst zonedDateTime = new ZonedDateTime(\n 2025, // year\n 6, // month (1-12)\n 15, // day\n 'America/New_York', // IANA time zone identifier\n -4 * 60 * 60 * 1000, // offset in milliseconds (EDT: -4 hours)\n 14, // hour (0-23)\n 30, // minute (0-59)\n 0 // second (0-59)\n);\n```\n\n### Creating date values\n\nUse the appropriate constructor based on the precision you need:\n\n```tsx\nimport { CalendarDate, CalendarDateTime } from '@internationalized/date';\n\n// For date-only pickers\nconst birthDate = new CalendarDate(1990, 5, 15);\n\n// For date and time pickers\nconst appointmentTime = new CalendarDateTime(2025, 12, 25, 10, 30, 0);\n```\n\n### Converting to strings\n\nUse the `toString()` method to convert date values to ISO 8601 format:\n\n```tsx\nconst date = new CalendarDate(2025, 6, 15);\ndate.toString(); // \"2025-06-15\"\n\nconst dateTime = new CalendarDateTime(2025, 6, 15, 14, 30, 0);\ndateTime.toString(); // \"2025-06-15T14:30:00\"\n```\n\n> [!TIP]\\\n> See [@internationalized/date documentation](https://react-spectrum.adobe.com/internationalized/date/) for complete API reference and advanced usage.\n\n## Usage examples\n\n### Size options\n\nThe `sm` and `md` size variants are available to match your interface density:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <DatePicker size=\"sm\" aria-label=\"Small date picker\" />\n <DatePicker size=\"md\" aria-label=\"Medium date picker\" />\n </Stack>\n)\n```\n\n### Visual variants\n\nChoose between `solid` and `ghost` variants to match your design context:\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <DatePicker variant=\"solid\" aria-label=\"Solid variant\" />\n <DatePicker variant=\"ghost\" aria-label=\"Ghost variant\" />\n </Stack>\n)\n```\n\n**Behavioral differences:**\n- `variant=\"solid\"`: Outlined input with background, suitable for forms\n- `variant=\"ghost\"`: Subtle background on hover, suitable for inline editing\n\n### Granularity control\n\nThe `granularity` prop controls which date/time segments are displayed and whether the calendar popover automatically closes on selection:\n\n```jsx live-dev\nimport { CalendarDate, CalendarDateTime } from '@internationalized/date';\n\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Day (date only - closes on select)</Text>\n <DatePicker\n granularity=\"day\"\n defaultValue={new CalendarDate(2025, 6, 15)}\n aria-label=\"Day granularity\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Hour (date + hour - stays open for time)</Text>\n <DatePicker\n granularity=\"hour\"\n defaultValue={new CalendarDateTime(2025, 6, 15, 14, 0, 0)}\n aria-label=\"Hour granularity\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Minute (date + hour + minute - stays open)</Text>\n <DatePicker\n granularity=\"minute\"\n defaultValue={new CalendarDateTime(2025, 6, 15, 14, 30, 0)}\n aria-label=\"Minute granularity\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Second (full precision - stays open)</Text>\n <DatePicker\n granularity=\"second\"\n defaultValue={new CalendarDateTime(2025, 6, 15, 14, 30, 45)}\n aria-label=\"Second granularity\"\n />\n </Stack>\n </Stack>\n)\n```\n\n**Automatic close behavior:**\n- When `granularity=\"day\"` (date only): Calendar closes automatically after selecting a date\n- When time is included (hour, minute, second): Calendar stays open so users can set both date and time\n\n### Hour cycle\n\nControl the time display format using the `hourCycle` prop when working with time values:\n\n```jsx live-dev\nimport { CalendarDateTime } from '@internationalized/date';\n\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">12-hour format (2:30 PM)</Text>\n <DatePicker\n defaultValue={new CalendarDateTime(2025, 6, 15, 14, 30, 0)}\n hourCycle={12}\n granularity=\"minute\"\n aria-label=\"12-hour format\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">24-hour format (14:30)</Text>\n <DatePicker\n defaultValue={new CalendarDateTime(2025, 6, 15, 14, 30, 0)}\n hourCycle={24}\n granularity=\"minute\"\n aria-label=\"24-hour format\"\n />\n </Stack>\n </Stack>\n)\n```\n\n### Time zone handling\n\nWhen using `ZonedDateTime` values, control time zone display with the `hideTimeZone` prop:\n\n```jsx live-dev\nimport { ZonedDateTime } from '@internationalized/date';\n\nconst App = () => {\n const zonedDateTime = new ZonedDateTime(\n 2025, // year\n 6, // month (1-12)\n 15, // day\n 'America/New_York', // IANA time zone identifier\n -4 * 60 * 60 * 1000, // offset in milliseconds (EDT: -4 hours)\n 14, // hour (0-23)\n 30, // minute (0-59)\n 0 // second (0-59)\n );\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">With time zone displayed</Text>\n <DatePicker\n defaultValue={zonedDateTime}\n hideTimeZone={false}\n granularity=\"minute\"\n aria-label=\"Date with timezone\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Time zone hidden</Text>\n <DatePicker\n defaultValue={zonedDateTime}\n hideTimeZone={true}\n granularity=\"minute\"\n aria-label=\"Date without timezone\"\n />\n </Stack>\n </Stack>\n );\n}\n```\n\n### Placeholder values\n\nSet a starting point for keyboard input when the field is empty using `placeholderValue`:\n\n```jsx live-dev\nimport { CalendarDate } from '@internationalized/date';\n\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">With placeholder (starts at 2025-06-15)</Text>\n <DatePicker\n placeholderValue={new CalendarDate(2025, 6, 15)}\n aria-label=\"Date with placeholder\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Without placeholder (starts at today)</Text>\n <DatePicker aria-label=\"Date without placeholder\" />\n </Stack>\n </Stack>\n)\n```\n\n### Close on select behavior\n\nControl whether the calendar closes automatically after date selection using `shouldCloseOnSelect`:\n\n```jsx live-dev\nimport { CalendarDate } from '@internationalized/date';\n\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Auto-close enabled (default for day granularity)</Text>\n <DatePicker\n granularity=\"day\"\n shouldCloseOnSelect={true}\n aria-label=\"Auto-close picker\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Auto-close disabled (stays open)</Text>\n <DatePicker\n granularity=\"day\"\n shouldCloseOnSelect={false}\n aria-label=\"Manual close picker\"\n />\n </Stack>\n </Stack>\n)\n```\n\n**Note:** When `granularity` includes time (hour, minute, second), `shouldCloseOnSelect` is automatically set to `false` to allow users to set both date and time.\n\n### Min/max validation\n\nRestrict date selection to a specific range using `minValue` and `maxValue`:\n\n```jsx live-dev\nimport { CalendarDate } from '@internationalized/date';\n\nconst App = () => {\n const [date, setDate] = useState(null);\n const minDate = new CalendarDate(2025, 6, 1);\n const maxDate = new CalendarDate(2025, 6, 30);\n \n const isInvalid = date && (\n date.compare(minDate) < 0 || \n date.compare(maxDate) > 0\n );\n\n return (\n <FormField.Root isInvalid={!!isInvalid}>\n <FormField.Label>Select a date in June 2025</FormField.Label>\n <FormField.Input>\n <DatePicker\n value={date}\n onChange={setDate}\n minValue={minDate}\n maxValue={maxDate}\n aria-label=\"Date range validation\"\n />\n </FormField.Input>\n <FormField.Description>\n Valid range: June 1-30, 2025\n </FormField.Description>\n {isInvalid && (\n <FormField.Error>\n Date must be between {minDate.toString()} and {maxDate.toString()}\n </FormField.Error>\n )}\n </FormField.Root>\n );\n}\n```\n\n### State variations\n\nDatePicker supports disabled, read-only, required, and invalid states:\n\n```jsx live-dev\nimport { CalendarDate } from '@internationalized/date';\n\nconst App = () => (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Default</Text>\n <DatePicker\n defaultValue={new CalendarDate(2025, 6, 15)}\n aria-label=\"Default state\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Disabled</Text>\n <DatePicker\n defaultValue={new CalendarDate(2025, 6, 15)}\n isDisabled\n aria-label=\"Disabled state\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Read-only</Text>\n <DatePicker\n defaultValue={new CalendarDate(2025, 6, 15)}\n isReadOnly\n aria-label=\"Read-only state\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Required</Text>\n <DatePicker\n isRequired\n aria-label=\"Required state\"\n />\n </Stack>\n <Stack direction=\"column\" gap=\"100\">\n <Text fontSize=\"sm\" fontWeight=\"600\">Invalid</Text>\n <DatePicker\n defaultValue={new CalendarDate(2025, 6, 15)}\n isInvalid\n aria-label=\"Invalid state\"\n />\n </Stack>\n </Stack>\n)\n```\n\n### Uncontrolled mode\n\nFor simpler use cases, use uncontrolled mode with `defaultValue` and `onChange`:\n\n```jsx live-dev\nimport { CalendarDate, type DateValue } from '@internationalized/date';\n\nconst App = () => {\n const [displayValue, setDisplayValue] = useState('No date selected');\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <DatePicker\n defaultValue={new CalendarDate(2025, 6, 15)}\n onChange={(value: DateValue | null) => {\n setDisplayValue(value ? value.toString() : 'No date selected');\n }}\n aria-label=\"Uncontrolled date picker\"\n />\n <Text fontSize=\"sm\">Selected: {displayValue}</Text>\n </Stack>\n );\n}\n```\n\nUse uncontrolled mode when you need to capture the selected date without managing state yourself.\n\n### Controlled mode\n\nFor scenarios requiring programmatic control or coordination with other components, use controlled mode:\n\n```jsx live-dev\nimport { CalendarDate, type DateValue } from '@internationalized/date';\n\nconst App = () => {\n const [value, setValue] = useState<DateValue | null>(new CalendarDate(2025, 6, 15));\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <DatePicker\n value={value}\n onChange={setValue}\n aria-label=\"Controlled date picker\"\n />\n <Text fontSize=\"sm\">\n {value ? `Selected: ${value.toString()}` : 'No selection'}\n </Text>\n <Stack direction=\"row\" gap=\"200\">\n <Button onPress={() => setValue(new CalendarDate(2025, 1, 1))}>\n Set to Jan 1\n </Button>\n <Button onPress={() => setValue(new CalendarDate(2025, 12, 31))}>\n Set to Dec 31\n </Button>\n <Button onPress={() => setValue(null)}>\n Clear\n </Button>\n </Stack>\n </Stack>\n );\n}\n```\n\nUse controlled mode when you need to:\n- Synchronize the value with external state\n- Validate or transform selections\n- Clear or programmatically set the value\n\n### Popover control\n\nControl the calendar popover's open state programmatically:\n\n```jsx live-dev\nimport { CalendarDate } from '@internationalized/date';\n\nconst App = () => {\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <DatePicker\n defaultValue={new CalendarDate(2025, 6, 15)}\n isOpen={isOpen}\n onOpenChange={setIsOpen}\n aria-label=\"Controlled popover\"\n />\n <Text fontSize=\"sm\">Popover is {isOpen ? 'open' : 'closed'}</Text>\n <Stack direction=\"row\" gap=\"200\">\n <Button onPress={() => setIsOpen(true)}>\n Open Calendar\n </Button>\n <Button onPress={() => setIsOpen(false)}>\n Close Calendar\n </Button>\n </Stack>\n </Stack>\n );\n}\n```\n\n### Internationalization\n\nDatePicker automatically adapts to different locales when wrapped with `NimbusI18nProvider`:\n\n```jsx live-dev\nimport { CalendarDate } from '@internationalized/date';\n\nconst App = () => {\n const [locale, setLocale] = useState('en-US');\n const dateValue = new CalendarDate(2025, 6, 15);\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Stack direction=\"row\" gap=\"200\">\n <Button\n variant={locale === 'en-US' ? 'solid' : 'outline'}\n onPress={() => setLocale('en-US')}\n >\n English (US)\n </Button>\n <Button\n variant={locale === 'de-DE' ? 'solid' : 'outline'}\n onPress={() => setLocale('de-DE')}\n >\n German\n </Button>\n <Button\n variant={locale === 'ja-JP' ? 'solid' : 'outline'}\n onPress={() => setLocale('ja-JP')}\n >\n Japanese\n </Button>\n </Stack>\n <NimbusI18nProvider locale={locale}>\n <DatePicker\n defaultValue={dateValue}\n aria-label=\"Localized date picker\"\n />\n </NimbusI18nProvider>\n <Text fontSize=\"sm\">Current locale: {locale}</Text>\n </Stack>\n );\n}\n```\n\n## Component requirements\n\n### Date value requirements\n\nAll date values **must** use `@internationalized/date` types:\n- `CalendarDate` for date-only pickers (year, month, day)\n- `CalendarDateTime` for date and time without timezone\n- `ZonedDateTime` for date, time, and timezone information\n\n## Accessibility\n\nThe DatePicker handles most accessibility requirements internally through React Aria's DatePicker. However, you must always associate an internationalized label with the component. Visual labels are preferable, and can be set by:\n\n- Wrapping the DatePicker in a FormField (recommended for forms):\n\n```tsx\n<FormField.Root>\n <FormField.Label>Birth Date</FormField.Label>\n <FormField.Input>\n <DatePicker />\n </FormField.Input>\n</FormField.Root>\n```\n\n- Associating a `<label>` element with the DatePicker using `aria-labelledby`:\n\n```tsx\n<label id=\"label-id\">\n {msg.format(labelMessage)}\n</label>\n<DatePicker aria-labelledby=\"label-id\" />\n```\n\nIf your design requires that the label should not be visible, the label should be set using the `aria-label` prop:\n\n```tsx\n<DatePicker aria-label={msg.format(labelMessage)} />\n```\n\nIf your use case requires tracking and analytics for this component, it is good practice to add a **persistent**, **unique** id to the component:\n\n```tsx\nconst PERSISTENT_ID = \"example-date-picker\";\n\nexport const Example = () => (\n <DatePicker id={PERSISTENT_ID} aria-label=\"Enter date\" />\n);\n```\n\n#### Keyboard navigation\n\nThe component supports full keyboard interaction for navigating and editing date segments, as well as calendar navigation:\n\n**Date input segments:**\n- `Tab` / `Shift+Tab`: Move between date segments (day, month, year, hour, etc.)\n- `Arrow Up` / `Arrow Down`: Increment or decrement the focused segment\n- `Page Up` / `Page Down`: Increment or decrement the focused segment by larger steps\n- `Home` / `End`: Set segment to minimum or maximum value\n- `0-9`: Type digits to set segment value\n- `Backspace`: Clear the focused segment\n\n**Calendar button:**\n- `Enter` / `Space`: Open the calendar popover\n\n**Calendar navigation:**\n- `Arrow keys`: Navigate between dates\n- `Enter` / `Space`: Select the focused date\n- `Page Up` / `Page Down`: Navigate by month\n- `Shift + Page Up` / `Shift + Page Down`: Navigate by year\n- `Home` / `End`: Navigate to start/end of row\n- `Escape`: Close the calendar popover\n\n## API reference\n\n<PropsTable id=\"DatePicker\" />\n\n## Common patterns\n\n### Appointment scheduler\n\nA pattern for scheduling appointments with date and time selection:\n\n```jsx live-dev\nimport { CalendarDateTime, type DateValue } from '@internationalized/date';\n\nconst App = () => {\n const [appointmentTime, setAppointmentTime] = useState<DateValue | null>(\n new CalendarDateTime(2025, 12, 15, 10, 0, 0)\n );\n \n const businessHoursStart = 9;\n const businessHoursEnd = 17;\n \n const isInvalidTime = appointmentTime && \n 'hour' in appointmentTime && (\n appointmentTime.hour < businessHoursStart || \n appointmentTime.hour >= businessHoursEnd\n );\n\n return (\n <FormField.Root isInvalid={isInvalidTime}>\n <FormField.Label>Appointment Time</FormField.Label>\n <FormField.Input>\n <DatePicker\n value={appointmentTime}\n onChange={setAppointmentTime}\n granularity=\"minute\"\n hourCycle={12}\n aria-label=\"Appointment time\"\n />\n </FormField.Input>\n <FormField.Description>\n Select a date and time between 9:00 AM and 5:00 PM\n </FormField.Description>\n {isInvalidTime && (\n <FormField.Error>\n Please select a time during business hours (9 AM - 5 PM)\n </FormField.Error>\n )}\n {appointmentTime && !isInvalidTime && (\n <Text fontSize=\"sm\" mt=\"200\">\n ✅ Appointment scheduled for {appointmentTime.toString()}\n </Text>\n )}\n </FormField.Root>\n );\n}\n```\n\n### Due date selector\n\nPattern for setting due dates with past date validation:\n\n```jsx live-dev\nimport { CalendarDate, today, getLocalTimeZone, type DateValue } from '@internationalized/date';\n\nconst App = () => {\n const [dueDate, setDueDate] = useState<DateValue | null>(null);\n const todayDate = today(getLocalTimeZone());\n \n const isInvalid = dueDate && dueDate.compare(todayDate) < 0;\n\n return (\n <FormField.Root isInvalid={!!isInvalid}>\n <FormField.Label>Task Due Date</FormField.Label>\n <FormField.Input>\n <DatePicker\n value={dueDate}\n onChange={setDueDate}\n minValue={todayDate}\n placeholderValue={todayDate}\n aria-label=\"Due date\"\n />\n </FormField.Input>\n <FormField.Description>\n Select a future date for task completion\n </FormField.Description>\n {isInvalid && (\n <FormField.Error>\n Due date cannot be in the past\n </FormField.Error>\n )}\n </FormField.Root>\n );\n}\n```\n\n### Event date selector\n\nPattern for selecting event dates with a reasonable range:\n\n```jsx live-dev\nimport { CalendarDate, today, getLocalTimeZone, type DateValue } from '@internationalized/date';\n\nconst App = () => {\n const [eventDate, setEventDate] = useState<DateValue | null>(null);\n const todayDate = today(getLocalTimeZone());\n const maxDate = todayDate.add({ years: 2 });\n\n return (\n <FormField.Root>\n <FormField.Label>Event Date</FormField.Label>\n <FormField.Input>\n <DatePicker\n value={eventDate}\n onChange={setEventDate}\n minValue={todayDate}\n maxValue={maxDate}\n placeholderValue={todayDate.add({ months: 1 })}\n aria-label=\"Event date\"\n />\n </FormField.Input>\n <FormField.Description>\n Select a date within the next 2 years\n </FormField.Description>\n {eventDate && (\n <Text fontSize=\"sm\" mt=\"200\">\n Event scheduled for {eventDate.toString()}\n </Text>\n )}\n </FormField.Root>\n );\n}\n```\n\n## Testing your implementation\n\nThese examples demonstrate how to test your implementation when using DatePicker within your application. As the component's internal functionality is already tested by Nimbus, these patterns help you verify your integration and application-specific logic.\n\n### Basic Rendering Tests\n\nVerify the DatePicker renders with expected elements and structure\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, within, waitFor } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { DatePicker, NimbusProvider } from \"@commercetools/nimbus\";\nimport { CalendarDate, CalendarDateTime } from \"@internationalized/date\";\n\ndescribe(\"DatePicker - Basic rendering\", () => {\n it(\"renders with proper structure and accessibility\", () => {\n render(\n <NimbusProvider>\n <DatePicker aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const dateGroup = screen.getByRole(\"group\", { name: \"Select a date\" });\n expect(dateGroup).toBeInTheDocument();\n expect(dateGroup).toHaveAttribute(\"aria-label\", \"Select a date\");\n });\n\n it(\"renders date input segments\", () => {\n render(\n <NimbusProvider>\n <DatePicker aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n expect(dateSegments.length).toBeGreaterThanOrEqual(3);\n });\n\n it(\"renders calendar toggle button\", () => {\n render(\n <NimbusProvider>\n <DatePicker aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const calendarButton = screen.getByRole(\"button\", { name: /calendar/i });\n expect(calendarButton).toBeInTheDocument();\n });\n\n it(\"renders with default value\", () => {\n const defaultValue = new CalendarDate(2025, 6, 15);\n\n render(\n <NimbusProvider>\n <DatePicker defaultValue={defaultValue} aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n expect(dateSegments[0]).toHaveAttribute(\"aria-valuenow\", \"6\");\n expect(dateSegments[1]).toHaveAttribute(\"aria-valuenow\", \"15\");\n expect(dateSegments[2]).toHaveAttribute(\"aria-valuenow\", \"2025\");\n });\n});\n```\n\n### Interaction Tests\n\nTest user interactions with date segments and calendar\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, within, waitFor } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { DatePicker, NimbusProvider } from \"@commercetools/nimbus\";\nimport { CalendarDate, CalendarDateTime } from \"@internationalized/date\";\n\ndescribe(\"DatePicker - Interactions\", () => {\n it(\"allows keyboard input in date segments\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <DatePicker aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n const firstSegment = dateSegments[0];\n\n await user.click(firstSegment);\n await user.keyboard(\"12\");\n\n await waitFor(() => {\n expect(firstSegment).toHaveAttribute(\"aria-valuenow\", \"12\");\n });\n });\n\n it(\"opens calendar popover when button is clicked\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <DatePicker aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const calendarButton = screen.getByRole(\"button\", { name: /calendar/i });\n\n expect(\n within(document.body).queryByRole(\"application\")\n ).not.toBeInTheDocument();\n\n await user.click(calendarButton);\n\n await waitFor(() => {\n expect(\n within(document.body).queryByRole(\"application\")\n ).toBeInTheDocument();\n });\n });\n\n it(\"closes calendar popover with Escape key\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <DatePicker aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const calendarButton = screen.getByRole(\"button\", { name: /calendar/i });\n await user.click(calendarButton);\n\n await waitFor(() => {\n expect(\n within(document.body).queryByRole(\"application\")\n ).toBeInTheDocument();\n });\n\n await user.keyboard(\"{Escape}\");\n\n await waitFor(() => {\n expect(\n within(document.body).queryByRole(\"application\")\n ).not.toBeInTheDocument();\n });\n });\n\n it(\"allows date selection from calendar\", async () => {\n const user = userEvent.setup();\n const onChange = vi.fn();\n\n render(\n <NimbusProvider>\n <DatePicker onChange={onChange} aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const calendarButton = screen.getByRole(\"button\", { name: /calendar/i });\n await user.click(calendarButton);\n\n await waitFor(() => {\n expect(\n within(document.body).queryByRole(\"application\")\n ).toBeInTheDocument();\n });\n\n const day5Cell = document.body.querySelector('[aria-label*=\"5,\"]');\n if (day5Cell) {\n await user.click(day5Cell);\n\n await waitFor(() => {\n expect(onChange).toHaveBeenCalled();\n });\n }\n });\n\n it(\"navigates between segments with Tab key\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <DatePicker aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n\n await user.tab();\n\n await waitFor(() => {\n expect(dateSegments[0]).toHaveFocus();\n });\n\n await user.keyboard(\"{ArrowRight}\");\n\n if (dateSegments.length > 1) {\n await waitFor(() => {\n expect(dateSegments[1]).toHaveFocus();\n });\n }\n });\n});\n```\n\n### Controlled Mode Tests\n\nTest controlled component behavior with external state\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, within, waitFor } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { DatePicker, NimbusProvider } from \"@commercetools/nimbus\";\nimport { CalendarDate, CalendarDateTime } from \"@internationalized/date\";\n\ndescribe(\"DatePicker - Controlled mode\", () => {\n it(\"renders controlled value\", () => {\n const value = new CalendarDate(2025, 6, 15);\n\n render(\n <NimbusProvider>\n <DatePicker\n value={value}\n onChange={vi.fn()}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n expect(dateSegments[0]).toHaveAttribute(\"aria-valuenow\", \"6\");\n expect(dateSegments[1]).toHaveAttribute(\"aria-valuenow\", \"15\");\n expect(dateSegments[2]).toHaveAttribute(\"aria-valuenow\", \"2025\");\n });\n\n it(\"calls onChange when date is modified\", async () => {\n const user = userEvent.setup();\n const onChange = vi.fn();\n const value = new CalendarDate(2025, 6, 15);\n\n render(\n <NimbusProvider>\n <DatePicker\n value={value}\n onChange={onChange}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n await user.click(dateSegments[0]);\n await user.keyboard(\"{Control>}a{/Control}\");\n await user.keyboard(\"8\");\n\n await waitFor(() => {\n expect(onChange).toHaveBeenCalled();\n });\n });\n\n it(\"updates when value prop changes\", () => {\n const { rerender } = render(\n <NimbusProvider>\n <DatePicker\n value={new CalendarDate(2025, 6, 15)}\n onChange={vi.fn()}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n expect(dateSegments[0]).toHaveAttribute(\"aria-valuenow\", \"6\");\n\n rerender(\n <NimbusProvider>\n <DatePicker\n value={new CalendarDate(2025, 12, 25)}\n onChange={vi.fn()}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n expect(dateSegments[0]).toHaveAttribute(\"aria-valuenow\", \"12\");\n expect(dateSegments[1]).toHaveAttribute(\"aria-valuenow\", \"25\");\n });\n});\n```\n\n### State Tests\n\nTest different component states (disabled, readonly, required, invalid)\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, within, waitFor } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { DatePicker, NimbusProvider } from \"@commercetools/nimbus\";\nimport { CalendarDate, CalendarDateTime } from \"@internationalized/date\";\n\ndescribe(\"DatePicker - States\", () => {\n it(\"renders in disabled state\", () => {\n render(\n <NimbusProvider>\n <DatePicker\n isDisabled\n defaultValue={new CalendarDate(2025, 6, 15)}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const clearButton = screen.getByRole(\"button\", { name: /clear/i });\n expect(clearButton).toBeDisabled();\n });\n\n it(\"renders in readonly state\", () => {\n render(\n <NimbusProvider>\n <DatePicker\n isReadOnly\n defaultValue={new CalendarDate(2025, 6, 15)}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const calendarButton = screen.getByRole(\"button\", { name: /calendar/i });\n expect(calendarButton).toBeDisabled();\n });\n\n it(\"renders in required state\", () => {\n render(\n <NimbusProvider>\n <DatePicker isRequired aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const dateGroup = screen.getByRole(\"group\");\n expect(dateGroup).toBeInTheDocument();\n });\n\n it(\"renders in invalid state\", () => {\n render(\n <NimbusProvider>\n <DatePicker\n isInvalid\n defaultValue={new CalendarDate(2025, 6, 15)}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const dateGroup = screen.getByRole(\"group\");\n expect(dateGroup).toBeInTheDocument();\n });\n});\n```\n\n### Granularity Tests\n\nTest different time granularity levels\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, within, waitFor } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { DatePicker, NimbusProvider } from \"@commercetools/nimbus\";\nimport { CalendarDate, CalendarDateTime } from \"@internationalized/date\";\n\ndescribe(\"DatePicker - Granularity\", () => {\n it(\"renders date-only segments with day granularity\", () => {\n render(\n <NimbusProvider>\n <DatePicker\n granularity=\"day\"\n defaultValue={new CalendarDate(2025, 6, 15)}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n expect(dateSegments).toHaveLength(3);\n });\n\n it(\"renders hour segments with hour granularity\", () => {\n render(\n <NimbusProvider>\n <DatePicker\n granularity=\"hour\"\n defaultValue={new CalendarDateTime(2025, 6, 15, 14)}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n expect(dateSegments.length).toBeGreaterThanOrEqual(4);\n });\n\n it(\"renders minute segments with minute granularity\", () => {\n render(\n <NimbusProvider>\n <DatePicker\n granularity=\"minute\"\n defaultValue={new CalendarDateTime(2025, 6, 15, 14, 30)}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n expect(dateSegments.length).toBeGreaterThanOrEqual(5);\n });\n\n it(\"renders second segments with second granularity\", () => {\n render(\n <NimbusProvider>\n <DatePicker\n granularity=\"second\"\n defaultValue={new CalendarDateTime(2025, 6, 15, 14, 30, 45)}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n expect(dateSegments.length).toBeGreaterThanOrEqual(6);\n });\n});\n```\n\n### Hour Cycle Tests\n\nTest 12-hour and 24-hour time formats\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, within, waitFor } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { DatePicker, NimbusProvider } from \"@commercetools/nimbus\";\nimport { CalendarDate, CalendarDateTime } from \"@internationalized/date\";\n\ndescribe(\"DatePicker - Hour cycle\", () => {\n it(\"displays 12-hour format with AM/PM\", () => {\n render(\n <NimbusProvider>\n <DatePicker\n granularity=\"minute\"\n hourCycle={12}\n defaultValue={new CalendarDateTime(2025, 6, 15, 14, 30)}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n const hourSegment = dateSegments[3];\n\n expect(hourSegment).toHaveAttribute(\"aria-valuetext\", \"2 PM\");\n });\n\n it(\"displays 24-hour format without AM/PM\", () => {\n render(\n <NimbusProvider>\n <DatePicker\n granularity=\"minute\"\n hourCycle={24}\n defaultValue={new CalendarDateTime(2025, 6, 15, 14, 30)}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n const dateSegments = screen.getAllByRole(\"spinbutton\");\n const hourSegment = dateSegments[3];\n\n expect(hourSegment).toHaveAttribute(\"aria-valuenow\", \"14\");\n });\n});\n```\n\n### Popover Control Tests\n\nTest controlled popover open/close state\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, within, waitFor } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\nimport { DatePicker, NimbusProvider } from \"@commercetools/nimbus\";\nimport { CalendarDate, CalendarDateTime } from \"@internationalized/date\";\n\ndescribe(\"DatePicker - Popover control\", () => {\n it(\"opens popover when isOpen is true\", async () => {\n render(\n <NimbusProvider>\n <DatePicker\n isOpen={true}\n onOpenChange={vi.fn()}\n aria-label=\"Select a date\"\n />\n </NimbusProvider>\n );\n\n await waitFor(() => {\n expect(\n within(document.body).queryByRole(\"application\")\n ).toBeInTheDocument();\n });\n });\n\n it(\"calls onOpenChange when popover state changes\", async () => {\n const user = userEvent.setup();\n const onOpenChange = vi.fn();\n\n render(\n <NimbusProvider>\n <DatePicker onOpenChange={onOpenChange} aria-label=\"Select a date\" />\n </NimbusProvider>\n );\n\n const calendarButton = screen.getByRole(\"button\", { name: /calendar/i });\n await user.click(calendarButton);\n\n await waitFor(() => {\n expect(onOpenChange).toHaveBeenCalledWith(true);\n });\n });\n});\n```\n\n\n## Resources\n\n- [Storybook](https://nimbus-storybook.vercel.app/?path=/docs/components-date-datepicker--docs)\n- [React Aria DatePicker](https://react-spectrum.adobe.com/react-aria/DatePicker.html)\n- [ARIA Date Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/)\n- [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/)\n- [DateInput Component](/components/inputs/dateinput)\n- [Calendar Component](/components/inputs/calendar)\n",
|
|
225
|
+
"toc": [
|
|
226
|
+
{
|
|
227
|
+
"value": "Getting started",
|
|
228
|
+
"href": "#getting-started",
|
|
229
|
+
"depth": 2,
|
|
230
|
+
"numbering": [
|
|
231
|
+
1,
|
|
232
|
+
1
|
|
233
|
+
],
|
|
234
|
+
"parent": "root"
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"value": "Import",
|
|
238
|
+
"href": "#import",
|
|
239
|
+
"depth": 3,
|
|
240
|
+
"numbering": [
|
|
241
|
+
1,
|
|
242
|
+
1,
|
|
243
|
+
1
|
|
244
|
+
],
|
|
245
|
+
"parent": "root"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"value": "Basic usage",
|
|
249
|
+
"href": "#basic-usage",
|
|
250
|
+
"depth": 3,
|
|
251
|
+
"numbering": [
|
|
252
|
+
1,
|
|
253
|
+
1,
|
|
254
|
+
2
|
|
255
|
+
],
|
|
256
|
+
"parent": "root"
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"value": "Working with date values",
|
|
260
|
+
"href": "#working-with-date-values",
|
|
261
|
+
"depth": 2,
|
|
262
|
+
"numbering": [
|
|
263
|
+
1,
|
|
264
|
+
2
|
|
265
|
+
],
|
|
266
|
+
"parent": "root"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"value": "Date types",
|
|
270
|
+
"href": "#date-types",
|
|
271
|
+
"depth": 3,
|
|
272
|
+
"numbering": [
|
|
273
|
+
1,
|
|
274
|
+
2,
|
|
275
|
+
1
|
|
276
|
+
],
|
|
277
|
+
"parent": "root"
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"value": "Creating date values",
|
|
281
|
+
"href": "#creating-date-values",
|
|
282
|
+
"depth": 3,
|
|
283
|
+
"numbering": [
|
|
284
|
+
1,
|
|
285
|
+
2,
|
|
286
|
+
2
|
|
287
|
+
],
|
|
288
|
+
"parent": "root"
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"value": "Converting to strings",
|
|
292
|
+
"href": "#converting-to-strings",
|
|
293
|
+
"depth": 3,
|
|
294
|
+
"numbering": [
|
|
295
|
+
1,
|
|
296
|
+
2,
|
|
297
|
+
3
|
|
298
|
+
],
|
|
299
|
+
"parent": "root"
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"value": "Usage examples",
|
|
303
|
+
"href": "#usage-examples",
|
|
304
|
+
"depth": 2,
|
|
305
|
+
"numbering": [
|
|
306
|
+
1,
|
|
307
|
+
3
|
|
308
|
+
],
|
|
309
|
+
"parent": "root"
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"value": "Size options",
|
|
313
|
+
"href": "#size-options",
|
|
314
|
+
"depth": 3,
|
|
315
|
+
"numbering": [
|
|
316
|
+
1,
|
|
317
|
+
3,
|
|
318
|
+
1
|
|
319
|
+
],
|
|
320
|
+
"parent": "root"
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"value": "Visual variants",
|
|
324
|
+
"href": "#visual-variants",
|
|
325
|
+
"depth": 3,
|
|
326
|
+
"numbering": [
|
|
327
|
+
1,
|
|
328
|
+
3,
|
|
329
|
+
2
|
|
330
|
+
],
|
|
331
|
+
"parent": "root"
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"value": "Granularity control",
|
|
335
|
+
"href": "#granularity-control",
|
|
336
|
+
"depth": 3,
|
|
337
|
+
"numbering": [
|
|
338
|
+
1,
|
|
339
|
+
3,
|
|
340
|
+
3
|
|
341
|
+
],
|
|
342
|
+
"parent": "root"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"value": "Hour cycle",
|
|
346
|
+
"href": "#hour-cycle",
|
|
347
|
+
"depth": 3,
|
|
348
|
+
"numbering": [
|
|
349
|
+
1,
|
|
350
|
+
3,
|
|
351
|
+
4
|
|
352
|
+
],
|
|
353
|
+
"parent": "root"
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"value": "Time zone handling",
|
|
357
|
+
"href": "#time-zone-handling",
|
|
358
|
+
"depth": 3,
|
|
359
|
+
"numbering": [
|
|
360
|
+
1,
|
|
361
|
+
3,
|
|
362
|
+
5
|
|
363
|
+
],
|
|
364
|
+
"parent": "root"
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"value": "Placeholder values",
|
|
368
|
+
"href": "#placeholder-values",
|
|
369
|
+
"depth": 3,
|
|
370
|
+
"numbering": [
|
|
371
|
+
1,
|
|
372
|
+
3,
|
|
373
|
+
6
|
|
374
|
+
],
|
|
375
|
+
"parent": "root"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"value": "Close on select behavior",
|
|
379
|
+
"href": "#close-on-select-behavior",
|
|
380
|
+
"depth": 3,
|
|
381
|
+
"numbering": [
|
|
382
|
+
1,
|
|
383
|
+
3,
|
|
384
|
+
7
|
|
385
|
+
],
|
|
386
|
+
"parent": "root"
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"value": "Min/max validation",
|
|
390
|
+
"href": "#minmax-validation",
|
|
391
|
+
"depth": 3,
|
|
392
|
+
"numbering": [
|
|
393
|
+
1,
|
|
394
|
+
3,
|
|
395
|
+
8
|
|
396
|
+
],
|
|
397
|
+
"parent": "root"
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"value": "State variations",
|
|
401
|
+
"href": "#state-variations",
|
|
402
|
+
"depth": 3,
|
|
403
|
+
"numbering": [
|
|
404
|
+
1,
|
|
405
|
+
3,
|
|
406
|
+
9
|
|
407
|
+
],
|
|
408
|
+
"parent": "root"
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
"value": "Uncontrolled mode",
|
|
412
|
+
"href": "#uncontrolled-mode",
|
|
413
|
+
"depth": 3,
|
|
414
|
+
"numbering": [
|
|
415
|
+
1,
|
|
416
|
+
3,
|
|
417
|
+
10
|
|
418
|
+
],
|
|
419
|
+
"parent": "root"
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
"value": "Controlled mode",
|
|
423
|
+
"href": "#controlled-mode",
|
|
424
|
+
"depth": 3,
|
|
425
|
+
"numbering": [
|
|
426
|
+
1,
|
|
427
|
+
3,
|
|
428
|
+
11
|
|
429
|
+
],
|
|
430
|
+
"parent": "root"
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"value": "Popover control",
|
|
434
|
+
"href": "#popover-control",
|
|
435
|
+
"depth": 3,
|
|
436
|
+
"numbering": [
|
|
437
|
+
1,
|
|
438
|
+
3,
|
|
439
|
+
12
|
|
440
|
+
],
|
|
441
|
+
"parent": "root"
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
"value": "Internationalization",
|
|
445
|
+
"href": "#internationalization",
|
|
446
|
+
"depth": 3,
|
|
447
|
+
"numbering": [
|
|
448
|
+
1,
|
|
449
|
+
3,
|
|
450
|
+
13
|
|
451
|
+
],
|
|
452
|
+
"parent": "root"
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
"value": "Component requirements",
|
|
456
|
+
"href": "#component-requirements",
|
|
457
|
+
"depth": 2,
|
|
458
|
+
"numbering": [
|
|
459
|
+
1,
|
|
460
|
+
4
|
|
461
|
+
],
|
|
462
|
+
"parent": "root"
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
"value": "Date value requirements",
|
|
466
|
+
"href": "#date-value-requirements",
|
|
467
|
+
"depth": 3,
|
|
468
|
+
"numbering": [
|
|
469
|
+
1,
|
|
470
|
+
4,
|
|
471
|
+
1
|
|
472
|
+
],
|
|
473
|
+
"parent": "root"
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
"value": "Accessibility",
|
|
477
|
+
"href": "#accessibility",
|
|
478
|
+
"depth": 2,
|
|
479
|
+
"numbering": [
|
|
480
|
+
1,
|
|
481
|
+
5
|
|
482
|
+
],
|
|
483
|
+
"parent": "root"
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
"value": "Keyboard navigation",
|
|
487
|
+
"href": "#keyboard-navigation",
|
|
488
|
+
"depth": 4,
|
|
489
|
+
"numbering": [
|
|
490
|
+
1,
|
|
491
|
+
5,
|
|
492
|
+
1,
|
|
493
|
+
1
|
|
494
|
+
],
|
|
495
|
+
"parent": "root"
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
"value": "API reference",
|
|
499
|
+
"href": "#api-reference",
|
|
500
|
+
"depth": 2,
|
|
501
|
+
"numbering": [
|
|
502
|
+
1,
|
|
503
|
+
6
|
|
504
|
+
],
|
|
505
|
+
"parent": "root"
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
"value": "Common patterns",
|
|
509
|
+
"href": "#common-patterns",
|
|
510
|
+
"depth": 2,
|
|
511
|
+
"numbering": [
|
|
512
|
+
1,
|
|
513
|
+
7
|
|
514
|
+
],
|
|
515
|
+
"parent": "root"
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
"value": "Appointment scheduler",
|
|
519
|
+
"href": "#appointment-scheduler",
|
|
520
|
+
"depth": 3,
|
|
521
|
+
"numbering": [
|
|
522
|
+
1,
|
|
523
|
+
7,
|
|
524
|
+
1
|
|
525
|
+
],
|
|
526
|
+
"parent": "root"
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
"value": "Due date selector",
|
|
530
|
+
"href": "#due-date-selector",
|
|
531
|
+
"depth": 3,
|
|
532
|
+
"numbering": [
|
|
533
|
+
1,
|
|
534
|
+
7,
|
|
535
|
+
2
|
|
536
|
+
],
|
|
537
|
+
"parent": "root"
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
"value": "Event date selector",
|
|
541
|
+
"href": "#event-date-selector",
|
|
542
|
+
"depth": 3,
|
|
543
|
+
"numbering": [
|
|
544
|
+
1,
|
|
545
|
+
7,
|
|
546
|
+
3
|
|
547
|
+
],
|
|
548
|
+
"parent": "root"
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
"value": "Testing your implementation",
|
|
552
|
+
"href": "#testing-your-implementation",
|
|
553
|
+
"depth": 2,
|
|
554
|
+
"numbering": [
|
|
555
|
+
1,
|
|
556
|
+
8
|
|
557
|
+
],
|
|
558
|
+
"parent": "root"
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
"value": "Basic Rendering Tests",
|
|
562
|
+
"href": "#basic-rendering-tests",
|
|
563
|
+
"depth": 3,
|
|
564
|
+
"numbering": [
|
|
565
|
+
1,
|
|
566
|
+
8,
|
|
567
|
+
1
|
|
568
|
+
],
|
|
569
|
+
"parent": "root"
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
"value": "Interaction Tests",
|
|
573
|
+
"href": "#interaction-tests",
|
|
574
|
+
"depth": 3,
|
|
575
|
+
"numbering": [
|
|
576
|
+
1,
|
|
577
|
+
8,
|
|
578
|
+
2
|
|
579
|
+
],
|
|
580
|
+
"parent": "root"
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
"value": "Controlled Mode Tests",
|
|
584
|
+
"href": "#controlled-mode-tests",
|
|
585
|
+
"depth": 3,
|
|
586
|
+
"numbering": [
|
|
587
|
+
1,
|
|
588
|
+
8,
|
|
589
|
+
3
|
|
590
|
+
],
|
|
591
|
+
"parent": "root"
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
"value": "State Tests",
|
|
595
|
+
"href": "#state-tests",
|
|
596
|
+
"depth": 3,
|
|
597
|
+
"numbering": [
|
|
598
|
+
1,
|
|
599
|
+
8,
|
|
600
|
+
4
|
|
601
|
+
],
|
|
602
|
+
"parent": "root"
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
"value": "Granularity Tests",
|
|
606
|
+
"href": "#granularity-tests",
|
|
607
|
+
"depth": 3,
|
|
608
|
+
"numbering": [
|
|
609
|
+
1,
|
|
610
|
+
8,
|
|
611
|
+
5
|
|
612
|
+
],
|
|
613
|
+
"parent": "root"
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
"value": "Hour Cycle Tests",
|
|
617
|
+
"href": "#hour-cycle-tests",
|
|
618
|
+
"depth": 3,
|
|
619
|
+
"numbering": [
|
|
620
|
+
1,
|
|
621
|
+
8,
|
|
622
|
+
6
|
|
623
|
+
],
|
|
624
|
+
"parent": "root"
|
|
625
|
+
},
|
|
626
|
+
{
|
|
627
|
+
"value": "Popover Control Tests",
|
|
628
|
+
"href": "#popover-control-tests",
|
|
629
|
+
"depth": 3,
|
|
630
|
+
"numbering": [
|
|
631
|
+
1,
|
|
632
|
+
8,
|
|
633
|
+
7
|
|
634
|
+
],
|
|
635
|
+
"parent": "root"
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
"value": "Resources",
|
|
639
|
+
"href": "#resources",
|
|
640
|
+
"depth": 2,
|
|
641
|
+
"numbering": [
|
|
642
|
+
1,
|
|
643
|
+
9
|
|
644
|
+
],
|
|
645
|
+
"parent": "root"
|
|
646
|
+
}
|
|
647
|
+
]
|
|
648
|
+
},
|
|
649
|
+
"guidelines": {
|
|
650
|
+
"mdx": "\n## Guidelines\n\nDate picker guidelines establish a standardized approach for creating intuitive\nand accessible date input components, ensuring consistency in presentation and\ninteraction for selecting dates across all applications.\n\n### Best practices\n\n- **Clear labeling:** Use explicit and descriptive labels that clearly indicate\n what date information is needed (e.g., \"Date of Birth,\" \"Event Date\").\n- **Provide format hints:** Clearly display the expected date format (e.g.,\n MM/DD/YYYY, YYYY-MM-DD) using placeholder text or helper text.\n- **Offer multiple input methods:** Allow users to both manually type in the\n date and select it from a visual calendar picker.\n- **Use input masks:** Consider using input masks to guide formatting as the\n user types, but ensure they don't hinder accessibility or flexibility.\n- **Validate input:** Provide real-time validation and clear error messages for\n incorrect date formats or invalid dates.\n- **Show current date:** In a calendar picker, clearly highlight the current\n date for easy reference.\n- **Enable easy navigation:** Make it simple to navigate months and years within\n the calendar picker (e.g., using forward/backward buttons and year dropdown).\n- **Indicate selected date:** Clearly visually distinguish the selected date in\n the calendar.\n- **Handle unavailable dates:** If certain dates are unavailable (e.g., past\n dates for future events), clearly indicate them as disabled.\n- **Ensure keyboard accessibility:** Make all parts of the DatePicker (input,\n calendar) navigable and operable using the keyboard.\n- **Provide sufficient contrast:** Ensure adequate color contrast between text,\n icons, and background elements for accessibility.\n- **Localization:** Adapt the date format and calendar display to the user's\n locale.\n- **Offer preset ranges:** For date range selections, provide common presets\n like \"Last week,\" \"This month,\" etc.\n\n### Usage\n\n> [!TIP]\\\n> When to use\n\n- **Specific date selection required:** When users need to choose a particular\n date, such as a birthdate, appointment date, or event date.\n- **Date-related tasks:** For features involving scheduling, filtering by date,\n setting deadlines, or defining date ranges.\n- **Standardized input format:** To ensure users enter dates in a consistent and\n predictable format, reducing data entry errors.\n- **Visual calendar navigation:** When users benefit from a visual\n representation of a calendar to navigate and select dates, especially for date\n ranges or when the day of the week is relevant.\n- **Accessibility needs:** To provide an accessible alternative to manual text\n input for users with disabilities, including keyboard navigation and screen\n reader support.\n- **Clear date context:** When the date is a primary piece of information and\n needs to be explicitly chosen.\n\n> [!CAUTION]\\\n> When not to use\n\n- **Approximate or vague dates:** When the exact date is not critical, and users\n might only know a month or year (consider a select dropdown or a less specific\n input).\n- **Dates far in the past or future:** For dates like birth dates, consider a\n direct text input with clear formatting hints or segmented inputs\n (month/day/year) to avoid excessive calendar navigation. However, a date\n picker can still be suitable if well-implemented with year selection.\n- **Simple \"today\" or \"now\" selection:** For actions that simply require the\n current date or time, a button or automated function might be more efficient.\n- **Limited screen real estate:** On very constrained interfaces, a compact text\n input with a clear format might be preferred over an expanded calendar, though\n accessibility should still be a priority.\n- **High frequency of typing known dates:** If users frequently know the exact\n date they need to enter and typing is faster for them, a well-formatted text\n input with validation might be sufficient alongside (or instead of) a date\n picker. (e.g. birthdays)\n- **Binary \"yes/no\" for date-related options:** For simple choices like \"Remind\n me?\" (implying the current date/time), a checkbox or switch might be more\n appropriate.\n\n### Labels and messaging\n\nClear labels and concise messaging are crucial for a date input to ensure users\nunderstand what date information is required and how to provide it correctly.\n\n> [!TIP]\\\n> **Do**\n>\n> - Do use a clear and descriptive label (e.g., \"Date of Birth,\" \"Event Date\").\n> - Do provide clear formatting hints (e.g., MM/DD/YYYY) as placeholder text or\n> helper text.\n> - Do validate the input and provide clear error messages for incorrect formats\n> or invalid dates.\n\n```jsx live\nconst App = () => (\n <FormField.Root>\n <FormField.Label>Active promotion date</FormField.Label>\n <FormField.Input>\n <DatePicker\n size=\"md\"\n aria-label=\"Active promotion date\"\n granularity=\"minute\"\n width=\"1/2\"\n />\n </FormField.Input>\n </FormField.Root>\n);\n```\n\n> [!CAUTION]\\\n> **Don't**\n>\n> - Don't rely solely on placeholder text for the label.\n> - Don't use ambiguous date formats without clear guidance.\n> - Don't fail to provide feedback on invalid input.\n\n\n\n### Interaction and selection\n\nThe ideal date picker interaction offers a seamless experience through intuitive\ncalendar navigation, clear visual feedback on selection, and the flexibility of\nboth direct typing and visual selection to accommodate user preferences and\naccessibility needs.\n\n> [!TIP]\\\n> **Do**\n>\n> - Do highlight the current date in the calendar picker for reference.\n> - Do provide a visual calendar picker for easy selection, especially for\n> non-familiar dates or date ranges.\n> - Do allow manual text input as an alternative for users who prefer it or know\n> the date.\n> - Do clearly indicate the selected date(s) in the calendar.\n> - Do enable easy navigation between months and years in the calendar.\n> - Do consider providing preset date ranges (e.g., \"Last Week,\" \"Next Month\")\n> when relevant.\n\n```jsx live\nconst App = () => (\n <FormField.Root>\n <FormField.Label>Delivery date</FormField.Label>\n <FormField.Input>\n <DatePicker\n size=\"md\"\n aria-label=\"Delivery date\"\n width=\"1/3\"\n defaultValue={new CalendarDate(2025, 5, 11)}\n />\n </FormField.Input>\n <FormField.Description>Format MM/DD/YYYY</FormField.Description>\n </FormField.Root>\n);\n```\n\n> [!CAUTION]\\\n> **Don't**\n>\n> - Don't use it for selecting vague or non-specific timeframes (e.g., \"sometime\n> next year\").\n> - Don't force users to only use the calendar picker if they prefer typing.\n> - Don't use it for simple \"today\" selections where a button might suffice.\n> - Don't auto-advance between date segments (day/month/year) in text input, as\n> it can hinder error correction.\n> - Don't make calendar navigation cumbersome.\n\n\n",
|
|
651
|
+
"toc": [
|
|
652
|
+
{
|
|
653
|
+
"value": "Guidelines",
|
|
654
|
+
"href": "#guidelines",
|
|
655
|
+
"depth": 2,
|
|
656
|
+
"numbering": [
|
|
657
|
+
1,
|
|
658
|
+
1
|
|
659
|
+
],
|
|
660
|
+
"parent": "root"
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
"value": "Best practices",
|
|
664
|
+
"href": "#best-practices",
|
|
665
|
+
"depth": 3,
|
|
666
|
+
"numbering": [
|
|
667
|
+
1,
|
|
668
|
+
1,
|
|
669
|
+
1
|
|
670
|
+
],
|
|
671
|
+
"parent": "root"
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
"value": "Usage",
|
|
675
|
+
"href": "#usage",
|
|
676
|
+
"depth": 3,
|
|
677
|
+
"numbering": [
|
|
678
|
+
1,
|
|
679
|
+
1,
|
|
680
|
+
2
|
|
681
|
+
],
|
|
682
|
+
"parent": "root"
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
"value": "Labels and messaging",
|
|
686
|
+
"href": "#labels-and-messaging",
|
|
687
|
+
"depth": 3,
|
|
688
|
+
"numbering": [
|
|
689
|
+
1,
|
|
690
|
+
1,
|
|
691
|
+
3
|
|
692
|
+
],
|
|
693
|
+
"parent": "root"
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
"value": "Interaction and selection",
|
|
697
|
+
"href": "#interaction-and-selection",
|
|
698
|
+
"depth": 3,
|
|
699
|
+
"numbering": [
|
|
700
|
+
1,
|
|
701
|
+
1,
|
|
702
|
+
4
|
|
703
|
+
],
|
|
704
|
+
"parent": "root"
|
|
705
|
+
}
|
|
706
|
+
]
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|