@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,73 +1,106 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
BottomSheetHost,
|
|
3
|
+
BottomSheet as Headless,
|
|
4
|
+
type BottomSheetProps as HeadlessBottomSheetProps,
|
|
5
|
+
} from "@delacour/react-native-bottom-sheet";
|
|
6
|
+
import type { ReactElement } from "react";
|
|
7
|
+
import { Presets } from "react-native-pulsar";
|
|
8
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
9
|
+
import { useKeyboardAnimationGuard } from "../../hooks/use-keyboard-state-sync";
|
|
10
|
+
import { BottomSheetBackground } from "./bottom-sheet-background";
|
|
4
11
|
import { BottomSheetClose } from "./bottom-sheet-close";
|
|
5
12
|
import { BottomSheetContainer } from "./bottom-sheet-container";
|
|
6
13
|
import { BottomSheetContent } from "./bottom-sheet-content";
|
|
7
14
|
import { BottomSheetDescription } from "./bottom-sheet-description";
|
|
15
|
+
import { BottomSheetFlatList } from "./bottom-sheet-flat-list";
|
|
8
16
|
import { BottomSheetFooter } from "./bottom-sheet-footer";
|
|
17
|
+
import { BottomSheetHandle } from "./bottom-sheet-handle";
|
|
18
|
+
import { BottomSheetLegendList } from "./bottom-sheet-legend-list";
|
|
9
19
|
import { BottomSheetOverlay } from "./bottom-sheet-overlay";
|
|
10
|
-
import {
|
|
20
|
+
import { BottomSheetProvider } from "./bottom-sheet-provider";
|
|
11
21
|
import { BottomSheetScrollView } from "./bottom-sheet-scroll-view";
|
|
22
|
+
import { BottomSheetSectionList } from "./bottom-sheet-section-list";
|
|
23
|
+
import { BottomSheetStep, BottomSheetSteps } from "./bottom-sheet-steps";
|
|
24
|
+
import { BottomSheetTextInput } from "./bottom-sheet-text-input";
|
|
12
25
|
import { BottomSheetTitle } from "./bottom-sheet-title";
|
|
13
26
|
import { BottomSheetTrigger } from "./bottom-sheet-trigger";
|
|
14
27
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Called whenever the sheet opens or closes — by a trigger, a swipe down, a
|
|
23
|
-
* press on the backdrop, `BottomSheet.Close`, or a controlled `isOpen`.
|
|
24
|
-
*
|
|
25
|
-
* One callback for every path, deliberately. gorhom's own `onClose` fires for
|
|
26
|
-
* the gesture alone, which is the shape that makes a caller wire three
|
|
27
|
-
* handlers and still miss one.
|
|
28
|
-
*/
|
|
29
|
-
onOpenChange?: (isOpen: boolean) => void;
|
|
30
|
-
};
|
|
28
|
+
/**
|
|
29
|
+
* Every prop the engine's root takes, with two defaults this skin fills in:
|
|
30
|
+
* `bottomInset` is the device's safe-area bottom unless a caller says
|
|
31
|
+
* otherwise, and the two haptics are the library's own.
|
|
32
|
+
*/
|
|
33
|
+
export type BottomSheetProps = HeadlessBottomSheetProps;
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
/**
|
|
36
|
+
* The haptics the sheet plays, as module-scope worklets.
|
|
37
|
+
*
|
|
38
|
+
* Both run on the UI thread from inside the engine's pan, so they are
|
|
39
|
+
* `Presets.System.*` — themselves worklets — and nothing else: a JS function
|
|
40
|
+
* here would be `undefined is not a function` at the moment a finger crosses a
|
|
41
|
+
* snap point. `selection` on a snap point because that is what a picker's tick feels
|
|
42
|
+
* like, and `impactLight` on a close because letting go of a sheet is a
|
|
43
|
+
* heavier event than passing a stop, but not by much.
|
|
44
|
+
*/
|
|
45
|
+
const snapPointHaptic = Presets.System.selection;
|
|
46
|
+
const closeHaptic = Presets.System.impactLight;
|
|
39
47
|
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
/**
|
|
49
|
+
* The engine's root with this library's defaults on it. It renders no view of
|
|
50
|
+
* its own.
|
|
51
|
+
*
|
|
52
|
+
* Three things happen here and nowhere else in the skin:
|
|
53
|
+
*
|
|
54
|
+
* - **`bottomInset` defaults to the safe-area bottom**, read from
|
|
55
|
+
* `useSafeAreaInsets()`. The engine reserves that band under the body or the
|
|
56
|
+
* sticky footer and gives it back to the keyboard as it arrives; a caller
|
|
57
|
+
* never pads for the home indicator by hand.
|
|
58
|
+
* - **The haptics are on by default.** Pass `onSnapPointHaptic={undefined}` to
|
|
59
|
+
* turn one off, or a worklet of your own to change it.
|
|
60
|
+
* - **The stale-keyboard guard runs on mount.** A sheet mounted while
|
|
61
|
+
* `KeyboardProvider`'s shared values are pinned open by a keyboard that
|
|
62
|
+
* vanished without a `will` event would lift for a keyboard that is not
|
|
63
|
+
* there; `Screen.Footer` runs the same repair for the same reason.
|
|
64
|
+
*
|
|
65
|
+
* `topInset` is left at the engine's zero, so a `%` snap point is a fraction of the
|
|
66
|
+
* whole window — the same fraction it was before this rewrite.
|
|
67
|
+
*/
|
|
68
|
+
function BottomSheetRoot({
|
|
69
|
+
bottomInset,
|
|
70
|
+
onSnapPointHaptic = snapPointHaptic,
|
|
71
|
+
onCloseHaptic = closeHaptic,
|
|
72
|
+
...props
|
|
73
|
+
}: BottomSheetProps): ReactElement {
|
|
74
|
+
const insets = useSafeAreaInsets();
|
|
75
|
+
useKeyboardAnimationGuard();
|
|
42
76
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
77
|
+
return (
|
|
78
|
+
<Headless
|
|
79
|
+
bottomInset={bottomInset ?? insets.bottom}
|
|
80
|
+
onCloseHaptic={onCloseHaptic}
|
|
81
|
+
onSnapPointHaptic={onSnapPointHaptic}
|
|
82
|
+
{...props}
|
|
83
|
+
/>
|
|
46
84
|
);
|
|
47
|
-
|
|
48
|
-
return <BottomSheetProvider value={context}>{children}</BottomSheetProvider>;
|
|
49
85
|
}
|
|
50
86
|
|
|
51
87
|
/**
|
|
52
88
|
* A panel that slides up from the bottom of the screen, over everything.
|
|
53
89
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
90
|
+
* A thin Uniwind skin over `@delacour/react-native-bottom-sheet`: every part
|
|
91
|
+
* here is the engine's part with this library's classes, `Text` presets and
|
|
92
|
+
* `Pressable` on it. The engine owns the state, the geometry, the gestures,
|
|
93
|
+
* the keyboard, the portal and the accessibility; this file owns what it looks
|
|
94
|
+
* like.
|
|
58
95
|
*
|
|
59
|
-
* **The app
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* `BottomSheet.Footer sticky` are lifted out of the tree and handed to gorhom as
|
|
65
|
-
* render props — see `BottomSheet.Portal` and `BottomSheet.Container` for why the
|
|
66
|
-
* anatomy is worth that. Everything else renders in place.
|
|
96
|
+
* **The app mounts `BottomSheetProvider` once**, inside `DelacourProvider` and
|
|
97
|
+
* around its navigator. `DelacourProvider` cannot do it — the engine is an
|
|
98
|
+
* optional peer of this library — so the provider is exported from this
|
|
99
|
+
* subpath for the app to place. Without it a `Portal` renders where it is
|
|
100
|
+
* written, which is the inline sheet.
|
|
67
101
|
*
|
|
68
102
|
* Controlled or not, from one hook: pass `isOpen` and `onOpenChange` to own the
|
|
69
|
-
* state, or nothing at all and let the sheet hold it.
|
|
70
|
-
* locked in on first render.
|
|
103
|
+
* state, or nothing at all and let the sheet hold it.
|
|
71
104
|
*
|
|
72
105
|
* @example
|
|
73
106
|
* <BottomSheet>
|
|
@@ -90,12 +123,12 @@ function BottomSheetRoot({ children, defaultOpen = false, isOpen, onOpenChange }
|
|
|
90
123
|
* </BottomSheet>
|
|
91
124
|
*
|
|
92
125
|
* @example
|
|
93
|
-
* // Controlled, and
|
|
94
|
-
* <BottomSheet isOpen={isOpen} onOpenChange={setOpen}>
|
|
126
|
+
* // Controlled, snapped, and scrolling.
|
|
127
|
+
* <BottomSheet dynamicSizing={false} isOpen={isOpen} onOpenChange={setOpen} snapPoints={["50%", "90%"]}>
|
|
95
128
|
* <BottomSheet.Portal>
|
|
96
129
|
* <BottomSheet.Overlay />
|
|
97
130
|
* <BottomSheet.Container>
|
|
98
|
-
* <BottomSheet.
|
|
131
|
+
* <BottomSheet.ScrollView>{rows}</BottomSheet.ScrollView>
|
|
99
132
|
* </BottomSheet.Container>
|
|
100
133
|
* </BottomSheet.Portal>
|
|
101
134
|
* </BottomSheet>
|
|
@@ -103,23 +136,43 @@ function BottomSheetRoot({ children, defaultOpen = false, isOpen, onOpenChange }
|
|
|
103
136
|
export const BottomSheet = Object.assign(BottomSheetRoot, {
|
|
104
137
|
/** The control that opens the sheet. `asChild` to make a `Button` the trigger. */
|
|
105
138
|
Trigger: BottomSheetTrigger,
|
|
106
|
-
/** Everything drawn above the app
|
|
107
|
-
Portal:
|
|
108
|
-
/** The scrim.
|
|
139
|
+
/** Everything drawn above the app, teleported to the nearest host. `inline` to render in place. */
|
|
140
|
+
Portal: Headless.Portal,
|
|
141
|
+
/** The scrim. Omit it and the sheet has none. */
|
|
109
142
|
Overlay: BottomSheetOverlay,
|
|
110
|
-
/** The
|
|
143
|
+
/** The panel that moves. Brings its own `Background` and `Handle` unless you write them. */
|
|
111
144
|
Container: BottomSheetContainer,
|
|
112
|
-
/** The
|
|
145
|
+
/** The panel's surface — `bg-popover`, top corners rounded, every corner when `detached`. */
|
|
146
|
+
Background: BottomSheetBackground,
|
|
147
|
+
/** The grabber's row, and the sheet's one adjustable accessibility element. */
|
|
148
|
+
Handle: BottomSheetHandle,
|
|
149
|
+
/** The static body. A sheet sized to its content is sized to this. */
|
|
113
150
|
Content: BottomSheetContent,
|
|
114
|
-
/** A scrolling body.
|
|
151
|
+
/** A scrolling body. Sizes to its rows, capped by `maxDynamicContentSize`, or fills explicit `snapPoints`. */
|
|
115
152
|
ScrollView: BottomSheetScrollView,
|
|
153
|
+
/** A virtualised body. */
|
|
154
|
+
FlatList: BottomSheetFlatList,
|
|
155
|
+
/** A virtualised body with sticky section headers. */
|
|
156
|
+
SectionList: BottomSheetSectionList,
|
|
157
|
+
/** A `LegendList` body. Needs the optional `@legendapp/list` peer. */
|
|
158
|
+
LegendList: BottomSheetLegendList,
|
|
159
|
+
/** Controls at the bottom. `sticky` pins them over the body and rides the keyboard. */
|
|
160
|
+
Footer: BottomSheetFooter,
|
|
116
161
|
/** The dismiss control, positioned out of the content's flow. */
|
|
117
162
|
Close: BottomSheetClose,
|
|
118
|
-
/** The sheet's heading — a `Text.Header`
|
|
163
|
+
/** The sheet's heading — a `Text.Header` that labels the panel for a screen reader. */
|
|
119
164
|
Title: BottomSheetTitle,
|
|
120
165
|
/** Supporting copy under the title — a muted `Text.Paragraph`. */
|
|
121
166
|
Description: BottomSheetDescription,
|
|
122
|
-
/**
|
|
123
|
-
|
|
167
|
+
/** An `Input` registered with the sheet, so the keyboard it raises is the sheet's. */
|
|
168
|
+
TextInput: BottomSheetTextInput,
|
|
169
|
+
/** A body whose contents follow a step machine and whose height glides between them. */
|
|
170
|
+
Steps: BottomSheetSteps,
|
|
171
|
+
/** One step of a `Steps` body. */
|
|
172
|
+
Step: BottomSheetStep,
|
|
173
|
+
/** A place for sheets to teleport to other than the root — the recipe for a native modal. */
|
|
174
|
+
Host: BottomSheetHost,
|
|
175
|
+
/** The engine's provider, sharing `OverlayProvider`'s teleport host. Mount it once, inside `DelacourProvider`. */
|
|
176
|
+
Provider: BottomSheetProvider,
|
|
124
177
|
displayName: "DelacourUI.BottomSheet",
|
|
125
178
|
});
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { resolveSheetBottomInset, resolveSheetScrollEndPadding } from "@delacour/react-native-bottom-sheet/core";
|
|
2
3
|
import { declaredTokens, tokenValue } from "../../styles/theme-tokens.test";
|
|
3
4
|
import {
|
|
4
5
|
BOTTOM_SHEET_BACKDROP_INDICES,
|
|
5
6
|
BOTTOM_SHEET_CLOSE_HIT_SLOP,
|
|
6
7
|
BOTTOM_SHEET_FOOTER_GAP,
|
|
7
8
|
BOTTOM_SHEET_FOOTER_PADDING,
|
|
8
|
-
BOTTOM_SHEET_KEYBOARD_DEFAULTS,
|
|
9
9
|
BOTTOM_SHEET_OVERLAY_OPACITY,
|
|
10
10
|
BOTTOM_SHEET_OVERLAY_TOKEN,
|
|
11
11
|
bottomSheetVariants,
|
|
12
|
-
resolveFooterPlacement,
|
|
13
|
-
resolveSheetBottomInset,
|
|
14
|
-
resolveSheetScrollEndPadding,
|
|
15
12
|
} from "./bottom-sheet.variants";
|
|
16
13
|
|
|
17
14
|
const LIGHT = declaredTokens("light");
|
|
@@ -33,6 +30,7 @@ function colorTokens(cls: string): string[] {
|
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
const SLOTS = bottomSheetVariants();
|
|
33
|
+
const DETACHED = bottomSheetVariants({ detached: true });
|
|
36
34
|
|
|
37
35
|
/**
|
|
38
36
|
* The slots this component declares, pinned rather than derived.
|
|
@@ -48,6 +46,8 @@ const SLOT_NAMES = [
|
|
|
48
46
|
"handleIndicator",
|
|
49
47
|
"content",
|
|
50
48
|
"scrollContent",
|
|
49
|
+
"steps",
|
|
50
|
+
"step",
|
|
51
51
|
"footer",
|
|
52
52
|
"stickyFooter",
|
|
53
53
|
"close",
|
|
@@ -82,8 +82,8 @@ describe("the overlay token", () => {
|
|
|
82
82
|
expect(alpha).toBeLessThan(1);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
//
|
|
86
|
-
// the
|
|
85
|
+
// Any other opacity would multiply against that alpha and land the scrim
|
|
86
|
+
// somewhere the theme did not ask for.
|
|
87
87
|
expect(BOTTOM_SHEET_OVERLAY_OPACITY).toBe(1);
|
|
88
88
|
});
|
|
89
89
|
|
|
@@ -113,90 +113,28 @@ describe("every token the slots name", () => {
|
|
|
113
113
|
|
|
114
114
|
describe("the backdrop indices", () => {
|
|
115
115
|
test("show the scrim from the first snap point and hide it only when closed", () => {
|
|
116
|
-
//
|
|
117
|
-
// on screen. A modal sheet has no resting state.
|
|
116
|
+
// A modal sheet has no resting state: presented or gone.
|
|
118
117
|
expect(BOTTOM_SHEET_BACKDROP_INDICES.appearsOnIndex).toBe(0);
|
|
119
118
|
expect(BOTTOM_SHEET_BACKDROP_INDICES.disappearsOnIndex).toBe(-1);
|
|
120
119
|
expect(BOTTOM_SHEET_BACKDROP_INDICES.disappearsOnIndex).toBeLessThan(BOTTOM_SHEET_BACKDROP_INDICES.appearsOnIndex);
|
|
121
120
|
});
|
|
122
121
|
});
|
|
123
122
|
|
|
124
|
-
describe("the
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
android_keyboardInputMode: "adjustResize",
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test("does not leave Android on gorhom's adjustPan", () => {
|
|
134
|
-
// `adjustPan` slides the whole window up instead of resizing it, which puts
|
|
135
|
-
// a sheet's footer off-screen. `resize` is what Expo configures and what
|
|
136
|
-
// `KeyboardProvider` requires, so this is the value that matches reality.
|
|
137
|
-
expect(BOTTOM_SHEET_KEYBOARD_DEFAULTS.android_keyboardInputMode).not.toBe("adjustPan");
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe("resolveFooterPlacement", () => {
|
|
142
|
-
const footer = (isSticky: boolean) => ({ isFooter: true, isSticky });
|
|
143
|
-
const other = { isFooter: false, isSticky: false };
|
|
144
|
-
|
|
145
|
-
test("reports none for children holding no footer", () => {
|
|
146
|
-
expect(resolveFooterPlacement([])).toBe("none");
|
|
147
|
-
expect(resolveFooterPlacement([other, other])).toBe("none");
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
test("reports inline for a footer that did not ask to be pinned", () => {
|
|
151
|
-
expect(resolveFooterPlacement([other, footer(false)])).toBe("inline");
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
test("reports sticky for one that did, wherever it sits", () => {
|
|
155
|
-
expect(resolveFooterPlacement([footer(true), other])).toBe("sticky");
|
|
156
|
-
expect(resolveFooterPlacement([other, footer(true)])).toBe("sticky");
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
test("lets a single sticky footer win over an inline one", () => {
|
|
160
|
-
// Two footers is not a state worth expressing, and the pinned one is the
|
|
161
|
-
// one a caller meant.
|
|
162
|
-
expect(resolveFooterPlacement([footer(false), footer(true)])).toBe("sticky");
|
|
163
|
-
expect(resolveFooterPlacement([footer(true), footer(false)])).toBe("sticky");
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
test("never reads a sticky flag off a child that is not a footer", () => {
|
|
167
|
-
expect(resolveFooterPlacement([{ isFooter: false, isSticky: true }])).toBe("none");
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
describe("resolveSheetBottomInset", () => {
|
|
172
|
-
test("gives the safe-area band to the content when nothing is pinned below it", () => {
|
|
123
|
+
describe("the inset helpers the engine's core exports", () => {
|
|
124
|
+
// They used to live here. They moved to the engine so the engine's own footer
|
|
125
|
+
// and body could share them; the skin re-exports them for the callers that
|
|
126
|
+
// imported them from `@delacour/react-native-ui/bottom-sheet`.
|
|
127
|
+
test("give the safe-area band to static content when nothing is pinned below it", () => {
|
|
173
128
|
expect(resolveSheetBottomInset({ bottom: 34, hasStickyFooter: false })).toBe(34);
|
|
174
129
|
});
|
|
175
130
|
|
|
176
|
-
test("
|
|
177
|
-
//
|
|
178
|
-
//
|
|
131
|
+
test("hold content off a pinned footer by the gap alone, never the band", () => {
|
|
132
|
+
// The footer's own box carries the band; the content asking for it too
|
|
133
|
+
// would count it twice.
|
|
179
134
|
expect(resolveSheetBottomInset({ bottom: 34, hasStickyFooter: true })).toBe(0);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
expect(resolveSheetBottomInset({ bottom: 0, hasStickyFooter: false })).toBe(0);
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
describe("resolveSheetScrollEndPadding", () => {
|
|
188
|
-
test("gives the safe-area band to the content when nothing is pinned below it", () => {
|
|
189
|
-
expect(resolveSheetScrollEndPadding({ bottom: 34, hasStickyFooter: false })).toBe(34);
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
test("holds the content off a pinned footer by the gap alone", () => {
|
|
193
|
-
// The scroll view's frame already stops at the footer's top edge, so the
|
|
194
|
-
// footer's height — band included — is not the content's to reserve.
|
|
195
|
-
expect(resolveSheetScrollEndPadding({ bottom: 34, hasStickyFooter: true })).toBe(BOTTOM_SHEET_FOOTER_GAP);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
test("keeps the gap on a device with no bottom inset", () => {
|
|
199
|
-
expect(resolveSheetScrollEndPadding({ bottom: 0, hasStickyFooter: true })).toBe(BOTTOM_SHEET_FOOTER_GAP);
|
|
135
|
+
expect(
|
|
136
|
+
resolveSheetScrollEndPadding({ bottom: 34, footerGap: BOTTOM_SHEET_FOOTER_GAP, hasStickyFooter: true })
|
|
137
|
+
).toBe(BOTTOM_SHEET_FOOTER_GAP);
|
|
200
138
|
});
|
|
201
139
|
});
|
|
202
140
|
|
|
@@ -228,7 +166,7 @@ describe("bottomSheetVariants slots", () => {
|
|
|
228
166
|
expect(declared.sort()).toEqual([...SLOT_NAMES].sort());
|
|
229
167
|
});
|
|
230
168
|
|
|
231
|
-
test("
|
|
169
|
+
test("an attached sheet's surface rounds its top corners only", () => {
|
|
232
170
|
const background = SLOTS.background();
|
|
233
171
|
expect(background).toMatch(/\brounded-t-/);
|
|
234
172
|
expect(background).not.toMatch(/\brounded-b-/);
|
|
@@ -237,6 +175,17 @@ describe("bottomSheetVariants slots", () => {
|
|
|
237
175
|
expect(background).not.toMatch(/\brounded-(?:none|xs|sm|md|lg|xl|2xl|3xl|full)\b/);
|
|
238
176
|
});
|
|
239
177
|
|
|
178
|
+
test("a detached card's surface rounds every corner, and only once", () => {
|
|
179
|
+
const background = DETACHED.background();
|
|
180
|
+
// The card floats, so its bottom edge is on screen and needs the radius.
|
|
181
|
+
expect(background).toMatch(/\brounded-2xl\b/);
|
|
182
|
+
// tailwind-merge has to have replaced the top-only radius, not stacked
|
|
183
|
+
// beside it — two radius utilities on one view is order-dependent.
|
|
184
|
+
expect(background).not.toMatch(/\brounded-t-/);
|
|
185
|
+
// The surface itself is unchanged.
|
|
186
|
+
expect(colorTokens(background)).toEqual(colorTokens(SLOTS.background()));
|
|
187
|
+
});
|
|
188
|
+
|
|
240
189
|
test("a pinned footer brings a surface and a line where an inline one does not", () => {
|
|
241
190
|
// It draws OVER the content, so without them the content scrolls straight
|
|
242
191
|
// through it. An inline footer is in the flow and needs neither.
|
|
@@ -246,10 +195,10 @@ describe("bottomSheetVariants slots", () => {
|
|
|
246
195
|
expect(SLOTS.footer()).not.toMatch(/\bborder-t\b/);
|
|
247
196
|
});
|
|
248
197
|
|
|
249
|
-
test("a pinned footer writes its vertical padding as
|
|
250
|
-
// The
|
|
251
|
-
//
|
|
252
|
-
//
|
|
198
|
+
test("a pinned footer writes its vertical padding as the engine's prop, never a class", () => {
|
|
199
|
+
// The engine measures the footer's inner box into the sheet's height, and
|
|
200
|
+
// padding handed to its `padding` prop lands on that box. A class on the
|
|
201
|
+
// outer view would be height the snap point never counts.
|
|
253
202
|
expect(SLOTS.stickyFooter()).not.toMatch(/\bp[tby]?-[\d.]+\b/);
|
|
254
203
|
expect(BOTTOM_SHEET_FOOTER_PADDING).toBeGreaterThan(0);
|
|
255
204
|
});
|
|
@@ -273,9 +222,20 @@ describe("bottomSheetVariants slots", () => {
|
|
|
273
222
|
expect(SLOTS.scrollContent()).toMatch(/\bpx-screen-gutter\b/);
|
|
274
223
|
});
|
|
275
224
|
|
|
225
|
+
test("a multi-step body keeps the gutter on the stack and the vertical padding on each step", () => {
|
|
226
|
+
// The engine measures each `Step`, not the box around the stack, so
|
|
227
|
+
// vertical padding on `steps` would be height the sheet never counts.
|
|
228
|
+
expect(SLOTS.steps()).toMatch(/\bpx-screen-gutter\b/);
|
|
229
|
+
expect(SLOTS.steps()).not.toMatch(/\bp[tby]-[\d.]+\b/);
|
|
230
|
+
expect(SLOTS.step()).not.toMatch(/\bpx-/);
|
|
231
|
+
// A step reads like static content: same gap, same top padding.
|
|
232
|
+
expect(SLOTS.step().match(/\bgap-[\d.]+\b/)?.[0]).toBe(SLOTS.content().match(/\bgap-[\d.]+\b/)?.[0]);
|
|
233
|
+
expect(SLOTS.step().match(/\bpt-[\d.]+\b/)?.[0]).toBe(SLOTS.content().match(/\bpt-[\d.]+\b/)?.[0]);
|
|
234
|
+
});
|
|
235
|
+
|
|
276
236
|
test("the overlay sets no opacity of its own", () => {
|
|
277
|
-
//
|
|
278
|
-
// would be a second writer of the same style property.
|
|
237
|
+
// The engine animates the scrim's opacity off the sheet's index; a class
|
|
238
|
+
// here would be a second writer of the same style property.
|
|
279
239
|
expect(SLOTS.overlay()).not.toMatch(/\bopacity-\d/);
|
|
280
240
|
});
|
|
281
241
|
|