@delacour/react-native-ui 0.1.0-alpha.4 → 0.2.0-alpha.20261010061731
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -6
- package/package.json +49 -5
- package/src/components/accordion/AGENTS.md +21 -9
- package/src/components/accordion/accordion-content.tsx +7 -4
- package/src/components/accordion/accordion-item.tsx +15 -13
- package/src/components/accordion/accordion.context.tsx +11 -5
- package/src/components/accordion/accordion.variants.test.ts +64 -3
- package/src/components/accordion/accordion.variants.ts +33 -9
- package/src/components/alert/AGENTS.md +102 -0
- package/src/components/alert/alert-action.tsx +17 -0
- package/src/components/alert/alert-close-button.tsx +50 -0
- package/src/components/alert/alert-content.tsx +15 -0
- package/src/components/alert/alert-description.tsx +16 -0
- package/src/components/alert/alert-glyphs.ts +25 -0
- package/src/components/alert/alert-indicator.tsx +40 -0
- package/src/components/alert/alert-title.tsx +18 -0
- package/src/components/alert/alert.context.tsx +69 -0
- package/src/components/alert/alert.tsx +160 -0
- package/src/components/alert/alert.types.ts +10 -0
- package/src/components/alert/alert.variants.test.ts +218 -0
- package/src/components/alert/alert.variants.ts +180 -0
- package/src/components/alert/index.ts +23 -0
- package/src/components/avatar/AGENTS.md +106 -0
- package/src/components/avatar/avatar-badge.tsx +51 -0
- package/src/components/avatar/avatar-group.tsx +139 -0
- package/src/components/avatar/avatar.context.tsx +93 -0
- package/src/components/avatar/avatar.tsx +201 -0
- package/src/components/avatar/avatar.utils.test.ts +174 -0
- package/src/components/avatar/avatar.utils.ts +141 -0
- package/src/components/avatar/avatar.variants.test.ts +251 -0
- package/src/components/avatar/avatar.variants.ts +270 -0
- package/src/components/avatar/index.ts +39 -0
- package/src/components/badge/AGENTS.md +10 -0
- package/src/components/badge/badge-close-button.tsx +2 -2
- package/src/components/badge/badge.context.tsx +2 -1
- package/src/components/badge/badge.tsx +13 -4
- package/src/components/badge/badge.variants.test.ts +26 -0
- package/src/components/badge/badge.variants.ts +21 -0
- package/src/components/bottom-sheet/AGENTS.md +186 -231
- package/src/components/bottom-sheet/bottom-sheet-background.tsx +31 -22
- package/src/components/bottom-sheet/bottom-sheet-close.tsx +23 -30
- package/src/components/bottom-sheet/bottom-sheet-container.tsx +54 -208
- package/src/components/bottom-sheet/bottom-sheet-content.tsx +25 -48
- package/src/components/bottom-sheet/bottom-sheet-description.tsx +8 -2
- package/src/components/bottom-sheet/bottom-sheet-flat-list.tsx +65 -0
- package/src/components/bottom-sheet/bottom-sheet-footer.tsx +53 -122
- package/src/components/bottom-sheet/bottom-sheet-handle.tsx +31 -26
- package/src/components/bottom-sheet/bottom-sheet-legend-list.tsx +69 -0
- package/src/components/bottom-sheet/bottom-sheet-overlay.tsx +25 -147
- package/src/components/bottom-sheet/bottom-sheet-provider.tsx +42 -0
- package/src/components/bottom-sheet/bottom-sheet-scroll-view.tsx +38 -62
- package/src/components/bottom-sheet/bottom-sheet-section-list.tsx +58 -0
- package/src/components/bottom-sheet/bottom-sheet-steps.tsx +88 -0
- package/src/components/bottom-sheet/bottom-sheet-text-input.tsx +44 -0
- package/src/components/bottom-sheet/bottom-sheet-title.tsx +12 -8
- package/src/components/bottom-sheet/bottom-sheet-trigger.tsx +19 -37
- package/src/components/bottom-sheet/bottom-sheet.tsx +113 -60
- package/src/components/bottom-sheet/bottom-sheet.variants.test.ts +47 -87
- package/src/components/bottom-sheet/bottom-sheet.variants.ts +50 -126
- package/src/components/bottom-sheet/index.ts +39 -17
- package/src/components/bottom-sheet/use-bottom-sheet-input.ts +16 -115
- package/src/components/button/AGENTS.md +51 -11
- package/src/components/button/button-group.tsx +44 -8
- package/src/components/button/button.context.tsx +10 -0
- package/src/components/button/button.tsx +7 -1
- package/src/components/button/button.variants.test.ts +190 -0
- package/src/components/button/button.variants.ts +87 -6
- package/src/components/button/index.ts +2 -0
- package/src/components/calendar/AGENTS.md +142 -0
- package/src/components/calendar/calendar-caption.tsx +116 -0
- package/src/components/calendar/calendar-day.tsx +103 -0
- package/src/components/calendar/calendar-grid.tsx +183 -0
- package/src/components/calendar/calendar-header.tsx +34 -0
- package/src/components/calendar/calendar-nav.tsx +51 -0
- package/src/components/calendar/calendar-picker.tsx +128 -0
- package/src/components/calendar/calendar-weekdays.tsx +48 -0
- package/src/components/calendar/calendar.context.tsx +108 -0
- package/src/components/calendar/calendar.date.test.ts +456 -0
- package/src/components/calendar/calendar.date.ts +584 -0
- package/src/components/calendar/calendar.tsx +389 -0
- package/src/components/calendar/calendar.types.ts +87 -0
- package/src/components/calendar/calendar.variants.test.ts +363 -0
- package/src/components/calendar/calendar.variants.ts +426 -0
- package/src/components/calendar/index.ts +96 -0
- package/src/components/card/AGENTS.md +92 -0
- package/src/components/card/card-action.tsx +16 -0
- package/src/components/card/card-content.tsx +12 -0
- package/src/components/card/card-description.tsx +12 -0
- package/src/components/card/card-footer.tsx +30 -0
- package/src/components/card/card-header.tsx +45 -0
- package/src/components/card/card-title.tsx +25 -0
- package/src/components/card/card.context.tsx +64 -0
- package/src/components/card/card.tsx +100 -0
- package/src/components/card/card.types.ts +13 -0
- package/src/components/card/card.variants.test.ts +240 -0
- package/src/components/card/card.variants.ts +177 -0
- package/src/components/card/index.ts +15 -0
- package/src/components/chart/AGENTS.md +8 -0
- package/src/components/chart/chart.tsx +8 -1
- package/src/components/chip/AGENTS.md +113 -0
- package/src/components/chip/chip-close-button.tsx +48 -0
- package/src/components/chip/chip-end-content.tsx +15 -0
- package/src/components/chip/chip-label.tsx +21 -0
- package/src/components/chip/chip-start-content.tsx +16 -0
- package/src/components/chip/chip.context.tsx +66 -0
- package/src/components/chip/chip.tsx +268 -0
- package/src/components/chip/chip.types.ts +10 -0
- package/src/components/chip/chip.variants.test.ts +335 -0
- package/src/components/chip/chip.variants.ts +321 -0
- package/src/components/chip/index.ts +24 -0
- package/src/components/collapsible/AGENTS.md +97 -0
- package/src/components/collapsible/collapsible-content.tsx +97 -0
- package/src/components/collapsible/collapsible-description.tsx +17 -0
- package/src/components/collapsible/collapsible-indicator.tsx +92 -0
- package/src/components/collapsible/collapsible-title.tsx +17 -0
- package/src/components/collapsible/collapsible-trigger.tsx +133 -0
- package/src/components/collapsible/collapsible.context.tsx +91 -0
- package/src/components/collapsible/collapsible.tsx +167 -0
- package/src/components/collapsible/collapsible.types.ts +9 -0
- package/src/components/collapsible/collapsible.variants.test.ts +338 -0
- package/src/components/collapsible/collapsible.variants.ts +228 -0
- package/src/components/collapsible/index.ts +32 -0
- package/src/components/context-menu/AGENTS.md +103 -0
- package/src/components/context-menu/context-menu-content.tsx +64 -0
- package/src/components/context-menu/context-menu-item.tsx +22 -0
- package/src/components/context-menu/context-menu-preview.tsx +60 -0
- package/src/components/context-menu/context-menu-trigger.tsx +160 -0
- package/src/components/context-menu/context-menu.context.tsx +91 -0
- package/src/components/context-menu/context-menu.tsx +90 -0
- package/src/components/context-menu/context-menu.variants.test.ts +266 -0
- package/src/components/context-menu/context-menu.variants.ts +147 -0
- package/src/components/context-menu/index.ts +18 -0
- package/src/components/dialog/AGENTS.md +97 -0
- package/src/components/dialog/dialog-body.tsx +21 -0
- package/src/components/dialog/dialog-close.tsx +82 -0
- package/src/components/dialog/dialog-content.tsx +153 -0
- package/src/components/dialog/dialog-description.tsx +23 -0
- package/src/components/dialog/dialog-footer.tsx +32 -0
- package/src/components/dialog/dialog-header.tsx +20 -0
- package/src/components/dialog/dialog-title.tsx +42 -0
- package/src/components/dialog/dialog-trigger.tsx +54 -0
- package/src/components/dialog/dialog.context.tsx +90 -0
- package/src/components/dialog/dialog.tsx +119 -0
- package/src/components/dialog/dialog.variants.test.ts +224 -0
- package/src/components/dialog/dialog.variants.ts +173 -0
- package/src/components/dialog/index.ts +30 -0
- package/src/components/drawer/AGENTS.md +123 -0
- package/src/components/drawer/drawer-body.tsx +46 -0
- package/src/components/drawer/drawer-close.tsx +76 -0
- package/src/components/drawer/drawer-content.tsx +186 -0
- package/src/components/drawer/drawer-description.tsx +23 -0
- package/src/components/drawer/drawer-footer.tsx +21 -0
- package/src/components/drawer/drawer-header.tsx +42 -0
- package/src/components/drawer/drawer-title.tsx +35 -0
- package/src/components/drawer/drawer-trigger.tsx +54 -0
- package/src/components/drawer/drawer.context.tsx +114 -0
- package/src/components/drawer/drawer.tsx +119 -0
- package/src/components/drawer/drawer.variants.test.ts +392 -0
- package/src/components/drawer/drawer.variants.ts +244 -0
- package/src/components/drawer/index.ts +41 -0
- package/src/components/drawer/use-drawer-pan.ts +108 -0
- package/src/components/empty-state/AGENTS.md +90 -0
- package/src/components/empty-state/empty-state-content.tsx +17 -0
- package/src/components/empty-state/empty-state-description.tsx +12 -0
- package/src/components/empty-state/empty-state-header.tsx +17 -0
- package/src/components/empty-state/empty-state-media.tsx +56 -0
- package/src/components/empty-state/empty-state-title.tsx +18 -0
- package/src/components/empty-state/empty-state.context.tsx +65 -0
- package/src/components/empty-state/empty-state.tsx +84 -0
- package/src/components/empty-state/empty-state.types.ts +14 -0
- package/src/components/empty-state/empty-state.variants.test.ts +245 -0
- package/src/components/empty-state/empty-state.variants.ts +132 -0
- package/src/components/empty-state/index.ts +20 -0
- package/src/components/fab/AGENTS.md +119 -0
- package/src/components/fab/fab-action.tsx +118 -0
- package/src/components/fab/fab-group.tsx +214 -0
- package/src/components/fab/fab-label.tsx +18 -0
- package/src/components/fab/fab.context.tsx +125 -0
- package/src/components/fab/fab.tsx +156 -0
- package/src/components/fab/fab.types.ts +17 -0
- package/src/components/fab/fab.variants.test.ts +274 -0
- package/src/components/fab/fab.variants.ts +234 -0
- package/src/components/fab/index.ts +37 -0
- package/src/components/feedback/AGENTS.md +95 -0
- package/src/components/feedback/feedback-action.tsx +16 -0
- package/src/components/feedback/feedback-cancel.tsx +34 -0
- package/src/components/feedback/feedback-close.tsx +21 -0
- package/src/components/feedback/feedback-content.tsx +24 -0
- package/src/components/feedback/feedback-field.tsx +70 -0
- package/src/components/feedback/feedback-footer.tsx +21 -0
- package/src/components/feedback/feedback-panel.tsx +54 -0
- package/src/components/feedback/feedback-submit.tsx +74 -0
- package/src/components/feedback/feedback-title.tsx +34 -0
- package/src/components/feedback/feedback-trigger.tsx +20 -0
- package/src/components/feedback/feedback.context.tsx +73 -0
- package/src/components/feedback/feedback.tsx +135 -0
- package/src/components/feedback/feedback.variants.test.ts +185 -0
- package/src/components/feedback/feedback.variants.ts +128 -0
- package/src/components/feedback/index.ts +24 -0
- package/src/components/field/AGENTS.md +19 -0
- package/src/components/field/field-label.tsx +19 -5
- package/src/components/field/field.context.tsx +17 -0
- package/src/components/field/field.tsx +15 -2
- package/src/components/field/field.variants.test.ts +24 -0
- package/src/components/field/field.variants.ts +20 -0
- package/src/components/field/index.ts +1 -0
- package/src/components/input/AGENTS.md +5 -0
- package/src/components/input/input.variants.test.ts +32 -0
- package/src/components/input/input.variants.ts +13 -1
- package/src/components/item/AGENTS.md +92 -0
- package/src/components/item/index.ts +25 -0
- package/src/components/item/item-actions.tsx +28 -0
- package/src/components/item/item-content.tsx +15 -0
- package/src/components/item/item-description.tsx +12 -0
- package/src/components/item/item-footer.tsx +13 -0
- package/src/components/item/item-group.tsx +32 -0
- package/src/components/item/item-header.tsx +13 -0
- package/src/components/item/item-media.tsx +37 -0
- package/src/components/item/item-separator.tsx +13 -0
- package/src/components/item/item-title.tsx +17 -0
- package/src/components/item/item.context.tsx +66 -0
- package/src/components/item/item.tsx +218 -0
- package/src/components/item/item.types.ts +12 -0
- package/src/components/item/item.variants.test.ts +263 -0
- package/src/components/item/item.variants.ts +200 -0
- package/src/components/kpi/AGENTS.md +125 -0
- package/src/components/kpi/index.ts +45 -0
- package/src/components/kpi/kpi-action.tsx +12 -0
- package/src/components/kpi/kpi-content.tsx +35 -0
- package/src/components/kpi/kpi-footer.tsx +52 -0
- package/src/components/kpi/kpi-group.tsx +70 -0
- package/src/components/kpi/kpi-header.tsx +25 -0
- package/src/components/kpi/kpi-icon.tsx +28 -0
- package/src/components/kpi/kpi-sparkline.tsx +145 -0
- package/src/components/kpi/kpi-stat.tsx +20 -0
- package/src/components/kpi/kpi-title.tsx +19 -0
- package/src/components/kpi/kpi-trend.tsx +105 -0
- package/src/components/kpi/kpi-value.tsx +32 -0
- package/src/components/kpi/kpi.context.tsx +111 -0
- package/src/components/kpi/kpi.tsx +154 -0
- package/src/components/kpi/kpi.types.ts +9 -0
- package/src/components/kpi/kpi.variants.test.ts +428 -0
- package/src/components/kpi/kpi.variants.ts +347 -0
- package/src/components/label/AGENTS.md +89 -0
- package/src/components/label/index.ts +10 -0
- package/src/components/label/label.tsx +97 -0
- package/src/components/label/label.variants.test.ts +176 -0
- package/src/components/label/label.variants.ts +123 -0
- package/src/components/menu/AGENTS.md +176 -0
- package/src/components/menu/index.ts +44 -0
- package/src/components/menu/menu-background.tsx +17 -0
- package/src/components/menu/menu-checkbox-item.tsx +57 -0
- package/src/components/menu/menu-content.tsx +303 -0
- package/src/components/menu/menu-item.tsx +162 -0
- package/src/components/menu/menu-label.tsx +14 -0
- package/src/components/menu/menu-radio-group.tsx +50 -0
- package/src/components/menu/menu-radio-item.tsx +57 -0
- package/src/components/menu/menu-separator.tsx +11 -0
- package/src/components/menu/menu-sub-content.tsx +72 -0
- package/src/components/menu/menu-sub-trigger.tsx +50 -0
- package/src/components/menu/menu-sub.tsx +75 -0
- package/src/components/menu/menu-trigger.tsx +57 -0
- package/src/components/menu/menu.context.tsx +214 -0
- package/src/components/menu/menu.tsx +88 -0
- package/src/components/menu/menu.types.ts +33 -0
- package/src/components/menu/menu.variants.test.ts +400 -0
- package/src/components/menu/menu.variants.ts +353 -0
- package/src/components/meter/AGENTS.md +135 -0
- package/src/components/meter/index.ts +43 -0
- package/src/components/meter/meter-fill.tsx +19 -0
- package/src/components/meter/meter-header.tsx +17 -0
- package/src/components/meter/meter-label.tsx +18 -0
- package/src/components/meter/meter-output.tsx +42 -0
- package/src/components/meter/meter-segments.tsx +83 -0
- package/src/components/meter/meter-track.tsx +16 -0
- package/src/components/meter/meter.context.tsx +62 -0
- package/src/components/meter/meter.tsx +286 -0
- package/src/components/meter/meter.types.ts +30 -0
- package/src/components/meter/meter.variants.test.ts +430 -0
- package/src/components/meter/meter.variants.ts +347 -0
- package/src/components/overlay/AGENTS.md +89 -0
- package/src/components/overlay/index.ts +27 -0
- package/src/components/overlay/overlay-portal.tsx +84 -0
- package/src/components/overlay/overlay-presence.test.ts +46 -0
- package/src/components/overlay/overlay-presence.ts +49 -0
- package/src/components/overlay/overlay-registry.test.ts +96 -0
- package/src/components/overlay/overlay-registry.ts +99 -0
- package/src/components/overlay/overlay-scrim.tsx +49 -0
- package/src/components/overlay/overlay.context.tsx +48 -0
- package/src/components/overlay/overlay.tsx +118 -0
- package/src/components/overlay/overlay.variants.test.ts +37 -0
- package/src/components/overlay/overlay.variants.ts +33 -0
- package/src/components/overlay/use-overlay-back-handler.ts +34 -0
- package/src/components/overlay/use-overlay-presence.ts +87 -0
- package/src/components/popover/AGENTS.md +138 -0
- package/src/components/popover/index.ts +48 -0
- package/src/components/popover/popover-anchor.tsx +49 -0
- package/src/components/popover/popover-arrow.tsx +89 -0
- package/src/components/popover/popover-close.tsx +73 -0
- package/src/components/popover/popover-content.tsx +235 -0
- package/src/components/popover/popover-description.tsx +18 -0
- package/src/components/popover/popover-title.tsx +33 -0
- package/src/components/popover/popover-trigger.tsx +56 -0
- package/src/components/popover/popover.context.tsx +71 -0
- package/src/components/popover/popover.position.test.ts +354 -0
- package/src/components/popover/popover.position.ts +286 -0
- package/src/components/popover/popover.tsx +123 -0
- package/src/components/popover/popover.variants.test.ts +135 -0
- package/src/components/popover/popover.variants.ts +85 -0
- package/src/components/popover/use-anchor-measure.ts +76 -0
- package/src/components/popover/use-anchored-content.ts +219 -0
- package/src/components/pressable/AGENTS.md +11 -1
- package/src/components/pressable/pressable.tsx +7 -2
- package/src/components/pressable/pressable.variants.test.ts +29 -0
- package/src/components/pressable/pressable.variants.ts +17 -0
- package/src/components/progress/AGENTS.md +120 -0
- package/src/components/progress/index.ts +40 -0
- package/src/components/progress/progress-fill.tsx +152 -0
- package/src/components/progress/progress-header.tsx +19 -0
- package/src/components/progress/progress-label.tsx +27 -0
- package/src/components/progress/progress-output.tsx +47 -0
- package/src/components/progress/progress-track.tsx +38 -0
- package/src/components/progress/progress.context.tsx +79 -0
- package/src/components/progress/progress.tsx +171 -0
- package/src/components/progress/progress.types.ts +23 -0
- package/src/components/progress/progress.variants.test.ts +335 -0
- package/src/components/progress/progress.variants.ts +284 -0
- package/src/components/progress-button/AGENTS.md +116 -0
- package/src/components/progress-button/index.ts +36 -0
- package/src/components/progress-button/progress-button-done.tsx +33 -0
- package/src/components/progress-button/progress-button-label.tsx +27 -0
- package/src/components/progress-button/progress-button.context.tsx +93 -0
- package/src/components/progress-button/progress-button.tsx +414 -0
- package/src/components/progress-button/progress-button.variants.test.ts +314 -0
- package/src/components/progress-button/progress-button.variants.ts +236 -0
- package/src/components/provider/AGENTS.md +38 -25
- package/src/components/provider/provider.tsx +38 -11
- package/src/components/radio/AGENTS.md +8 -10
- package/src/components/radio/radio.variants.test.ts +5 -6
- package/src/components/radio/radio.variants.ts +6 -7
- package/src/components/rating/AGENTS.md +143 -0
- package/src/components/rating/index.ts +43 -0
- package/src/components/rating/rating-output.tsx +39 -0
- package/src/components/rating/rating-star.tsx +70 -0
- package/src/components/rating/rating-stars.tsx +219 -0
- package/src/components/rating/rating.context.tsx +79 -0
- package/src/components/rating/rating.tsx +163 -0
- package/src/components/rating/rating.variants.test.ts +347 -0
- package/src/components/rating/rating.variants.ts +354 -0
- package/src/components/selection-mode/AGENTS.md +155 -0
- package/src/components/selection-mode/index.ts +43 -0
- package/src/components/selection-mode/selection-mode-action.tsx +65 -0
- package/src/components/selection-mode/selection-mode-bar.tsx +79 -0
- package/src/components/selection-mode/selection-mode-group.tsx +123 -0
- package/src/components/selection-mode/selection-mode-header.tsx +85 -0
- package/src/components/selection-mode/selection-mode-indicator.tsx +118 -0
- package/src/components/selection-mode/selection-mode-item.tsx +182 -0
- package/src/components/selection-mode/selection-mode.context.tsx +89 -0
- package/src/components/selection-mode/selection-mode.tsx +207 -0
- package/src/components/selection-mode/selection-mode.types.ts +36 -0
- package/src/components/selection-mode/selection-mode.variants.test.ts +292 -0
- package/src/components/selection-mode/selection-mode.variants.ts +329 -0
- package/src/components/skeleton/AGENTS.md +120 -0
- package/src/components/skeleton/index.ts +15 -0
- package/src/components/skeleton/skeleton-clock.ts +48 -0
- package/src/components/skeleton/skeleton-group.tsx +64 -0
- package/src/components/skeleton/skeleton-shimmer.tsx +80 -0
- package/src/components/skeleton/skeleton.context.tsx +45 -0
- package/src/components/skeleton/skeleton.tsx +227 -0
- package/src/components/skeleton/skeleton.variants.test.ts +245 -0
- package/src/components/skeleton/skeleton.variants.ts +222 -0
- package/src/components/slide-button/AGENTS.md +122 -0
- package/src/components/slide-button/index.ts +43 -0
- package/src/components/slide-button/slide-button-label.tsx +70 -0
- package/src/components/slide-button/slide-button-thumb.tsx +93 -0
- package/src/components/slide-button/slide-button.context.tsx +76 -0
- package/src/components/slide-button/slide-button.tsx +457 -0
- package/src/components/slide-button/slide-button.variants.test.ts +288 -0
- package/src/components/slide-button/slide-button.variants.ts +324 -0
- package/src/components/slider/index.ts +2 -0
- package/src/components/slider/slider-thumb.tsx +33 -1
- package/src/components/slider/slider.variants.test.ts +52 -0
- package/src/components/slider/slider.variants.ts +56 -2
- package/src/components/stack-card/AGENTS.md +169 -0
- package/src/components/stack-card/index.ts +37 -0
- package/src/components/stack-card/stack-card-action.tsx +66 -0
- package/src/components/stack-card/stack-card-actions.tsx +18 -0
- package/src/components/stack-card/stack-card-card.tsx +71 -0
- package/src/components/stack-card/stack-card-empty.tsx +30 -0
- package/src/components/stack-card/stack-card-slot.tsx +90 -0
- package/src/components/stack-card/stack-card-stamp.tsx +76 -0
- package/src/components/stack-card/stack-card.context.tsx +117 -0
- package/src/components/stack-card/stack-card.tsx +557 -0
- package/src/components/stack-card/stack-card.types.ts +26 -0
- package/src/components/stack-card/stack-card.variants.test.ts +355 -0
- package/src/components/stack-card/stack-card.variants.ts +360 -0
- package/src/components/steps/AGENTS.md +153 -0
- package/src/components/steps/index.ts +45 -0
- package/src/components/steps/steps-connector.tsx +31 -0
- package/src/components/steps/steps-description.tsx +26 -0
- package/src/components/steps/steps-indicator.tsx +106 -0
- package/src/components/steps/steps-item.tsx +225 -0
- package/src/components/steps/steps-panel.tsx +41 -0
- package/src/components/steps/steps-title.tsx +32 -0
- package/src/components/steps/steps-track.tsx +59 -0
- package/src/components/steps/steps.context.tsx +123 -0
- package/src/components/steps/steps.tsx +166 -0
- package/src/components/steps/steps.variants.test.ts +388 -0
- package/src/components/steps/steps.variants.ts +468 -0
- package/src/components/surface/AGENTS.md +82 -0
- package/src/components/surface/index.ts +15 -0
- package/src/components/surface/surface.context.tsx +56 -0
- package/src/components/surface/surface.tsx +87 -0
- package/src/components/surface/surface.variants.test.ts +227 -0
- package/src/components/surface/surface.variants.ts +165 -0
- package/src/components/swipe/AGENTS.md +140 -0
- package/src/components/swipe/index.ts +31 -0
- package/src/components/swipe/swipe-action.tsx +99 -0
- package/src/components/swipe/swipe-end.tsx +14 -0
- package/src/components/swipe/swipe-group.tsx +55 -0
- package/src/components/swipe/swipe-panel.tsx +55 -0
- package/src/components/swipe/swipe-start.tsx +15 -0
- package/src/components/swipe/swipe.context.tsx +135 -0
- package/src/components/swipe/swipe.tsx +393 -0
- package/src/components/swipe/swipe.types.ts +7 -0
- package/src/components/swipe/swipe.variants.test.ts +337 -0
- package/src/components/swipe/swipe.variants.ts +290 -0
- package/src/components/switch/switch.variants.ts +2 -2
- package/src/components/tabs/AGENTS.md +4 -3
- package/src/components/tabs/tabs.variants.test.ts +1 -1
- package/src/components/tabs/tabs.variants.ts +4 -6
- package/src/components/text/AGENTS.md +8 -2
- package/src/components/text/text.tsx +7 -0
- package/src/components/text/text.variants.test.ts +24 -1
- package/src/components/text/text.variants.ts +5 -0
- package/src/components/textarea/AGENTS.md +89 -0
- package/src/components/textarea/index.ts +16 -0
- package/src/components/textarea/textarea.tsx +157 -0
- package/src/components/textarea/textarea.variants.test.ts +219 -0
- package/src/components/textarea/textarea.variants.ts +171 -0
- package/src/components/toast/AGENTS.md +140 -0
- package/src/components/toast/index.ts +74 -0
- package/src/components/toast/toast-action.tsx +59 -0
- package/src/components/toast/toast-api.ts +32 -0
- package/src/components/toast/toast-close.tsx +44 -0
- package/src/components/toast/toast-content.tsx +11 -0
- package/src/components/toast/toast-description.tsx +11 -0
- package/src/components/toast/toast-indicator.tsx +34 -0
- package/src/components/toast/toast-item.tsx +308 -0
- package/src/components/toast/toast-title.tsx +13 -0
- package/src/components/toast/toast-viewport.tsx +135 -0
- package/src/components/toast/toast.context.tsx +69 -0
- package/src/components/toast/toast.store.test.ts +259 -0
- package/src/components/toast/toast.store.ts +338 -0
- package/src/components/toast/toast.timer.test.ts +64 -0
- package/src/components/toast/toast.timer.ts +51 -0
- package/src/components/toast/toast.tsx +132 -0
- package/src/components/toast/toast.variants.test.ts +393 -0
- package/src/components/toast/toast.variants.ts +304 -0
- package/src/components/toggle-button/AGENTS.md +106 -0
- package/src/components/toggle-button/index.ts +30 -0
- package/src/components/toggle-button/toggle-button-group.tsx +156 -0
- package/src/components/toggle-button/toggle-button-label.tsx +19 -0
- package/src/components/toggle-button/toggle-button.context.tsx +130 -0
- package/src/components/toggle-button/toggle-button.tsx +172 -0
- package/src/components/toggle-button/toggle-button.variants.test.ts +189 -0
- package/src/components/toggle-button/toggle-button.variants.ts +160 -0
- package/src/components/tooltip/AGENTS.md +133 -0
- package/src/components/tooltip/index.ts +28 -0
- package/src/components/tooltip/tooltip-arrow.tsx +40 -0
- package/src/components/tooltip/tooltip-content.tsx +179 -0
- package/src/components/tooltip/tooltip-description.tsx +19 -0
- package/src/components/tooltip/tooltip-text.tsx +21 -0
- package/src/components/tooltip/tooltip-title.tsx +20 -0
- package/src/components/tooltip/tooltip-trigger.tsx +103 -0
- package/src/components/tooltip/tooltip.context.tsx +68 -0
- package/src/components/tooltip/tooltip.tsx +213 -0
- package/src/components/tooltip/tooltip.variants.test.ts +231 -0
- package/src/components/tooltip/tooltip.variants.ts +177 -0
- package/src/hooks/use-calm-motion.tsx +31 -0
- package/src/lib/calm-motion.test.ts +17 -0
- package/src/lib/calm-motion.ts +23 -0
- package/src/lib/cn.parity.test.ts +62 -0
- package/src/lib/cn.test.ts +14 -0
- package/src/lib/cn.ts +11 -6
- package/src/no-gorhom.test.ts +54 -0
- package/src/styles/geometry.test.ts +1 -0
- package/src/styles/theme.css +4 -0
- package/src/styles/tokens.css +44 -0
- package/src/styles/tokens.test.ts +56 -0
- package/src/styles/tokens.ts +29 -1
- package/src/components/bottom-sheet/bottom-sheet-portal.tsx +0 -72
- package/src/components/bottom-sheet/bottom-sheet.context.tsx +0 -135
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { type ReactElement, useCallback, useMemo } from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import Animated, { useAnimatedStyle } from "react-native-reanimated";
|
|
4
|
+
import { Icon, type IconComponent } from "../icon/icon";
|
|
5
|
+
import { IconDefaultsProvider } from "../icon/icon.context";
|
|
6
|
+
import { Pressable } from "../pressable/pressable";
|
|
7
|
+
import { Text } from "../text/text";
|
|
8
|
+
import { useSwipePart, useSwipeTilePart } from "./swipe.context";
|
|
9
|
+
import {
|
|
10
|
+
resolveSwipeActionForegroundToken,
|
|
11
|
+
SWIPE_TILE_WIDTH,
|
|
12
|
+
type SwipeActionColor,
|
|
13
|
+
swipeVariants,
|
|
14
|
+
} from "./swipe.variants";
|
|
15
|
+
|
|
16
|
+
export type SwipeActionProps = {
|
|
17
|
+
/** The tile's caption, and the name a screen reader offers the action under. Required. */
|
|
18
|
+
label: string;
|
|
19
|
+
/** A Central Icon component, drawn above the label at the tile's size and ink. */
|
|
20
|
+
icon?: IconComponent;
|
|
21
|
+
color?: SwipeActionColor;
|
|
22
|
+
onPress: () => void;
|
|
23
|
+
/** Leave the row open after the action runs — for a toggle such as a bookmark. */
|
|
24
|
+
isKeptOpen?: boolean;
|
|
25
|
+
className?: string;
|
|
26
|
+
labelClassName?: string;
|
|
27
|
+
/** Forwarded to the tile's pressable, for an end-to-end test or a capture flow to find it. */
|
|
28
|
+
testID?: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* One tile behind the row.
|
|
33
|
+
*
|
|
34
|
+
* Positioned by its own animated style off the row's offset: short of fully
|
|
35
|
+
* open it is overlapped by the tile outside it, so the set emerges from under
|
|
36
|
+
* the row; past fully open the outermost tile grows into the overshoot. The
|
|
37
|
+
* worklet restates `resolveTileLayout`, which the tests pin.
|
|
38
|
+
*
|
|
39
|
+
* Takes the icon as a **component** rather than composed children, because the
|
|
40
|
+
* tile has to size and tint the glyph itself; it renders it through
|
|
41
|
+
* `IconDefaultsProvider`, the same inheritance a `Button` uses.
|
|
42
|
+
*/
|
|
43
|
+
export function SwipeAction({
|
|
44
|
+
label,
|
|
45
|
+
icon,
|
|
46
|
+
color = "default",
|
|
47
|
+
onPress,
|
|
48
|
+
isKeptOpen = false,
|
|
49
|
+
className,
|
|
50
|
+
labelClassName,
|
|
51
|
+
testID,
|
|
52
|
+
}: SwipeActionProps): ReactElement {
|
|
53
|
+
const swipe = useSwipePart("Swipe.Action");
|
|
54
|
+
const { side, index, count } = useSwipeTilePart("Swipe.Action");
|
|
55
|
+
const { offset, runAction } = swipe;
|
|
56
|
+
const slots = swipeVariants({ color, side });
|
|
57
|
+
const order = side === "end" ? index : count - 1 - index;
|
|
58
|
+
|
|
59
|
+
const tileStyle = useAnimatedStyle(() => {
|
|
60
|
+
const tileWidth = SWIPE_TILE_WIDTH;
|
|
61
|
+
const reveal = Math.max(0, side === "start" ? offset.value : -offset.value);
|
|
62
|
+
const total = count * tileWidth;
|
|
63
|
+
const isPacked = reveal <= total;
|
|
64
|
+
const x = isPacked ? (count > 0 ? (order * reveal) / count : 0) : order * tileWidth;
|
|
65
|
+
const width = !isPacked && order === count - 1 ? reveal - order * tileWidth : tileWidth;
|
|
66
|
+
return side === "end" ? { start: x, width } : { end: x, width };
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const handlePress = useCallback(() => runAction(onPress, isKeptOpen), [isKeptOpen, onPress, runAction]);
|
|
70
|
+
const iconDefaults = useMemo(
|
|
71
|
+
() => ({ className: "size-icon-md", color: resolveSwipeActionForegroundToken(color) }),
|
|
72
|
+
[color]
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<Animated.View className={slots.tile({ className })} style={[{ zIndex: order }, tileStyle]}>
|
|
77
|
+
<Pressable
|
|
78
|
+
accessibilityLabel={label}
|
|
79
|
+
accessibilityRole="button"
|
|
80
|
+
className={slots.tilePressable()}
|
|
81
|
+
feedback="fade"
|
|
82
|
+
onPress={handlePress}
|
|
83
|
+
testID={testID}
|
|
84
|
+
>
|
|
85
|
+
<View className={slots.tileContent()}>
|
|
86
|
+
{icon ? (
|
|
87
|
+
<IconDefaultsProvider value={iconDefaults}>
|
|
88
|
+
<Icon icon={icon} />
|
|
89
|
+
</IconDefaultsProvider>
|
|
90
|
+
) : null}
|
|
91
|
+
<Text className={slots.tileLabel({ className: labelClassName })} numberOfLines={1}>
|
|
92
|
+
{label}
|
|
93
|
+
</Text>
|
|
94
|
+
</View>
|
|
95
|
+
</Pressable>
|
|
96
|
+
</Animated.View>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
SwipeAction.displayName = "DelacourUI.Swipe.Action";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { SwipePanelProps } from "./swipe.types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Marks the tiles behind the row's end edge — the edge text runs toward —
|
|
6
|
+
* revealed by sliding the row toward `start`.
|
|
7
|
+
*
|
|
8
|
+
* A marker, never rendered: the root lifts its children out by element type and
|
|
9
|
+
* lays them out itself. On its own it renders nothing.
|
|
10
|
+
*/
|
|
11
|
+
export function SwipeEnd(_props: SwipePanelProps): ReactElement | null {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
SwipeEnd.displayName = "DelacourUI.Swipe.End";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type ReactElement, useCallback, useMemo, useRef } from "react";
|
|
2
|
+
import { View, type ViewProps } from "react-native";
|
|
3
|
+
import { cn } from "../../lib/cn";
|
|
4
|
+
import { type SwipeGroupContextValue, SwipeGroupProvider } from "./swipe.context";
|
|
5
|
+
|
|
6
|
+
export type SwipeGroupProps = ViewProps & {
|
|
7
|
+
className?: string;
|
|
8
|
+
/** One row open at a time: opening one closes the rest. Default `true`. */
|
|
9
|
+
isExclusive?: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Coordinates the rows beneath it. Renders a plain `View`.
|
|
14
|
+
*
|
|
15
|
+
* **Rows register themselves through context**, rather than the group walking
|
|
16
|
+
* its children, so a row nested in a `ListGroup`, a `.map()` or a custom
|
|
17
|
+
* component still belongs. The registry is a ref — joining or leaving it
|
|
18
|
+
* re-renders nothing.
|
|
19
|
+
*/
|
|
20
|
+
export function SwipeGroup({ className, isExclusive = true, children, ...props }: SwipeGroupProps): ReactElement {
|
|
21
|
+
const rows = useRef(new Map<string, () => void>());
|
|
22
|
+
|
|
23
|
+
const register = useCallback((id: string, close: () => void) => {
|
|
24
|
+
rows.current.set(id, close);
|
|
25
|
+
return () => {
|
|
26
|
+
if (rows.current.get(id) === close) rows.current.delete(id);
|
|
27
|
+
};
|
|
28
|
+
}, []);
|
|
29
|
+
|
|
30
|
+
const notifyOpen = useCallback(
|
|
31
|
+
(id: string) => {
|
|
32
|
+
if (!isExclusive) return;
|
|
33
|
+
for (const [other, close] of rows.current) if (other !== id) close();
|
|
34
|
+
},
|
|
35
|
+
[isExclusive]
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const closeAll = useCallback(() => {
|
|
39
|
+
for (const close of rows.current.values()) close();
|
|
40
|
+
}, []);
|
|
41
|
+
|
|
42
|
+
const value = useMemo<SwipeGroupContextValue>(
|
|
43
|
+
() => ({ closeAll, notifyOpen, register }),
|
|
44
|
+
[closeAll, notifyOpen, register]
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<SwipeGroupProvider value={value}>
|
|
49
|
+
<View className={cn(className)} {...props}>
|
|
50
|
+
{children}
|
|
51
|
+
</View>
|
|
52
|
+
</SwipeGroupProvider>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
SwipeGroup.displayName = "DelacourUI.Swipe.Group";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import Animated, { useAnimatedStyle } from "react-native-reanimated";
|
|
3
|
+
import { SwipeTileProvider, useSwipePart } from "./swipe.context";
|
|
4
|
+
import { resolveOutermostIndex, type SwipeSide, type SwipeTileProps, swipeVariants } from "./swipe.variants";
|
|
5
|
+
|
|
6
|
+
type SwipePanelLayerProps = {
|
|
7
|
+
side: SwipeSide;
|
|
8
|
+
/** The `Swipe.Action` elements lifted out of the side's marker. */
|
|
9
|
+
tiles: ReactElement<SwipeTileProps>[];
|
|
10
|
+
/** Hidden from assistive technology while the row is shut. */
|
|
11
|
+
isHidden: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const START_EDGE = { start: 0 } as const;
|
|
15
|
+
const END_EDGE = { end: 0 } as const;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The layer behind one edge of the row. Internal: the root renders one per side
|
|
19
|
+
* that has tiles.
|
|
20
|
+
*
|
|
21
|
+
* **Exactly as wide as the gap the row has left**, animated off the same offset
|
|
22
|
+
* the row moves on — never wider, so it cannot paint over a row that has no
|
|
23
|
+
* background of its own, and never narrower, so there is no hole. Its own
|
|
24
|
+
* colour is the outermost tile's, so the overshoot that tile grows into reads
|
|
25
|
+
* as the same action.
|
|
26
|
+
*
|
|
27
|
+
* Pinned by logical `start` / `end` rather than `left` / `right`, so the layout
|
|
28
|
+
* mirrors under right to left with no sign of its own; only the row's
|
|
29
|
+
* translation has to flip.
|
|
30
|
+
*/
|
|
31
|
+
export function SwipePanelLayer({ side, tiles, isHidden }: SwipePanelLayerProps): ReactElement {
|
|
32
|
+
const { offset } = useSwipePart("Swipe.Panel");
|
|
33
|
+
const outermost = tiles[resolveOutermostIndex(side, tiles.length)];
|
|
34
|
+
const slots = swipeVariants({ color: outermost?.props.color ?? "default", side });
|
|
35
|
+
|
|
36
|
+
const panelStyle = useAnimatedStyle(() => ({
|
|
37
|
+
width: Math.max(0, side === "start" ? offset.value : -offset.value),
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<Animated.View
|
|
42
|
+
accessibilityElementsHidden={isHidden}
|
|
43
|
+
className={slots.panel()}
|
|
44
|
+
importantForAccessibility={isHidden ? "no-hide-descendants" : "auto"}
|
|
45
|
+
style={[side === "start" ? START_EDGE : END_EDGE, panelStyle]}
|
|
46
|
+
>
|
|
47
|
+
{tiles.map((tile, index) => (
|
|
48
|
+
<SwipeTileProvider key={tile.key ?? index} value={{ count: tiles.length, index, side }}>
|
|
49
|
+
{tile}
|
|
50
|
+
</SwipeTileProvider>
|
|
51
|
+
))}
|
|
52
|
+
</Animated.View>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
SwipePanelLayer.displayName = "DelacourUI.Swipe.Panel";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { SwipePanelProps } from "./swipe.types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Marks the tiles behind the row's start edge — revealed by sliding the row
|
|
6
|
+
* toward `end`.
|
|
7
|
+
*
|
|
8
|
+
* A marker, never rendered: the root lifts its children out by element type and
|
|
9
|
+
* lays them out itself, because only the root knows how wide the gap is. On its
|
|
10
|
+
* own it renders nothing.
|
|
11
|
+
*/
|
|
12
|
+
export function SwipeStart(_props: SwipePanelProps): ReactElement | null {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
SwipeStart.displayName = "DelacourUI.Swipe.Start";
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { createContext, type ReactElement, type ReactNode, use } from "react";
|
|
2
|
+
import type { SharedValue } from "react-native-reanimated";
|
|
3
|
+
import type { SwipeOpenSide, SwipeSide } from "./swipe.variants";
|
|
4
|
+
|
|
5
|
+
export type SwipeContextValue = {
|
|
6
|
+
/** The side that is settled open, or null. Changes on a settle, never during a drag. */
|
|
7
|
+
openSide: SwipeOpenSide;
|
|
8
|
+
/** Slides the row aside to reveal `side`. A side with no panel stays shut. */
|
|
9
|
+
open: (side: SwipeSide) => void;
|
|
10
|
+
/** Slides the row back over its panels. */
|
|
11
|
+
close: () => void;
|
|
12
|
+
/** The row's logical offset — positive reveals `start`. Internal to the parts. */
|
|
13
|
+
offset: SharedValue<number>;
|
|
14
|
+
/** Whether the layout runs right to left, read once from `I18nManager`. */
|
|
15
|
+
isRTL: boolean;
|
|
16
|
+
/** Runs a tile's action, then closes the row unless it asks to stay open. */
|
|
17
|
+
runAction: (onPress: () => void, isKeptOpen: boolean) => void;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const SwipeContext = createContext<SwipeContextValue | null>(null);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Supplies a row's state to its tiles.
|
|
24
|
+
*
|
|
25
|
+
* In a leaf of its own, importing nothing but types, so a part can read it
|
|
26
|
+
* without importing `./swipe` and closing a cycle (package AGENTS.md rule 3).
|
|
27
|
+
*/
|
|
28
|
+
export function SwipeProvider({ value, children }: { value: SwipeContextValue; children: ReactNode }): ReactElement {
|
|
29
|
+
return <SwipeContext value={value}>{children}</SwipeContext>;
|
|
30
|
+
}
|
|
31
|
+
SwipeProvider.displayName = "DelacourUI.Swipe.Provider";
|
|
32
|
+
|
|
33
|
+
/** The enclosing row, or null outside a `<Swipe>`. */
|
|
34
|
+
export function useSwipeContext(): SwipeContextValue | null {
|
|
35
|
+
return use(SwipeContext);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Reads the enclosing row: which side is open, and `open` / `close`.
|
|
40
|
+
*
|
|
41
|
+
* For a custom child of the row that has to close it — a button inside the row
|
|
42
|
+
* that acts and then tucks the actions away. Throws outside a `<Swipe>`.
|
|
43
|
+
*/
|
|
44
|
+
export function useSwipe(): SwipeContextValue {
|
|
45
|
+
const context = useSwipeContext();
|
|
46
|
+
if (!context) throw new Error("useSwipe must be called inside a <Swipe>.");
|
|
47
|
+
return context;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The enclosing row, for a part that cannot work without it.
|
|
52
|
+
*
|
|
53
|
+
* Internal: deliberately not re-exported from `index.ts`.
|
|
54
|
+
*/
|
|
55
|
+
export function useSwipePart(component: string): SwipeContextValue {
|
|
56
|
+
const context = useSwipeContext();
|
|
57
|
+
if (!context) throw new Error(`${component} must be rendered inside a <Swipe>.`);
|
|
58
|
+
return context;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type SwipeTileContextValue = {
|
|
62
|
+
side: SwipeSide;
|
|
63
|
+
/** Source order within its panel. */
|
|
64
|
+
index: number;
|
|
65
|
+
/** How many tiles share the panel. */
|
|
66
|
+
count: number;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const SwipeTileContext = createContext<SwipeTileContextValue | null>(null);
|
|
70
|
+
|
|
71
|
+
/** Where a tile sits in its panel. The root wraps every tile it lifts out in one. */
|
|
72
|
+
export function SwipeTileProvider({
|
|
73
|
+
value,
|
|
74
|
+
children,
|
|
75
|
+
}: {
|
|
76
|
+
value: SwipeTileContextValue;
|
|
77
|
+
children: ReactNode;
|
|
78
|
+
}): ReactElement {
|
|
79
|
+
return <SwipeTileContext value={value}>{children}</SwipeTileContext>;
|
|
80
|
+
}
|
|
81
|
+
SwipeTileProvider.displayName = "DelacourUI.Swipe.TileProvider";
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* A tile's place in its panel. Internal.
|
|
85
|
+
*
|
|
86
|
+
* Throws when a `Swipe.Action` was rendered anywhere but inside `Swipe.Start`
|
|
87
|
+
* or `Swipe.End` — the root lifts tiles out of those two markers only.
|
|
88
|
+
*/
|
|
89
|
+
export function useSwipeTilePart(component: string): SwipeTileContextValue {
|
|
90
|
+
const context = use(SwipeTileContext);
|
|
91
|
+
if (!context) throw new Error(`${component} must be written inside <Swipe.Start> or <Swipe.End>.`);
|
|
92
|
+
return context;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export type SwipeGroupContextValue = {
|
|
96
|
+
/** Adds a row's close to the group. Returns the matching unregister. */
|
|
97
|
+
register: (id: string, close: () => void) => () => void;
|
|
98
|
+
/** Tells the group `id` has opened, so an exclusive group closes the rest. */
|
|
99
|
+
notifyOpen: (id: string) => void;
|
|
100
|
+
/** Closes every row in the group. */
|
|
101
|
+
closeAll: () => void;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const SwipeGroupContext = createContext<SwipeGroupContextValue | null>(null);
|
|
105
|
+
|
|
106
|
+
/** Supplies a group's registry to the rows beneath it, however deeply they are nested. */
|
|
107
|
+
export function SwipeGroupProvider({
|
|
108
|
+
value,
|
|
109
|
+
children,
|
|
110
|
+
}: {
|
|
111
|
+
value: SwipeGroupContextValue;
|
|
112
|
+
children: ReactNode;
|
|
113
|
+
}): ReactElement {
|
|
114
|
+
return <SwipeGroupContext value={value}>{children}</SwipeGroupContext>;
|
|
115
|
+
}
|
|
116
|
+
SwipeGroupProvider.displayName = "DelacourUI.Swipe.Group.Provider";
|
|
117
|
+
|
|
118
|
+
/** The enclosing group, or null for a row standing on its own. */
|
|
119
|
+
export function useSwipeGroupContext(): SwipeGroupContextValue | null {
|
|
120
|
+
return use(SwipeGroupContext);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const NO_GROUP = { closeAll: () => {} } as const;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Closes every row in the enclosing `Swipe.Group` — before a list scrolls away,
|
|
127
|
+
* or when a screen loses focus.
|
|
128
|
+
*
|
|
129
|
+
* Outside a group it returns a no-op rather than throwing, so a screen can call
|
|
130
|
+
* it whether or not its rows are grouped.
|
|
131
|
+
*/
|
|
132
|
+
export function useSwipeGroup(): { closeAll: () => void } {
|
|
133
|
+
const group = useSwipeGroupContext();
|
|
134
|
+
return group ? { closeAll: group.closeAll } : NO_GROUP;
|
|
135
|
+
}
|