@cdx-ui/components 0.2.2 → 0.2.4
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/AGENTS.md +24 -0
- package/README.md +6 -2
- package/coverage.svg +1 -1
- package/docs/components/accordion/content.md +538 -0
- package/docs/components/alert/content.md +203 -0
- package/docs/components/alert-dialog/content.md +319 -0
- package/docs/components/avatar/content.md +368 -0
- package/docs/components/avatar/design.md +202 -0
- package/docs/components/badge/content.md +235 -0
- package/docs/components/bottom-sheet/content.md +351 -0
- package/docs/components/bottom-sheet/design.md +249 -0
- package/docs/components/breadcrumbs/content.md +169 -0
- package/docs/components/button/content.md +398 -0
- package/docs/components/button/design.md +258 -0
- package/docs/components/calendar/content.md +137 -0
- package/docs/components/card/content.md +283 -0
- package/docs/components/carousel/content.md +416 -0
- package/docs/components/checkbox/content.md +236 -0
- package/docs/components/checkbox/design.md +214 -0
- package/docs/components/chip/content.md +439 -0
- package/docs/components/chip/design.md +418 -0
- package/docs/components/color-area/content.md +86 -0
- package/docs/components/color-field/content.md +134 -0
- package/docs/components/color-picker/content.md +208 -0
- package/docs/components/color-slider/content.md +120 -0
- package/docs/components/color-swatch/content.md +64 -0
- package/docs/components/color-swatch-picker/content.md +126 -0
- package/docs/components/content.md +97 -0
- package/docs/components/currency-input/content.md +205 -0
- package/docs/components/data-grid/content.md +522 -0
- package/docs/components/date-field/content.md +147 -0
- package/docs/components/date-picker/content.md +360 -0
- package/docs/components/date-range-picker/content.md +301 -0
- package/docs/components/date-time-field/content.md +157 -0
- package/docs/components/date-time-list/content.md +105 -0
- package/docs/components/date-time-picker/content.md +272 -0
- package/docs/components/dialog/content.md +436 -0
- package/docs/components/dialog/design.md +192 -0
- package/docs/components/divider/content.md +112 -0
- package/docs/components/drawer/content.md +436 -0
- package/docs/components/field/content.md +277 -0
- package/docs/components/form/content.md +62 -0
- package/docs/components/full-screen-dialog/content.md +881 -0
- package/docs/components/heading/content.md +55 -0
- package/docs/components/icon/content.md +190 -0
- package/docs/components/icon-button/content.md +200 -0
- package/docs/components/icon-button/design.md +165 -0
- package/docs/components/image/content.md +104 -0
- package/docs/components/input/content.md +281 -0
- package/docs/components/input/design.md +389 -0
- package/docs/components/insurance-disclosure/content.md +103 -0
- package/docs/components/link/content.md +180 -0
- package/docs/components/link/design.md +160 -0
- package/docs/components/list-item/content.md +695 -0
- package/docs/components/menu/content.md +1247 -0
- package/docs/components/month-calendar/content.md +84 -0
- package/docs/components/month-picker/content.md +273 -0
- package/docs/components/otp-input/content.md +327 -0
- package/docs/components/progress-bar/content.md +87 -0
- package/docs/components/progress-circle/content.md +176 -0
- package/docs/components/progress-segmented/content.md +119 -0
- package/docs/components/quick-action-button/content.md +154 -0
- package/docs/components/quick-action-button/design.md +170 -0
- package/docs/components/radio/content.md +224 -0
- package/docs/components/range-calendar/content.md +123 -0
- package/docs/components/reorderable-list/content.md +309 -0
- package/docs/components/scoped-theme/content.md +47 -0
- package/docs/components/scroll-shadow/content.md +686 -0
- package/docs/components/select/content.md +400 -0
- package/docs/components/select/design.md +301 -0
- package/docs/components/skeleton/content.md +103 -0
- package/docs/components/slider/content.md +423 -0
- package/docs/components/stack/content.md +161 -0
- package/docs/components/switch/content.md +150 -0
- package/docs/components/switch/design.md +208 -0
- package/docs/components/table/content.md +548 -0
- package/docs/components/table-pagination/content.md +177 -0
- package/docs/components/tabs/content.md +292 -0
- package/docs/components/text/content.md +142 -0
- package/docs/components/textarea/content.md +222 -0
- package/docs/components/tile/content.md +703 -0
- package/docs/components/toast/content.md +456 -0
- package/docs/components/toggle-button/content.md +505 -0
- package/docs/components/tooltip/content.md +350 -0
- package/docs/components/virtualized-list/content.md +250 -0
- package/docs/foundations/content.md +9 -0
- package/docs/foundations/expressions/icons/content.md +19 -0
- package/docs/foundations/styles/tokens/all-tokens/content.md +192 -0
- package/docs/foundations/styles/tokens/what-are-tokens/content.md +33 -0
- package/docs/foundations/styles/tokens/what-are-tokens/design.md +33 -0
- package/docs/getting-started/content.md +4 -0
- package/docs/getting-started/designers/content.md +13 -0
- package/docs/getting-started/designers/design.md +13 -0
- package/docs/getting-started/developers/accessibility/content.md +31 -0
- package/docs/getting-started/developers/content.md +612 -0
- package/docs/getting-started/developers/styling/content.md +193 -0
- package/docs/llms.txt +193 -0
- package/docs/patterns/account-management/content.md +75 -0
- package/docs/patterns/authentication/content.md +52 -0
- package/docs/patterns/content.md +10 -0
- package/docs/patterns/dashboard/content.md +39 -0
- package/docs/patterns/empty-states/content.md +31 -0
- package/docs/patterns/forms/content.md +109 -0
- package/docs/patterns/onboarding/content.md +69 -0
- package/docs/patterns/payments/content.md +35 -0
- package/docs/patterns/settings/content.md +72 -0
- package/docs/resources/content.md +9 -0
- package/docs/resources/figma-libraries/content.md +42 -0
- package/docs/resources/release-notes/0.0.1-beta.118/content.md +27 -0
- package/docs/resources/release-notes/0.0.1-beta.122/content.md +21 -0
- package/docs/resources/release-notes/0.0.1-beta.124/content.md +16 -0
- package/docs/resources/release-notes/0.0.1-beta.126/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.127/content.md +14 -0
- package/docs/resources/release-notes/0.0.1-beta.128/content.md +9 -0
- package/docs/resources/release-notes/0.0.1-beta.129/content.md +18 -0
- package/docs/resources/release-notes/0.0.1-beta.130/content.md +18 -0
- package/docs/resources/release-notes/0.0.1-beta.133/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.134/content.md +17 -0
- package/docs/resources/release-notes/0.0.1-beta.136/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.137/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.138/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.139/content.md +13 -0
- package/docs/resources/release-notes/0.0.1-beta.140/content.md +26 -0
- package/docs/resources/release-notes/0.0.1-beta.141/content.md +63 -0
- package/docs/resources/release-notes/0.0.1-beta.142/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.143/content.md +12 -0
- package/docs/resources/release-notes/0.0.1-beta.144/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.145/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.147/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.149/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.150/content.md +13 -0
- package/docs/resources/release-notes/0.0.1-beta.152/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.154/content.md +15 -0
- package/docs/resources/release-notes/0.0.1-beta.156/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.158/content.md +9 -0
- package/docs/resources/release-notes/0.0.1-beta.159/content.md +11 -0
- package/docs/resources/release-notes/0.0.1-beta.160/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.161/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.163/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.164/content.md +9 -0
- package/docs/resources/release-notes/0.0.1-beta.166/content.md +17 -0
- package/docs/resources/release-notes/0.0.1-beta.167/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.168/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.169/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.171/content.md +16 -0
- package/docs/resources/release-notes/0.0.1-beta.172/content.md +24 -0
- package/docs/resources/release-notes/0.0.1-beta.173/content.md +15 -0
- package/docs/resources/release-notes/0.0.1-beta.174/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.176/content.md +32 -0
- package/docs/resources/release-notes/0.0.1-beta.179/content.md +11 -0
- package/docs/resources/release-notes/0.0.1-beta.182/content.md +13 -0
- package/docs/resources/release-notes/0.0.1-beta.185/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.187/content.md +27 -0
- package/docs/resources/release-notes/0.1.1/content.md +23 -0
- package/docs/resources/release-notes/0.1.2/content.md +7 -0
- package/docs/resources/release-notes/0.1.4/content.md +19 -0
- package/docs/resources/release-notes/0.1.5/content.md +7 -0
- package/docs/resources/release-notes/0.1.6/content.md +7 -0
- package/docs/resources/release-notes/0.2.0/content.md +31 -0
- package/docs/resources/release-notes/0.2.1/content.md +17 -0
- package/docs/resources/release-notes/0.2.2/content.md +11 -0
- package/docs/resources/release-notes/0.2.3/content.md +15 -0
- package/docs/resources/release-notes/content.md +64 -0
- package/lib/commonjs/components/Checkbox/index.js.map +1 -1
- package/lib/commonjs/components/DateTimeList/index.js +11 -26
- package/lib/commonjs/components/DateTimeList/index.js.map +1 -1
- package/lib/commonjs/components/DateTimeList/styles.js +2 -12
- package/lib/commonjs/components/DateTimeList/styles.js.map +1 -1
- package/lib/commonjs/components/Heading/index.js.map +1 -1
- package/lib/commonjs/components/Icon/index.js.map +1 -1
- package/lib/commonjs/components/ListItem/index.js +170 -9
- package/lib/commonjs/components/ListItem/index.js.map +1 -1
- package/lib/commonjs/components/ListItem/styles.js +38 -2
- package/lib/commonjs/components/ListItem/styles.js.map +1 -1
- package/lib/commonjs/components/Menu/index.js +11 -5
- package/lib/commonjs/components/Menu/index.js.map +1 -1
- package/lib/commonjs/components/RangeCalendar/index.js.map +1 -1
- package/lib/commonjs/components/ReorderableList/ReorderableListShared.js +91 -0
- package/lib/commonjs/components/ReorderableList/ReorderableListShared.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/index.js +135 -0
- package/lib/commonjs/components/ReorderableList/index.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/index.web.js +233 -0
- package/lib/commonjs/components/ReorderableList/index.web.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/labels.js +47 -0
- package/lib/commonjs/components/ReorderableList/labels.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/reorderItems.js +16 -0
- package/lib/commonjs/components/ReorderableList/reorderItems.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/rowContext.js +42 -0
- package/lib/commonjs/components/ReorderableList/rowContext.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/types.js +6 -0
- package/lib/commonjs/components/ReorderableList/types.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/useReorder.js +131 -0
- package/lib/commonjs/components/ReorderableList/useReorder.js.map +1 -0
- package/lib/commonjs/components/ReorderableList/webDnd.js +64 -0
- package/lib/commonjs/components/ReorderableList/webDnd.js.map +1 -0
- package/lib/commonjs/components/ScopedTheme/index.js.map +1 -1
- package/lib/commonjs/components/ScrollShadow/gradient.js +29 -0
- package/lib/commonjs/components/ScrollShadow/gradient.js.map +1 -0
- package/lib/commonjs/components/ScrollShadow/index.js +171 -44
- package/lib/commonjs/components/ScrollShadow/index.js.map +1 -1
- package/lib/commonjs/components/ScrollShadow/styles.js +58 -14
- package/lib/commonjs/components/ScrollShadow/styles.js.map +1 -1
- package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js +63 -0
- package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
- package/lib/commonjs/components/ScrollShadow/useScrollShadow.js +48 -8
- package/lib/commonjs/components/ScrollShadow/useScrollShadow.js.map +1 -1
- package/lib/commonjs/components/Skeleton/index.js.map +1 -1
- package/lib/commonjs/components/TablePagination/index.js.map +1 -1
- package/lib/commonjs/components/Tabs/index.js +16 -23
- package/lib/commonjs/components/Tabs/index.js.map +1 -1
- package/lib/commonjs/components/Tabs/styles.js +1 -10
- package/lib/commonjs/components/Tabs/styles.js.map +1 -1
- package/lib/commonjs/components/Text/index.js.map +1 -1
- package/lib/commonjs/components/Tile/styles.js +1 -1
- package/lib/commonjs/components/Tile/styles.js.map +1 -1
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/figma/ListItem.SectionHeader.figma.js +20 -5
- package/lib/commonjs/figma/ListItem.SectionHeader.figma.js.map +1 -1
- package/lib/commonjs/reorderable-list.js +17 -0
- package/lib/commonjs/reorderable-list.js.map +1 -0
- package/lib/module/components/Checkbox/index.js.map +1 -1
- package/lib/module/components/DateTimeList/index.js +12 -27
- package/lib/module/components/DateTimeList/index.js.map +1 -1
- package/lib/module/components/DateTimeList/styles.js +1 -11
- package/lib/module/components/DateTimeList/styles.js.map +1 -1
- package/lib/module/components/Heading/index.js.map +1 -1
- package/lib/module/components/Icon/index.js.map +1 -1
- package/lib/module/components/ListItem/index.js +163 -14
- package/lib/module/components/ListItem/index.js.map +1 -1
- package/lib/module/components/ListItem/styles.js +37 -1
- package/lib/module/components/ListItem/styles.js.map +1 -1
- package/lib/module/components/Menu/index.js +11 -5
- package/lib/module/components/Menu/index.js.map +1 -1
- package/lib/module/components/RangeCalendar/index.js.map +1 -1
- package/lib/module/components/ReorderableList/ReorderableListShared.js +86 -0
- package/lib/module/components/ReorderableList/ReorderableListShared.js.map +1 -0
- package/lib/module/components/ReorderableList/index.js +130 -0
- package/lib/module/components/ReorderableList/index.js.map +1 -0
- package/lib/module/components/ReorderableList/index.web.js +229 -0
- package/lib/module/components/ReorderableList/index.web.js.map +1 -0
- package/lib/module/components/ReorderableList/labels.js +41 -0
- package/lib/module/components/ReorderableList/labels.js.map +1 -0
- package/lib/module/components/ReorderableList/reorderItems.js +12 -0
- package/lib/module/components/ReorderableList/reorderItems.js.map +1 -0
- package/lib/module/components/ReorderableList/rowContext.js +38 -0
- package/lib/module/components/ReorderableList/rowContext.js.map +1 -0
- package/lib/module/components/ReorderableList/types.js +4 -0
- package/lib/module/components/ReorderableList/types.js.map +1 -0
- package/lib/module/components/ReorderableList/useReorder.js +123 -0
- package/lib/module/components/ReorderableList/useReorder.js.map +1 -0
- package/lib/module/components/ReorderableList/webDnd.js +59 -0
- package/lib/module/components/ReorderableList/webDnd.js.map +1 -0
- package/lib/module/components/ScopedTheme/index.js.map +1 -1
- package/lib/module/components/ScrollShadow/gradient.js +24 -0
- package/lib/module/components/ScrollShadow/gradient.js.map +1 -0
- package/lib/module/components/ScrollShadow/index.js +170 -48
- package/lib/module/components/ScrollShadow/index.js.map +1 -1
- package/lib/module/components/ScrollShadow/styles.js +57 -13
- package/lib/module/components/ScrollShadow/styles.js.map +1 -1
- package/lib/module/components/ScrollShadow/useComposedScrollHandler.js +57 -0
- package/lib/module/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
- package/lib/module/components/ScrollShadow/useScrollShadow.js +46 -8
- package/lib/module/components/ScrollShadow/useScrollShadow.js.map +1 -1
- package/lib/module/components/Skeleton/index.js.map +1 -1
- package/lib/module/components/TablePagination/index.js.map +1 -1
- package/lib/module/components/Tabs/index.js +17 -24
- package/lib/module/components/Tabs/index.js.map +1 -1
- package/lib/module/components/Tabs/styles.js +0 -9
- package/lib/module/components/Tabs/styles.js.map +1 -1
- package/lib/module/components/Text/index.js.map +1 -1
- package/lib/module/components/Tile/styles.js +1 -1
- package/lib/module/components/Tile/styles.js.map +1 -1
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/figma/ListItem.SectionHeader.figma.js +20 -5
- package/lib/module/figma/ListItem.SectionHeader.figma.js.map +1 -1
- package/lib/module/reorderable-list.js +4 -0
- package/lib/module/reorderable-list.js.map +1 -0
- package/lib/typescript/components/Checkbox/index.d.ts +22 -0
- package/lib/typescript/components/Checkbox/index.d.ts.map +1 -1
- package/lib/typescript/components/DateTimeList/index.d.ts.map +1 -1
- package/lib/typescript/components/DateTimeList/styles.d.ts +1 -4
- package/lib/typescript/components/DateTimeList/styles.d.ts.map +1 -1
- package/lib/typescript/components/Heading/index.d.ts +20 -2
- package/lib/typescript/components/Heading/index.d.ts.map +1 -1
- package/lib/typescript/components/Icon/index.d.ts +2 -0
- package/lib/typescript/components/Icon/index.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/index.d.ts +28 -5
- package/lib/typescript/components/ListItem/index.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/styles.d.ts +6 -1
- package/lib/typescript/components/ListItem/styles.d.ts.map +1 -1
- package/lib/typescript/components/Menu/index.d.ts +116 -4
- package/lib/typescript/components/Menu/index.d.ts.map +1 -1
- package/lib/typescript/components/RangeCalendar/index.d.ts +2 -0
- package/lib/typescript/components/RangeCalendar/index.d.ts.map +1 -1
- package/lib/typescript/components/ReorderableList/ReorderableListShared.d.ts +31 -0
- package/lib/typescript/components/ReorderableList/ReorderableListShared.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/index.d.ts +8 -0
- package/lib/typescript/components/ReorderableList/index.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/index.web.d.ts +8 -0
- package/lib/typescript/components/ReorderableList/index.web.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/labels.d.ts +16 -0
- package/lib/typescript/components/ReorderableList/labels.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/reorderItems.d.ts +3 -0
- package/lib/typescript/components/ReorderableList/reorderItems.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/rowContext.d.ts +57 -0
- package/lib/typescript/components/ReorderableList/rowContext.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/types.d.ts +75 -0
- package/lib/typescript/components/ReorderableList/types.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/useReorder.d.ts +31 -0
- package/lib/typescript/components/ReorderableList/useReorder.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableList/webDnd.d.ts +27 -0
- package/lib/typescript/components/ReorderableList/webDnd.d.ts.map +1 -0
- package/lib/typescript/components/ScopedTheme/index.d.ts +6 -1
- package/lib/typescript/components/ScopedTheme/index.d.ts.map +1 -1
- package/lib/typescript/components/ScrollShadow/gradient.d.ts +7 -0
- package/lib/typescript/components/ScrollShadow/gradient.d.ts.map +1 -0
- package/lib/typescript/components/ScrollShadow/index.d.ts +57 -15
- package/lib/typescript/components/ScrollShadow/index.d.ts.map +1 -1
- package/lib/typescript/components/ScrollShadow/styles.d.ts +8 -2
- package/lib/typescript/components/ScrollShadow/styles.d.ts.map +1 -1
- package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts +13 -0
- package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts.map +1 -0
- package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts +15 -2
- package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts.map +1 -1
- package/lib/typescript/components/Skeleton/index.d.ts +3 -0
- package/lib/typescript/components/Skeleton/index.d.ts.map +1 -1
- package/lib/typescript/components/TablePagination/index.d.ts +54 -0
- package/lib/typescript/components/TablePagination/index.d.ts.map +1 -1
- package/lib/typescript/components/Tabs/index.d.ts.map +1 -1
- package/lib/typescript/components/Tabs/styles.d.ts +0 -7
- package/lib/typescript/components/Tabs/styles.d.ts.map +1 -1
- package/lib/typescript/components/Text/index.d.ts +12 -2
- package/lib/typescript/components/Text/index.d.ts.map +1 -1
- package/lib/typescript/components/Tile/styles.d.ts.map +1 -1
- package/lib/typescript/components/ToggleButton/styles.d.ts +1 -1
- package/lib/typescript/components/index.d.ts +1 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/figma/ListItem.SectionHeader.figma.d.ts.map +1 -1
- package/lib/typescript/reorderable-list.d.ts +2 -0
- package/lib/typescript/reorderable-list.d.ts.map +1 -0
- package/package.json +37 -8
- package/src/components/Checkbox/index.tsx +22 -0
- package/src/components/DateTimeList/index.tsx +13 -26
- package/src/components/DateTimeList/styles.ts +1 -10
- package/src/components/Heading/index.tsx +10 -1
- package/src/components/Icon/index.tsx +2 -0
- package/src/components/ListItem/index.tsx +232 -15
- package/src/components/ListItem/styles.ts +41 -0
- package/src/components/Menu/index.tsx +128 -12
- package/src/components/RangeCalendar/index.tsx +2 -0
- package/src/components/ReorderableList/ReorderableListShared.tsx +113 -0
- package/src/components/ReorderableList/index.tsx +162 -0
- package/src/components/ReorderableList/index.web.tsx +254 -0
- package/src/components/ReorderableList/labels.ts +52 -0
- package/src/components/ReorderableList/reorderItems.ts +16 -0
- package/src/components/ReorderableList/rowContext.tsx +72 -0
- package/src/components/ReorderableList/types.ts +80 -0
- package/src/components/ReorderableList/useReorder.ts +159 -0
- package/src/components/ReorderableList/webDnd.ts +60 -0
- package/src/components/ScopedTheme/index.tsx +6 -1
- package/src/components/ScrollShadow/gradient.ts +48 -0
- package/src/components/ScrollShadow/index.tsx +300 -69
- package/src/components/ScrollShadow/styles.ts +45 -28
- package/src/components/ScrollShadow/useComposedScrollHandler.ts +58 -0
- package/src/components/ScrollShadow/useScrollShadow.ts +72 -10
- package/src/components/Skeleton/index.tsx +3 -0
- package/src/components/TablePagination/index.tsx +54 -0
- package/src/components/Tabs/index.tsx +25 -35
- package/src/components/Tabs/styles.ts +0 -9
- package/src/components/Text/index.tsx +6 -1
- package/src/components/Tile/styles.ts +4 -1
- package/src/components/index.ts +5 -0
- package/src/reorderable-list.ts +1 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
# Date Picker (https://design.candescent.com/docs/components/date-picker)
|
|
2
|
+
|
|
3
|
+
Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=12349-9879), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/date-time-datepicker--standalone)
|
|
4
|
+
|
|
5
|
+
`DatePicker` pairs a segmented `DateField` with a `Calendar` and coordinates the surface that presents it. Values are `DateId` strings in `YYYY-MM-DD` format.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Calendar, DateField, DatePicker, Field } from '@cdx-ui/components';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic
|
|
12
|
+
|
|
13
|
+
Because the date field is editable, keep the `DatePicker.Trigger` around the suffix icon only, so typing in the field does not open the calendar. Then present the calendar — `DatePicker.Popover` anchors to the field and is the preferred surface on web. For surface-driven selection with no typing, you can instead wrap the whole `DateField.Group` in the trigger, as [DateRangePicker](https://design.candescent.com/docs/components/date-range-picker/content.md) and [MonthPicker](https://design.candescent.com/docs/components/month-picker/content.md) do.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { useState } from 'react';
|
|
17
|
+
import { DateField, DatePicker, Field } from '@cdx-ui/components';
|
|
18
|
+
import type { DateId } from '@cdx-ui/formatters';
|
|
19
|
+
|
|
20
|
+
export default function DatePickerBasicDemo() {
|
|
21
|
+
const [value, setValue] = useState<DateId | undefined>();
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Field className="w-full max-w-xs">
|
|
25
|
+
<DatePicker value={value} onValueChange={setValue}>
|
|
26
|
+
<Field.Label>Transfer date</Field.Label>
|
|
27
|
+
<DateField.Group fullWidth>
|
|
28
|
+
<DateField.Input />
|
|
29
|
+
<DateField.Suffix>
|
|
30
|
+
<DatePicker.Trigger>
|
|
31
|
+
<DatePicker.TriggerIndicator />
|
|
32
|
+
</DatePicker.Trigger>
|
|
33
|
+
</DateField.Suffix>
|
|
34
|
+
</DateField.Group>
|
|
35
|
+
<DatePicker.Popover>
|
|
36
|
+
<DatePicker.Calendar aria-label="Transfer date" />
|
|
37
|
+
</DatePicker.Popover>
|
|
38
|
+
</DatePicker>
|
|
39
|
+
</Field>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Dialog
|
|
45
|
+
|
|
46
|
+
Use `DatePicker.Dialog` to present the calendar in a modal surface.
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { useState } from 'react';
|
|
50
|
+
import { DateField, DatePicker, Field } from '@cdx-ui/components';
|
|
51
|
+
import type { DateId } from '@cdx-ui/formatters';
|
|
52
|
+
|
|
53
|
+
export default function DatePickerDialogDemo() {
|
|
54
|
+
const [value, setValue] = useState<DateId | undefined>();
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Field className="w-full max-w-xs">
|
|
58
|
+
<DatePicker value={value} onValueChange={setValue}>
|
|
59
|
+
<Field.Label>Transfer date</Field.Label>
|
|
60
|
+
<DateField.Group fullWidth>
|
|
61
|
+
<DateField.Input />
|
|
62
|
+
<DateField.Suffix>
|
|
63
|
+
<DatePicker.Trigger>
|
|
64
|
+
<DatePicker.TriggerIndicator />
|
|
65
|
+
</DatePicker.Trigger>
|
|
66
|
+
</DateField.Suffix>
|
|
67
|
+
</DateField.Group>
|
|
68
|
+
<DatePicker.Dialog>
|
|
69
|
+
<DatePicker.Calendar aria-label="Transfer date" />
|
|
70
|
+
</DatePicker.Dialog>
|
|
71
|
+
</DatePicker>
|
|
72
|
+
</Field>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Bottom sheet
|
|
78
|
+
|
|
79
|
+
Use `DatePicker.BottomSheet` to present the calendar in a sheet that slides up from the bottom — the preferred surface on native. It wires open state only, so compose `BottomSheet.Header` and `BottomSheet.Content` as its children.
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import { useState } from 'react';
|
|
83
|
+
import { BottomSheet, DateField, DatePicker, Field } from '@cdx-ui/components';
|
|
84
|
+
import type { DateId } from '@cdx-ui/formatters';
|
|
85
|
+
import { PickerBottomSheetFrame } from './_frame';
|
|
86
|
+
|
|
87
|
+
export default function DatePickerBottomSheetDemo() {
|
|
88
|
+
const [value, setValue] = useState<DateId | undefined>();
|
|
89
|
+
const [open, setOpen] = useState(false);
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<PickerBottomSheetFrame>
|
|
93
|
+
<Field className="w-full max-w-xs">
|
|
94
|
+
<DatePicker value={value} onValueChange={setValue} isOpen={open} onOpenChange={setOpen}>
|
|
95
|
+
<Field.Label>Transfer date</Field.Label>
|
|
96
|
+
<DateField.Group fullWidth>
|
|
97
|
+
<DateField.Input />
|
|
98
|
+
<DateField.Suffix>
|
|
99
|
+
<DatePicker.Trigger>
|
|
100
|
+
<DatePicker.TriggerIndicator />
|
|
101
|
+
</DatePicker.Trigger>
|
|
102
|
+
</DateField.Suffix>
|
|
103
|
+
</DateField.Group>
|
|
104
|
+
<DatePicker.BottomSheet>
|
|
105
|
+
<BottomSheet.Header title="Select date" onClose={() => setOpen(false)} />
|
|
106
|
+
<BottomSheet.Content>
|
|
107
|
+
<DatePicker.Calendar aria-label="Transfer date" />
|
|
108
|
+
</BottomSheet.Content>
|
|
109
|
+
</DatePicker.BottomSheet>
|
|
110
|
+
</DatePicker>
|
|
111
|
+
</Field>
|
|
112
|
+
</PickerBottomSheetFrame>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Standalone
|
|
118
|
+
|
|
119
|
+
Render a `Calendar` inline instead of a presentation surface when the field and calendar share the screen.
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import { useState } from 'react';
|
|
123
|
+
import { Calendar, DateField, DatePicker, Field } from '@cdx-ui/components';
|
|
124
|
+
import type { DateId } from '@cdx-ui/formatters';
|
|
125
|
+
|
|
126
|
+
export default function DatePickerStandaloneDemo() {
|
|
127
|
+
const [value, setValue] = useState<DateId | undefined>();
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<Field className="w-full max-w-sm">
|
|
131
|
+
<DatePicker value={value} onValueChange={setValue}>
|
|
132
|
+
<Field.Label>Transfer date</Field.Label>
|
|
133
|
+
<DateField.Group fullWidth>
|
|
134
|
+
<DateField.Input />
|
|
135
|
+
</DateField.Group>
|
|
136
|
+
<Calendar
|
|
137
|
+
className="mt-2"
|
|
138
|
+
aria-label="Transfer date"
|
|
139
|
+
value={value}
|
|
140
|
+
onValueChange={setValue}
|
|
141
|
+
/>
|
|
142
|
+
</DatePicker>
|
|
143
|
+
</Field>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Unavailable dates
|
|
149
|
+
|
|
150
|
+
Pass `isDateUnavailable` to disable weekends, holidays, or any other day the calendar should not offer, and add an empty `Field.Error` to the `Field` so a typed unavailable or out-of-range date explains itself.
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
import { useState } from 'react';
|
|
154
|
+
import { DateField, DatePicker, Field } from '@cdx-ui/components';
|
|
155
|
+
import { dateId, monthId, type DateId } from '@cdx-ui/formatters';
|
|
156
|
+
import { isNonBusinessDay } from '../calendar/_business-days';
|
|
157
|
+
|
|
158
|
+
const LABELS = { validationUnavailable: 'Payments do not process on weekends or bank holidays' };
|
|
159
|
+
|
|
160
|
+
export default function DatePickerBusinessDaysDemo() {
|
|
161
|
+
const [value, setValue] = useState<DateId | undefined>();
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<Field className="w-full max-w-xs">
|
|
165
|
+
<Field.Label>Payment date</Field.Label>
|
|
166
|
+
<DatePicker
|
|
167
|
+
value={value}
|
|
168
|
+
onValueChange={setValue}
|
|
169
|
+
minValue={dateId('2026-11-02')}
|
|
170
|
+
isDateUnavailable={isNonBusinessDay}
|
|
171
|
+
labels={LABELS}
|
|
172
|
+
>
|
|
173
|
+
<DateField.Group fullWidth>
|
|
174
|
+
<DateField.Input />
|
|
175
|
+
<DateField.Suffix>
|
|
176
|
+
<DatePicker.Trigger>
|
|
177
|
+
<DatePicker.TriggerIndicator />
|
|
178
|
+
</DatePicker.Trigger>
|
|
179
|
+
</DateField.Suffix>
|
|
180
|
+
</DateField.Group>
|
|
181
|
+
<DatePicker.Popover>
|
|
182
|
+
<DatePicker.Calendar defaultMonthId={monthId('2026-11-01')} aria-label="Payment date" />
|
|
183
|
+
</DatePicker.Popover>
|
|
184
|
+
</DatePicker>
|
|
185
|
+
<Field.Helper>Payments process on business days only.</Field.Helper>
|
|
186
|
+
<Field.Error />
|
|
187
|
+
</Field>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Custom error messages
|
|
193
|
+
|
|
194
|
+
Override `validationBeforeMin`, `validationAfterMax`, and `validationUnavailable` in `labels` to reword the message an empty `Field.Error` shows, using `{date}` for the bound.
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
import { useState } from 'react';
|
|
198
|
+
import { DateField, DatePicker, Field } from '@cdx-ui/components';
|
|
199
|
+
import { dateId, monthId, type DateId } from '@cdx-ui/formatters';
|
|
200
|
+
import { isNonBusinessDay } from '../calendar/_business-days';
|
|
201
|
+
|
|
202
|
+
const LABELS = {
|
|
203
|
+
validationBeforeMin: 'Payments can be scheduled from {date}',
|
|
204
|
+
validationAfterMax: 'Payments can be scheduled up to {date}',
|
|
205
|
+
validationUnavailable: 'Payments do not process on weekends or bank holidays',
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export default function DatePickerCustomMessagesDemo() {
|
|
209
|
+
const [value, setValue] = useState<DateId | undefined>(dateId('2026-10-30'));
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<Field className="w-full max-w-xs">
|
|
213
|
+
<Field.Label>Payment date</Field.Label>
|
|
214
|
+
<DatePicker
|
|
215
|
+
value={value}
|
|
216
|
+
onValueChange={setValue}
|
|
217
|
+
minValue={dateId('2026-11-02')}
|
|
218
|
+
maxValue={dateId('2026-12-31')}
|
|
219
|
+
isDateUnavailable={isNonBusinessDay}
|
|
220
|
+
labels={LABELS}
|
|
221
|
+
>
|
|
222
|
+
<DateField.Group fullWidth>
|
|
223
|
+
<DateField.Input />
|
|
224
|
+
<DateField.Suffix>
|
|
225
|
+
<DatePicker.Trigger>
|
|
226
|
+
<DatePicker.TriggerIndicator />
|
|
227
|
+
</DatePicker.Trigger>
|
|
228
|
+
</DateField.Suffix>
|
|
229
|
+
</DateField.Group>
|
|
230
|
+
<DatePicker.Popover>
|
|
231
|
+
<DatePicker.Calendar defaultMonthId={monthId('2026-11-01')} aria-label="Payment date" />
|
|
232
|
+
</DatePicker.Popover>
|
|
233
|
+
</DatePicker>
|
|
234
|
+
<Field.Helper>Payments process on business days only.</Field.Helper>
|
|
235
|
+
<Field.Error />
|
|
236
|
+
</Field>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Custom trigger
|
|
242
|
+
|
|
243
|
+
Set `asChild` on `DatePicker.Trigger` to open the calendar from a custom pressable such as an `IconButton`, keeping the segmented field for direct entry. The trigger merges its press and expanded-state accessibility props onto the child.
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
import { Box, DateField, DatePicker, Field, IconButton } from '@cdx-ui/components';
|
|
247
|
+
import { CalendarToday } from '@cdx-ui/icons';
|
|
248
|
+
|
|
249
|
+
export default function DatePickerCustomTriggerDemo() {
|
|
250
|
+
return (
|
|
251
|
+
<Field className="w-full max-w-xs">
|
|
252
|
+
<DatePicker>
|
|
253
|
+
<Field.Label>Transfer date</Field.Label>
|
|
254
|
+
<Box className="flex-row items-center gap-2">
|
|
255
|
+
<DateField.Group fullWidth>
|
|
256
|
+
<DateField.Input />
|
|
257
|
+
</DateField.Group>
|
|
258
|
+
<DatePicker.Trigger asChild>
|
|
259
|
+
<IconButton as={CalendarToday} variant="subtle" accessibilityLabel="Open calendar" />
|
|
260
|
+
</DatePicker.Trigger>
|
|
261
|
+
</Box>
|
|
262
|
+
<DatePicker.Popover>
|
|
263
|
+
<DatePicker.Calendar aria-label="Transfer date" />
|
|
264
|
+
</DatePicker.Popover>
|
|
265
|
+
</DatePicker>
|
|
266
|
+
</Field>
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## API
|
|
272
|
+
|
|
273
|
+
### DatePicker
|
|
274
|
+
|
|
275
|
+
Root of the compound. Owns the selected value, open state, `locale`, and `labels`, and provides `DateField` styling context to the field. Compose exactly one presentation surface — `DatePicker.Popover`, `DatePicker.Dialog`, or `DatePicker.BottomSheet` — per picker.
|
|
276
|
+
|
|
277
|
+
`minValue`, `maxValue`, and `isDateUnavailable` apply to both the calendar and typed entry. The calendar disables days that break a rule; a complete typed date that breaks one is kept in the field and still emitted through `onValueChange`, but renders invalid. Partial input is never invalid. The picker reports its invalid state to the enclosing `Field`, so the field root, `Field.Helper`, and `Field.Error` reflect it wherever they sit in the field. A `Field.Error` with no children renders the matching `labels` message (`validationBeforeMin`, `validationAfterMax`, or `validationUnavailable`), with the `{date}` bound formatted in the picker's `locale`. `onValidationChange` reports the `DateValidationReason` (`beforeMin`, `afterMax`, or `unavailable`) and that message whenever the reason or the formatted message changes — including a new bound, `locale`, or `labels` that keeps the same reason — and `undefined` once the value is valid or cleared. It fires before paint, so anything you render from it appears in the same frame as the invalid styling. Consumer `isInvalid` is OR-ed with this validation: it can force the invalid state but cannot hide a rule violation. The same checks are available outside the component as `getDateValidationReason` and `formatDateValidationMessage`. Define `isDateUnavailable` outside the component or memoize it.
|
|
278
|
+
|
|
279
|
+
| Prop | Type | Default | Description |
|
|
280
|
+
| --- | --- | --- | --- |
|
|
281
|
+
| `className?` | `string` | — | — |
|
|
282
|
+
| `children?` | `ReactNode` | — | — |
|
|
283
|
+
| `asChild?` | `boolean` | — | — |
|
|
284
|
+
| `value?` | `DateId` | — | — |
|
|
285
|
+
| `defaultValue?` | `DateId` | — | — |
|
|
286
|
+
| `onValueChange?` | `((value: DateId) => void)` | — | — |
|
|
287
|
+
| `isOpen?` | `boolean` | — | Controlled open state. Use `defaultOpen` for the uncontrolled variant. |
|
|
288
|
+
| `defaultOpen?` | `boolean` | — | — |
|
|
289
|
+
| `onOpenChange?` | `((open: boolean) => void)` | — | — |
|
|
290
|
+
| `isDisabled?` | `boolean` | — | — |
|
|
291
|
+
| `isReadOnly?` | `boolean` | — | — |
|
|
292
|
+
| `isInvalid?` | `boolean` | — | Forces the invalid state. OR-ed with the picker's own validation: setting `true` marks the field invalid, but `false` never hides a `minValue` / `maxValue` / `isDateUnavailable` violation. |
|
|
293
|
+
| `isRequired?` | `boolean` | — | — |
|
|
294
|
+
| `minValue?` | `DateId` | — | Earliest selectable date, applied to the embedded calendar and to typed entry. Build with `dateId(...)`. |
|
|
295
|
+
| `maxValue?` | `DateId` | — | Latest selectable date, applied to the embedded calendar and to typed entry. Build with `dateId(...)`. |
|
|
296
|
+
| `isDateUnavailable?` | `((date: DateId) => boolean)` | — | Returns `true` for dates that cannot be selected, such as weekends or holidays. The calendar renders them disabled; a typed unavailable date is kept and emitted but renders invalid. Pass a stable (memoized) function. |
|
|
297
|
+
| `onValidationChange?` | `((reason: DateValidationReason, message: string) => void)` | — | Called when the committed value starts or stops violating `minValue`, `maxValue`, or `isDateUnavailable`, and again when the formatted message changes while the reason stays the same — a new bound, `locale`, or `labels` while the value is still `beforeMin`, for example. Receives the reason and its `labels` message formatted in `locale`, or `undefined` for both once the value is valid or cleared. Fires before paint, so state set here renders in the same frame as the invalid styling. Not needed to show the message: an empty `Field.Error` anywhere in the enclosing `Field` already renders it. |
|
|
298
|
+
| `name?` | `string` | — | — |
|
|
299
|
+
| `locale?` | `string` | — | — |
|
|
300
|
+
| `labels?` | `Partial<DateComponentLabels>` | — | — |
|
|
301
|
+
|
|
302
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
303
|
+
|
|
304
|
+
## Sub-components
|
|
305
|
+
|
|
306
|
+
### DatePicker.Trigger
|
|
307
|
+
|
|
308
|
+
Toggles the presentation surface and announces its expanded state. For an editable field, wrap only the `DatePicker.TriggerIndicator` inside a `DateField.Suffix`; for surface-driven selection, wrap the whole `DateField.Group` so the entire field is the tap target. Its accessible name defaults to the picker's `openDatePicker` label. Set `asChild` to merge its press and accessibility props onto a custom interactive child — for example an `IconButton` — instead of rendering the default pressable.
|
|
309
|
+
|
|
310
|
+
| Prop | Type | Default | Description |
|
|
311
|
+
| --- | --- | --- | --- |
|
|
312
|
+
| `className?` | `string` | — | — |
|
|
313
|
+
| `children?` | `ReactNode` | — | Either children or a render prop that receives a boolean reflecting whether the component is currently pressed. |
|
|
314
|
+
| `ref?` | `React.Ref<View>` | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). |
|
|
315
|
+
| `asChild?` | `boolean` | — | Merge press / a11y props onto the single child instead of rendering a `Pressable`. Use when the trigger should be another interactive host (e.g. `IconButton`). For a larger field hit target, prefer wrapping `DateField.Group` as children without `asChild` so the outer `Pressable` covers the whole input chrome. |
|
|
316
|
+
| `key?` | `React.Key \| null` | — | — |
|
|
317
|
+
|
|
318
|
+
Inherits all [`PressableProps`](https://reactnative.dev/docs/pressable#props).
|
|
319
|
+
|
|
320
|
+
### DatePicker.TriggerIndicator
|
|
321
|
+
|
|
322
|
+
Renders the calendar icon inside `DatePicker.Trigger`. Takes no props.
|
|
323
|
+
|
|
324
|
+
### DatePicker.Calendar
|
|
325
|
+
|
|
326
|
+
Renders the picker's `Calendar`, wired to the shared value, `minValue`, `maxValue`, `isDateUnavailable`, `locale`, and `labels`. Accepts all [`Calendar`](https://design.candescent.com/docs/components/calendar/content.md) props except `value`, `onValueChange`, `minValue`, `maxValue`, and `isDateUnavailable`, which the picker controls.
|
|
327
|
+
|
|
328
|
+
| Prop | Type | Default | Description |
|
|
329
|
+
| --- | --- | --- | --- |
|
|
330
|
+
| `className?` | `string` | — | — |
|
|
331
|
+
| `children?` | `ReactNode` | — | — |
|
|
332
|
+
| `ref?` | `React.Ref<View>` | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). |
|
|
333
|
+
| `defaultValue?` | `DateId` | — | Uncontrolled initial selection as a `YYYY-MM-DD` string. |
|
|
334
|
+
| `locale?` | `string` | — | BCP 47 locale for weekday and month formatting. Defaults to `en-US`. |
|
|
335
|
+
| `labels?` | `Partial<DateComponentLabels>` | — | — |
|
|
336
|
+
| `monthId?` | `MonthId` | — | Month shown in the grid as a `YYYY-MM-01` string. Follows the selected `value` unless controlled. |
|
|
337
|
+
| `defaultMonthId?` | `MonthId` | — | Uncontrolled initial month as a `YYYY-MM-01` string. |
|
|
338
|
+
| `onMonthIdChange?` | `((monthId: MonthId) => void)` | — | — |
|
|
339
|
+
| `disabled?` | `boolean` | — | — |
|
|
340
|
+
| `key?` | `React.Key \| null` | — | — |
|
|
341
|
+
|
|
342
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
343
|
+
|
|
344
|
+
### DatePicker.Popover
|
|
345
|
+
|
|
346
|
+
Presents the calendar in an anchored popover, positioned above or below the field based on available space. Wires the surface's open state and renders its children.
|
|
347
|
+
|
|
348
|
+
### DatePicker.Dialog
|
|
349
|
+
|
|
350
|
+
Presents the calendar in a modal dialog. Wires the surface's open state and renders its children.
|
|
351
|
+
|
|
352
|
+
### DatePicker.BottomSheet
|
|
353
|
+
|
|
354
|
+
Presents the calendar in a bottom sheet, the preferred surface on native. It wires open state only — compose `BottomSheet.Header` and `BottomSheet.Content` (or any sheet layout) as its children.
|
|
355
|
+
|
|
356
|
+
## Accessibility
|
|
357
|
+
|
|
358
|
+
Give the picker an accessible name with `Field.Label` or `aria-label`, and pass `aria-label` to `DatePicker.Calendar` to name the grid. `DatePicker.Trigger` announces the localized `openDatePicker` label, which `labels` can override. While `disabled`, the trigger does not open a surface.
|
|
359
|
+
|
|
360
|
+
Unavailable days render in the calendar's disabled state with no per-day reason announced, so add a `Field.Helper` that explains which days are unavailable and why — for example, "Payments process on business days only." When a typed date breaks a rule, `Field.Error` replaces the helper and is announced as an alert. On web the segments also carry `aria-invalid`; on iOS and Android, which have no equivalent, each segment's accessible name gains the localized `segmentInvalid` label (for example "Day, invalid") and its hint carries the error message.
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# Date Range Picker (https://design.candescent.com/docs/components/date-range-picker)
|
|
2
|
+
|
|
3
|
+
Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=12449-28564), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/date-time-daterangepicker--standalone)
|
|
4
|
+
|
|
5
|
+
`DateRangePicker` pairs two segmented `DateField` inputs with a `RangeCalendar` and coordinates the surface that presents it. The start and end values are `DateId` strings in `YYYY-MM-DD` format.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { DateField, DateRangePicker, Field } from '@cdx-ui/components';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic
|
|
12
|
+
|
|
13
|
+
Wrap the whole `DateField.Group` — a start input, a `DateRangePicker.RangeSeparator`, an end input, and a decorative `DateRangePicker.TriggerIndicator` in a `DateField.Suffix` — in a single `DateRangePicker.Trigger` so the entire range field is one large tap target. Because range selection is surface-driven, there is no typing to interrupt. `DateRangePicker.Popover` anchors to the field and is the preferred surface on web.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { useState } from 'react';
|
|
17
|
+
import { DateField, DateRangePicker, Field, type DateRangeValue } from '@cdx-ui/components';
|
|
18
|
+
|
|
19
|
+
export default function DateRangePickerBasicDemo() {
|
|
20
|
+
const [value, setValue] = useState<DateRangeValue | undefined>();
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Field className="w-full max-w-sm">
|
|
24
|
+
<DateRangePicker value={value} onValueChange={setValue}>
|
|
25
|
+
<Field.Label>Trip dates</Field.Label>
|
|
26
|
+
<DateRangePicker.Trigger className="w-full">
|
|
27
|
+
<DateField.Group fullWidth>
|
|
28
|
+
<DateField.Input slot="start" />
|
|
29
|
+
<DateRangePicker.RangeSeparator />
|
|
30
|
+
<DateField.Input slot="end" />
|
|
31
|
+
<DateField.Suffix>
|
|
32
|
+
<DateRangePicker.TriggerIndicator />
|
|
33
|
+
</DateField.Suffix>
|
|
34
|
+
</DateField.Group>
|
|
35
|
+
</DateRangePicker.Trigger>
|
|
36
|
+
<DateRangePicker.Popover>
|
|
37
|
+
<DateRangePicker.Calendar accessibilityLabel="Trip dates" />
|
|
38
|
+
</DateRangePicker.Popover>
|
|
39
|
+
</DateRangePicker>
|
|
40
|
+
</Field>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Dialog
|
|
46
|
+
|
|
47
|
+
Use `DateRangePicker.Dialog` to present the range calendar in a modal surface.
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { useState } from 'react';
|
|
51
|
+
import { DateField, DateRangePicker, Field, type DateRangeValue } from '@cdx-ui/components';
|
|
52
|
+
|
|
53
|
+
export default function DateRangePickerDialogDemo() {
|
|
54
|
+
const [value, setValue] = useState<DateRangeValue | undefined>();
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Field className="w-full max-w-sm">
|
|
58
|
+
<DateRangePicker value={value} onValueChange={setValue}>
|
|
59
|
+
<Field.Label>Trip dates</Field.Label>
|
|
60
|
+
<DateRangePicker.Trigger className="w-full">
|
|
61
|
+
<DateField.Group fullWidth>
|
|
62
|
+
<DateField.Input slot="start" />
|
|
63
|
+
<DateRangePicker.RangeSeparator />
|
|
64
|
+
<DateField.Input slot="end" />
|
|
65
|
+
<DateField.Suffix>
|
|
66
|
+
<DateRangePicker.TriggerIndicator />
|
|
67
|
+
</DateField.Suffix>
|
|
68
|
+
</DateField.Group>
|
|
69
|
+
</DateRangePicker.Trigger>
|
|
70
|
+
<DateRangePicker.Dialog>
|
|
71
|
+
<DateRangePicker.Calendar accessibilityLabel="Trip dates" />
|
|
72
|
+
</DateRangePicker.Dialog>
|
|
73
|
+
</DateRangePicker>
|
|
74
|
+
</Field>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Bottom sheet
|
|
80
|
+
|
|
81
|
+
Use `DateRangePicker.BottomSheet` to present the range calendar in a sheet that slides up from the bottom — the preferred surface on native. It wires open state only, so compose `BottomSheet.Header` and `BottomSheet.Content` as its children.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import { useState } from 'react';
|
|
85
|
+
import {
|
|
86
|
+
BottomSheet,
|
|
87
|
+
DateField,
|
|
88
|
+
DateRangePicker,
|
|
89
|
+
Field,
|
|
90
|
+
type DateRangeValue,
|
|
91
|
+
} from '@cdx-ui/components';
|
|
92
|
+
import { PickerBottomSheetFrame } from './_frame';
|
|
93
|
+
|
|
94
|
+
export default function DateRangePickerBottomSheetDemo() {
|
|
95
|
+
const [value, setValue] = useState<DateRangeValue | undefined>();
|
|
96
|
+
const [open, setOpen] = useState(false);
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<PickerBottomSheetFrame>
|
|
100
|
+
<Field className="w-full max-w-sm">
|
|
101
|
+
<DateRangePicker
|
|
102
|
+
value={value}
|
|
103
|
+
onValueChange={setValue}
|
|
104
|
+
isOpen={open}
|
|
105
|
+
onOpenChange={setOpen}
|
|
106
|
+
>
|
|
107
|
+
<Field.Label>Trip dates</Field.Label>
|
|
108
|
+
<DateRangePicker.Trigger className="w-full">
|
|
109
|
+
<DateField.Group fullWidth>
|
|
110
|
+
<DateField.Input slot="start" />
|
|
111
|
+
<DateRangePicker.RangeSeparator />
|
|
112
|
+
<DateField.Input slot="end" />
|
|
113
|
+
<DateField.Suffix>
|
|
114
|
+
<DateRangePicker.TriggerIndicator />
|
|
115
|
+
</DateField.Suffix>
|
|
116
|
+
</DateField.Group>
|
|
117
|
+
</DateRangePicker.Trigger>
|
|
118
|
+
<DateRangePicker.BottomSheet>
|
|
119
|
+
<BottomSheet.Header title="Select dates" onClose={() => setOpen(false)} />
|
|
120
|
+
<BottomSheet.Content>
|
|
121
|
+
<DateRangePicker.Calendar accessibilityLabel="Trip dates" />
|
|
122
|
+
</BottomSheet.Content>
|
|
123
|
+
</DateRangePicker.BottomSheet>
|
|
124
|
+
</DateRangePicker>
|
|
125
|
+
</Field>
|
|
126
|
+
</PickerBottomSheetFrame>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Standalone
|
|
132
|
+
|
|
133
|
+
Render a `DateRangePicker.Calendar` inline instead of a presentation surface when the fields and calendar share the screen.
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import { useState } from 'react';
|
|
137
|
+
import { DateField, DateRangePicker, Field, type DateRangeValue } from '@cdx-ui/components';
|
|
138
|
+
|
|
139
|
+
export default function DateRangePickerStandaloneDemo() {
|
|
140
|
+
const [value, setValue] = useState<DateRangeValue | undefined>();
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<Field className="w-full max-w-sm">
|
|
144
|
+
<DateRangePicker value={value} onValueChange={setValue}>
|
|
145
|
+
<Field.Label>Trip dates</Field.Label>
|
|
146
|
+
<DateField.Group fullWidth>
|
|
147
|
+
<DateField.Input slot="start" />
|
|
148
|
+
<DateRangePicker.RangeSeparator />
|
|
149
|
+
<DateField.Input slot="end" />
|
|
150
|
+
</DateField.Group>
|
|
151
|
+
<DateRangePicker.Calendar className="mt-2" accessibilityLabel="Trip dates" />
|
|
152
|
+
</DateRangePicker>
|
|
153
|
+
</Field>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Custom trigger
|
|
159
|
+
|
|
160
|
+
Set `asChild` on `DateRangePicker.Trigger` to drive selection from a custom pressable such as a `Chip` — ideal for a filter row where the chip reflects the active range. The trigger merges its press and expanded-state accessibility props onto the child.
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
import { useState } from 'react';
|
|
164
|
+
import { Box, Chip, DateRangePicker, type DateRangeValue } from '@cdx-ui/components';
|
|
165
|
+
import { CalendarToday } from '@cdx-ui/icons';
|
|
166
|
+
|
|
167
|
+
const monthDay = new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric' });
|
|
168
|
+
|
|
169
|
+
function formatDateId(id: string) {
|
|
170
|
+
const [year, month, day] = id.split('-').map(Number);
|
|
171
|
+
return monthDay.format(new Date(year, month - 1, day));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function formatRange(value: DateRangeValue | undefined) {
|
|
175
|
+
if (!value?.startId) return 'Any dates';
|
|
176
|
+
if (!value.endId) return `${formatDateId(value.startId)} – …`;
|
|
177
|
+
return `${formatDateId(value.startId)} – ${formatDateId(value.endId)}`;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export default function DateRangePickerCustomTriggerDemo() {
|
|
181
|
+
const [value, setValue] = useState<DateRangeValue | undefined>();
|
|
182
|
+
const hasRange = !!value?.startId;
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<DateRangePicker value={value} onValueChange={setValue}>
|
|
186
|
+
<Box className="flex-row flex-wrap items-center gap-2">
|
|
187
|
+
<Chip variant="outline">
|
|
188
|
+
<Chip.Label>All accounts</Chip.Label>
|
|
189
|
+
</Chip>
|
|
190
|
+
<DateRangePicker.Trigger asChild>
|
|
191
|
+
<Chip variant={hasRange ? 'subtle' : 'outline'} color={hasRange ? 'action' : 'neutral'}>
|
|
192
|
+
<Chip.Icon as={CalendarToday} position="leading" />
|
|
193
|
+
<Chip.Label>{formatRange(value)}</Chip.Label>
|
|
194
|
+
</Chip>
|
|
195
|
+
</DateRangePicker.Trigger>
|
|
196
|
+
<Chip variant="outline">
|
|
197
|
+
<Chip.Label>All statuses</Chip.Label>
|
|
198
|
+
</Chip>
|
|
199
|
+
</Box>
|
|
200
|
+
<DateRangePicker.Popover>
|
|
201
|
+
<DateRangePicker.Calendar accessibilityLabel="Filter by date range" />
|
|
202
|
+
</DateRangePicker.Popover>
|
|
203
|
+
</DateRangePicker>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## API
|
|
209
|
+
|
|
210
|
+
### DateRangePicker
|
|
211
|
+
|
|
212
|
+
Root of the compound. Owns the start and end values, open state, `locale`, and `labels`, and provides `DateField` styling context to the fields. Compose exactly one presentation surface — `DateRangePicker.Popover`, `DateRangePicker.Dialog`, or `DateRangePicker.BottomSheet` — per picker.
|
|
213
|
+
|
|
214
|
+
| Prop | Type | Default | Description |
|
|
215
|
+
| --- | --- | --- | --- |
|
|
216
|
+
| `className?` | `string` | — | — |
|
|
217
|
+
| `children?` | `ReactNode` | — | — |
|
|
218
|
+
| `asChild?` | `boolean` | — | — |
|
|
219
|
+
| `value?` | `DateRangeValue` | — | Controlled range value as `{ startId, endId? }`. Build the ids with `dateId(...)` from `@cdx-ui/formatters` — a bare string will not type-check. |
|
|
220
|
+
| `defaultValue?` | `DateRangeValue` | — | Uncontrolled initial range, in the same shape as `value`. |
|
|
221
|
+
| `onValueChange?` | `((value: DateRangeValue) => void)` | — | Called as the range changes. Emits `{ startId, endId? }` during selection — a **partial** range (with `endId` undefined) is emitted after the first endpoint is picked — and `undefined` when the range is fully cleared. |
|
|
222
|
+
| `focusedField?` | `'start' \| 'end'` | — | — |
|
|
223
|
+
| `defaultFocusedField?` | `'start' \| 'end'` | — | — |
|
|
224
|
+
| `onFocusedFieldChange?` | `((field: RangeCalendarFocus) => void)` | — | — |
|
|
225
|
+
| `isOpen?` | `boolean` | — | Controlled open state. Use `defaultOpen` for the uncontrolled variant. |
|
|
226
|
+
| `defaultOpen?` | `boolean` | — | — |
|
|
227
|
+
| `onOpenChange?` | `((open: boolean) => void)` | — | — |
|
|
228
|
+
| `isDisabled?` | `boolean` | — | — |
|
|
229
|
+
| `isReadOnly?` | `boolean` | — | — |
|
|
230
|
+
| `isInvalid?` | `boolean` | — | — |
|
|
231
|
+
| `isRequired?` | `boolean` | — | — |
|
|
232
|
+
| `locale?` | `string` | — | — |
|
|
233
|
+
| `labels?` | `Partial<DateComponentLabels>` | — | — |
|
|
234
|
+
| `name?` | `string` | — | Form field name used when the selected range is submitted. |
|
|
235
|
+
|
|
236
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
237
|
+
|
|
238
|
+
## Sub-components
|
|
239
|
+
|
|
240
|
+
### DateRangePicker.Trigger
|
|
241
|
+
|
|
242
|
+
Toggles the presentation surface and announces its expanded state. Because range selection is surface-driven, wrap the entire `DateField.Group` so the whole field is the tap target, with a decorative `DateRangePicker.TriggerIndicator` in the `DateField.Suffix`. Its accessible name defaults to the picker's `openDateRangePicker` label. Set `asChild` to merge its press and accessibility props onto a custom interactive child — for example an `IconButton` — instead of rendering the default pressable.
|
|
243
|
+
|
|
244
|
+
| Prop | Type | Default | Description |
|
|
245
|
+
| --- | --- | --- | --- |
|
|
246
|
+
| `className?` | `string` | — | — |
|
|
247
|
+
| `children?` | `ReactNode` | — | Either children or a render prop that receives a boolean reflecting whether the component is currently pressed. |
|
|
248
|
+
| `ref?` | `React.Ref<View>` | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). |
|
|
249
|
+
| `asChild?` | `boolean` | — | Merge press / a11y props onto the single child instead of rendering a `Pressable`. Use when the trigger should be another interactive host (e.g. `IconButton`). For a larger field hit target, prefer wrapping `DateField.Group` as children without `asChild` so the outer `Pressable` covers the whole input chrome. |
|
|
250
|
+
| `key?` | `React.Key \| null` | — | — |
|
|
251
|
+
|
|
252
|
+
Inherits all [`PressableProps`](https://reactnative.dev/docs/pressable#props).
|
|
253
|
+
|
|
254
|
+
### DateRangePicker.TriggerIndicator
|
|
255
|
+
|
|
256
|
+
Renders the decorative calendar icon, typically inside the `DateField.Suffix` of a full-field `DateRangePicker.Trigger`. Takes no props.
|
|
257
|
+
|
|
258
|
+
### DateRangePicker.RangeSeparator
|
|
259
|
+
|
|
260
|
+
Renders the localized separator between the start and end inputs. Takes no props.
|
|
261
|
+
|
|
262
|
+
### DateRangePicker.Calendar
|
|
263
|
+
|
|
264
|
+
Renders the picker's `RangeCalendar`, wired to the shared start and end values, `locale`, and `labels`. Accepts all [`RangeCalendar`](https://design.candescent.com/docs/components/range-calendar/content.md) props except the range value and focus props, which the picker controls.
|
|
265
|
+
|
|
266
|
+
| Prop | Type | Default | Description |
|
|
267
|
+
| --- | --- | --- | --- |
|
|
268
|
+
| `className?` | `string` | — | Additional Uniwind/Tailwind classes, merged after the calendar's own styles. |
|
|
269
|
+
| `children?` | `ReactNode` | — | Custom calendar body. Omit to render the default header and month grid. |
|
|
270
|
+
| `ref?` | `React.Ref<View>` | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). |
|
|
271
|
+
| `asChild?` | `boolean` | — | Render the consumer's child element in place of the default `View` host. |
|
|
272
|
+
| `defaultFocusedField?` | `'start' \| 'end'` | `'start'` | Initial active field when uncontrolled. |
|
|
273
|
+
| `locale?` | `string` | `'en-US'` | BCP 47 locale for month and weekday names. |
|
|
274
|
+
| `labels?` | `Partial<DateComponentLabels>` | — | Overrides for the built-in UI copy, such as the previous- and next-month button labels. |
|
|
275
|
+
| `defaultStartValue?` | `DateId` | — | Initial range start when uncontrolled. |
|
|
276
|
+
| `defaultEndValue?` | `DateId` | — | Initial range end when uncontrolled. |
|
|
277
|
+
| `monthId?` | `MonthId` | — | Controlled visible month. When set, `defaultMonthId` has no effect. |
|
|
278
|
+
| `defaultMonthId?` | `MonthId` | — | Initial visible month when uncontrolled. Defaults to the month of the range, or today. |
|
|
279
|
+
| `onMonthIdChange?` | `((monthId: MonthId) => void)` | — | Called with the new visible month when the user navigates months. |
|
|
280
|
+
| `minValue?` | `DateId` | — | Earliest selectable date. Build with `dateId(...)` from `@cdx-ui/formatters`. |
|
|
281
|
+
| `maxValue?` | `DateId` | — | Latest selectable date. Build with `dateId(...)` from `@cdx-ui/formatters`. |
|
|
282
|
+
| `disabled?` | `boolean` | `false` | Prevents day selection and month navigation. |
|
|
283
|
+
| `key?` | `React.Key \| null` | — | — |
|
|
284
|
+
|
|
285
|
+
Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
|
|
286
|
+
|
|
287
|
+
### DateRangePicker.Popover
|
|
288
|
+
|
|
289
|
+
Presents the range calendar in an anchored popover, positioned above or below the field based on available space. Wires the surface's open state and renders its children.
|
|
290
|
+
|
|
291
|
+
### DateRangePicker.Dialog
|
|
292
|
+
|
|
293
|
+
Presents the range calendar in a modal dialog. Wires the surface's open state and renders its children.
|
|
294
|
+
|
|
295
|
+
### DateRangePicker.BottomSheet
|
|
296
|
+
|
|
297
|
+
Presents the range calendar in a bottom sheet, the preferred surface on native. It wires open state only — compose `BottomSheet.Header` and `BottomSheet.Content` (or any sheet layout) as its children.
|
|
298
|
+
|
|
299
|
+
## Accessibility
|
|
300
|
+
|
|
301
|
+
Give the picker an accessible name with `Field.Label` or `aria-label`, and pass `aria-label` to `DateRangePicker.Calendar` to name the grid. `DateRangePicker.Trigger` announces the localized `openDateRangePicker` label, which `labels` can override. While `disabled`, the trigger does not open a surface.
|