@delacour/react-native-ui 0.1.0-alpha.4 → 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 +10 -6
- package/package.json +48 -4
- 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 -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 +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 +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/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 +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,242 +1,197 @@
|
|
|
1
1
|
# BottomSheet
|
|
2
2
|
|
|
3
|
-
A panel that slides up
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
`BottomSheet.Content`, `BottomSheet.ScrollView`, `BottomSheet.Close`,
|
|
7
|
-
`BottomSheet.Title`, `BottomSheet.Description` and `BottomSheet.Footer`.
|
|
3
|
+
A panel that slides up from the bottom of the screen, over everything — a
|
|
4
|
+
Uniwind skin on `@delacour/react-native-bottom-sheet`, this repository's own
|
|
5
|
+
headless engine.
|
|
8
6
|
|
|
9
|
-
`import { BottomSheet } from "@delacour/react-native-ui/bottom-sheet";`
|
|
7
|
+
`import { BottomSheet, BottomSheetProvider } from "@delacour/react-native-ui/bottom-sheet";`
|
|
8
|
+
|
|
9
|
+
The engine is an **optional peer**, like `@delacour/react-native-charts` is
|
|
10
|
+
for `Chart`: an app that never imports this subpath never resolves it, and
|
|
11
|
+
never has to build its native peer `react-native-teleport`. The consequence is
|
|
12
|
+
the one thing a consumer has to do that no other component asks of them —
|
|
13
|
+
**mount `BottomSheetProvider` once**, inside `DelacourProvider` and around the
|
|
14
|
+
navigator. `DelacourProvider` cannot mount it without importing the engine. See
|
|
15
|
+
[DelacourProvider](../provider/AGENTS.md).
|
|
10
16
|
|
|
11
17
|
## Files
|
|
12
18
|
|
|
13
19
|
| File | What it holds |
|
|
14
20
|
| --- | --- |
|
|
15
|
-
| `index.ts` | → `@delacour/react-native-ui/bottom-sheet
|
|
16
|
-
| `bottom-sheet.tsx` |
|
|
17
|
-
| `bottom-sheet
|
|
18
|
-
| `bottom-sheet
|
|
19
|
-
| `bottom-sheet-
|
|
20
|
-
| `bottom-sheet-
|
|
21
|
-
| `bottom-sheet-
|
|
22
|
-
| `bottom-sheet-
|
|
23
|
-
| `bottom-sheet-
|
|
24
|
-
| `bottom-sheet-
|
|
25
|
-
| `bottom-sheet-
|
|
26
|
-
| `bottom-sheet-
|
|
27
|
-
| `bottom-sheet-
|
|
28
|
-
| `bottom-sheet-
|
|
29
|
-
| `bottom-sheet.
|
|
30
|
-
| `bottom-sheet.
|
|
31
|
-
| `bottom-sheet.
|
|
32
|
-
| `
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
`
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
`
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
declarative form — `snapToIndex`, `expand`, `collapse`.
|
|
185
|
-
- **`accessible` defaults to `false`, and it is the least obvious line in the
|
|
186
|
-
component.** gorhom marks the sheet's content container `accessible` with the
|
|
187
|
-
label "Bottom Sheet" and the `adjustable` role. On iOS an `accessible`
|
|
188
|
-
container collapses its whole subtree into ONE element, so every field, button
|
|
189
|
-
and line of copy inside becomes unreachable to VoiceOver — the form gallery
|
|
190
|
-
route was a single "Bottom Sheet" element until this default was flipped. It is
|
|
191
|
-
[`Field`](../field/AGENTS.md)'s rule one component along: the row is `accessible={false}` so the
|
|
192
|
-
control stays the element a screen reader sees. Verified with
|
|
193
|
-
`native-describe-screen` on a simulator, not assumed.
|
|
194
|
-
- **Three defaults differ from gorhom's, and each is a modal-sheet decision.**
|
|
195
|
-
`enablePanDownToClose` is on, because a modal sheet has no collapsed resting
|
|
196
|
-
state to pan down to. The backdrop appears on index `0` and disappears on `-1`
|
|
197
|
-
rather than `1` and `0`, for the same reason — gorhom's defaults suit a
|
|
198
|
-
persistent sheet that dims the app only once expanded. And the keyboard trio
|
|
199
|
-
is `interactive` / `restore` / `adjustResize`: leaving Android on gorhom's
|
|
200
|
-
`adjustPan` slides the whole window up instead of resizing it and puts the
|
|
201
|
-
footer off-screen, where `resize` is already what Expo configures and what
|
|
202
|
-
`KeyboardProvider` requires. All are ordinary props; `BOTTOM_SHEET_KEYBOARD_DEFAULTS`
|
|
203
|
-
is a const so a test pins the trio rather than three inline literals.
|
|
204
|
-
- **`--overlay` is a token, not a `bg-black/50`.** A pure-black scrim over
|
|
205
|
-
a near-black dark theme is nearly invisible, so the two variants carry
|
|
206
|
-
different alphas — and because the alpha lives in the token, the backdrop's
|
|
207
|
-
`opacity` defaults to **1** rather than gorhom's 0.5, which would multiply the
|
|
208
|
-
two and land the scrim at a fifth of what the theme asked for. It takes no
|
|
209
|
-
`-foreground`: nothing is drawn on a scrim, and the sheet in front brings its
|
|
210
|
-
own. A test pins the token against both `@variant` blocks and pins the opacity
|
|
211
|
-
against the alpha being there.
|
|
212
|
-
|
|
213
|
-
## Input
|
|
214
|
-
|
|
215
|
-
- **`useBottomSheetInput()` is why `Input` still works in here.** A sheet only
|
|
216
|
-
grows for the keyboard when it knows the focused field is one of its own, and
|
|
217
|
-
gorhom's answer is to use its `BottomSheetTextInput` — which would leave this
|
|
218
|
-
package's `Input`, its variants, its `Input.Group` and its `Field` cascade
|
|
219
|
-
unusable inside a sheet. The registration is exposed as `{ onFocus, onBlur, ref }`
|
|
220
|
-
instead, so `Input` imports nothing from `@gorhom/bottom-sheet` and the hook is
|
|
221
|
-
inert outside a sheet. The `ref` is not optional polish: without it, moving
|
|
222
|
-
focus between two fields in one sheet reads as the keyboard closing and
|
|
223
|
-
reopening and the sheet resizes twice on the way. It covers the keyboard half only:
|
|
224
|
-
a *drag* across a field can still be claimed by the sheet's content pan, since
|
|
225
|
-
gorhom's input is built on Gesture Handler's `TextInput` and this one is not.
|
|
226
|
-
If that ever bites, the fix is `enableContentPanningGesture={false}` on the
|
|
227
|
-
container. The *tap* half is the scrim's problem and is solved above.
|
|
21
|
+
| `index.ts` | → `@delacour/react-native-ui/bottom-sheet`. The compound, the variants, the provider and the hooks re-exported from the engine, and the two compat aliases below |
|
|
22
|
+
| `bottom-sheet.tsx` | `BottomSheet` — the engine's root with this library's defaults: `bottomInset` from the safe area, the two haptics, the stale-keyboard guard. The `Object.assign` names every part |
|
|
23
|
+
| `bottom-sheet.variants.ts` | The slotted `tv()` — `overlay`, `background` (with a `detached` variant), `handle`, `handleIndicator`, `content`, `scrollContent`, `steps`, `step`, `footer`, `stickyFooter`, `close`, `title` — and the numeric constants the engine's props take |
|
|
24
|
+
| `bottom-sheet.variants.test.ts` | Every token the slots name exists in both themes; the rules below, pinned |
|
|
25
|
+
| `bottom-sheet-trigger.tsx` | `BottomSheet.Trigger` — this library's `Pressable`, or `asChild` to donate the press |
|
|
26
|
+
| `bottom-sheet-overlay.tsx` | `BottomSheet.Overlay` — the engine's scrim in `bg-overlay`, opacity 1 |
|
|
27
|
+
| `bottom-sheet-container.tsx` | `BottomSheet.Container` — the panel; writes `Background` and `Handle` when the caller writes neither |
|
|
28
|
+
| `bottom-sheet-background.tsx` | `BottomSheet.Background` — `bg-popover`, top corners rounded, every corner when detached |
|
|
29
|
+
| `bottom-sheet-handle.tsx` | `BottomSheet.Handle` — the engine's row with the pill inside it |
|
|
30
|
+
| `bottom-sheet-content.tsx` | `BottomSheet.Content` — the static body, gutter and gap on the measured box |
|
|
31
|
+
| `bottom-sheet-scroll-view.tsx` | `BottomSheet.ScrollView` — classes on an inner `View` |
|
|
32
|
+
| `bottom-sheet-flat-list.tsx` | `BottomSheet.FlatList` — classes on the content container |
|
|
33
|
+
| `bottom-sheet-section-list.tsx` | `BottomSheet.SectionList` — same |
|
|
34
|
+
| `bottom-sheet-legend-list.tsx` | `BottomSheet.LegendList` — built here with `createBottomSheetScrollable`, because `@legendapp/list` is this library's optional peer and not the engine's |
|
|
35
|
+
| `bottom-sheet-footer.tsx` | `BottomSheet.Footer` — inline by default, `sticky` to pin |
|
|
36
|
+
| `bottom-sheet-close.tsx` | `BottomSheet.Close` — the engine's `Close asChild` around `Pressable feedback="fade"` and an `IconCrossSmall` |
|
|
37
|
+
| `bottom-sheet-title.tsx` | `BottomSheet.Title` — the engine's `Title asChild` around `Text.Header` |
|
|
38
|
+
| `bottom-sheet-description.tsx` | `BottomSheet.Description` — `Description asChild` around a muted `Text.Paragraph` |
|
|
39
|
+
| `bottom-sheet-text-input.tsx` | `BottomSheet.TextInput` — `Input` spread with the engine's registration |
|
|
40
|
+
| `bottom-sheet-steps.tsx` | `BottomSheet.Steps` and `BottomSheet.Step` — the multi-step body, gutter on the stack and vertical padding on each step |
|
|
41
|
+
| `use-bottom-sheet-input.ts` | `useBottomSheetInput()` — the engine's `useBottomSheetTextInput` under the name this library shipped |
|
|
42
|
+
|
|
43
|
+
`Portal`, `Host` and `Provider` are the engine's own, re-exported unchanged:
|
|
44
|
+
none of them draws anything a class could reach.
|
|
45
|
+
|
|
46
|
+
## Anatomy
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<BottomSheet snapPoints? dynamicSizing? maxDynamicContentSize? detached? keyboardBehavior? …>
|
|
50
|
+
<BottomSheet.Trigger asChild><Button /></BottomSheet.Trigger>
|
|
51
|
+
<BottomSheet.Portal inline? hostName?>
|
|
52
|
+
<BottomSheet.Overlay pressBehavior? />
|
|
53
|
+
<BottomSheet.Container backgroundClassName? handleClassName? handleIndicatorClassName?>
|
|
54
|
+
<BottomSheet.Background /> <BottomSheet.Handle /> // written for you unless you write them
|
|
55
|
+
<BottomSheet.Content> | <BottomSheet.ScrollView> | <BottomSheet.FlatList> | <BottomSheet.SectionList> | <BottomSheet.LegendList> | <BottomSheet.Steps controller>
|
|
56
|
+
<BottomSheet.Close /> <BottomSheet.Title /> <BottomSheet.Description /> <BottomSheet.TextInput />
|
|
57
|
+
<BottomSheet.Footer sticky? />
|
|
58
|
+
</BottomSheet.Container>
|
|
59
|
+
</BottomSheet.Portal>
|
|
60
|
+
</BottomSheet>
|
|
61
|
+
|
|
62
|
+
<BottomSheetProvider /> // once, in the app root
|
|
63
|
+
<BottomSheet.Host name="modal" /> // last in a native modal screen
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`Container` is the panel that moves; `Content` is the static body inside it.
|
|
67
|
+
Sizing and behaviour — `snapPoints`, `dynamicSizing`, `maxDynamicContentSize`,
|
|
68
|
+
`keyboardBehavior`, `detached`, the haptics — are the **root's** props. The
|
|
69
|
+
engine's names win everywhere; this skin aliases nothing.
|
|
70
|
+
|
|
71
|
+
## What the engine owns
|
|
72
|
+
|
|
73
|
+
Everything that is not a class. The open state and the intent queue; the
|
|
74
|
+
height-space geometry and the snap points; the handle and content pans and how a
|
|
75
|
+
list shares a finger with them; the keyboard — who owns it, `interactive` /
|
|
76
|
+
`extend` / `fillParent` / `none`, the lift and the restore; the sticky footer's
|
|
77
|
+
line and the safe-area band under it; the teleport portal, the hosts, the
|
|
78
|
+
registry that stacks sheets and answers Android's back button; the detached
|
|
79
|
+
card's frame; the step machine and the height that glides between steps; and
|
|
80
|
+
the accessibility — the panel is a modal view labelled by the title, the
|
|
81
|
+
handle is the one adjustable element. Its `AGENTS.md` and the `AGENTS.md` in
|
|
82
|
+
each of its `src/*` folders carry the reasoning and the device verification;
|
|
83
|
+
read those before touching behaviour, because behaviour is not here.
|
|
84
|
+
|
|
85
|
+
## What this skin owns
|
|
86
|
+
|
|
87
|
+
- **Classes, from one `tv()`.** Every part is the engine's part with a slot
|
|
88
|
+
from `bottomSheetVariants` on it. The engine's parts take `style`, not
|
|
89
|
+
`className`, so each is wrapped in `withUniwind` **once, at module scope** —
|
|
90
|
+
in render the wrapper would mint a new component type every pass, remount
|
|
91
|
+
the panel and re-attach the pans. Rule 7's carve-out for third-party
|
|
92
|
+
components applies: the engine is another package.
|
|
93
|
+
- **Where the classes land.** `Content`, `Footer` and `Steps` hand `style` to
|
|
94
|
+
the engine's *measured* inner view, so a class there is height the dynamic
|
|
95
|
+
snap point counts. `ScrollView` puts its content classes on an inner `View`
|
|
96
|
+
rather than the content container, so the one style this file writes there —
|
|
97
|
+
the gap above a pinned footer — has a single writer. The three virtualised
|
|
98
|
+
lists have no inner box, so theirs go on `contentContainerClassName`; the
|
|
99
|
+
engine flattens the resulting array to one object before the list measures
|
|
100
|
+
it, which is what makes that safe where it was not with the library this
|
|
101
|
+
replaces.
|
|
102
|
+
- **`Container` writes `Background` and `Handle` for you** when the children
|
|
103
|
+
hold neither, detected by element type. Write either yourself and it writes
|
|
104
|
+
nothing: a custom handle with no surface is a decision. The three
|
|
105
|
+
`*ClassName` props reach only the parts it writes.
|
|
106
|
+
- **`Title` and `Description` are `Text` presets**, through the engine's
|
|
107
|
+
`asChild`. The engine contributes the `nativeID` the panel is labelled by and
|
|
108
|
+
the heading role; the preset contributes the type. The `title` slot carries
|
|
109
|
+
`pr-8` for the close control and nothing else — a `text-lg` there would be a
|
|
110
|
+
second definition of `Text.Header` — and the test asserts it.
|
|
111
|
+
- **`Close` and `Trigger` are this library's `Pressable`**, through `asChild`.
|
|
112
|
+
The engine's press handler is donated to the pressable rather than wrapping
|
|
113
|
+
it, because two tap gestures in an ancestor/descendant pair give the touch to
|
|
114
|
+
the descendant and a wrapping trigger never fires. `Close` presses with
|
|
115
|
+
`fade` and an 8pt slop, for `Badge.CloseButton`'s and `Checkbox`'s reasons.
|
|
116
|
+
- **The root fills in three defaults.** `bottomInset` is `useSafeAreaInsets().bottom`,
|
|
117
|
+
so the engine reserves the home-indicator band and nobody pads for it by
|
|
118
|
+
hand. `onSnapPointHaptic` is `Presets.System.selection` and `onCloseHaptic` is
|
|
119
|
+
`Presets.System.impactLight` — pulsar's presets are worklets, so they are
|
|
120
|
+
passed as they are; a JS function there is `undefined is not a function` on
|
|
121
|
+
the UI thread. And `useKeyboardAnimationGuard()` runs on mount, the same
|
|
122
|
+
stale-keyboard repair `Screen.Footer` runs. `topInset` stays at the engine's
|
|
123
|
+
zero, so a `%` snap point is the fraction of the window it always was.
|
|
124
|
+
- **`Footer.sticky` defaults to `false`**, matching `Screen.Footer`, and this is
|
|
125
|
+
the one engine default the skin overrides. A pinned footer takes
|
|
126
|
+
`padding={BOTTOM_SHEET_FOOTER_PADDING}` through the engine's prop rather
|
|
127
|
+
than a class, so the padding is inside the box the snap point measures; the
|
|
128
|
+
`stickyFooter` slot carries the gutter, the surface and the hairline, and
|
|
129
|
+
the test asserts it carries no vertical padding.
|
|
130
|
+
- **The overlay's opacity is 1**, because `--overlay` carries its own alpha and
|
|
131
|
+
the two theme variants carry different ones. `BOTTOM_SHEET_OVERLAY_OPACITY`
|
|
132
|
+
and `BOTTOM_SHEET_BACKDROP_INDICES` restate the engine's defaults so a test
|
|
133
|
+
can pin them against the theme.
|
|
134
|
+
- **`LegendList` is built here.** The engine exports
|
|
135
|
+
`createBottomSheetScrollable` and ships `ScrollView`, `FlatList` and
|
|
136
|
+
`SectionList`; `@legendapp/list` is this library's optional peer, so its
|
|
137
|
+
body is made here, once at module scope, and registered as a flat list.
|
|
138
|
+
|
|
139
|
+
## Compat
|
|
140
|
+
|
|
141
|
+
Two names survive from the previous implementation for callers that imported
|
|
142
|
+
them: `useBottomSheetInput()` is the engine's `useBottomSheetTextInput()`, and
|
|
143
|
+
`BottomSheetHandle` is the engine's `BottomSheetRef`, marked deprecated.
|
|
144
|
+
`resolveSheetBottomInset` and `resolveSheetScrollEndPadding` moved into the
|
|
145
|
+
engine's `./core` and are re-exported from here. `useBottomSheetContext()` is
|
|
146
|
+
the engine's `useOptionalBottomSheet()`.
|
|
147
|
+
|
|
148
|
+
Gone: `BOTTOM_SHEET_KEYBOARD_DEFAULTS` (the engine's `keyboardBehavior` and
|
|
149
|
+
`keyboardBlurBehavior` defaults are the same values, and there is no Android
|
|
150
|
+
input-mode prop), `resolveFooterPlacement` (nothing is hoisted any more), and
|
|
151
|
+
the container and portal contexts (the engine provides its contexts once, at
|
|
152
|
+
the root, and teleport keeps the React tree in place so they reach every part).
|
|
153
|
+
|
|
154
|
+
## No longer needed
|
|
155
|
+
|
|
156
|
+
The previous implementation, on a third-party modal, documented sixteen
|
|
157
|
+
workarounds. Every one of them is either the engine's job now or simply not a
|
|
158
|
+
problem it has:
|
|
159
|
+
|
|
160
|
+
- dismiss-before-present deadlock — state opens, intents move; closing a closed
|
|
161
|
+
sheet is nothing
|
|
162
|
+
- the backdrop stealing taps from a `TextInput` — the overlay is a `Pressable`
|
|
163
|
+
written before the panel, resolved by view order
|
|
164
|
+
- context lost across the portal — teleport moves the native view, not the tree
|
|
165
|
+
- `accessible` collapsing the panel into one element — the panel is a modal
|
|
166
|
+
view, never `accessible`
|
|
167
|
+
- the footer's `bottomInset` band — the geometry's footer line holds still
|
|
168
|
+
through the keyboard; the band is a spacer it owns
|
|
169
|
+
- `enableFooterMarginAdjustment` committing a render per frame — the body's
|
|
170
|
+
spacer is an animated style off `footerHeight`
|
|
171
|
+
- `android_keyboardInputMode` — keyboard-controller owns the window
|
|
172
|
+
- stale keyboard values — the root runs the guard; the engine runs the same
|
|
173
|
+
reconcile on every presentation
|
|
174
|
+
- an input's drag captured by the sheet — the content pan fails on horizontal
|
|
175
|
+
movement and yields to the field
|
|
176
|
+
- `snapPoints` identity re-deriving under an open sheet — normalised once per
|
|
177
|
+
change, on the UI thread
|
|
178
|
+
- nesting a sheet in a sheet — the registry stacks them; `stackBehavior` and
|
|
179
|
+
`dismissAll` are for exactly that
|
|
180
|
+
- `ScrollView` needing `dynamicSizing={false}` and `snapPoints` — a list's
|
|
181
|
+
content size is the dynamic snap point
|
|
182
|
+
- lifting `Overlay` and a sticky `Footer` out of the tree as render props —
|
|
183
|
+
every part renders where it is written
|
|
184
|
+
- a `Content` inside a `Container` paying the safe-area band by hand — the
|
|
185
|
+
geometry reserves it
|
|
186
|
+
- a sheet mounted while the keyboard was up floating a keyboard-height off the
|
|
187
|
+
bottom — ownership is decided per keyboard, sticky through a transition
|
|
188
|
+
- two footers, one inline and one sticky, needing a placement rule — a footer
|
|
189
|
+
is where you write it
|
|
228
190
|
|
|
229
191
|
## Structure
|
|
230
192
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
- **There is no `FullWindowOverlay`, so nothing imports `react-native-screens`.**
|
|
237
|
-
`BottomSheetModal` hosts itself in the `BottomSheetModalProvider` that
|
|
238
|
-
`DelacourProvider` mounts, which covers everything short of drawing over a
|
|
239
|
-
*native* stack modal. gorhom's `containerComponent` is the escape hatch if a
|
|
240
|
-
call site ever needs that; it is not worth the optional peer, the iOS element
|
|
241
|
-
inspector and the keyboard caveats before then.
|
|
242
|
-
|
|
193
|
+
Pattern B, compound and context — the contexts are the engine's. The parts
|
|
194
|
+
never import `./bottom-sheet` or `./index` (rule 3); they import the engine and
|
|
195
|
+
`./bottom-sheet.variants`. `bun test` reaches the variants and the constants;
|
|
196
|
+
the behaviour is the engine's and is verified there, and the skin on a
|
|
197
|
+
simulator through `apps/playground`'s Bottom sheet galleries.
|
|
@@ -1,35 +1,44 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
BottomSheet as Headless,
|
|
3
|
+
type BottomSheetBackgroundProps as HeadlessProps,
|
|
4
|
+
useBottomSheetInternal,
|
|
5
|
+
} from "@delacour/react-native-bottom-sheet";
|
|
2
6
|
import type { ReactElement } from "react";
|
|
3
|
-
import {
|
|
7
|
+
import { withUniwind } from "uniwind";
|
|
4
8
|
import { bottomSheetVariants } from "./bottom-sheet.variants";
|
|
5
9
|
|
|
6
|
-
|
|
10
|
+
type StyledBackgroundComponent = (props: HeadlessProps & { className?: string }) => ReactElement | null;
|
|
11
|
+
|
|
12
|
+
// Third-party to Uniwind, so `className` needs the wrapper — and it has to be
|
|
13
|
+
// built at module scope or every render mints a new component type.
|
|
14
|
+
const StyledBackground = withUniwind(Headless.Background) as unknown as StyledBackgroundComponent;
|
|
15
|
+
|
|
16
|
+
export type BottomSheetBackgroundProps = HeadlessProps & {
|
|
7
17
|
className?: string;
|
|
8
18
|
};
|
|
9
19
|
|
|
10
20
|
/**
|
|
11
|
-
* The sheet's
|
|
21
|
+
* The sheet's surface: the box behind the handle and the content.
|
|
12
22
|
*
|
|
13
|
-
*
|
|
14
|
-
* `
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
23
|
+
* `bg-popover`, top corners rounded — and every corner when the root is
|
|
24
|
+
* `detached`, because a floating card has a bottom edge on screen. The engine
|
|
25
|
+
* sizes it: an attached surface fills the panel and its bottom edge is always
|
|
26
|
+
* off-screen; a detached one is exactly the sheet's height, so the corners this
|
|
27
|
+
* rounds are the ones you see.
|
|
18
28
|
*
|
|
19
|
-
*
|
|
20
|
-
* `[StyleSheet.absoluteFill, backgroundStyle]`; drop it and the surface collapses
|
|
21
|
-
* to nothing and the sheet renders transparent over the app.
|
|
29
|
+
* `Container` writes one for you unless you write it — see there.
|
|
22
30
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
31
|
+
* @example
|
|
32
|
+
* <BottomSheet.Background className="bg-card" />
|
|
25
33
|
*/
|
|
26
|
-
export function BottomSheetBackground({
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
+
export function BottomSheetBackground({ className, ...props }: BottomSheetBackgroundProps): ReactElement {
|
|
35
|
+
const { detached } = useBottomSheetInternal();
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<StyledBackground
|
|
39
|
+
className={bottomSheetVariants({ detached: detached !== null }).background({ className })}
|
|
40
|
+
{...props}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
34
43
|
}
|
|
35
44
|
BottomSheetBackground.displayName = "DelacourUI.BottomSheet.Background";
|