@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
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
type IMenuTriggerProps,
|
|
36
36
|
} from '@cdx-ui/primitives';
|
|
37
37
|
import { cn, ParentContext, useParentContext, useStyleContext } from '@cdx-ui/utils';
|
|
38
|
+
import { ScrollShadow } from '../ScrollShadow';
|
|
38
39
|
import { Icon, type IconProps } from '../Icon';
|
|
39
40
|
import { checkboxIconVariants, checkboxIndicatorVariants } from '../Checkbox/styles';
|
|
40
41
|
import { radioIndicatorVariants, radioInnerDotVariants } from '../Radio/styles';
|
|
@@ -98,7 +99,10 @@ const useMenuItemStyleValue = (
|
|
|
98
99
|
// =============================================================================
|
|
99
100
|
|
|
100
101
|
export interface MenuProps extends ViewProps, IMenuOverlayRootProps {
|
|
102
|
+
/** Additional Uniwind/Tailwind classes, merged after the root's own styles. */
|
|
101
103
|
className?: string;
|
|
104
|
+
/** The `Menu.Trigger` and `Menu.Popup`. */
|
|
105
|
+
children?: ReactNode;
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
const MenuOverlayRoot = forwardRef<View, MenuProps>(
|
|
@@ -122,7 +126,9 @@ MenuOverlayRoot.displayName = 'Menu';
|
|
|
122
126
|
// =============================================================================
|
|
123
127
|
|
|
124
128
|
export interface MenuTriggerProps extends IMenuTriggerProps {
|
|
129
|
+
/** Additional Uniwind/Tailwind classes, merged after the trigger's own styles. */
|
|
125
130
|
className?: string;
|
|
131
|
+
/** Trigger content (or the element to render when `asChild` is set). */
|
|
126
132
|
children?: ReactNode;
|
|
127
133
|
}
|
|
128
134
|
|
|
@@ -147,7 +153,9 @@ MenuTrigger.displayName = 'Menu.Trigger';
|
|
|
147
153
|
// =============================================================================
|
|
148
154
|
|
|
149
155
|
export interface MenuPopupProps extends IMenuPopupProps {
|
|
156
|
+
/** Additional Uniwind/Tailwind classes, merged after the popup's own styles. */
|
|
150
157
|
className?: string;
|
|
158
|
+
/** Popup content, typically a `Menu.Content`. */
|
|
151
159
|
children?: ReactNode;
|
|
152
160
|
}
|
|
153
161
|
|
|
@@ -178,8 +186,16 @@ MenuPopup.displayName = 'Menu.Popup';
|
|
|
178
186
|
// =============================================================================
|
|
179
187
|
|
|
180
188
|
export interface MenuContentProps
|
|
181
|
-
extends ViewProps, Omit<IMenuProps, 'scrollable'>, MenuRootVariantProps {
|
|
189
|
+
extends ViewProps, Omit<IMenuProps, 'scrollable'>, Omit<MenuRootVariantProps, 'scrollable'> {
|
|
190
|
+
/** Additional Uniwind/Tailwind classes, merged after the menu surface's own styles. */
|
|
182
191
|
className?: string;
|
|
192
|
+
/**
|
|
193
|
+
* Caps the surface height and scrolls its items. Content inside a `Menu.Popup` always scrolls.
|
|
194
|
+
* @default false
|
|
195
|
+
*/
|
|
196
|
+
scrollable?: MenuRootVariantProps['scrollable'];
|
|
197
|
+
/** The menu's items, groups and separators. */
|
|
198
|
+
children?: ReactNode;
|
|
183
199
|
/** Visual-only surface without menu semantics (e.g. inside Select listbox). */
|
|
184
200
|
asSurface?: boolean;
|
|
185
201
|
}
|
|
@@ -207,14 +223,16 @@ const MenuContent = forwardRef<View, MenuContentProps>(
|
|
|
207
223
|
: mergeDataAttributes(props, dataAttributes({ slot: 'menu-content' }));
|
|
208
224
|
|
|
209
225
|
const content = shouldScroll ? (
|
|
210
|
-
<
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
226
|
+
<ScrollShadow className="shrink" style={constrainedStyle} surface="primary">
|
|
227
|
+
<ScrollView
|
|
228
|
+
className="shrink"
|
|
229
|
+
style={[MENU_SCROLL_STYLE, constrainedStyle]}
|
|
230
|
+
scrollEventThrottle={16}
|
|
231
|
+
nestedScrollEnabled
|
|
232
|
+
>
|
|
233
|
+
{children}
|
|
234
|
+
</ScrollView>
|
|
235
|
+
</ScrollShadow>
|
|
218
236
|
) : (
|
|
219
237
|
children
|
|
220
238
|
);
|
|
@@ -241,14 +259,28 @@ MenuContent.displayName = 'Menu.Content';
|
|
|
241
259
|
// ITEM
|
|
242
260
|
// =============================================================================
|
|
243
261
|
|
|
244
|
-
export interface MenuItemProps
|
|
262
|
+
export interface MenuItemProps
|
|
263
|
+
extends Omit<MenuItemVariantProps, 'color' | 'inset' | 'layout'>, IMenuItemProps {
|
|
264
|
+
/** Render the consumer's child element in place of the default `Pressable` host. */
|
|
245
265
|
asChild?: boolean;
|
|
246
266
|
/**
|
|
247
267
|
* Color theme applied to the item content and interaction states.
|
|
248
268
|
* @default 'neutral'
|
|
249
269
|
*/
|
|
250
270
|
color?: 'neutral' | 'danger';
|
|
271
|
+
/**
|
|
272
|
+
* Indents the item content so its label lines up with items that have a leading icon.
|
|
273
|
+
* @default false
|
|
274
|
+
*/
|
|
275
|
+
inset?: MenuItemVariantProps['inset'];
|
|
276
|
+
/**
|
|
277
|
+
* Set automatically: `filter` when the item contains a `Menu.ItemControl` or `Menu.ItemAction`.
|
|
278
|
+
* @internal
|
|
279
|
+
*/
|
|
280
|
+
layout?: MenuItemVariantProps['layout'];
|
|
281
|
+
/** Additional Uniwind/Tailwind classes, merged after the item's own styles. */
|
|
251
282
|
className?: string;
|
|
283
|
+
/** Item content, typically a `Menu.ItemLabel` with optional icon, shortcut and indicator slots. */
|
|
252
284
|
children?: ReactNode;
|
|
253
285
|
}
|
|
254
286
|
|
|
@@ -279,10 +311,27 @@ const MenuItem = forwardRef<View, MenuItemProps>(
|
|
|
279
311
|
MenuItem.displayName = 'Menu.Item';
|
|
280
312
|
|
|
281
313
|
export interface MenuCheckboxItemProps
|
|
282
|
-
extends Omit<MenuItemVariantProps, 'color'>, IMenuCheckboxItemProps {
|
|
314
|
+
extends Omit<MenuItemVariantProps, 'color' | 'inset' | 'layout'>, IMenuCheckboxItemProps {
|
|
315
|
+
/** Render the consumer's child element in place of the default `Pressable` host. */
|
|
283
316
|
asChild?: boolean;
|
|
317
|
+
/**
|
|
318
|
+
* Color theme applied to the item content and interaction states.
|
|
319
|
+
* @default 'neutral'
|
|
320
|
+
*/
|
|
284
321
|
color?: 'neutral' | 'danger';
|
|
322
|
+
/**
|
|
323
|
+
* Indents the item content so its label lines up with items that have a leading icon.
|
|
324
|
+
* @default false
|
|
325
|
+
*/
|
|
326
|
+
inset?: MenuItemVariantProps['inset'];
|
|
327
|
+
/**
|
|
328
|
+
* Set automatically: `filter` when the item contains a `Menu.ItemControl` or `Menu.ItemAction`.
|
|
329
|
+
* @internal
|
|
330
|
+
*/
|
|
331
|
+
layout?: MenuItemVariantProps['layout'];
|
|
332
|
+
/** Additional Uniwind/Tailwind classes, merged after the item's own styles. */
|
|
285
333
|
className?: string;
|
|
334
|
+
/** Item content, typically a `Menu.ItemLabel` with optional icon, shortcut and indicator slots. */
|
|
286
335
|
children?: ReactNode;
|
|
287
336
|
}
|
|
288
337
|
|
|
@@ -311,8 +360,11 @@ const MenuCheckboxItem = forwardRef<View, MenuCheckboxItemProps>(
|
|
|
311
360
|
MenuCheckboxItem.displayName = 'Menu.CheckboxItem';
|
|
312
361
|
|
|
313
362
|
export interface MenuRadioGroupProps extends IMenuRadioGroupProps {
|
|
363
|
+
/** Render the consumer's child element in place of the default `View` host. */
|
|
314
364
|
asChild?: boolean;
|
|
365
|
+
/** Additional Uniwind/Tailwind classes, merged after the group's own styles. */
|
|
315
366
|
className?: string;
|
|
367
|
+
/** The `Menu.RadioItem` options in the group. */
|
|
316
368
|
children?: ReactNode;
|
|
317
369
|
}
|
|
318
370
|
|
|
@@ -334,10 +386,27 @@ const MenuRadioGroup = forwardRef<View, MenuRadioGroupProps>(
|
|
|
334
386
|
MenuRadioGroup.displayName = 'Menu.RadioGroup';
|
|
335
387
|
|
|
336
388
|
export interface MenuRadioItemProps
|
|
337
|
-
extends Omit<MenuItemVariantProps, 'color'>, IMenuRadioItemProps {
|
|
389
|
+
extends Omit<MenuItemVariantProps, 'color' | 'inset' | 'layout'>, IMenuRadioItemProps {
|
|
390
|
+
/** Render the consumer's child element in place of the default `Pressable` host. */
|
|
338
391
|
asChild?: boolean;
|
|
392
|
+
/**
|
|
393
|
+
* Color theme applied to the item content and interaction states.
|
|
394
|
+
* @default 'neutral'
|
|
395
|
+
*/
|
|
339
396
|
color?: 'neutral' | 'danger';
|
|
397
|
+
/**
|
|
398
|
+
* Indents the item content so its label lines up with items that have a leading icon.
|
|
399
|
+
* @default false
|
|
400
|
+
*/
|
|
401
|
+
inset?: MenuItemVariantProps['inset'];
|
|
402
|
+
/**
|
|
403
|
+
* Set automatically: `filter` when the item contains a `Menu.ItemControl` or `Menu.ItemAction`.
|
|
404
|
+
* @internal
|
|
405
|
+
*/
|
|
406
|
+
layout?: MenuItemVariantProps['layout'];
|
|
407
|
+
/** Additional Uniwind/Tailwind classes, merged after the item's own styles. */
|
|
340
408
|
className?: string;
|
|
409
|
+
/** Item content, typically a `Menu.ItemLabel` with optional icon, shortcut and indicator slots. */
|
|
341
410
|
children?: ReactNode;
|
|
342
411
|
}
|
|
343
412
|
|
|
@@ -383,8 +452,12 @@ MenuRadioItem.displayName = 'Menu.RadioItem';
|
|
|
383
452
|
// =============================================================================
|
|
384
453
|
|
|
385
454
|
export interface MenuItemLabelProps extends TextProps {
|
|
455
|
+
/** Render the consumer's child element in place of the default `Text` host. */
|
|
386
456
|
asChild?: boolean;
|
|
457
|
+
/** Additional Uniwind/Tailwind classes, merged after the label's own styles. */
|
|
387
458
|
className?: string;
|
|
459
|
+
/** Label text. */
|
|
460
|
+
children?: ReactNode;
|
|
388
461
|
/** Checked state when used outside a selectable Menu item (e.g. `Select.ItemLabel`). */
|
|
389
462
|
isChecked?: boolean;
|
|
390
463
|
}
|
|
@@ -423,10 +496,18 @@ const MenuItemLabel = forwardRef<Text, MenuItemLabelProps>(
|
|
|
423
496
|
MenuItemLabel.displayName = 'Menu.ItemLabel';
|
|
424
497
|
|
|
425
498
|
export interface MenuItemIconProps extends Omit<IconProps, 'as' | 'children' | 'color'> {
|
|
499
|
+
/** Render the consumer's child element in place of the icon. */
|
|
426
500
|
asChild?: boolean;
|
|
501
|
+
/** The `@cdx-ui/icons` component to render. */
|
|
427
502
|
as?: IconProps['as'];
|
|
503
|
+
/**
|
|
504
|
+
* Side of the label the icon sits on; sets the spacing between them.
|
|
505
|
+
* @default 'leading'
|
|
506
|
+
*/
|
|
428
507
|
position?: IconSlotPosition;
|
|
508
|
+
/** Additional Uniwind/Tailwind classes, merged after the icon's own styles. */
|
|
429
509
|
className?: string;
|
|
510
|
+
/** The element to render when `asChild` is set. */
|
|
430
511
|
children?: ReactNode;
|
|
431
512
|
}
|
|
432
513
|
|
|
@@ -482,8 +563,12 @@ const MenuItemIcon = ({
|
|
|
482
563
|
MenuItemIcon.displayName = 'Menu.ItemIcon';
|
|
483
564
|
|
|
484
565
|
export interface MenuItemShortcutProps extends TextProps {
|
|
566
|
+
/** Render the consumer's child element in place of the default `Text` host. */
|
|
485
567
|
asChild?: boolean;
|
|
568
|
+
/** Additional Uniwind/Tailwind classes, merged after the shortcut's own styles. */
|
|
486
569
|
className?: string;
|
|
570
|
+
/** Shortcut hint text, such as `⌘C`. */
|
|
571
|
+
children?: ReactNode;
|
|
487
572
|
}
|
|
488
573
|
|
|
489
574
|
const MenuItemShortcut = forwardRef<Text, MenuItemShortcutProps>(
|
|
@@ -509,11 +594,23 @@ const MenuItemShortcut = forwardRef<Text, MenuItemShortcutProps>(
|
|
|
509
594
|
MenuItemShortcut.displayName = 'Menu.ItemShortcut';
|
|
510
595
|
|
|
511
596
|
export interface MenuItemIndicatorProps extends Omit<IconProps, 'as' | 'children' | 'color'> {
|
|
597
|
+
/** Render the consumer's child element in place of the icon. */
|
|
512
598
|
asChild?: boolean;
|
|
599
|
+
/**
|
|
600
|
+
* The `@cdx-ui/icons` component to render.
|
|
601
|
+
* @default Check
|
|
602
|
+
*/
|
|
513
603
|
as?: IconProps['as'];
|
|
604
|
+
/** Shows the indicator. Defaults to the checked state of the enclosing item. */
|
|
514
605
|
isChecked?: boolean;
|
|
606
|
+
/**
|
|
607
|
+
* Side of the label the indicator sits on; sets the spacing between them.
|
|
608
|
+
* @default 'trailing'
|
|
609
|
+
*/
|
|
515
610
|
position?: IconSlotPosition;
|
|
611
|
+
/** Additional Uniwind/Tailwind classes, merged after the indicator's own styles. */
|
|
516
612
|
className?: string;
|
|
613
|
+
/** The element to render when `asChild` is set. */
|
|
517
614
|
children?: ReactNode;
|
|
518
615
|
}
|
|
519
616
|
|
|
@@ -575,8 +672,12 @@ MenuItemIndicator.displayName = 'Menu.ItemIndicator';
|
|
|
575
672
|
// =============================================================================
|
|
576
673
|
|
|
577
674
|
export interface MenuSectionLabelProps extends TextProps {
|
|
675
|
+
/** Render the consumer's child element in place of the default `Text` host. */
|
|
578
676
|
asChild?: boolean;
|
|
677
|
+
/** Additional Uniwind/Tailwind classes, merged after the section label's own styles. */
|
|
579
678
|
className?: string;
|
|
679
|
+
/** Section heading text. */
|
|
680
|
+
children?: ReactNode;
|
|
580
681
|
}
|
|
581
682
|
|
|
582
683
|
const MenuSectionLabel = forwardRef<Text, MenuSectionLabelProps>(
|
|
@@ -601,7 +702,10 @@ const MenuSectionLabel = forwardRef<Text, MenuSectionLabelProps>(
|
|
|
601
702
|
MenuSectionLabel.displayName = 'Menu.SectionLabel';
|
|
602
703
|
|
|
603
704
|
export interface MenuSeparatorProps extends ViewProps {
|
|
705
|
+
/** Additional Uniwind/Tailwind classes, merged after the separator's own styles. */
|
|
604
706
|
className?: string;
|
|
707
|
+
/** Not rendered; the separator draws its own line. */
|
|
708
|
+
children?: ReactNode;
|
|
605
709
|
}
|
|
606
710
|
|
|
607
711
|
const MenuSeparator = forwardRef<View, MenuSeparatorProps>(
|
|
@@ -630,8 +734,11 @@ MenuSeparator.displayName = 'Menu.Separator';
|
|
|
630
734
|
// =============================================================================
|
|
631
735
|
|
|
632
736
|
export interface MenuGroupHeaderProps extends ViewProps {
|
|
737
|
+
/** Render the consumer's child element in place of the default `View` host. */
|
|
633
738
|
asChild?: boolean;
|
|
739
|
+
/** Additional Uniwind/Tailwind classes, merged after the group header's own styles. */
|
|
634
740
|
className?: string;
|
|
741
|
+
/** Header content, typically a `Menu.ItemLabel` and an optional `Menu.ItemAction`. */
|
|
635
742
|
children?: ReactNode;
|
|
636
743
|
}
|
|
637
744
|
|
|
@@ -666,7 +773,9 @@ const MenuGroupHeader = forwardRef<View, MenuGroupHeaderProps>(
|
|
|
666
773
|
MenuGroupHeader.displayName = 'Menu.GroupHeader';
|
|
667
774
|
|
|
668
775
|
export interface MenuItemActionProps extends IMenuItemActionProps {
|
|
776
|
+
/** Additional Uniwind/Tailwind classes, merged after the action's own styles. */
|
|
669
777
|
className?: string;
|
|
778
|
+
/** The trailing interactive control, such as a `Button`. */
|
|
670
779
|
children?: ReactNode;
|
|
671
780
|
}
|
|
672
781
|
|
|
@@ -688,7 +797,10 @@ const MenuItemAction = forwardRef<View, MenuItemActionProps>(
|
|
|
688
797
|
MenuItemAction.displayName = 'Menu.ItemAction';
|
|
689
798
|
|
|
690
799
|
export interface MenuItemControlProps extends ViewProps {
|
|
800
|
+
/** Additional Uniwind/Tailwind classes, merged after the control's own styles. */
|
|
691
801
|
className?: string;
|
|
802
|
+
/** Not rendered; the control draws a checkbox or radio that mirrors the enclosing item. */
|
|
803
|
+
children?: ReactNode;
|
|
692
804
|
}
|
|
693
805
|
|
|
694
806
|
const MenuItemControl = ({ className, style, ...props }: MenuItemControlProps) => {
|
|
@@ -740,8 +852,12 @@ const MenuItemControl = ({ className, style, ...props }: MenuItemControlProps) =
|
|
|
740
852
|
MenuItemControl.displayName = 'Menu.ItemControl';
|
|
741
853
|
|
|
742
854
|
export interface MenuItemCountProps extends TextProps {
|
|
855
|
+
/** Render the consumer's child element in place of the default `Text` host. */
|
|
743
856
|
asChild?: boolean;
|
|
857
|
+
/** Additional Uniwind/Tailwind classes, merged after the count's own styles. */
|
|
744
858
|
className?: string;
|
|
859
|
+
/** The count to display. */
|
|
860
|
+
children?: ReactNode;
|
|
745
861
|
}
|
|
746
862
|
|
|
747
863
|
const MenuItemCount = forwardRef<Text, MenuItemCountProps>(
|
|
@@ -22,7 +22,9 @@ import { calendarRootVariants } from '../Calendar/styles';
|
|
|
22
22
|
|
|
23
23
|
export interface RangeCalendarProps
|
|
24
24
|
extends Omit<RangeCalendarRootProps, 'children'>, Omit<ViewProps, 'children'> {
|
|
25
|
+
/** Additional Uniwind/Tailwind classes, merged after the calendar's own styles. */
|
|
25
26
|
className?: string;
|
|
27
|
+
/** Custom calendar body. Omit to render the default header and month grid. */
|
|
26
28
|
children?: ReactNode;
|
|
27
29
|
}
|
|
28
30
|
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Fragment,
|
|
3
|
+
forwardRef,
|
|
4
|
+
useEffect,
|
|
5
|
+
useMemo,
|
|
6
|
+
type ForwardedRef,
|
|
7
|
+
type ReactElement,
|
|
8
|
+
type ReactNode,
|
|
9
|
+
} from 'react';
|
|
10
|
+
import { ScrollView, StyleSheet, type ScrollViewProps, type ViewStyle } from 'react-native';
|
|
11
|
+
import { dataAttributes, mergeDataAttributes } from '@cdx-ui/primitives';
|
|
12
|
+
import { findDuplicateKeys } from './useReorder';
|
|
13
|
+
|
|
14
|
+
export interface ReorderableRowInfo<T> {
|
|
15
|
+
item: T;
|
|
16
|
+
/** Consumer key from `keyExtractor`. */
|
|
17
|
+
key: string;
|
|
18
|
+
/** Position of `item` in `data`. */
|
|
19
|
+
index: number;
|
|
20
|
+
count: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ReorderableListSharedProps<T> extends Omit<ScrollViewProps, 'children'> {
|
|
24
|
+
data: T[];
|
|
25
|
+
keyExtractor: (item: T, index: number) => string;
|
|
26
|
+
/** Renders each row. Ignored when `children` is set. */
|
|
27
|
+
renderRow?: (info: ReorderableRowInfo<T>) => ReactNode;
|
|
28
|
+
/** Replaces the per-row rendering (native renders the engine's own container here). */
|
|
29
|
+
children?: ReactNode;
|
|
30
|
+
/** Scroll host. Defaults to `ScrollView`. */
|
|
31
|
+
ScrollComponent?: typeof ScrollView;
|
|
32
|
+
className?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let hasWarnedDuplicateKeys = false;
|
|
36
|
+
|
|
37
|
+
const styles = StyleSheet.create({
|
|
38
|
+
root: { flexGrow: 0, minHeight: 0 },
|
|
39
|
+
content: { flexGrow: 0 },
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Longhands for a consumer `flex`, placed between the `flexGrow: 0` default and the consumer style.
|
|
44
|
+
* Yoga lets a longhand beat the shorthand, so `flex: 1` alone keeps grow 0 with basis 0 and the
|
|
45
|
+
* list collapses to zero height.
|
|
46
|
+
*/
|
|
47
|
+
export function flexLonghands(flex: number | undefined): ViewStyle | undefined {
|
|
48
|
+
if (flex === undefined) return undefined;
|
|
49
|
+
if (flex > 0) return { flexGrow: flex, flexShrink: 1, flexBasis: 0 };
|
|
50
|
+
if (flex < 0) return { flexGrow: 0, flexShrink: -flex };
|
|
51
|
+
return { flexGrow: 0, flexShrink: 0 };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function ReorderableListSharedInner<T>(
|
|
55
|
+
{
|
|
56
|
+
data,
|
|
57
|
+
keyExtractor,
|
|
58
|
+
renderRow,
|
|
59
|
+
children,
|
|
60
|
+
ScrollComponent = ScrollView,
|
|
61
|
+
style,
|
|
62
|
+
contentContainerStyle,
|
|
63
|
+
...props
|
|
64
|
+
}: ReorderableListSharedProps<T>,
|
|
65
|
+
ref: ForwardedRef<ScrollView>,
|
|
66
|
+
) {
|
|
67
|
+
const keyToIndex = useMemo(() => {
|
|
68
|
+
const map = new Map<string, number>();
|
|
69
|
+
data.forEach((item, index) => map.set(keyExtractor(item, index), index));
|
|
70
|
+
return map;
|
|
71
|
+
}, [data, keyExtractor]);
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (!__DEV__ || hasWarnedDuplicateKeys) return;
|
|
75
|
+
const duplicates = findDuplicateKeys(data, keyExtractor);
|
|
76
|
+
if (duplicates.length > 0) {
|
|
77
|
+
hasWarnedDuplicateKeys = true;
|
|
78
|
+
console.warn(
|
|
79
|
+
`[ReorderableList] keyExtractor returned duplicate keys (${duplicates.join(', ')}). Keys must be stable and unique per item — do not derive them from the index.`,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}, [data, keyExtractor]);
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<ScrollComponent
|
|
86
|
+
ref={ref}
|
|
87
|
+
style={[styles.root, flexLonghands(StyleSheet.flatten(style)?.flex), style]}
|
|
88
|
+
contentContainerStyle={[styles.content, contentContainerStyle]}
|
|
89
|
+
{...props}
|
|
90
|
+
role="list"
|
|
91
|
+
{...mergeDataAttributes(props, dataAttributes({ slot: 'reorderable-list' }))}
|
|
92
|
+
>
|
|
93
|
+
{children ??
|
|
94
|
+
data.map((item, index) => {
|
|
95
|
+
const key = keyExtractor(item, index);
|
|
96
|
+
return (
|
|
97
|
+
<Fragment key={key}>
|
|
98
|
+
{renderRow?.({
|
|
99
|
+
item,
|
|
100
|
+
key,
|
|
101
|
+
index: keyToIndex.get(key) ?? index,
|
|
102
|
+
count: data.length,
|
|
103
|
+
})}
|
|
104
|
+
</Fragment>
|
|
105
|
+
);
|
|
106
|
+
})}
|
|
107
|
+
</ScrollComponent>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const ReorderableListShared = forwardRef(ReorderableListSharedInner) as <T>(
|
|
112
|
+
props: ReorderableListSharedProps<T> & { ref?: ForwardedRef<ScrollView> },
|
|
113
|
+
) => ReactElement | null;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
forwardRef,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useMemo,
|
|
7
|
+
useState,
|
|
8
|
+
type ReactElement,
|
|
9
|
+
type Ref,
|
|
10
|
+
} from 'react';
|
|
11
|
+
import { AccessibilityInfo, ScrollView } from 'react-native';
|
|
12
|
+
import Animated, { useAnimatedReaction, useAnimatedRef } from 'react-native-reanimated';
|
|
13
|
+
import Sortable, {
|
|
14
|
+
useItemContext,
|
|
15
|
+
type SortableGridDragEndParams,
|
|
16
|
+
type SortableGridRenderItemInfo,
|
|
17
|
+
} from 'react-native-sortables';
|
|
18
|
+
import { scheduleOnRN } from 'react-native-worklets';
|
|
19
|
+
import { mergeRefs } from '@cdx-ui/utils';
|
|
20
|
+
import { ReorderableListShared } from './ReorderableListShared';
|
|
21
|
+
import { ReorderableRowProvider, type ReorderableRowHandle } from './rowContext';
|
|
22
|
+
import type { ReorderableListProps } from './types';
|
|
23
|
+
import { useReorderableRowValue, useReorderController, type ReorderController } from './useReorder';
|
|
24
|
+
|
|
25
|
+
export type {
|
|
26
|
+
ReorderableListLabels,
|
|
27
|
+
ReorderableListProps,
|
|
28
|
+
ReorderableListRenderItemInfo,
|
|
29
|
+
} from './types';
|
|
30
|
+
|
|
31
|
+
const nativeHandle: ReorderableRowHandle = {
|
|
32
|
+
props: {},
|
|
33
|
+
ref: undefined,
|
|
34
|
+
wrap: (host, style) => <Sortable.Handle style={style}>{host}</Sortable.Handle>,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const AnimatedScrollView = Animated.ScrollView as unknown as typeof ScrollView;
|
|
38
|
+
|
|
39
|
+
interface NativeListContextValue<T> {
|
|
40
|
+
renderItem: ReorderableListProps<T>['renderItem'];
|
|
41
|
+
controller: ReorderController<T>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const NativeListContext = createContext<NativeListContextValue<unknown> | null>(null);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* sortables keeps rendered rows mounted and only re-renders a row when its item, index, or the
|
|
48
|
+
* grid's `renderItem` identity changes. The grid gets a stable `renderItem`; the consumer's
|
|
49
|
+
* (usually inline) `renderItem` reaches rows through context instead.
|
|
50
|
+
*/
|
|
51
|
+
function NativeRow<T>({ item, index }: SortableGridRenderItemInfo<T>) {
|
|
52
|
+
const list = useContext(NativeListContext) as NativeListContextValue<T>;
|
|
53
|
+
const { isActive } = useItemContext();
|
|
54
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
55
|
+
|
|
56
|
+
useAnimatedReaction(
|
|
57
|
+
() => isActive.get(),
|
|
58
|
+
(active, previous) => {
|
|
59
|
+
if (active !== (previous ?? false)) scheduleOnRN(setIsDragging, active);
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const rowValue = useReorderableRowValue({
|
|
64
|
+
index,
|
|
65
|
+
count: list.controller.data.length,
|
|
66
|
+
isDragging,
|
|
67
|
+
handle: nativeHandle,
|
|
68
|
+
labels: list.controller.labels,
|
|
69
|
+
moveItem: list.controller.moveItem,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<ReorderableRowProvider value={rowValue}>
|
|
74
|
+
{list.renderItem({ item, index, isDragging })}
|
|
75
|
+
</ReorderableRowProvider>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const renderGridItem = (info: SortableGridRenderItemInfo<unknown>) => <NativeRow {...info} />;
|
|
80
|
+
|
|
81
|
+
function ReorderableListInner<T>(
|
|
82
|
+
{
|
|
83
|
+
data,
|
|
84
|
+
keyExtractor,
|
|
85
|
+
onReorder,
|
|
86
|
+
onReorderIndices,
|
|
87
|
+
renderItem,
|
|
88
|
+
getItemLabel,
|
|
89
|
+
labels,
|
|
90
|
+
scrollEventThrottle = 16,
|
|
91
|
+
...rest
|
|
92
|
+
}: ReorderableListProps<T>,
|
|
93
|
+
ref: Ref<ScrollView>,
|
|
94
|
+
) {
|
|
95
|
+
const scrollableRef = useAnimatedRef<ScrollView>();
|
|
96
|
+
const mergedRef = useMemo(() => mergeRefs(ref, scrollableRef), [ref, scrollableRef]);
|
|
97
|
+
|
|
98
|
+
const controller = useReorderController({
|
|
99
|
+
data,
|
|
100
|
+
onReorder,
|
|
101
|
+
onReorderIndices,
|
|
102
|
+
getItemLabel,
|
|
103
|
+
labels,
|
|
104
|
+
announce: AccessibilityInfo.announceForAccessibility,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const listValue = useMemo(
|
|
108
|
+
() => ({ renderItem, controller }) as NativeListContextValue<unknown>,
|
|
109
|
+
[controller, renderItem],
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const gridKeyExtractor = useMemo(() => {
|
|
113
|
+
const keys = new Map<T, string>();
|
|
114
|
+
data.forEach((item, index) => keys.set(item, keyExtractor(item, index)));
|
|
115
|
+
return (item: T) => keys.get(item) ?? keyExtractor(item, data.indexOf(item));
|
|
116
|
+
}, [data, keyExtractor]);
|
|
117
|
+
|
|
118
|
+
const handleDragEnd = useCallback(
|
|
119
|
+
({ fromIndex, toIndex, data: reordered }: SortableGridDragEndParams<T>) => {
|
|
120
|
+
if (fromIndex === toIndex) return;
|
|
121
|
+
const message = controller.describe('dropped', fromIndex, toIndex);
|
|
122
|
+
onReorder(reordered);
|
|
123
|
+
onReorderIndices?.(fromIndex, toIndex);
|
|
124
|
+
if (message) AccessibilityInfo.announceForAccessibility(message);
|
|
125
|
+
},
|
|
126
|
+
[controller, onReorder, onReorderIndices],
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<NativeListContext.Provider value={listValue}>
|
|
131
|
+
<ReorderableListShared
|
|
132
|
+
ref={mergedRef}
|
|
133
|
+
ScrollComponent={AnimatedScrollView}
|
|
134
|
+
data={data}
|
|
135
|
+
keyExtractor={keyExtractor}
|
|
136
|
+
scrollEventThrottle={scrollEventThrottle}
|
|
137
|
+
{...rest}
|
|
138
|
+
>
|
|
139
|
+
<Sortable.Grid
|
|
140
|
+
columns={1}
|
|
141
|
+
data={data}
|
|
142
|
+
keyExtractor={gridKeyExtractor}
|
|
143
|
+
renderItem={renderGridItem as (info: SortableGridRenderItemInfo<T>) => ReactElement}
|
|
144
|
+
scrollableRef={scrollableRef}
|
|
145
|
+
customHandle
|
|
146
|
+
dragActivationDelay={0}
|
|
147
|
+
overDrag="vertical"
|
|
148
|
+
activeItemScale={1}
|
|
149
|
+
inactiveItemOpacity={1}
|
|
150
|
+
activeItemShadowOpacity={0}
|
|
151
|
+
onDragEnd={handleDragEnd}
|
|
152
|
+
/>
|
|
153
|
+
</ReorderableListShared>
|
|
154
|
+
</NativeListContext.Provider>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export const ReorderableList = forwardRef(ReorderableListInner) as <T>(
|
|
159
|
+
props: ReorderableListProps<T> & { ref?: Ref<ScrollView> },
|
|
160
|
+
) => ReactElement | null;
|
|
161
|
+
|
|
162
|
+
(ReorderableList as { displayName?: string }).displayName = 'ReorderableList';
|