@delacour/react-native-ui 0.1.0-alpha.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -7
- 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 +5 -0
- package/src/components/badge/badge.tsx +6 -1
- package/src/components/bottom-sheet/AGENTS.md +186 -221
- 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 -207
- 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 -120
- 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 -52
- 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 -70
- package/src/components/bottom-sheet/bottom-sheet.variants.ts +50 -105
- 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 +45 -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 +2 -1
- package/src/components/button/button.variants.test.ts +154 -0
- package/src/components/button/button.variants.ts +71 -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 +88 -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 +94 -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 +9 -1
- 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/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/screen/screen-navbar-back-button.tsx +1 -1
- 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 +72 -0
- package/src/components/surface/index.ts +15 -0
- package/src/components/surface/surface.context.tsx +54 -0
- package/src/components/surface/surface.tsx +70 -0
- package/src/components/surface/surface.variants.test.ts +180 -0
- package/src/components/surface/surface.variants.ts +133 -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/textarea/AGENTS.md +86 -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.test.ts +14 -0
- package/src/lib/cn.ts +2 -2
- 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 +11 -0
- package/src/styles/tokens.test.ts +22 -0
- package/src/styles/tokens.ts +20 -0
- package/src/components/bottom-sheet/bottom-sheet-portal.tsx +0 -72
- package/src/components/bottom-sheet/bottom-sheet.context.tsx +0 -135
|
@@ -1,45 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "@gorhom/bottom-sheet";
|
|
9
|
-
import {
|
|
10
|
-
Children,
|
|
11
|
-
cloneElement,
|
|
12
|
-
isValidElement,
|
|
13
|
-
type ReactElement,
|
|
14
|
-
type ReactNode,
|
|
15
|
-
useCallback,
|
|
16
|
-
useEffect,
|
|
17
|
-
useMemo,
|
|
18
|
-
useRef,
|
|
19
|
-
} from "react";
|
|
20
|
-
import { useSharedValue } from "react-native-reanimated";
|
|
21
|
-
import { useKeyboardAnimationGuard } from "../../hooks/use-keyboard-state-sync";
|
|
22
|
-
import {
|
|
23
|
-
BottomSheetContainerProvider,
|
|
24
|
-
BottomSheetProvider,
|
|
25
|
-
useBottomSheetPart,
|
|
26
|
-
useBottomSheetPortalContext,
|
|
27
|
-
} from "./bottom-sheet.context";
|
|
28
|
-
import {
|
|
29
|
-
BOTTOM_SHEET_KEYBOARD_DEFAULTS,
|
|
30
|
-
type BottomSheetFooterFlag,
|
|
31
|
-
type BottomSheetFooterPlacement,
|
|
32
|
-
resolveFooterPlacement,
|
|
33
|
-
} from "./bottom-sheet.variants";
|
|
2
|
+
BottomSheet as Headless,
|
|
3
|
+
type BottomSheetContainerProps as HeadlessProps,
|
|
4
|
+
} from "@delacour/react-native-bottom-sheet";
|
|
5
|
+
import { Children, isValidElement, type ReactElement, type ReactNode } from "react";
|
|
6
|
+
import { withUniwind } from "uniwind";
|
|
7
|
+
import { cn } from "../../lib/cn";
|
|
34
8
|
import { BottomSheetBackground } from "./bottom-sheet-background";
|
|
35
|
-
import { BottomSheetFooter, type BottomSheetFooterProps } from "./bottom-sheet-footer";
|
|
36
9
|
import { BottomSheetHandle } from "./bottom-sheet-handle";
|
|
37
10
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The engine's panel, taught `className`.
|
|
13
|
+
*
|
|
14
|
+
* `withUniwind`'s return type maps over a component's props and loses the
|
|
15
|
+
* shape of anything animated, so the signature is restated. Built at module
|
|
16
|
+
* scope: in render it would mint a new component type every pass and remount
|
|
17
|
+
* the whole sheet.
|
|
18
|
+
*/
|
|
19
|
+
type StyledContainerComponent = (props: HeadlessProps & { className?: string }) => ReactElement | null;
|
|
20
|
+
|
|
21
|
+
const StyledContainer = withUniwind(Headless.Container) as unknown as StyledContainerComponent;
|
|
22
|
+
|
|
23
|
+
export type BottomSheetContainerProps = HeadlessProps & {
|
|
24
|
+
className?: string;
|
|
43
25
|
/** Classes for the sheet's surface — the box behind the handle and the content. */
|
|
44
26
|
backgroundClassName?: string;
|
|
45
27
|
/** Classes for the row the grabber sits in. */
|
|
@@ -48,43 +30,29 @@ export type BottomSheetContainerProps = Omit<
|
|
|
48
30
|
handleIndicatorClassName?: string;
|
|
49
31
|
};
|
|
50
32
|
|
|
33
|
+
/** Whether any direct child is one of the two parts the container would otherwise write itself. */
|
|
34
|
+
function hasSurfaceParts(children: ReactNode): boolean {
|
|
35
|
+
return Children.toArray(children).some(
|
|
36
|
+
(child) => isValidElement(child) && (child.type === BottomSheetBackground || child.type === BottomSheetHandle)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
51
40
|
/**
|
|
52
|
-
* The
|
|
53
|
-
*
|
|
54
|
-
* Every gorhom prop passes through, so snap points, dynamic sizing, the pan
|
|
55
|
-
* gestures and the animation configs are all reachable. Four are not, because
|
|
56
|
-
* this component supplies them: the backdrop and the footer are cloned from the
|
|
57
|
-
* parts a caller wrote, and the background and the handle are rendered as views
|
|
58
|
-
* of this package's own so they can take a `className` rather than a style.
|
|
59
|
-
*
|
|
60
|
-
* **It takes no `className`.** gorhom's modal wears an animated style that the
|
|
61
|
-
* sheet's own position writes to every frame, so there is nothing here for a
|
|
62
|
-
* class to reach that `backgroundClassName` does not already reach better. The
|
|
63
|
-
* same trade `Screen.Footer` makes — that file takes a `style` and never a
|
|
64
|
-
* `className`, and so wraps nothing in `withUniwind`.
|
|
41
|
+
* The panel — the surface that moves.
|
|
65
42
|
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* programmatic close all arrive at the same `onOpenChange`. gorhom's own
|
|
69
|
-
* `onDismiss` is therefore not forwarded: two callbacks for one event is two
|
|
70
|
-
* things that can disagree. `useBottomSheet().sheetRef` is still there for the
|
|
71
|
-
* imperative calls with no declarative form — `snapToIndex`, `expand`.
|
|
43
|
+
* The engine positions it, sizes it to the frame and translates it by the
|
|
44
|
+
* sheet's geometry; this adds classes and the two parts every sheet has.
|
|
72
45
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* the
|
|
78
|
-
* filled in at all. This is `Field`'s rule one component along: the row is
|
|
79
|
-
* `accessible={false}` so the control stays the element a screen reader sees.
|
|
80
|
-
* Pass `accessible` to opt back into gorhom's behaviour for a sheet whose body
|
|
81
|
-
* really is one adjustable thing.
|
|
46
|
+
* **It writes `Background` and `Handle` for you** when the children hold
|
|
47
|
+
* neither, so the common sheet is `Container > Content` and nothing else. Write
|
|
48
|
+
* either one yourself and it writes nothing — a container with a custom handle
|
|
49
|
+
* and no surface is a decision, not an omission. The three `*ClassName` props
|
|
50
|
+
* reach the parts it writes; a part you write takes its own `className`.
|
|
82
51
|
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* can be turned back off.
|
|
52
|
+
* **Sizing and behaviour live on the root, not here.** `snapPoints`,
|
|
53
|
+
* `dynamicSizing`, `maxDynamicContentSize`, `keyboardBehavior` and the rest
|
|
54
|
+
* are `BottomSheet`'s props: the engine resolves them once for every part, and
|
|
55
|
+
* a panel that carried them would be a second place to look.
|
|
88
56
|
*
|
|
89
57
|
* @example
|
|
90
58
|
* <BottomSheet.Container>
|
|
@@ -92,154 +60,33 @@ export type BottomSheetContainerProps = Omit<
|
|
|
92
60
|
* </BottomSheet.Container>
|
|
93
61
|
*
|
|
94
62
|
* @example
|
|
95
|
-
* // A
|
|
96
|
-
* <BottomSheet.Container
|
|
97
|
-
* <BottomSheet.
|
|
98
|
-
* <BottomSheet.
|
|
63
|
+
* // A custom grabber; the surface still comes with it.
|
|
64
|
+
* <BottomSheet.Container backgroundClassName="bg-card">
|
|
65
|
+
* <BottomSheet.Background className="bg-card" />
|
|
66
|
+
* <BottomSheet.Handle><MyGrabber /></BottomSheet.Handle>
|
|
67
|
+
* <BottomSheet.Content>{…}</BottomSheet.Content>
|
|
99
68
|
* </BottomSheet.Container>
|
|
100
69
|
*/
|
|
101
70
|
export function BottomSheetContainer({
|
|
102
|
-
accessible = false,
|
|
103
71
|
backgroundClassName,
|
|
104
72
|
children,
|
|
105
|
-
|
|
73
|
+
className,
|
|
106
74
|
handleClassName,
|
|
107
75
|
handleIndicatorClassName,
|
|
108
76
|
...props
|
|
109
77
|
}: BottomSheetContainerProps): ReactElement {
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
// keyboard that is not there. `Screen.Footer` runs the same repair on mount.
|
|
116
|
-
useKeyboardAnimationGuard();
|
|
117
|
-
|
|
118
|
-
// Whether this sheet has ever been presented. A JS ref rather than state:
|
|
119
|
-
// nothing renders differently for it, and it has to be readable inside the
|
|
120
|
-
// effect that sets it.
|
|
121
|
-
const hasPresentedRef = useRef(false);
|
|
122
|
-
|
|
123
|
-
const { content, footer, placement } = useMemo(() => hoistFooter(children), [children]);
|
|
124
|
-
const hasStickyFooter = placement === "sticky";
|
|
125
|
-
const overlay = portal?.overlay ?? null;
|
|
126
|
-
|
|
127
|
-
// Written by the pinned footer's own onLayout, read by the body's spacer. It
|
|
128
|
-
// lives here because the two are siblings in gorhom's tree and neither can see
|
|
129
|
-
// the other — the footer is rendered outside the children this file wraps.
|
|
130
|
-
const footerHeight = useSharedValue(0);
|
|
131
|
-
|
|
132
|
-
const containerValue = useMemo(() => ({ footerHeight, hasStickyFooter }), [footerHeight, hasStickyFooter]);
|
|
133
|
-
|
|
134
|
-
const backdropComponent = useMemo(
|
|
135
|
-
() =>
|
|
136
|
-
overlay === null ? undefined : (backdropProps: BottomSheetBackdropProps) => cloneElement(overlay, backdropProps),
|
|
137
|
-
[overlay]
|
|
78
|
+
const surface = hasSurfaceParts(children) ? null : (
|
|
79
|
+
<>
|
|
80
|
+
<BottomSheetBackground className={backgroundClassName} />
|
|
81
|
+
<BottomSheetHandle className={handleClassName} indicatorClassName={handleIndicatorClassName} />
|
|
82
|
+
</>
|
|
138
83
|
);
|
|
139
84
|
|
|
140
|
-
const footerComponent = useMemo(
|
|
141
|
-
() =>
|
|
142
|
-
footer === null
|
|
143
|
-
? undefined
|
|
144
|
-
: (footerProps: GorhomBottomSheetFooterProps) => cloneElement(footer, { ...footerProps, footerHeight }),
|
|
145
|
-
[footer, footerHeight]
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
const backgroundComponent = useCallback(
|
|
149
|
-
(backgroundProps: GorhomBottomSheetBackgroundProps) => (
|
|
150
|
-
<BottomSheetBackground {...backgroundProps} className={backgroundClassName} />
|
|
151
|
-
),
|
|
152
|
-
[backgroundClassName]
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
const handleComponent = useCallback(
|
|
156
|
-
(handleProps: GorhomBottomSheetHandleProps) => (
|
|
157
|
-
<BottomSheetHandle {...handleProps} className={handleClassName} indicatorClassName={handleIndicatorClassName} />
|
|
158
|
-
),
|
|
159
|
-
[handleClassName, handleIndicatorClassName]
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
const handleDismiss = useCallback(() => {
|
|
163
|
-
hasPresentedRef.current = false;
|
|
164
|
-
setOpen(false);
|
|
165
|
-
}, [setOpen]);
|
|
166
|
-
|
|
167
|
-
useEffect(() => {
|
|
168
|
-
if (isOpen) {
|
|
169
|
-
hasPresentedRef.current = true;
|
|
170
|
-
sheetRef.current?.present();
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Dismissing a modal that was never presented is NOT a no-op, and this is
|
|
175
|
-
// the sharpest edge in the component. gorhom's modal starts at status
|
|
176
|
-
// `INITIAL`; `dismiss()` reads that as a live sheet being closed and moves
|
|
177
|
-
// it to `DISMISSING`, where it stays. The next `present()` then mounts the
|
|
178
|
-
// portal and renders the sheet — and it never animates in, never lays out
|
|
179
|
-
// its content, and never fires `onChange`. Nothing is logged, nothing
|
|
180
|
-
// throws, and the screen simply does not change.
|
|
181
|
-
if (!hasPresentedRef.current) return;
|
|
182
|
-
hasPresentedRef.current = false;
|
|
183
|
-
sheetRef.current?.dismiss();
|
|
184
|
-
}, [isOpen, sheetRef]);
|
|
185
|
-
|
|
186
85
|
return (
|
|
187
|
-
<
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
enablePanDownToClose={enablePanDownToClose}
|
|
192
|
-
footerComponent={footerComponent}
|
|
193
|
-
handleComponent={handleComponent}
|
|
194
|
-
onDismiss={handleDismiss}
|
|
195
|
-
ref={sheetRef}
|
|
196
|
-
{...BOTTOM_SHEET_KEYBOARD_DEFAULTS}
|
|
197
|
-
{...props}
|
|
198
|
-
>
|
|
199
|
-
<BottomSheetProvider value={sheet}>
|
|
200
|
-
<BottomSheetContainerProvider value={containerValue}>{content}</BottomSheetContainerProvider>
|
|
201
|
-
</BottomSheetProvider>
|
|
202
|
-
</BottomSheetModal>
|
|
86
|
+
<StyledContainer className={cn(className)} {...props}>
|
|
87
|
+
{surface}
|
|
88
|
+
{children}
|
|
89
|
+
</StyledContainer>
|
|
203
90
|
);
|
|
204
91
|
}
|
|
205
92
|
BottomSheetContainer.displayName = "DelacourUI.BottomSheet.Container";
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Splits a container's children into the body and a footer to be pinned.
|
|
209
|
-
*
|
|
210
|
-
* gorhom takes a footer as a `footerComponent` render prop rather than as a
|
|
211
|
-
* child, so a sticky one has to leave the tree it was written in; an inline one
|
|
212
|
-
* stays put and is simply part of the body. {@link resolveFooterPlacement} is the
|
|
213
|
-
* decision and is pure, so `bun test` reaches the whole matrix — this walk only
|
|
214
|
-
* turns children into the flags it reads.
|
|
215
|
-
*
|
|
216
|
-
* Lives here rather than with the parts: it is the container that lifts its own
|
|
217
|
-
* children, and importing it from `bottom-sheet-footer.tsx` would close a cycle.
|
|
218
|
-
* See AGENTS.md.
|
|
219
|
-
*/
|
|
220
|
-
function hoistFooter(children: ReactNode): {
|
|
221
|
-
content: ReactNode;
|
|
222
|
-
footer: ReactElement<BottomSheetFooterProps> | null;
|
|
223
|
-
placement: BottomSheetFooterPlacement;
|
|
224
|
-
} {
|
|
225
|
-
const items = Children.toArray(children);
|
|
226
|
-
const flags: BottomSheetFooterFlag[] = [];
|
|
227
|
-
let footer: ReactElement<BottomSheetFooterProps> | null = null;
|
|
228
|
-
|
|
229
|
-
for (const child of items) {
|
|
230
|
-
if (!isValidElement(child) || child.type !== BottomSheetFooter) {
|
|
231
|
-
flags.push({ isFooter: false, isSticky: false });
|
|
232
|
-
continue;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const element = child as ReactElement<BottomSheetFooterProps>;
|
|
236
|
-
const isSticky = element.props.sticky === true;
|
|
237
|
-
flags.push({ isFooter: true, isSticky });
|
|
238
|
-
if (isSticky) footer ??= element;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
const placement = resolveFooterPlacement(flags);
|
|
242
|
-
if (placement !== "sticky" || footer === null) return { content: items, footer: null, placement };
|
|
243
|
-
|
|
244
|
-
return { content: items.filter((child) => child !== footer), footer, placement };
|
|
245
|
-
}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BottomSheet as Headless,
|
|
3
|
+
type BottomSheetContentProps as HeadlessProps,
|
|
4
|
+
} from "@delacour/react-native-bottom-sheet";
|
|
2
5
|
import type { ReactElement } from "react";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
6
|
-
import { useBottomSheetContainerContext } from "./bottom-sheet.context";
|
|
7
|
-
import { BOTTOM_SHEET_FOOTER_GAP, bottomSheetVariants, resolveSheetBottomInset } from "./bottom-sheet.variants";
|
|
6
|
+
import { withUniwind } from "uniwind";
|
|
7
|
+
import { BOTTOM_SHEET_FOOTER_GAP, bottomSheetVariants } from "./bottom-sheet.variants";
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
type StyledContentComponent = (props: HeadlessProps & { className?: string }) => ReactElement | null;
|
|
10
|
+
|
|
11
|
+
// Built once at module scope; the classes land on the engine's inner, measured
|
|
12
|
+
// view, which is the one that takes `style`.
|
|
13
|
+
const StyledContent = withUniwind(Headless.Content) as unknown as StyledContentComponent;
|
|
14
|
+
|
|
15
|
+
export type BottomSheetContentProps = HeadlessProps & {
|
|
10
16
|
className?: string;
|
|
11
17
|
};
|
|
12
18
|
|
|
@@ -14,28 +20,12 @@ export type BottomSheetContentProps = ViewProps & {
|
|
|
14
20
|
* The sheet's body — what a caller writes the title, the copy and the controls
|
|
15
21
|
* into.
|
|
16
22
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* **A pinned footer is reserved by a spacer, not by gorhom's
|
|
25
|
-
* `enableFooterMarginAdjustment`.** That prop turns the footer's measured height
|
|
26
|
-
* into content-container padding through React state — a commit on every frame
|
|
27
|
-
* of the keyboard animation, because the footer changes height as it gives up
|
|
28
|
-
* its safe-area band. A spacer whose height is an animated style off the same
|
|
29
|
-
* shared value costs nothing on the JS thread, and `Screen` already reserves its
|
|
30
|
-
* own chrome exactly this way. The spacer sits OUTSIDE the classed box so the
|
|
31
|
-
* content's own `gap` does not land in front of it and quietly double the
|
|
32
|
-
* {@link BOTTOM_SHEET_FOOTER_GAP} the footer is held off by.
|
|
33
|
-
*
|
|
34
|
-
* **The safe-area band goes on the OUTER box, and only when nothing else is
|
|
35
|
-
* paying for it** — a pinned footer's own box carries it, so
|
|
36
|
-
* {@link resolveSheetBottomInset} withholds it here. The band comes from
|
|
37
|
-
* `useSafeAreaInsets()` and never from `pb-safe`, which compiles to
|
|
38
|
-
* `env(safe-area-inset-bottom)` and resolves to zero on React Native.
|
|
23
|
+
* The engine's `Content` with the library's gutter and gap on its measured
|
|
24
|
+
* box. Everything the old body had to do by hand is the engine's now: the
|
|
25
|
+
* body is clamped to the space the handle, a sticky footer, the keyboard and
|
|
26
|
+
* the safe-area band leave; a spacer the footer's height plus `footerGap`
|
|
27
|
+
* keeps the last line above a pinned footer; and the band under it is
|
|
28
|
+
* reserved by the geometry rather than padded here.
|
|
39
29
|
*
|
|
40
30
|
* @example
|
|
41
31
|
* <BottomSheet.Content>
|
|
@@ -43,24 +33,11 @@ export type BottomSheetContentProps = ViewProps & {
|
|
|
43
33
|
* <BottomSheet.Description>This cannot be undone.</BottomSheet.Description>
|
|
44
34
|
* </BottomSheet.Content>
|
|
45
35
|
*/
|
|
46
|
-
export function BottomSheetContent({
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const reserve = useAnimatedStyle(() => ({
|
|
54
|
-
height: footerHeight === undefined ? 0 : footerHeight.value + BOTTOM_SHEET_FOOTER_GAP,
|
|
55
|
-
}));
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<BottomSheetView style={{ paddingBottom }}>
|
|
59
|
-
<View className={bottomSheetVariants().content({ className })} style={style} {...props}>
|
|
60
|
-
{children}
|
|
61
|
-
</View>
|
|
62
|
-
{hasStickyFooter ? <Animated.View style={reserve} /> : null}
|
|
63
|
-
</BottomSheetView>
|
|
64
|
-
);
|
|
36
|
+
export function BottomSheetContent({
|
|
37
|
+
className,
|
|
38
|
+
footerGap = BOTTOM_SHEET_FOOTER_GAP,
|
|
39
|
+
...props
|
|
40
|
+
}: BottomSheetContentProps): ReactElement {
|
|
41
|
+
return <StyledContent className={bottomSheetVariants().content({ className })} footerGap={footerGap} {...props} />;
|
|
65
42
|
}
|
|
66
43
|
BottomSheetContent.displayName = "DelacourUI.BottomSheet.Content";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BottomSheet as Headless } from "@delacour/react-native-bottom-sheet";
|
|
1
2
|
import type { ReactElement } from "react";
|
|
2
3
|
import { cn } from "../../lib/cn";
|
|
3
4
|
import { Text, type TextPresetProps } from "../text";
|
|
@@ -10,7 +11,8 @@ export type BottomSheetDescriptionProps = TextPresetProps;
|
|
|
10
11
|
* *Is* a `Text.Paragraph`, defaulting to the muted token — the title is what the
|
|
11
12
|
* sheet is about and this is what it means, so the two need to read as a
|
|
12
13
|
* hierarchy rather than as two equal lines. `color` is an ordinary prop, so a
|
|
13
|
-
* description that needs the page colour asks for it.
|
|
14
|
+
* description that needs the page colour asks for it. The engine's
|
|
15
|
+
* `Description asChild` gives it the `nativeID` a skin can describe the panel by.
|
|
14
16
|
*
|
|
15
17
|
* It has no slot in `bottomSheetVariants`, and that is deliberate: it carries no
|
|
16
18
|
* layout of its own, and `tv` emits `undefined` for an empty class string, so a
|
|
@@ -24,6 +26,10 @@ export function BottomSheetDescription({
|
|
|
24
26
|
color = "muted",
|
|
25
27
|
...props
|
|
26
28
|
}: BottomSheetDescriptionProps): ReactElement {
|
|
27
|
-
return
|
|
29
|
+
return (
|
|
30
|
+
<Headless.Description asChild>
|
|
31
|
+
<Text.Paragraph className={cn(className)} color={color} {...props} />
|
|
32
|
+
</Headless.Description>
|
|
33
|
+
);
|
|
28
34
|
}
|
|
29
35
|
BottomSheetDescription.displayName = "DelacourUI.BottomSheet.Description";
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BottomSheet as Headless,
|
|
3
|
+
type BottomSheetFlatListProps as HeadlessProps,
|
|
4
|
+
useBottomSheetInternal,
|
|
5
|
+
} from "@delacour/react-native-bottom-sheet";
|
|
6
|
+
import type { ReactElement, Ref } from "react";
|
|
7
|
+
import type { FlatList } from "react-native";
|
|
8
|
+
import { withUniwind } from "uniwind";
|
|
9
|
+
import { cn } from "../../lib/cn";
|
|
10
|
+
import { BOTTOM_SHEET_FOOTER_GAP, bottomSheetVariants } from "./bottom-sheet.variants";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The class props `withUniwind` adds, restated so the generic survives.
|
|
14
|
+
*
|
|
15
|
+
* `withUniwind`'s own return type maps over a component's props and collapses
|
|
16
|
+
* `<ItemT>` in the process, which would leave `data` and `renderItem` checking
|
|
17
|
+
* against `unknown`. Writing the signature out keeps inference and still
|
|
18
|
+
* declares exactly the two props the wrapper adds — the same move
|
|
19
|
+
* `Screen.LegendList` makes.
|
|
20
|
+
*/
|
|
21
|
+
type StyledFlatListComponent = <ItemT>(
|
|
22
|
+
props: HeadlessProps<ItemT> & { ref?: Ref<FlatList<ItemT>>; className?: string; contentContainerClassName?: string }
|
|
23
|
+
) => ReactElement | null;
|
|
24
|
+
|
|
25
|
+
// Built at module scope, or every render mints a new component type and
|
|
26
|
+
// remounts the list.
|
|
27
|
+
const StyledFlatList = withUniwind(Headless.FlatList) as unknown as StyledFlatListComponent;
|
|
28
|
+
|
|
29
|
+
export type BottomSheetFlatListProps<ItemT> = HeadlessProps<ItemT> & {
|
|
30
|
+
ref?: Ref<FlatList<ItemT>>;
|
|
31
|
+
className?: string;
|
|
32
|
+
/** Classes for the content container. Same gutter and gap as `Content`. */
|
|
33
|
+
contentContainerClassName?: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A virtualised body.
|
|
38
|
+
*
|
|
39
|
+
* The engine's `FlatList` — the scroll lock, the drag budget and content size
|
|
40
|
+
* as the dynamic snap point are all its — with the library's gutter on the content
|
|
41
|
+
* container. A virtualised list has no inner box to put the classes on, so
|
|
42
|
+
* here they go on `contentContainerClassName`; the engine flattens the
|
|
43
|
+
* resulting style to one object before the list measures it.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* <BottomSheet.FlatList data={rows} keyExtractor={(row) => row.id} renderItem={renderRow} />
|
|
47
|
+
*/
|
|
48
|
+
export function BottomSheetFlatList<ItemT>({
|
|
49
|
+
className,
|
|
50
|
+
contentContainerClassName,
|
|
51
|
+
contentContainerStyle,
|
|
52
|
+
...props
|
|
53
|
+
}: BottomSheetFlatListProps<ItemT>): ReactElement {
|
|
54
|
+
const { hasFooter } = useBottomSheetInternal();
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<StyledFlatList
|
|
58
|
+
className={cn(className)}
|
|
59
|
+
contentContainerClassName={bottomSheetVariants().scrollContent({ className: contentContainerClassName })}
|
|
60
|
+
contentContainerStyle={[{ paddingBottom: hasFooter ? BOTTOM_SHEET_FOOTER_GAP : 0 }, contentContainerStyle]}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
BottomSheetFlatList.displayName = "DelacourUI.BottomSheet.FlatList";
|