pixelize-native-library 1.2.0 → 1.2.1
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/lib/module/core/MODULE.md +2 -1
- package/lib/module/core/gradient/AccentGradientFill.js +80 -0
- package/lib/module/core/gradient/darkenHex.js +13 -0
- package/lib/module/core/gradient/gradientStops.js +27 -0
- package/lib/module/core/gradient/index.js +7 -0
- package/lib/module/core/gradient/withAlpha.js +19 -0
- package/lib/module/core/haptics/MODULE.md +4 -0
- package/lib/module/core/haptics/context.js +7 -0
- package/lib/module/core/haptics/haptics.js +17 -0
- package/lib/module/core/haptics/index.js +6 -0
- package/lib/module/core/haptics/useHaptics.js +73 -0
- package/lib/module/core/icon/MODULE.md +16 -9
- package/lib/module/core/icon/icons/trending-up.js +10 -0
- package/lib/module/core/icon/resolve.js +2 -0
- package/lib/module/core/media/expoImage.js +6 -0
- package/lib/module/core/motion/MODULE.md +12 -12
- package/lib/module/core/motion/config.js +4 -1
- package/lib/module/core/motion/index.js +2 -1
- package/lib/module/core/motion/usePressState.js +145 -0
- package/lib/module/core/style/index.js +1 -0
- package/lib/module/core/style/radius.js +4 -0
- package/lib/module/index.js +1 -0
- package/lib/module/modules/accordion/Accordion.js +69 -49
- package/lib/module/modules/accordion/Accordion.variants.js +4 -3
- package/lib/module/modules/accordion/MODULE.md +2 -1
- package/lib/module/modules/alert-dialog/AlertDialog.js +6 -5
- package/lib/module/modules/alert-dialog/AlertDialog.variants.js +4 -0
- package/lib/module/modules/app-bar/AppBar.js +6 -4
- package/lib/module/modules/app-bar/AppBar.variants.js +1 -2
- package/lib/module/modules/avatar/Avatar.js +7 -1
- package/lib/module/modules/avatar/Avatar.variants.js +1 -1
- package/lib/module/modules/avatar/MODULE.md +2 -2
- package/lib/module/modules/avatar-group/AvatarGroup.js +10 -6
- package/lib/module/modules/avatar-group/AvatarGroup.variants.js +23 -0
- package/lib/module/modules/avatar-group/MODULE.md +16 -0
- package/lib/module/modules/badge/Badge.js +11 -5
- package/lib/module/modules/badge/Badge.variants.js +2 -1
- package/lib/module/modules/badge/MODULE.md +5 -5
- package/lib/module/modules/banner/Banner.js +106 -60
- package/lib/module/modules/banner/Banner.variants.js +2 -2
- package/lib/module/modules/banner/MODULE.md +7 -2
- package/lib/module/modules/bottom-nav/BottomNav.js +6 -3
- package/lib/module/modules/bottom-nav/BottomNav.variants.js +9 -10
- package/lib/module/modules/bottom-nav/BottomNavOverflowSheet.js +28 -4
- package/lib/module/modules/bottom-nav/BottomNavTab.js +28 -4
- package/lib/module/modules/bottom-nav/MODULE.md +10 -1
- package/lib/module/modules/bottom-sheet/BottomSheet.js +20 -7
- package/lib/module/modules/bottom-sheet/BottomSheet.variants.js +15 -5
- package/lib/module/modules/bottom-sheet/MODULE.md +13 -2
- package/lib/module/modules/button/Button.js +87 -101
- package/lib/module/modules/button/Button.variants.js +8 -7
- package/lib/module/modules/button/MODULE.md +6 -0
- package/lib/module/modules/button-group/ButtonGroup.js +36 -37
- package/lib/module/modules/button-group/ButtonGroup.variants.js +21 -46
- package/lib/module/modules/button-group/MODULE.md +25 -30
- package/lib/module/modules/card/Card.js +117 -19
- package/lib/module/modules/card/Card.variants.js +1 -0
- package/lib/module/modules/card/MODULE.md +13 -10
- package/lib/module/modules/charts/BarChart.js +29 -14
- package/lib/module/modules/charts/BarList.js +31 -18
- package/lib/module/modules/charts/Charts.variants.js +66 -2
- package/lib/module/modules/charts/DonutChart.js +9 -4
- package/lib/module/modules/charts/LineChart.js +5 -3
- package/lib/module/modules/charts/MODULE.md +24 -11
- package/lib/module/modules/charts/PieChart.js +13 -4
- package/lib/module/modules/charts/Sparkline.js +4 -2
- package/lib/module/modules/checkbox/Checkbox.js +10 -2
- package/lib/module/modules/checkbox/MODULE.md +5 -0
- package/lib/module/modules/chip/Chip.js +83 -38
- package/lib/module/modules/chip/Chip.variants.js +15 -3
- package/lib/module/modules/chip/MODULE.md +6 -4
- package/lib/module/modules/combobox/Combobox.js +93 -57
- package/lib/module/modules/combobox/Combobox.variants.js +22 -7
- package/lib/module/modules/combobox/MODULE.md +14 -4
- package/lib/module/modules/composer/Composer.js +9 -2
- package/lib/module/modules/composer/Composer.variants.js +2 -0
- package/lib/module/modules/composer/MODULE.md +5 -0
- package/lib/module/modules/copy-button/CopyButton.js +22 -4
- package/lib/module/modules/copy-button/CopyButton.variants.js +4 -2
- package/lib/module/modules/copy-button/MODULE.md +5 -0
- package/lib/module/modules/data-table/DataTable.js +28 -9
- package/lib/module/modules/data-table/DataTable.variants.js +3 -2
- package/lib/module/modules/data-table/MODULE.md +1 -0
- package/lib/module/modules/date-picker/Calendar.js +75 -29
- package/lib/module/modules/date-picker/DatePicker.variants.js +24 -9
- package/lib/module/modules/date-picker/MODULE.md +25 -4
- package/lib/module/modules/date-picker/PickerField.js +13 -4
- package/lib/module/modules/date-picker/PickerShell.js +2 -0
- package/lib/module/modules/date-picker/TimePicker.js +13 -18
- package/lib/module/modules/divider/Divider.variants.js +6 -5
- package/lib/module/modules/divider/MODULE.md +2 -0
- package/lib/module/modules/drawer/Drawer.js +20 -8
- package/lib/module/modules/drawer/Drawer.variants.js +4 -4
- package/lib/module/modules/drawer/MODULE.md +3 -0
- package/lib/module/modules/empty-state/EmptyState.js +18 -29
- package/lib/module/modules/empty-state/EmptyState.variants.js +7 -0
- package/lib/module/modules/empty-state/MODULE.md +1 -0
- package/lib/module/modules/fab/Fab.js +41 -61
- package/lib/module/modules/fab/Fab.variants.js +15 -1
- package/lib/module/modules/fab/FabGroup.js +84 -57
- package/lib/module/modules/fab/MODULE.md +19 -6
- package/lib/module/modules/file-grid/FileGrid.js +30 -16
- package/lib/module/modules/file-grid/FileGrid.variants.js +2 -2
- package/lib/module/modules/file-grid/MODULE.md +3 -1
- package/lib/module/modules/file-upload/FileUpload.variants.js +3 -1
- package/lib/module/modules/file-upload/MODULE.md +2 -0
- package/lib/module/modules/filter-sheet/FilterChip.js +11 -3
- package/lib/module/modules/filter-sheet/FilterSheetBody.js +15 -3
- package/lib/module/modules/filter-sheet/MODULE.md +9 -0
- package/lib/module/modules/folder-row/FolderRow.js +29 -17
- package/lib/module/modules/folder-row/FolderRow.variants.js +4 -2
- package/lib/module/modules/folder-row/MODULE.md +2 -1
- package/lib/module/modules/gantt/Gantt.js +30 -9
- package/lib/module/modules/gantt/Gantt.variants.js +36 -0
- package/lib/module/modules/gantt/MODULE.md +11 -1
- package/lib/module/modules/image-viewer/ImageViewer.js +35 -5
- package/lib/module/modules/image-viewer/MODULE.md +6 -0
- package/lib/module/modules/input/Input.js +20 -7
- package/lib/module/modules/input/Input.variants.js +8 -7
- package/lib/module/modules/input/MODULE.md +2 -0
- package/lib/module/modules/list-item/ListItem.js +48 -26
- package/lib/module/modules/list-item/ListItem.variants.js +11 -2
- package/lib/module/modules/list-item/MODULE.md +2 -3
- package/lib/module/modules/markdown/MODULE.md +8 -1
- package/lib/module/modules/markdown/Markdown.js +57 -22
- package/lib/module/modules/markdown/Markdown.variants.js +2 -1
- package/lib/module/modules/menu/MODULE.md +11 -0
- package/lib/module/modules/menu/Menu.js +99 -40
- package/lib/module/modules/menu/Menu.variants.js +3 -3
- package/lib/module/modules/message-bubble/MODULE.md +4 -1
- package/lib/module/modules/message-bubble/MessageBubble.js +4 -5
- package/lib/module/modules/message-bubble/MessageBubble.variants.js +5 -5
- package/lib/module/modules/modal/MODULE.md +11 -0
- package/lib/module/modules/modal/Modal.js +87 -35
- package/lib/module/modules/modal/Modal.variants.js +2 -2
- package/lib/module/modules/more-items/MODULE.md +5 -0
- package/lib/module/modules/more-items/MoreItems.js +7 -1
- package/lib/module/modules/more-items/MoreItems.variants.js +4 -1
- package/lib/module/modules/multi-select/MODULE.md +5 -0
- package/lib/module/modules/multi-select/MultiSelect.js +23 -1
- package/lib/module/modules/multi-select/MultiSelect.variants.js +4 -2
- package/lib/module/modules/number-input/MODULE.md +2 -1
- package/lib/module/modules/number-input/NumberInput.js +97 -84
- package/lib/module/modules/number-input/NumberInput.variants.js +9 -6
- package/lib/module/modules/org-switcher/MODULE.md +13 -1
- package/lib/module/modules/org-switcher/OrgSwitcher.js +13 -2
- package/lib/module/modules/org-switcher/OrgSwitcher.variants.js +4 -2
- package/lib/module/modules/pagination/MODULE.md +2 -2
- package/lib/module/modules/pagination/Pagination.js +76 -37
- package/lib/module/modules/pagination/Pagination.variants.js +4 -2
- package/lib/module/modules/pagination/PaginationControls.js +55 -35
- package/lib/module/modules/pin-input/MODULE.md +5 -1
- package/lib/module/modules/pin-input/PinInput.js +9 -2
- package/lib/module/modules/pin-input/PinInput.variants.js +2 -1
- package/lib/module/modules/radio-group/MODULE.md +2 -2
- package/lib/module/modules/radio-group/RadioGroup.js +122 -63
- package/lib/module/modules/radio-group/RadioGroup.variants.js +2 -1
- package/lib/module/modules/reorder/MODULE.md +2 -0
- package/lib/module/modules/reorder/Reorder.js +4 -3
- package/lib/module/modules/reorder/Reorder.variants.js +4 -2
- package/lib/module/modules/rich-text/MODULE.md +3 -1
- package/lib/module/modules/rich-text/RichText.js +42 -22
- package/lib/module/modules/rich-text-editor/MODULE.md +4 -1
- package/lib/module/modules/rich-text-editor/RichTextEditor.js +8 -1
- package/lib/module/modules/rich-text-editor/RichTextEditor.variants.js +9 -6
- package/lib/module/modules/screen/MODULE.md +7 -0
- package/lib/module/modules/screen/Screen.js +50 -17
- package/lib/module/modules/screen/Screen.variants.js +18 -0
- package/lib/module/modules/search-bar/MODULE.md +1 -0
- package/lib/module/modules/search-bar/SearchBar.js +46 -26
- package/lib/module/modules/search-bar/SearchBar.variants.js +11 -8
- package/lib/module/modules/section/MODULE.md +2 -0
- package/lib/module/modules/section/Section.js +8 -15
- package/lib/module/modules/section/Section.variants.js +1 -6
- package/lib/module/modules/segmented-control/MODULE.md +3 -1
- package/lib/module/modules/segmented-control/SegmentedControl.js +110 -46
- package/lib/module/modules/segmented-control/SegmentedControl.variants.js +3 -2
- package/lib/module/modules/select/MODULE.md +26 -5
- package/lib/module/modules/select/Select.js +39 -12
- package/lib/module/modules/select/Select.variants.js +36 -12
- package/lib/module/modules/skeleton/MODULE.md +23 -27
- package/lib/module/modules/skeleton/Skeleton.js +46 -51
- package/lib/module/modules/skeleton/Skeleton.variants.js +17 -75
- package/lib/module/modules/slider/MODULE.md +2 -0
- package/lib/module/modules/slider/Slider.js +2 -1
- package/lib/module/modules/stage-progress/MODULE.md +12 -8
- package/lib/module/modules/stage-progress/StageProgress.js +94 -47
- package/lib/module/modules/stage-progress/StageProgress.variants.js +17 -12
- package/lib/module/modules/stat-tile/MODULE.md +2 -0
- package/lib/module/modules/stat-tile/StatTile.js +15 -10
- package/lib/module/modules/stat-tile/StatTile.variants.js +2 -0
- package/lib/module/modules/state-block/MODULE.md +3 -0
- package/lib/module/modules/state-block/StateBlock.js +11 -6
- package/lib/module/modules/state-block/StateBlock.variants.js +7 -0
- package/lib/module/modules/surface/MODULE.md +59 -0
- package/lib/module/modules/surface/Surface.js +42 -0
- package/lib/module/modules/surface/Surface.variants.js +33 -0
- package/lib/module/modules/surface/index.js +4 -0
- package/lib/module/modules/swipeable-row/MODULE.md +9 -0
- package/lib/module/modules/swipeable-row/SwipeableRow.js +28 -7
- package/lib/module/modules/switch/MODULE.md +2 -0
- package/lib/module/modules/switch/Switch.js +8 -2
- package/lib/module/modules/tabs/MODULE.md +2 -1
- package/lib/module/modules/tabs/Tabs.js +37 -18
- package/lib/module/modules/tabs/Tabs.variants.js +4 -2
- package/lib/module/modules/text/MODULE.md +5 -2
- package/lib/module/modules/text/Text.js +18 -6
- package/lib/module/modules/text/Text.variants.js +108 -44
- package/lib/module/modules/textarea/MODULE.md +2 -0
- package/lib/module/modules/textarea/Textarea.js +3 -2
- package/lib/module/modules/textarea/Textarea.variants.js +2 -1
- package/lib/module/modules/toast/MODULE.md +8 -4
- package/lib/module/modules/toast/Toast.js +31 -13
- package/lib/module/modules/toast/Toast.variants.js +5 -0
- package/lib/module/modules/tooltip/MODULE.md +15 -11
- package/lib/module/modules/tooltip/Tooltip.js +41 -9
- package/lib/module/modules/tooltip/Tooltip.variants.js +8 -1
- package/lib/module/theme/MODULE.md +3 -1
- package/lib/module/theme/platform/MODULE.md +14 -2
- package/lib/module/theme/platform/elevation.native.js +0 -44
- package/lib/module/theme/platform/floatingSurface.native.js +75 -0
- package/lib/module/theme/platform/highlight.native.js +59 -0
- package/lib/module/theme/platform/index.js +5 -0
- package/lib/module/theme/platform/motion.native.js +31 -11
- package/lib/module/theme/platform/stateLayer.native.js +14 -0
- package/lib/module/theme/platform/surfaces.native.js +11 -0
- package/lib/module/theme/provider/PixelizeProvider.js +12 -5
- package/lib/module/theme/tokens/MODULE.md +32 -28
- package/lib/module/theme/tokens/THEME-CONTRACT.md +137 -0
- package/lib/module/theme/tokens/assertPalette.js +29 -0
- package/lib/module/theme/tokens/brands/emerald/palette.light.js +7 -6
- package/lib/module/theme/tokens/brands/lavender/palette.light.js +3 -2
- package/lib/module/theme/tokens/brands/meadow/palette.light.js +7 -6
- package/lib/module/theme/tokens/brands/radiant/palette.light.js +7 -6
- package/lib/module/theme/tokens/brands/rosewood/palette.light.js +7 -6
- package/lib/module/theme/tokens/brands/skyline/palette.light.js +7 -6
- package/lib/module/theme/tokens/brands/slate/palette.light.js +8 -10
- package/lib/module/theme/tokens/brands/storefront/palette.light.js +7 -6
- package/lib/module/theme/tokens/brands/zinc/palette.dark.js +3 -2
- package/lib/module/theme/tokens/brands/zinc/palette.light.js +3 -2
- package/lib/module/theme/tokens/builders/buildDarkPalette.js +3 -2
- package/lib/module/theme/tokens/builders/finalizePalette.js +34 -0
- package/lib/module/theme/tokens/builders/liftToContrast.js +44 -0
- package/lib/module/theme/tokens/builders/placeholderInk.js +22 -0
- package/lib/module/theme/tokens/builders/semanticText.js +14 -0
- package/lib/module/theme/tokens/builders/surfaceRungs.js +44 -0
- package/lib/module/theme/tokens/index.js +5 -0
- package/lib/module/theme/tokens/roles/index.js +5 -0
- package/lib/typescript/core/gradient/AccentGradientFill.d.ts +7 -0
- package/lib/typescript/core/gradient/darkenHex.d.ts +2 -0
- package/lib/typescript/core/gradient/gradientStops.d.ts +10 -0
- package/lib/typescript/core/gradient/index.d.ts +5 -0
- package/lib/typescript/core/gradient/withAlpha.d.ts +2 -0
- package/lib/typescript/core/haptics/context.d.ts +3 -0
- package/lib/typescript/core/haptics/haptics.d.ts +33 -0
- package/lib/typescript/core/haptics/index.d.ts +6 -0
- package/lib/typescript/core/haptics/useHaptics.d.ts +12 -0
- package/lib/typescript/core/icon/icons/trending-up.d.ts +3 -0
- package/lib/typescript/core/icon/names.d.ts +1 -1
- package/lib/typescript/core/media/expoImage.d.ts +15 -6
- package/lib/typescript/core/media/pickers.d.ts +5 -5
- package/lib/typescript/core/motion/config.d.ts +2 -1
- package/lib/typescript/core/motion/index.d.ts +3 -1
- package/lib/typescript/core/motion/usePressState.d.ts +21 -0
- package/lib/typescript/core/style/index.d.ts +1 -0
- package/lib/typescript/core/style/radius.d.ts +2 -0
- package/lib/typescript/index.d.ts +4 -2
- package/lib/typescript/modules/accordion/Accordion.variants.d.ts +2 -2
- package/lib/typescript/modules/alert-dialog/AlertDialog.variants.d.ts +1 -0
- package/lib/typescript/modules/avatar/Avatar.variants.d.ts +1 -1
- package/lib/typescript/modules/avatar-group/AvatarGroup.d.ts +4 -2
- package/lib/typescript/modules/avatar-group/AvatarGroup.variants.d.ts +19 -0
- package/lib/typescript/modules/banner/Banner.d.ts +2 -0
- package/lib/typescript/modules/bottom-nav/BottomNav.variants.d.ts +1 -3
- package/lib/typescript/modules/bottom-sheet/BottomSheet.variants.d.ts +3 -1
- package/lib/typescript/modules/button/Button.d.ts +0 -25
- package/lib/typescript/modules/button/Button.variants.d.ts +6 -6
- package/lib/typescript/modules/button-group/ButtonGroup.d.ts +0 -19
- package/lib/typescript/modules/button-group/ButtonGroup.variants.d.ts +22 -56
- package/lib/typescript/modules/card/Card.d.ts +7 -5
- package/lib/typescript/modules/charts/Charts.variants.d.ts +29 -1
- package/lib/typescript/modules/chip/Chip.d.ts +3 -1
- package/lib/typescript/modules/chip/Chip.variants.d.ts +6 -2
- package/lib/typescript/modules/chip/index.d.ts +1 -1
- package/lib/typescript/modules/combobox/Combobox.variants.d.ts +17 -4
- package/lib/typescript/modules/data-table/DataTable.variants.d.ts +1 -1
- package/lib/typescript/modules/date-picker/DatePicker.variants.d.ts +15 -3
- package/lib/typescript/modules/date-picker/TimePicker.d.ts +1 -7
- package/lib/typescript/modules/divider/Divider.variants.d.ts +4 -4
- package/lib/typescript/modules/empty-state/EmptyState.d.ts +2 -0
- package/lib/typescript/modules/empty-state/EmptyState.variants.d.ts +1 -0
- package/lib/typescript/modules/fab/Fab.variants.d.ts +2 -0
- package/lib/typescript/modules/folder-row/FolderRow.d.ts +0 -8
- package/lib/typescript/modules/gantt/Gantt.variants.d.ts +21 -0
- package/lib/typescript/modules/input/Input.variants.d.ts +6 -6
- package/lib/typescript/modules/list-item/ListItem.d.ts +1 -5
- package/lib/typescript/modules/list-item/ListItem.variants.d.ts +137 -1
- package/lib/typescript/modules/markdown/Markdown.d.ts +7 -0
- package/lib/typescript/modules/message-bubble/MessageBubble.d.ts +2 -2
- package/lib/typescript/modules/message-bubble/MessageBubble.variants.d.ts +1 -2
- package/lib/typescript/modules/number-input/NumberInput.variants.d.ts +7 -5
- package/lib/typescript/modules/pagination/PaginationControls.d.ts +1 -4
- package/lib/typescript/modules/reorder/Reorder.d.ts +1 -1
- package/lib/typescript/modules/screen/Screen.d.ts +3 -9
- package/lib/typescript/modules/screen/Screen.variants.d.ts +4 -0
- package/lib/typescript/modules/search-bar/SearchBar.variants.d.ts +6 -6
- package/lib/typescript/modules/section/Section.variants.d.ts +0 -3
- package/lib/typescript/modules/segmented-control/SegmentedControl.variants.d.ts +1 -1
- package/lib/typescript/modules/select/Select.d.ts +4 -1
- package/lib/typescript/modules/select/Select.variants.d.ts +22 -8
- package/lib/typescript/modules/select/index.d.ts +1 -1
- package/lib/typescript/modules/skeleton/Skeleton.d.ts +3 -18
- package/lib/typescript/modules/skeleton/Skeleton.variants.d.ts +12 -68
- package/lib/typescript/modules/stage-progress/StageProgress.variants.d.ts +15 -6
- package/lib/typescript/modules/state-block/StateBlock.d.ts +4 -0
- package/lib/typescript/modules/state-block/StateBlock.variants.d.ts +1 -0
- package/lib/typescript/modules/surface/Surface.d.ts +19 -0
- package/lib/typescript/modules/surface/Surface.variants.d.ts +15 -0
- package/lib/typescript/modules/surface/index.d.ts +4 -0
- package/lib/typescript/modules/text/Text.d.ts +8 -4
- package/lib/typescript/modules/text/Text.variants.d.ts +14 -11
- package/lib/typescript/modules/toast/Toast.variants.d.ts +2 -0
- package/lib/typescript/modules/tooltip/Tooltip.variants.d.ts +7 -0
- package/lib/typescript/theme/index.d.ts +1 -1
- package/lib/typescript/theme/platform/elevation.native.d.ts +0 -30
- package/lib/typescript/theme/platform/floatingSurface.native.d.ts +10 -0
- package/lib/typescript/theme/platform/highlight.native.d.ts +17 -0
- package/lib/typescript/theme/platform/index.d.ts +9 -0
- package/lib/typescript/theme/platform/motion.native.d.ts +33 -13
- package/lib/typescript/theme/platform/stateLayer.native.d.ts +11 -0
- package/lib/typescript/theme/platform/surfaces.native.d.ts +8 -0
- package/lib/typescript/theme/provider/PixelizeProvider.d.ts +1 -1
- package/lib/typescript/theme/provider/types.d.ts +8 -0
- package/lib/typescript/theme/tokens/assertPalette.d.ts +10 -0
- package/lib/typescript/theme/tokens/brands/emerald/palette.light.d.ts +4 -3
- package/lib/typescript/theme/tokens/brands/lavender/palette.light.d.ts +4 -3
- package/lib/typescript/theme/tokens/brands/meadow/palette.light.d.ts +4 -3
- package/lib/typescript/theme/tokens/brands/radiant/palette.light.d.ts +4 -3
- package/lib/typescript/theme/tokens/brands/rosewood/palette.light.d.ts +4 -3
- package/lib/typescript/theme/tokens/brands/skyline/palette.light.d.ts +4 -3
- package/lib/typescript/theme/tokens/brands/slate/palette.light.d.ts +4 -3
- package/lib/typescript/theme/tokens/brands/storefront/palette.light.d.ts +4 -3
- package/lib/typescript/theme/tokens/brands/zinc/palette.light.d.ts +4 -3
- package/lib/typescript/theme/tokens/builders/finalizePalette.d.ts +4 -0
- package/lib/typescript/theme/tokens/builders/liftToContrast.d.ts +9 -0
- package/lib/typescript/theme/tokens/builders/placeholderInk.d.ts +13 -0
- package/lib/typescript/theme/tokens/builders/semanticText.d.ts +4 -0
- package/lib/typescript/theme/tokens/builders/surfaceRungs.d.ts +12 -0
- package/lib/typescript/theme/tokens/index.d.ts +5 -0
- package/lib/typescript/theme/tokens/roles/index.d.ts +1 -0
- package/lib/typescript/theme/tokens/types.d.ts +8 -7
- package/package.json +10 -2
- package/registry.json +5 -0
|
@@ -11,10 +11,16 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { memo, useCallback, useMemo } from "react";
|
|
14
|
-
import { Animated, Pressable, Text, View } from "react-native";
|
|
14
|
+
import { Animated, Platform, Pressable, Text as RNText, View } from "react-native";
|
|
15
|
+
import Reanimated, { FadeInDown, FadeOut, LinearTransition, ReduceMotion } from "react-native-reanimated";
|
|
15
16
|
import { Icon } from "../../core/icon/index.js";
|
|
16
17
|
import { useEnterExit } from "../../core/motion/index.js";
|
|
18
|
+
import { concentric } from "../../core/style/index.js";
|
|
19
|
+
import { elevation, floatingSurfaceStyle, highlight } from "../../theme/platform/index.js";
|
|
20
|
+
import { rippleColor } from "../../theme/platform/stateLayer.native.js";
|
|
21
|
+
import { elevation as elevationTokens } from "../../theme/tokens/primitives/index.js";
|
|
17
22
|
import { useTheme } from "../../theme/hooks.js";
|
|
23
|
+
import { resolveTextStyle } from "../text/Text.variants.js";
|
|
18
24
|
import { BANNER_DISMISS_ICON_SIZE, BANNER_ICON_SIZE, BANNER_MIN_TOUCH_TARGET, bannerStructure, resolveBannerAccessibility, resolveBannerIcon, resolveBannerTone } from "./Banner.variants.js";
|
|
19
25
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
20
26
|
const ICON_STROKE = 2;
|
|
@@ -38,6 +44,7 @@ export const Banner = /*#__PURE__*/memo(function Banner({
|
|
|
38
44
|
onDismiss,
|
|
39
45
|
dismissLabel = "Dismiss",
|
|
40
46
|
action,
|
|
47
|
+
actions,
|
|
41
48
|
style,
|
|
42
49
|
testID
|
|
43
50
|
}) {
|
|
@@ -50,13 +57,25 @@ export const Banner = /*#__PURE__*/memo(function Banner({
|
|
|
50
57
|
message
|
|
51
58
|
}), [tone, title, message]);
|
|
52
59
|
const glyph = icon === null ? undefined : icon ?? resolveBannerIcon(tone);
|
|
53
|
-
const handleAction = useCallback(
|
|
60
|
+
const handleAction = useCallback(item => item.onPress(), []);
|
|
61
|
+
const bannerActions = useMemo(() => {
|
|
62
|
+
const list = [];
|
|
63
|
+
if (action !== undefined) list.push(action);
|
|
64
|
+
if (actions !== undefined) list.push(...actions);
|
|
65
|
+
return list;
|
|
66
|
+
}, [action, actions]);
|
|
67
|
+
const floatingStyle = useMemo(() => {
|
|
68
|
+
highlight("subtle", theme.mode);
|
|
69
|
+
elevation(elevationTokens.sm);
|
|
70
|
+
void theme.elevatedSurfaces;
|
|
71
|
+
return floatingSurfaceStyle(theme, "sm");
|
|
72
|
+
}, [theme]);
|
|
73
|
+
const iconChipRadius = useMemo(() => concentric(theme.radii.lg, theme.space[3]), [theme.radii.lg, theme.space]);
|
|
54
74
|
|
|
55
75
|
// `style` stays last; the enter/exit style holds only opacity/transform, which `LayoutStyle` cannot name.
|
|
56
76
|
const rootStyle = useMemo(() => [bannerStructure(theme), {
|
|
57
|
-
backgroundColor: colors.fill
|
|
58
|
-
|
|
59
|
-
}, enterExit.style, style], [theme, colors, enterExit.style, style]);
|
|
77
|
+
backgroundColor: colors.fill
|
|
78
|
+
}, floatingStyle, enterExit.style, style], [theme, floatingStyle, colors, enterExit.style, style]);
|
|
60
79
|
const contentStyle = useMemo(() => ({
|
|
61
80
|
flex: 1,
|
|
62
81
|
rowGap: theme.space[1]
|
|
@@ -64,72 +83,99 @@ export const Banner = /*#__PURE__*/memo(function Banner({
|
|
|
64
83
|
const textBlockStyle = useMemo(() => ({
|
|
65
84
|
rowGap: theme.space[1]
|
|
66
85
|
}), [theme]);
|
|
67
|
-
const titleStyle = useMemo(() => [
|
|
68
|
-
fontSize: theme.fontSizes.md,
|
|
86
|
+
const titleStyle = useMemo(() => [resolveTextStyle(theme, "subheading"), {
|
|
69
87
|
color: colors.text
|
|
70
|
-
}], [theme, colors]);
|
|
71
|
-
const messageStyle = useMemo(() => [
|
|
72
|
-
fontSize: theme.fontSizes.sm,
|
|
88
|
+
}], [theme, colors.text]);
|
|
89
|
+
const messageStyle = useMemo(() => [resolveTextStyle(theme, "body-sm"), {
|
|
73
90
|
color: colors.text
|
|
74
|
-
}], [theme, colors]);
|
|
75
|
-
const
|
|
76
|
-
alignSelf: "flex-start",
|
|
77
|
-
paddingVertical: theme.space[1]
|
|
78
|
-
}), [theme]);
|
|
79
|
-
const actionLabelStyle = useMemo(() => [theme.fontStyleForWeight(theme.fontWeights.semibold), {
|
|
80
|
-
fontSize: theme.fontSizes.sm,
|
|
91
|
+
}], [theme, colors.text]);
|
|
92
|
+
const actionLabelStyle = useMemo(() => [resolveTextStyle(theme, "label-sm"), {
|
|
81
93
|
color: colors.text,
|
|
82
94
|
textDecorationLine: "underline"
|
|
83
|
-
}], [theme, colors]);
|
|
95
|
+
}], [theme, colors.text]);
|
|
96
|
+
const actionRowStyle = useMemo(() => ({
|
|
97
|
+
flexDirection: "row",
|
|
98
|
+
flexWrap: "wrap",
|
|
99
|
+
columnGap: theme.space[3]
|
|
100
|
+
}), [theme]);
|
|
84
101
|
const actionHitSlop = useMemo(() => hitSlopFor(theme.fontSizes.sm), [theme]);
|
|
102
|
+
const actionRipple = useMemo(() => Platform.OS === "android" ? {
|
|
103
|
+
color: rippleColor(theme.mode),
|
|
104
|
+
borderless: false
|
|
105
|
+
} : undefined, [theme.mode]);
|
|
106
|
+
const dismissRipple = useMemo(() => Platform.OS === "android" ? {
|
|
107
|
+
color: rippleColor(theme.mode),
|
|
108
|
+
borderless: true
|
|
109
|
+
} : undefined, [theme.mode]);
|
|
85
110
|
if (!enterExit.mounted) return null;
|
|
86
|
-
return /*#__PURE__*/
|
|
111
|
+
return /*#__PURE__*/_jsx(Reanimated.View, {
|
|
87
112
|
testID: testID,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
113
|
+
entering: FadeInDown.springify().reduceMotion(ReduceMotion.System),
|
|
114
|
+
exiting: FadeOut.reduceMotion(ReduceMotion.System),
|
|
115
|
+
layout: LinearTransition.reduceMotion(ReduceMotion.System),
|
|
116
|
+
children: /*#__PURE__*/_jsxs(Animated.View, {
|
|
117
|
+
style: rootStyle,
|
|
118
|
+
children: [glyph && /*#__PURE__*/_jsx(View, {
|
|
119
|
+
style: {
|
|
120
|
+
borderRadius: iconChipRadius,
|
|
121
|
+
borderCurve: "continuous",
|
|
122
|
+
overflow: "hidden",
|
|
123
|
+
padding: theme.space[1]
|
|
124
|
+
},
|
|
125
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
126
|
+
name: glyph,
|
|
127
|
+
size: BANNER_ICON_SIZE,
|
|
128
|
+
color: colors.text,
|
|
129
|
+
strokeWidth: ICON_STROKE
|
|
130
|
+
})
|
|
131
|
+
}), /*#__PURE__*/_jsxs(View, {
|
|
132
|
+
style: contentStyle,
|
|
133
|
+
children: [/*#__PURE__*/_jsxs(View, {
|
|
134
|
+
accessible: a11y.accessible,
|
|
135
|
+
accessibilityRole: a11y.accessibilityRole,
|
|
136
|
+
accessibilityLabel: a11y.accessibilityLabel,
|
|
137
|
+
style: textBlockStyle,
|
|
138
|
+
children: [title && /*#__PURE__*/_jsx(RNText, {
|
|
139
|
+
style: titleStyle,
|
|
140
|
+
children: title
|
|
141
|
+
}), /*#__PURE__*/_jsx(RNText, {
|
|
142
|
+
style: messageStyle,
|
|
143
|
+
children: message
|
|
144
|
+
})]
|
|
145
|
+
}), bannerActions.length > 0 && /*#__PURE__*/_jsx(View, {
|
|
146
|
+
style: actionRowStyle,
|
|
147
|
+
children: bannerActions.map((item, index) => /*#__PURE__*/_jsx(Pressable, {
|
|
148
|
+
testID: testID ? `${testID}-action-${index}` : undefined,
|
|
149
|
+
accessibilityRole: "button",
|
|
150
|
+
accessibilityLabel: item.label,
|
|
151
|
+
onPress: () => handleAction(item),
|
|
152
|
+
hitSlop: actionHitSlop,
|
|
153
|
+
android_ripple: actionRipple,
|
|
154
|
+
style: {
|
|
155
|
+
alignSelf: "flex-start",
|
|
156
|
+
paddingVertical: theme.space[1]
|
|
157
|
+
},
|
|
158
|
+
children: /*#__PURE__*/_jsx(RNText, {
|
|
159
|
+
style: actionLabelStyle,
|
|
160
|
+
children: item.label
|
|
161
|
+
})
|
|
162
|
+
}, `${item.label}-${index}`))
|
|
107
163
|
})]
|
|
108
|
-
}),
|
|
109
|
-
testID: testID ? `${testID}-
|
|
164
|
+
}), onDismiss && /*#__PURE__*/_jsx(Pressable, {
|
|
165
|
+
testID: testID ? `${testID}-dismiss` : undefined,
|
|
110
166
|
accessibilityRole: "button",
|
|
111
|
-
accessibilityLabel:
|
|
112
|
-
onPress:
|
|
113
|
-
hitSlop:
|
|
114
|
-
|
|
115
|
-
children: /*#__PURE__*/_jsx(
|
|
116
|
-
|
|
117
|
-
|
|
167
|
+
accessibilityLabel: dismissLabel,
|
|
168
|
+
onPress: onDismiss,
|
|
169
|
+
hitSlop: DISMISS_HIT_SLOP,
|
|
170
|
+
android_ripple: dismissRipple,
|
|
171
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
172
|
+
name: "x",
|
|
173
|
+
size: BANNER_DISMISS_ICON_SIZE,
|
|
174
|
+
color: colors.text,
|
|
175
|
+
strokeWidth: ICON_STROKE
|
|
118
176
|
})
|
|
119
177
|
})]
|
|
120
|
-
})
|
|
121
|
-
testID: testID ? `${testID}-dismiss` : undefined,
|
|
122
|
-
accessibilityRole: "button",
|
|
123
|
-
accessibilityLabel: dismissLabel,
|
|
124
|
-
onPress: onDismiss,
|
|
125
|
-
hitSlop: DISMISS_HIT_SLOP,
|
|
126
|
-
children: /*#__PURE__*/_jsx(Icon, {
|
|
127
|
-
name: "x",
|
|
128
|
-
size: BANNER_DISMISS_ICON_SIZE,
|
|
129
|
-
color: colors.text,
|
|
130
|
-
strokeWidth: ICON_STROKE
|
|
131
|
-
})
|
|
132
|
-
})]
|
|
178
|
+
})
|
|
133
179
|
});
|
|
134
180
|
});
|
|
135
181
|
//# sourceMappingURL=Banner.js.map
|
|
@@ -109,8 +109,8 @@ export const bannerStructure = createThemedVariants(theme => ({
|
|
|
109
109
|
alignItems: "flex-start",
|
|
110
110
|
columnGap: theme.space[3],
|
|
111
111
|
padding: theme.space[3],
|
|
112
|
-
borderRadius: theme.radii.
|
|
113
|
-
|
|
112
|
+
borderRadius: theme.radii.lg,
|
|
113
|
+
borderCurve: "continuous"
|
|
114
114
|
},
|
|
115
115
|
variants: {},
|
|
116
116
|
defaultVariants: {}
|
|
@@ -30,9 +30,10 @@ of a family that is easy to confuse:
|
|
|
30
30
|
| `icon` | `IconName \| null` | per tone | `null` suppresses the glyph entirely. |
|
|
31
31
|
| `onDismiss` | `() => void` | — | Absent = the banner cannot be closed. |
|
|
32
32
|
| `dismissLabel` | `string` | `"Dismiss"` | Screen-reader name for the close control. |
|
|
33
|
-
| `action` | `{ label, onPress }` | — | One inline action;
|
|
33
|
+
| `action` | `{ label, onPress }` | — | One inline action; use with `actions` for multiple. |
|
|
34
|
+
| `actions` | `BannerAction[]` | — | Additional actions rendered after `action`. |
|
|
34
35
|
| `style` | `LayoutStyle` | — | Layout-only, outermost, applied exactly once, last. |
|
|
35
|
-
| `testID` | `string` | — | Seeds `${testID}-dismiss` and `${testID}-action`. |
|
|
36
|
+
| `testID` | `string` | — | Seeds `${testID}-dismiss` and `${testID}-action-{index}`. |
|
|
36
37
|
|
|
37
38
|
## Accessibility contract (WCAG)
|
|
38
39
|
|
|
@@ -57,6 +58,10 @@ of a family that is easy to confuse:
|
|
|
57
58
|
canvas instead — otherwise a solid banner could be invisible on a same-toned page.
|
|
58
59
|
- **2.5.8 / 2.5.5 target size** — the dismiss glyph (16dp) and the action label are padded to a 44dp
|
|
59
60
|
touch target via `hitSlop`, so the visual size never dictates the tap size.
|
|
61
|
+
- **Android touch feedback** — both the dismiss control and the action link carry `android_ripple`
|
|
62
|
+
(`rippleColor(theme.mode)`), gated on `Platform.OS === "android"`. The dismiss glyph is
|
|
63
|
+
round/icon-only, so its ripple is `borderless: true`; the action link is a text target, so its
|
|
64
|
+
ripple is `borderless: false`.
|
|
60
65
|
- **2.3.3** — nothing animates; a banner appears and stays. Nothing to suppress.
|
|
61
66
|
- **1.3.1** — the tone icon is redundant with the accessible title/message node right beside it (the
|
|
62
67
|
glyph repeats what `resolveBannerAccessibility`'s `alert`/`text` role and label already say), so it
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
import { memo, useCallback, useMemo } from "react";
|
|
29
29
|
import { Platform, StyleSheet, View } from "react-native";
|
|
30
|
+
import { floatingBackground, floatingSurfaceStyle } from "../../theme/platform/index.js";
|
|
30
31
|
import { useTheme } from "../../theme/hooks.js";
|
|
31
32
|
import { Button } from "../button/index.js";
|
|
32
33
|
import { Drawer } from "../drawer/index.js";
|
|
@@ -82,6 +83,10 @@ export const BottomNav = /*#__PURE__*/memo(function BottomNav(props) {
|
|
|
82
83
|
testID
|
|
83
84
|
} = props;
|
|
84
85
|
const theme = useTheme();
|
|
86
|
+
const barDepth = useMemo(() => ({
|
|
87
|
+
backgroundColor: floatingBackground(theme, "md"),
|
|
88
|
+
...floatingSurfaceStyle(theme, "md")
|
|
89
|
+
}), [theme]);
|
|
85
90
|
const bottomInset = resolveBottomNavBottomInset(theme.space[2], Platform.OS);
|
|
86
91
|
const moreSelected = active.kind === "more";
|
|
87
92
|
const overflowBadgeTotal = resolveBottomNavOverflowBadgeTotal(overflowSections);
|
|
@@ -109,9 +114,7 @@ export const BottomNav = /*#__PURE__*/memo(function BottomNav(props) {
|
|
|
109
114
|
children: [/*#__PURE__*/_jsxs(View, {
|
|
110
115
|
testID: testID,
|
|
111
116
|
accessibilityRole: "tablist",
|
|
112
|
-
style: [bottomNavBarStructure(theme), {
|
|
113
|
-
backgroundColor: theme.colors.bg.surface,
|
|
114
|
-
borderTopColor: theme.colors.border.default,
|
|
117
|
+
style: [bottomNavBarStructure(theme), barDepth, {
|
|
115
118
|
paddingBottom: bottomInset
|
|
116
119
|
}, style],
|
|
117
120
|
children: [coreTabs.map(tab => /*#__PURE__*/_jsx(BottomNavTab, {
|
|
@@ -120,8 +120,8 @@ export function resolveOverflowSheetHeight(windowHeight) {
|
|
|
120
120
|
*/
|
|
121
121
|
export function resolveBottomNavTabColors(colors, active) {
|
|
122
122
|
return {
|
|
123
|
-
icon: active ? colors.
|
|
124
|
-
label: active ? colors.
|
|
123
|
+
icon: active ? colors.accent.text : colors.fg.muted,
|
|
124
|
+
label: active ? colors.accent.text : colors.fg.muted,
|
|
125
125
|
indicator: colors.accent.solid
|
|
126
126
|
};
|
|
127
127
|
}
|
|
@@ -157,13 +157,10 @@ export function resolveEditRowState(input) {
|
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
/**
|
|
161
|
-
|
|
162
|
-
* inline over this — never a hardcoded hex here. */
|
|
163
|
-
export const bottomNavBarStructure = createThemedVariants(theme => ({
|
|
160
|
+
/** Tabs laid out as equal-width flex children; the bar separates from content by tone + elevation. */
|
|
161
|
+
export const bottomNavBarStructure = createThemedVariants(_theme => ({
|
|
164
162
|
base: {
|
|
165
|
-
flexDirection: "row"
|
|
166
|
-
borderTopWidth: theme.borderWidths.thin
|
|
163
|
+
flexDirection: "row"
|
|
167
164
|
}
|
|
168
165
|
}));
|
|
169
166
|
|
|
@@ -190,7 +187,8 @@ export const bottomNavFocusRingStructure = createThemedVariants(theme => ({
|
|
|
190
187
|
right: 0,
|
|
191
188
|
bottom: 0,
|
|
192
189
|
borderWidth: theme.borderWidths.thick,
|
|
193
|
-
borderRadius: theme.radii.
|
|
190
|
+
borderRadius: theme.radii.md,
|
|
191
|
+
borderCurve: "continuous"
|
|
194
192
|
}
|
|
195
193
|
}));
|
|
196
194
|
|
|
@@ -242,7 +240,8 @@ export const editRowStructure = createThemedVariants(theme => ({
|
|
|
242
240
|
minHeight: MIN_TOUCH_TARGET,
|
|
243
241
|
columnGap: theme.space[2],
|
|
244
242
|
paddingHorizontal: theme.space[3],
|
|
245
|
-
borderRadius: theme.radii.
|
|
243
|
+
borderRadius: theme.radii.md,
|
|
244
|
+
borderCurve: "continuous"
|
|
246
245
|
}
|
|
247
246
|
}));
|
|
248
247
|
//# sourceMappingURL=BottomNav.variants.js.map
|
|
@@ -21,10 +21,11 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
24
|
-
import { Animated, Pressable, ScrollView, StyleSheet, Text, useWindowDimensions, View } from "react-native";
|
|
24
|
+
import { Animated, Platform, Pressable, ScrollView, StyleSheet, Text, useWindowDimensions, View } from "react-native";
|
|
25
25
|
import { Icon } from "../../core/icon/index.js";
|
|
26
26
|
import { useAnimatedValue, useMotion } from "../../core/motion/index.js";
|
|
27
27
|
import { useTheme } from "../../theme/hooks.js";
|
|
28
|
+
import { rippleColor } from "../../theme/platform/stateLayer.native.js";
|
|
28
29
|
import { Button } from "../button/index.js";
|
|
29
30
|
import { Input } from "../input/index.js";
|
|
30
31
|
import { editRowStructure, EDIT_SLOT_INDICATOR_SIZE, OVERFLOW_ROW_ICON_SIZE, overflowRowStructure, overflowSectionHeaderStructure, resolveBottomNavBadge, resolveBottomNavDestinationAccessibilityLabel, resolveEditRowState, resolveOverflowSheetHeight } from "./BottomNav.variants.js";
|
|
@@ -71,6 +72,14 @@ export const BottomNavOverflowSheet = /*#__PURE__*/memo(function BottomNavOverfl
|
|
|
71
72
|
}
|
|
72
73
|
wasEditing.current = isEditing;
|
|
73
74
|
}, [edit?.editing, coreTabs.length]);
|
|
75
|
+
const androidRipple = useMemo(() => Platform.OS === "android" ? {
|
|
76
|
+
color: rippleColor(theme.mode)
|
|
77
|
+
} : undefined, [theme.mode]);
|
|
78
|
+
const rowStyle = useCallback(({
|
|
79
|
+
pressed
|
|
80
|
+
}) => [overflowRowStructure(theme), pressed && {
|
|
81
|
+
backgroundColor: theme.colors.bg.sunken
|
|
82
|
+
}], [theme]);
|
|
74
83
|
const sheetHeight = resolveOverflowSheetHeight(windowHeight);
|
|
75
84
|
const isSearching = normalizeQuery(query).length > 0;
|
|
76
85
|
const matches = isSearching ? matchDestinations(query, overflowSections) : [];
|
|
@@ -107,7 +116,8 @@ export const BottomNavOverflowSheet = /*#__PURE__*/memo(function BottomNavOverfl
|
|
|
107
116
|
}),
|
|
108
117
|
"aria-selected": isRowSelected(destination.id),
|
|
109
118
|
onPress: () => handleRowPress(destination),
|
|
110
|
-
|
|
119
|
+
android_ripple: androidRipple,
|
|
120
|
+
style: rowStyle,
|
|
111
121
|
children: [/*#__PURE__*/_jsx(BottomNavIconWithBadge, {
|
|
112
122
|
icon: destination.icon,
|
|
113
123
|
iconSize: OVERFLOW_ROW_ICON_SIZE,
|
|
@@ -177,7 +187,12 @@ export const BottomNavOverflowSheet = /*#__PURE__*/memo(function BottomNavOverfl
|
|
|
177
187
|
testID: testID ? `${testID}-reset` : undefined,
|
|
178
188
|
accessibilityRole: "menuitem",
|
|
179
189
|
onPress: edit.onResetToDefault,
|
|
180
|
-
|
|
190
|
+
android_ripple: androidRipple,
|
|
191
|
+
style: ({
|
|
192
|
+
pressed
|
|
193
|
+
}) => [editRowStructure(theme), pressed && {
|
|
194
|
+
backgroundColor: theme.colors.bg.sunken
|
|
195
|
+
}],
|
|
181
196
|
children: [/*#__PURE__*/_jsx(Icon, {
|
|
182
197
|
name: "refresh-cw",
|
|
183
198
|
size: OVERFLOW_ROW_ICON_SIZE,
|
|
@@ -251,6 +266,14 @@ const EditSlotChip = /*#__PURE__*/memo(function EditSlotChip({
|
|
|
251
266
|
const opacityMotionStyle = useMemo(() => ({
|
|
252
267
|
opacity
|
|
253
268
|
}), [opacity]);
|
|
269
|
+
const androidRipple = useMemo(() => Platform.OS === "android" ? {
|
|
270
|
+
color: rippleColor(theme.mode)
|
|
271
|
+
} : undefined, [theme.mode]);
|
|
272
|
+
const chipStyle = useCallback(({
|
|
273
|
+
pressed
|
|
274
|
+
}) => [editRowStructure(theme), pressed && {
|
|
275
|
+
backgroundColor: theme.colors.bg.sunken
|
|
276
|
+
}], [theme]);
|
|
254
277
|
useEffect(() => {
|
|
255
278
|
const toValue = selected ? 1 : 0;
|
|
256
279
|
running.current?.stop();
|
|
@@ -278,7 +301,8 @@ const EditSlotChip = /*#__PURE__*/memo(function EditSlotChip({
|
|
|
278
301
|
},
|
|
279
302
|
accessibilityLabel: `${tab.label}, slot ${index + 1}`,
|
|
280
303
|
onPress: () => onPress(index),
|
|
281
|
-
|
|
304
|
+
android_ripple: androidRipple,
|
|
305
|
+
style: chipStyle,
|
|
282
306
|
children: [/*#__PURE__*/_jsx(Icon, {
|
|
283
307
|
name: tab.icon,
|
|
284
308
|
size: OVERFLOW_ROW_ICON_SIZE,
|
|
@@ -16,12 +16,16 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
19
|
-
import { Animated, Pressable, StyleSheet, Text } from "react-native";
|
|
19
|
+
import { Animated, Platform, Pressable, StyleSheet, Text } from "react-native";
|
|
20
|
+
import Reanimated from "react-native-reanimated";
|
|
20
21
|
import { useAnimatedValue, useMotion } from "../../core/motion/index.js";
|
|
22
|
+
import { usePressState } from "../../core/motion/usePressState.js";
|
|
23
|
+
import { rippleColor, stateLayerScrim } from "../../theme/platform/stateLayer.native.js";
|
|
21
24
|
import { useTheme } from "../../theme/hooks.js";
|
|
22
25
|
import { BOTTOM_NAV_ACTIVE_DOT_SIZE, BOTTOM_NAV_ICON_SIZE, BOTTOM_NAV_SETTLE_SCALE, bottomNavFocusRingStructure, bottomNavTabStructure, resolveBottomNavAccessibility, resolveBottomNavBadge, resolveBottomNavDestinationAccessibilityLabel, resolveBottomNavTabColors } from "./BottomNav.variants.js";
|
|
23
26
|
import { BottomNavIconWithBadge } from "./BottomNavIconWithBadge.js";
|
|
24
27
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
28
|
+
const AnimatedPressable = Reanimated.createAnimatedComponent(Pressable);
|
|
25
29
|
export const BottomNavTab = /*#__PURE__*/memo(function BottomNavTab({
|
|
26
30
|
id,
|
|
27
31
|
label,
|
|
@@ -36,6 +40,7 @@ export const BottomNavTab = /*#__PURE__*/memo(function BottomNavTab({
|
|
|
36
40
|
}) {
|
|
37
41
|
const theme = useTheme();
|
|
38
42
|
const motion = useMotion();
|
|
43
|
+
const press = usePressState(false);
|
|
39
44
|
const [focused, setFocused] = useState(false);
|
|
40
45
|
const colors = resolveBottomNavTabColors(theme.colors, selected);
|
|
41
46
|
const a11y = resolveBottomNavAccessibility({
|
|
@@ -71,7 +76,16 @@ export const BottomNavTab = /*#__PURE__*/memo(function BottomNavTab({
|
|
|
71
76
|
const handlePress = useCallback(() => onPress(id), [onPress, id]);
|
|
72
77
|
const handleFocus = useCallback(() => setFocused(true), []);
|
|
73
78
|
const handleBlur = useCallback(() => setFocused(false), []);
|
|
74
|
-
|
|
79
|
+
const overlayStaticStyle = useMemo(() => ({
|
|
80
|
+
backgroundColor: stateLayerScrim(theme.mode),
|
|
81
|
+
borderRadius: theme.radii.md,
|
|
82
|
+
borderCurve: "continuous"
|
|
83
|
+
}), [theme.mode, theme.radii.md]);
|
|
84
|
+
const androidRipple = useMemo(() => Platform.OS === "android" ? {
|
|
85
|
+
color: rippleColor(theme.mode),
|
|
86
|
+
borderless: false
|
|
87
|
+
} : undefined, [theme.mode]);
|
|
88
|
+
return /*#__PURE__*/_jsxs(AnimatedPressable, {
|
|
75
89
|
testID: testID,
|
|
76
90
|
accessibilityRole: a11y.accessibilityRole,
|
|
77
91
|
accessibilityLabel: resolveBottomNavDestinationAccessibilityLabel({
|
|
@@ -83,10 +97,20 @@ export const BottomNavTab = /*#__PURE__*/memo(function BottomNavTab({
|
|
|
83
97
|
"aria-expanded": a11y["aria-expanded"],
|
|
84
98
|
"aria-disabled": a11y["aria-disabled"],
|
|
85
99
|
onPress: handlePress,
|
|
100
|
+
onPressIn: press.handlers.onPressIn,
|
|
101
|
+
onPressOut: press.handlers.onPressOut,
|
|
102
|
+
onLayout: press.onLayout,
|
|
86
103
|
onFocus: handleFocus,
|
|
87
104
|
onBlur: handleBlur,
|
|
88
|
-
|
|
89
|
-
|
|
105
|
+
android_ripple: androidRipple,
|
|
106
|
+
style: [bottomNavTabStructure(theme), {
|
|
107
|
+
overflow: "hidden"
|
|
108
|
+
}, press.animatedStyle],
|
|
109
|
+
children: [/*#__PURE__*/_jsx(Reanimated.View, {
|
|
110
|
+
pointerEvents: "none",
|
|
111
|
+
testID: testID ? `${testID}-press-overlay` : undefined,
|
|
112
|
+
style: [StyleSheet.absoluteFill, overlayStaticStyle, press.overlayStyle]
|
|
113
|
+
}), focused && /*#__PURE__*/_jsx(Animated.View, {
|
|
90
114
|
pointerEvents: "none",
|
|
91
115
|
testID: testID ? `${testID}-focus-ring` : undefined,
|
|
92
116
|
style: [bottomNavFocusRingStructure(theme), {
|
|
@@ -134,7 +134,8 @@ imports `@react-native-async-storage/async-storage` and never reads a value it w
|
|
|
134
134
|
modes, in `BottomNav.test.ts` — never eyeballed.
|
|
135
135
|
- **2.3.3** — every animation here runs through `core/motion`'s `useMotion()` (opacity + transform
|
|
136
136
|
only, always native-driver): the active-tab dot, the badge settle, and the edit-mode slot
|
|
137
|
-
indicator.
|
|
137
|
+
indicator. Tab presses use `usePressState` (scale + state-layer overlay). When `motion.enabled`
|
|
138
|
+
is false the animated value is `setValue`'d AND the resting style
|
|
138
139
|
is rendered outright, so the state is correct on the very first frame with no tween at all. The
|
|
139
140
|
sheet's own slide/fade is inherited transitively through Drawer.
|
|
140
141
|
- **2.4.7 / 2.4.11** — a `border.focus` offset ring on keyboard/AT focus per tab, identical pattern to
|
|
@@ -226,3 +227,11 @@ not a runtime guarantee); core tabs are not independently searchable from the sh
|
|
|
226
227
|
- Theme imports decoupled to `theme/hooks`; optional peers (reanimated, gesture-handler, flash-list) load at runtime.
|
|
227
228
|
- List-heavy surfaces use `VirtualList` with device-tier window sizing where applicable.
|
|
228
229
|
- `React.memo` + stable callbacks retained; render-item/key-extractor hoisted per ESLint perf rules.
|
|
230
|
+
|
|
231
|
+
## Round 5 tonal
|
|
232
|
+
|
|
233
|
+
- Bar's top hairline dropped — `floatingBackground`/`floatingSurfaceStyle` already give it a tonal
|
|
234
|
+
fill plus real shadow/`elevation`, so the extra `borderTopWidth` was redundant decorative chrome.
|
|
235
|
+
- Tabs gained `android_ripple` alongside their existing state-layer overlay (Button's pattern).
|
|
236
|
+
- Overflow-sheet rows and edit-slot chips gained a pressed fill (`bg.sunken`) + `android_ripple` —
|
|
237
|
+
previously plain `Pressable`s with zero visual press feedback.
|
|
@@ -16,12 +16,15 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
19
|
-
import { Modal as RNModal, Pressable, StyleSheet, useWindowDimensions, View } from "react-native";
|
|
19
|
+
import { Modal as RNModal, Platform, Pressable, StyleSheet, useWindowDimensions, View } from "react-native";
|
|
20
20
|
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
21
|
-
import Animated, {
|
|
21
|
+
import Animated, { useAnimatedStyle, useSharedValue, withSpring, withTiming } from "react-native-reanimated";
|
|
22
|
+
import { scheduleOnRN } from "react-native-worklets";
|
|
22
23
|
import { useMotion } from "../../core/motion/index.js";
|
|
24
|
+
import { elevation, floatingBackground, floatingSurfaceStyle, highlight } from "../../theme/platform/index.js";
|
|
25
|
+
import { elevation as elevationTokens } from "../../theme/tokens/primitives/index.js";
|
|
23
26
|
import { useTheme } from "../../theme/hooks.js";
|
|
24
|
-
import { BOTTOM_SHEET_BACKDROP, bottomSheetGrabberStructure, bottomSheetHandleStructure, bottomSheetPanelStructure, resolveBottomSheetPanelColors, resolveBottomSheetSnapOffset, resolveNearestSnapIndex } from "./BottomSheet.variants.js";
|
|
27
|
+
import { BOTTOM_SHEET_BACKDROP, bottomSheetGrabberStructure, bottomSheetHandleStructure, bottomSheetPanelStructure, resolveBottomSheetBottomInset, resolveBottomSheetPanelColors, resolveBottomSheetSnapOffset, resolveNearestSnapIndex } from "./BottomSheet.variants.js";
|
|
25
28
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
26
29
|
/** Module-level so the default never hands `snapOffsets` a fresh array identity each render. */
|
|
27
30
|
const DEFAULT_SNAP_POINTS = [0.5];
|
|
@@ -44,6 +47,7 @@ export const BottomSheet = /*#__PURE__*/memo(function BottomSheet({
|
|
|
44
47
|
height: windowHeight
|
|
45
48
|
} = useWindowDimensions();
|
|
46
49
|
const panelColors = useMemo(() => resolveBottomSheetPanelColors(theme.colors), [theme.colors]);
|
|
50
|
+
const bottomInset = useMemo(() => resolveBottomSheetBottomInset(theme.space[5], Platform.OS), [theme.space]);
|
|
47
51
|
const [mounted, setMounted] = useState(visible);
|
|
48
52
|
const mountedRef = useRef(mounted);
|
|
49
53
|
mountedRef.current = mounted;
|
|
@@ -114,7 +118,7 @@ export const BottomSheet = /*#__PURE__*/memo(function BottomSheet({
|
|
|
114
118
|
if (projected > windowHeight * DISMISS_PROJECTION) {
|
|
115
119
|
slideTo(windowHeight);
|
|
116
120
|
// Sliding away is not closing: the panel stays mounted and `accessibilityViewIsModal`.
|
|
117
|
-
|
|
121
|
+
scheduleOnRN(onRequestClose);
|
|
118
122
|
return;
|
|
119
123
|
}
|
|
120
124
|
const index = resolveNearestSnapIndex(projected, snapOffsets);
|
|
@@ -130,9 +134,18 @@ export const BottomSheet = /*#__PURE__*/memo(function BottomSheet({
|
|
|
130
134
|
const scrimStyle = useAnimatedStyle(() => ({
|
|
131
135
|
opacity: scrim.value
|
|
132
136
|
}));
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
137
|
+
const floatingStyle = useMemo(() => {
|
|
138
|
+
highlight("subtle", theme.mode);
|
|
139
|
+
elevation(elevationTokens.lg);
|
|
140
|
+
void theme.elevatedSurfaces;
|
|
141
|
+
return {
|
|
142
|
+
backgroundColor: floatingBackground(theme, "lg"),
|
|
143
|
+
...floatingSurfaceStyle(theme, "lg")
|
|
144
|
+
};
|
|
145
|
+
}, [theme]);
|
|
146
|
+
const rootPanelStyle = useMemo(() => [bottomSheetPanelStructure(theme), floatingStyle, {
|
|
147
|
+
paddingBottom: bottomInset
|
|
148
|
+
}, panelStyle, style], [theme, floatingStyle, bottomInset, panelStyle, style]);
|
|
136
149
|
const grabberStyle = useMemo(() => [bottomSheetGrabberStructure(theme), {
|
|
137
150
|
backgroundColor: panelColors.grabber
|
|
138
151
|
}], [theme, panelColors.grabber]);
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { createThemedVariants } from "../../core/style/index.js";
|
|
4
|
-
|
|
4
|
+
import { withAlpha } from "../../core/gradient/index.js";
|
|
5
|
+
import { MOTION_TRANSFORM } from "../../core/motion/config.js";
|
|
6
|
+
|
|
7
|
+
// Shared `scrimOpacity` knob, not a locally-guessed hex suffix — same resting value as Modal/Drawer/Menu.
|
|
8
|
+
export const BOTTOM_SHEET_BACKDROP = withAlpha("#000000", MOTION_TRANSFORM.scrimOpacity);
|
|
9
|
+
|
|
10
|
+
// Duplicated from Drawer's resolver on purpose — no react-native-safe-area-context peer dependency.
|
|
11
|
+
export const BOTTOM_SHEET_IOS_HOME_INDICATOR_INSET = 20;
|
|
12
|
+
export function resolveBottomSheetBottomInset(basePadding, platformOS) {
|
|
13
|
+
return platformOS === "ios" ? basePadding + BOTTOM_SHEET_IOS_HOME_INDICATOR_INSET : basePadding;
|
|
14
|
+
}
|
|
5
15
|
export function resolveBottomSheetSnapOffset(snapFraction, windowHeight) {
|
|
6
16
|
const clamped = Math.max(0.1, Math.min(0.95, snapFraction));
|
|
7
17
|
return windowHeight * (1 - clamped);
|
|
@@ -27,10 +37,10 @@ export function resolveBottomSheetPanelColors(colors) {
|
|
|
27
37
|
}
|
|
28
38
|
export const bottomSheetPanelStructure = createThemedVariants(theme => ({
|
|
29
39
|
base: {
|
|
30
|
-
borderTopLeftRadius: theme.radii.
|
|
31
|
-
borderTopRightRadius: theme.radii.
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
borderTopLeftRadius: theme.radii.xl,
|
|
41
|
+
borderTopRightRadius: theme.radii.xl,
|
|
42
|
+
borderCurve: "continuous",
|
|
43
|
+
maxHeight: "92%"
|
|
34
44
|
}
|
|
35
45
|
}));
|
|
36
46
|
export const bottomSheetHandleStructure = createThemedVariants(theme => ({
|
|
@@ -9,7 +9,7 @@ dismissal path reports through `onRequestClose` and lets the parent flip `visibl
|
|
|
9
9
|
|
|
10
10
|
- backdrop press, and `onAccessibilityEscape` on the panel;
|
|
11
11
|
- a swipe released past `DISMISS_PROJECTION` (0.85 of the window, velocity folded in) — the gesture
|
|
12
|
-
slides the panel out **and** `
|
|
12
|
+
slides the panel out **and** `scheduleOnRN(onRequestClose)`.
|
|
13
13
|
|
|
14
14
|
The panel carries `accessibilityViewIsModal` for as long as it is mounted, so a swipe that only slid
|
|
15
15
|
it off-screen would leave a VoiceOver user sealed inside an invisible modal. That is why the gesture
|
|
@@ -41,7 +41,18 @@ Nothing is wired here on purpose. BottomSheet always presents through React Nati
|
|
|
41
41
|
grabber. The grabber is the sheet's only drag target (the pan is attached to the handle, not the
|
|
42
42
|
panel body), so WCAG 1.4.11 applies: the previous `border.default` is the decorative boundary role
|
|
43
43
|
and measured **1.16–1.43:1** on the surface across all 18 palettes. `border.interactive` clears 3:1
|
|
44
|
-
everywhere (min 3.32, emerald light). The backdrop
|
|
44
|
+
everywhere (min 3.32, emerald light). The backdrop (`BOTTOM_SHEET_BACKDROP`) is
|
|
45
|
+
`withAlpha("#000000", MOTION_TRANSFORM.scrimOpacity)` — the same shared `scrimOpacity` knob as
|
|
46
|
+
Modal/Drawer/Menu's resting scrim, not a locally-guessed hex suffix — still not a palette role.
|
|
47
|
+
|
|
48
|
+
## Known gaps
|
|
49
|
+
|
|
50
|
+
- **No `react-native-safe-area-context` wiring** — same gap `Drawer` documents: listed as an
|
|
51
|
+
optional peer but not a real `peerDependencies` entry. Bottom padding instead uses
|
|
52
|
+
`resolveBottomSheetBottomInset` (a caller-supplied base padding + a static
|
|
53
|
+
`BOTTOM_SHEET_IOS_HOME_INDICATOR_INSET` on iOS), duplicated locally rather than sharing `Drawer`'s
|
|
54
|
+
resolver on purpose — modules never import across `src/modules/*`. Revisit once the package
|
|
55
|
+
becomes a real peer dependency.
|
|
45
56
|
|
|
46
57
|
## Tests
|
|
47
58
|
|