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
|
@@ -23,11 +23,14 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import { createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
26
|
-
import { AccessibilityInfo, Animated, Pressable, StyleSheet, Text, View } from "react-native";
|
|
26
|
+
import { AccessibilityInfo, Animated, Platform, Pressable, StyleSheet, Text, View } from "react-native";
|
|
27
27
|
import { useAnimatedValue, useMotion } from "../../core/motion/index.js";
|
|
28
|
+
import { useHaptics } from "../../core/haptics/index.js";
|
|
28
29
|
import { Icon } from "../../core/icon/index.js";
|
|
29
30
|
import { useTheme } from "../../theme/hooks.js";
|
|
30
|
-
import {
|
|
31
|
+
import { elevation, floatingBackground, floatingSurfaceStyle, highlight } from "../../theme/platform/index.js";
|
|
32
|
+
import { elevation as elevationTokens } from "../../theme/tokens/primitives/index.js";
|
|
33
|
+
import { CLOSE_BUTTON_SIZE, CLOSE_HIT_SLOP, CLOSE_ICON_SIZE, resolveAutoDismissDelay, resolveToastBottomInset, resolveToastTone, toastAccentBarStructure, toastCardStructure, toastOverlayStructure } from "./Toast.variants.js";
|
|
31
34
|
import { useScreenReaderEnabled } from "./toastScreenReader.js";
|
|
32
35
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
33
36
|
const ToastContext = /*#__PURE__*/createContext(undefined);
|
|
@@ -37,6 +40,7 @@ export const ToastProvider = /*#__PURE__*/memo(function ToastProvider({
|
|
|
37
40
|
}) {
|
|
38
41
|
const theme = useTheme();
|
|
39
42
|
const motion = useMotion();
|
|
43
|
+
const haptics = useHaptics();
|
|
40
44
|
const screenReaderEnabled = useScreenReaderEnabled();
|
|
41
45
|
const [toast, setToast] = useState(null);
|
|
42
46
|
const progress = useAnimatedValue(0);
|
|
@@ -91,6 +95,11 @@ export const ToastProvider = /*#__PURE__*/memo(function ToastProvider({
|
|
|
91
95
|
message: options.message,
|
|
92
96
|
tone
|
|
93
97
|
});
|
|
98
|
+
if (tone === "success") {
|
|
99
|
+
haptics.notification("success");
|
|
100
|
+
} else if (tone === "danger") {
|
|
101
|
+
haptics.notification("error");
|
|
102
|
+
}
|
|
94
103
|
// The real cross-platform screen-reader announcement: `accessibilityLiveRegion` (see
|
|
95
104
|
// `ToastCard`'s Text) is Android-only, so it alone leaves iOS VoiceOver silent. This
|
|
96
105
|
// imperative call reaches both VoiceOver and TalkBack.
|
|
@@ -101,7 +110,7 @@ export const ToastProvider = /*#__PURE__*/memo(function ToastProvider({
|
|
|
101
110
|
}).start();
|
|
102
111
|
delay.current = resolveAutoDismissDelay(options.duration, tone, screenReaderEnabled);
|
|
103
112
|
armDismissTimer();
|
|
104
|
-
}, [armDismissTimer, clearTimers, progress, motion, screenReaderEnabled]);
|
|
113
|
+
}, [armDismissTimer, clearTimers, progress, motion, screenReaderEnabled, haptics]);
|
|
105
114
|
|
|
106
115
|
// Pause while the user is reading (WCAG 2.2.1): leaving re-arms the FULL delay rather than the
|
|
107
116
|
// remainder — the message effectively restarts, which is the generous direction.
|
|
@@ -128,13 +137,18 @@ export const ToastProvider = /*#__PURE__*/memo(function ToastProvider({
|
|
|
128
137
|
show,
|
|
129
138
|
dismiss: hide
|
|
130
139
|
}), [show, hide]);
|
|
140
|
+
const overlayStyle = useMemo(() => position === "bottom" ? [toastOverlayStructure(theme, {
|
|
141
|
+
position
|
|
142
|
+
}), {
|
|
143
|
+
bottom: resolveToastBottomInset(theme.space[4], Platform.OS)
|
|
144
|
+
}] : toastOverlayStructure(theme, {
|
|
145
|
+
position
|
|
146
|
+
}), [theme, position]);
|
|
131
147
|
return /*#__PURE__*/_jsxs(ToastContext.Provider, {
|
|
132
148
|
value: contextValue,
|
|
133
149
|
children: [children, /*#__PURE__*/_jsx(View, {
|
|
134
150
|
pointerEvents: "box-none",
|
|
135
|
-
style:
|
|
136
|
-
position
|
|
137
|
-
}),
|
|
151
|
+
style: overlayStyle,
|
|
138
152
|
children: toast !== null && /*#__PURE__*/_jsx(ToastCard, {
|
|
139
153
|
toast: toast,
|
|
140
154
|
theme: theme,
|
|
@@ -166,6 +180,15 @@ const ToastCard = /*#__PURE__*/memo(function ToastCard({
|
|
|
166
180
|
onFocusOut
|
|
167
181
|
}) {
|
|
168
182
|
const toneColors = resolveToastTone(theme.colors, toast.tone);
|
|
183
|
+
const floatingStyle = useMemo(() => {
|
|
184
|
+
highlight("subtle", theme.mode);
|
|
185
|
+
elevation(elevationTokens.sm);
|
|
186
|
+
void theme.elevatedSurfaces;
|
|
187
|
+
return {
|
|
188
|
+
backgroundColor: floatingBackground(theme, "sm"),
|
|
189
|
+
...floatingSurfaceStyle(theme, "sm")
|
|
190
|
+
};
|
|
191
|
+
}, [theme]);
|
|
169
192
|
const translateY = progress.interpolate({
|
|
170
193
|
inputRange: [0, 1],
|
|
171
194
|
outputRange: position === "top" ? [-offsetY, 0] : [offsetY, 0]
|
|
@@ -173,18 +196,13 @@ const ToastCard = /*#__PURE__*/memo(function ToastCard({
|
|
|
173
196
|
return /*#__PURE__*/_jsxs(Animated.View, {
|
|
174
197
|
testID: "pixelize-toast",
|
|
175
198
|
accessibilityRole: "alert"
|
|
176
|
-
//
|
|
177
|
-
// a touch responder that competes with the close button for the tap. `onFocus`/`onBlur` on a
|
|
178
|
-
// View catch focus BUBBLING out of the close button (react-native-web), which is the only
|
|
179
|
-
// focusable thing in here; the button repeats them for native, where focus does not bubble.
|
|
199
|
+
// Pointer events, not Pressable: hovering to read must not compete with the close button's tap.
|
|
180
200
|
,
|
|
181
201
|
onPointerEnter: onHoverIn,
|
|
182
202
|
onPointerLeave: onHoverOut,
|
|
183
203
|
onFocus: onFocusIn,
|
|
184
204
|
onBlur: onFocusOut,
|
|
185
|
-
style: [toastCardStructure(theme), {
|
|
186
|
-
backgroundColor: toneColors.background
|
|
187
|
-
}, theme.elevation.lg, {
|
|
205
|
+
style: [toastCardStructure(theme), floatingStyle, {
|
|
188
206
|
opacity: progress,
|
|
189
207
|
transform: [{
|
|
190
208
|
translateY
|
|
@@ -29,6 +29,10 @@ export const CLOSE_HIT_SLOP = slopFor(CLOSE_BUTTON_SIZE);
|
|
|
29
29
|
|
|
30
30
|
/** `duration` on `ToastOptions` defaults to this when omitted — except for `danger` (see below). */
|
|
31
31
|
export const DEFAULT_TOAST_DURATION = 3000;
|
|
32
|
+
export const TOAST_IOS_HOME_INDICATOR_INSET = 20;
|
|
33
|
+
export function resolveToastBottomInset(basePadding, platformOS) {
|
|
34
|
+
return platformOS === "ios" ? basePadding + TOAST_IOS_HOME_INDICATOR_INSET : basePadding;
|
|
35
|
+
}
|
|
32
36
|
|
|
33
37
|
/**
|
|
34
38
|
* How long a toast stays up. `"persistent"` = until the user dismisses it (or a later `show()`
|
|
@@ -108,6 +112,7 @@ export const toastCardStructure = createThemedVariants(theme => ({
|
|
|
108
112
|
alignItems: "center",
|
|
109
113
|
columnGap: theme.space[3],
|
|
110
114
|
borderRadius: theme.radii.md,
|
|
115
|
+
borderCurve: "continuous",
|
|
111
116
|
paddingVertical: theme.space[3],
|
|
112
117
|
paddingRight: theme.space[3],
|
|
113
118
|
overflow: "hidden"
|
|
@@ -31,11 +31,15 @@ reads `bg.raised` / `fg.default`, so there is nothing appearance-wise for a call
|
|
|
31
31
|
|
|
32
32
|
## Accessibility contract (WCAG)
|
|
33
33
|
|
|
34
|
-
- **1.4.13 Content on Hover or Focus —
|
|
34
|
+
- **1.4.13 Content on Hover or Focus — 3 of 3.** *Persistent* ✅ (no auto-dismiss on the hover/focus
|
|
35
35
|
path — only long-press arms `autoHideMs`). *Dismissible* ✅ (Escape hides the tip via
|
|
36
36
|
`useDismissOnEscape` from `core/a11y/keyboard`, without moving focus; web-only by construction —
|
|
37
|
-
the native file is a no-op, and native has no hover/keyboard-focus tip to dismiss). *Hoverable*
|
|
38
|
-
—
|
|
37
|
+
the native file is a no-op, and native has no hover/keyboard-focus tip to dismiss). *Hoverable* ✅
|
|
38
|
+
— the bubble accepts pointer events and carries its own `onPointerEnter`/`onPointerLeave` (the
|
|
39
|
+
same primitive `Toast`'s card uses for a non-`Pressable` hover target); a hover-out on the trigger
|
|
40
|
+
doesn't hide immediately, it arms `TOOLTIP_TIMING.hoverOutGraceMs` (200ms) so the pointer has time
|
|
41
|
+
to cross the `theme.space[1]` gap onto the bubble, which cancels the pending hide on entry and
|
|
42
|
+
re-arms its own grace window on exit.
|
|
39
43
|
- **1.3.1 / no gesture-only content** — the whole point of this module. On **native** the trigger's
|
|
40
44
|
`accessibilityHint` is set to `mergeAccessibilityHint(existingHint, label)`, so a screen-reader
|
|
41
45
|
user gets the tip's content with the trigger itself and no long-press. The existing hint is
|
|
@@ -92,6 +96,11 @@ reads `bg.raised` / `fg.default`, so there is nothing appearance-wise for a call
|
|
|
92
96
|
- **Auto-hide fallback** (`TOOLTIP_TIMING.autoHideMs`, 2.5s) — guards against a long-press tip
|
|
93
97
|
staying open forever if `onPressOut` never fires (a cancelled gesture, or assistive tech invoking
|
|
94
98
|
`onLongPress` directly without a matching press-out).
|
|
99
|
+
- **The bubble's own hover pair uses `onPointerEnter`/`onPointerLeave`, not `Pressable`.** Same
|
|
100
|
+
reason as `Toast`'s card: turning the bubble into a touch responder would buy nothing and could
|
|
101
|
+
compete for gestures with whatever it's overlapping. A single `hideTimer` ref is shared between
|
|
102
|
+
the hover-out grace delay and the long-press `autoHideMs` fallback — safe because `show`/`hide`
|
|
103
|
+
always clear whichever one is pending before arming the other, so the two paths never collide.
|
|
95
104
|
|
|
96
105
|
## Known gaps
|
|
97
106
|
|
|
@@ -105,13 +114,6 @@ reads `bg.raised` / `fg.default`, so there is nothing appearance-wise for a call
|
|
|
105
114
|
`Text` handles only `onPress`) — this is the bug the example app hit.
|
|
106
115
|
- **`Menu` and `Tooltip` cannot nest either way.** `Menu` clones only `onPress` onto its trigger, and
|
|
107
116
|
`TooltipProps` has no `onPress`, so a Tooltip-wrapped Menu trigger never opens the menu.
|
|
108
|
-
- **1.4.13 *hoverable* is still unmet, and needs BOTH halves to land at once.** The bubble is
|
|
109
|
-
`pointerEvents="none"`, so a pointer can never reach the tip; and `handleHoverOut` hides
|
|
110
|
-
immediately, with no grace period for crossing the `theme.space[1]` gap between trigger and
|
|
111
|
-
bubble. Fixing only one half delivers nothing — enabling pointer events without a grace delay just
|
|
112
|
-
makes the tip vanish mid-gap. This is a behavioural redesign (a hover-tracked bubble with its own
|
|
113
|
-
hover handlers plus a close delay), deliberately not attempted as part of the flat-`aria-*`
|
|
114
|
-
migration.
|
|
115
117
|
- **2.2.1 on the long-press path** — `TOOLTIP_TIMING.autoHideMs` (2.5s) is a content-set time limit
|
|
116
118
|
with no turn-off/adjust/extend, and no WCAG exception covers it. It exists as a stuck-tip guard for
|
|
117
119
|
when `onPressOut` never fires (cancelled gesture, or AT invoking `onLongPress` directly), and in
|
|
@@ -127,10 +129,12 @@ reads `bg.raised` / `fg.default`, so there is nothing appearance-wise for a call
|
|
|
127
129
|
|
|
128
130
|
## Performance
|
|
129
131
|
|
|
130
|
-
Wrapped in `React.memo` (repo-wide re-render audit, 2026-07-17 — see root `CLAUDE.md`). `clearHideTimer`/`hide`/`show` are `useCallback`'d, and all six handlers `cloneElement` injects into the consumer-supplied `children` trigger are extracted to `handleLongPress`/`handlePressOut`/`handleHoverIn`/`handleHoverOut`/`handleFocus`/`handleBlur` (`useCallback`) instead of inline lambdas — same idiom `Menu.tsx` uses for its own trigger, since a fresh closure there would defeat a memoized trigger (e.g. this library's own `Button`).
|
|
132
|
+
Wrapped in `React.memo` (repo-wide re-render audit, 2026-07-17 — see root `CLAUDE.md`). `clearHideTimer`/`hide`/`show`/`scheduleHide` and the bubble's own `handleBubbleHoverIn`/`handleBubbleHoverOut` are all `useCallback`'d, and all six handlers `cloneElement` injects into the consumer-supplied `children` trigger are extracted to `handleLongPress`/`handlePressOut`/`handleHoverIn`/`handleHoverOut`/`handleFocus`/`handleBlur` (`useCallback`) instead of inline lambdas — same idiom `Menu.tsx` uses for its own trigger, since a fresh closure there would defeat a memoized trigger (e.g. this library's own `Button`).
|
|
131
133
|
|
|
132
134
|
## Modernization (v1.0.7)
|
|
133
135
|
|
|
134
136
|
- Theme imports decoupled to `theme/hooks`; optional peers (reanimated, gesture-handler, flash-list) load at runtime.
|
|
135
137
|
- List-heavy surfaces use `VirtualList` with device-tier window sizing where applicable.
|
|
136
138
|
- `React.memo` + stable callbacks retained; render-item/key-extractor hoisted per ESLint perf rules.
|
|
139
|
+
|
|
140
|
+
Button trigger focus ring is native `outline*` on the pressable (no sibling focus view).
|
|
@@ -32,6 +32,8 @@ import { cloneElement, memo, useCallback, useEffect, useId, useMemo, useRef, use
|
|
|
32
32
|
import { Animated, StyleSheet, Text, View } from "react-native";
|
|
33
33
|
import { useDismissOnEscape } from "../../core/a11y/keyboard";
|
|
34
34
|
import { useEnterExit, useMotion } from "../../core/motion/index.js";
|
|
35
|
+
import { elevation, floatingBackground, floatingSurfaceStyle, highlight } from "../../theme/platform/index.js";
|
|
36
|
+
import { elevation as elevationTokens } from "../../theme/tokens/primitives/index.js";
|
|
35
37
|
import { useTheme } from "../../theme/hooks.js";
|
|
36
38
|
import { mergeAccessibilityHint, TOOLTIP_TIMING, tooltipBubbleStructure } from "./Tooltip.variants.js";
|
|
37
39
|
|
|
@@ -65,6 +67,15 @@ export const Tooltip = /*#__PURE__*/memo(function Tooltip({
|
|
|
65
67
|
setVisible(false);
|
|
66
68
|
}, [clearHideTimer]);
|
|
67
69
|
|
|
70
|
+
// WCAG 1.4.13 hoverable: a hover-out doesn't hide immediately — it gives the pointer
|
|
71
|
+
// `hoverOutGraceMs` to cross the gap onto the bubble itself. Reuses `hideTimer`/`hide`: this and
|
|
72
|
+
// the long-press `autoHideMs` fallback below never overlap, since `show`/`hide` always clear
|
|
73
|
+
// whichever one is pending before arming the other.
|
|
74
|
+
const scheduleHide = useCallback(() => {
|
|
75
|
+
clearHideTimer();
|
|
76
|
+
hideTimer.current = setTimeout(hide, TOOLTIP_TIMING.hoverOutGraceMs);
|
|
77
|
+
}, [clearHideTimer, hide]);
|
|
78
|
+
|
|
68
79
|
// `autoHide` is the gesture path only: a pointer or keyboard tip must stay up as long as the
|
|
69
80
|
// trigger is hovered/focused (WCAG 1.4.13), and hover-out/blur are reliable enough not to need
|
|
70
81
|
// the fallback.
|
|
@@ -102,8 +113,22 @@ export const Tooltip = /*#__PURE__*/memo(function Tooltip({
|
|
|
102
113
|
const handleHoverOut = useCallback(event => {
|
|
103
114
|
children.props.onHoverOut?.(event);
|
|
104
115
|
hovered.current = false;
|
|
105
|
-
hide(
|
|
106
|
-
|
|
116
|
+
// Not an immediate hide: the pointer may be about to land on the bubble (WCAG 1.4.13
|
|
117
|
+
// hoverable) — `handleBubbleHoverIn` cancels this if it does.
|
|
118
|
+
scheduleHide();
|
|
119
|
+
}, [children, scheduleHide]);
|
|
120
|
+
|
|
121
|
+
// The bubble's own hover pair, mirroring the trigger's — same `onPointerEnter`/`onPointerLeave`
|
|
122
|
+
// primitive Toast's card uses for a non-Pressable hover target (see Toast.tsx), since turning the
|
|
123
|
+
// bubble into a `Pressable` would make it a touch responder for no reason.
|
|
124
|
+
const handleBubbleHoverIn = useCallback(() => {
|
|
125
|
+
clearHideTimer();
|
|
126
|
+
}, [clearHideTimer]);
|
|
127
|
+
const handleBubbleHoverOut = useCallback(() => {
|
|
128
|
+
// The pointer left the bubble; if it isn't back on the trigger either, the grace period starts
|
|
129
|
+
// again rather than hiding outright, since a fast re-entry (bubble -> trigger) is still valid.
|
|
130
|
+
if (!hovered.current) scheduleHide();
|
|
131
|
+
}, [scheduleHide]);
|
|
107
132
|
const handleFocus = useCallback(event => {
|
|
108
133
|
children.props.onFocus?.(event);
|
|
109
134
|
show(false);
|
|
@@ -122,12 +147,18 @@ export const Tooltip = /*#__PURE__*/memo(function Tooltip({
|
|
|
122
147
|
accessibilityHint: mergeAccessibilityHint(children.props.accessibilityHint, label),
|
|
123
148
|
"aria-describedby": bubble.mounted ? bubbleId : undefined
|
|
124
149
|
});
|
|
125
|
-
const bubbleStyle = useMemo(() =>
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
150
|
+
const bubbleStyle = useMemo(() => {
|
|
151
|
+
highlight("subtle", theme.mode);
|
|
152
|
+
elevation(elevationTokens.md);
|
|
153
|
+
void theme.elevatedSurfaces;
|
|
154
|
+
return [tooltipBubbleStructure(theme, {
|
|
155
|
+
placement
|
|
156
|
+
}), {
|
|
157
|
+
backgroundColor: floatingBackground(theme, "md"),
|
|
158
|
+
zIndex: theme.zIndices.tooltip,
|
|
159
|
+
...floatingSurfaceStyle(theme, "md")
|
|
160
|
+
}, bubble.style];
|
|
161
|
+
}, [theme, placement, bubble.style]);
|
|
131
162
|
const labelStyle = useMemo(() => [theme.fontStyleForWeight(theme.fontWeights.regular), {
|
|
132
163
|
fontSize: theme.fontSizes.sm,
|
|
133
164
|
color: theme.colors.fg.default
|
|
@@ -144,7 +175,8 @@ export const Tooltip = /*#__PURE__*/memo(function Tooltip({
|
|
|
144
175
|
_jsx(Animated.View, {
|
|
145
176
|
testID: testID ? `${testID}-bubble` : undefined,
|
|
146
177
|
id: bubbleId,
|
|
147
|
-
|
|
178
|
+
onPointerEnter: handleBubbleHoverIn,
|
|
179
|
+
onPointerLeave: handleBubbleHoverOut,
|
|
148
180
|
"aria-hidden": true,
|
|
149
181
|
style: bubbleStyle,
|
|
150
182
|
children: /*#__PURE__*/_jsx(Text, {
|
|
@@ -23,7 +23,14 @@ import { createThemedVariants } from "../../core/style/index.js";
|
|
|
23
23
|
*/
|
|
24
24
|
export const TOOLTIP_TIMING = {
|
|
25
25
|
/** Fallback auto-dismiss so a tip can't stay stuck open if `onPressOut` never fires. */
|
|
26
|
-
autoHideMs: 2500
|
|
26
|
+
autoHideMs: 2500,
|
|
27
|
+
/**
|
|
28
|
+
* Grace period before a hover-out actually hides the bubble, so a pointer crossing the
|
|
29
|
+
* `theme.space[1]` gap to the bubble itself doesn't lose the tip mid-transit (WCAG 1.4.13
|
|
30
|
+
* hoverable). The CSS/UI convention for this exact case; entering the bubble before it elapses
|
|
31
|
+
* cancels the hide.
|
|
32
|
+
*/
|
|
33
|
+
hoverOutGraceMs: 200
|
|
27
34
|
};
|
|
28
35
|
|
|
29
36
|
/**
|
|
@@ -8,7 +8,9 @@ hooks components read. It sits on top of three siblings — `tokens/` (the copy-
|
|
|
8
8
|
and holds React state — none of which may appear in `tokens/`. It mirrors web's `Theme/provider/`
|
|
9
9
|
in *shape and export names* (`PixelizeProvider`, `useThemeMode`), not byte-for-byte.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
`Theme` includes `elevatedSurfaces` (dark-mode background steps) when resolved by the provider.
|
|
12
|
+
|
|
13
|
+
## Public surface
|
|
12
14
|
|
|
13
15
|
| Export | Kind | Purpose |
|
|
14
16
|
|---|---|---|
|
|
@@ -17,7 +17,10 @@ platform values, so the token says `1` / `600` and this layer resolves it.
|
|
|
17
17
|
|---|---|---|
|
|
18
18
|
| `rem(n)` | `number` | Identity — RN lengths are already DP. Web returns `n/16 + 'rem'`. |
|
|
19
19
|
| `hairline` | `number` | `StyleSheet.hairlineWidth` — density-dependent, resolved at runtime. |
|
|
20
|
-
| `
|
|
20
|
+
| `highlight(level, mode)` | `BoxShadowArray` | Mode-aware inset top-edge highlight. |
|
|
21
|
+
| `highlightLevels(level, mode)` | `BoxShadowArray` | Alias of `highlight` — never hardcodes light palette. |
|
|
22
|
+
| `floatingBackground(theme, level)` | `string` | Light: role bg; dark: `elevatedSurfaces` step. |
|
|
23
|
+
| `floatingSurfaceStyle(theme, level)` | `ViewStyle` | `elevation` + `highlight` + `borderCurve`. |
|
|
21
24
|
| `interFontFamilies` | `Record<FontWeightValue, string>` | Weight value (`'400'`…`'700'`) → Inter face name. |
|
|
22
25
|
| `systemFontFamily` | `string` | `System` (iOS) / `sans-serif` (Android). |
|
|
23
26
|
| `fontStyleForWeight(weight, interLoaded?)` | `FontStyleForWeight` | Weight value → `{fontFamily}` or system fallback. |
|
|
@@ -29,7 +32,16 @@ Types: `ElevationStyle`, `FontWeightValue` (`= (typeof fontWeights)[keyof typeof
|
|
|
29
32
|
|
|
30
33
|
## Key behaviours
|
|
31
34
|
|
|
32
|
-
### Elevation
|
|
35
|
+
### Elevation emits full `boxShadow` stacks (New Arch peer >= 0.82)
|
|
36
|
+
|
|
37
|
+
`elevation(token)` maps every `layers[]` entry to `boxShadow` plus `elevation` for Android
|
|
38
|
+
low-API z-order. `highlight()` adds inset top-edge bands; `composeBoxShadow()` merges outset and
|
|
39
|
+
inset. `springs` exports Material 3 physics triples for Reanimated 4.5. `elevatedSurfaces()` adds
|
|
40
|
+
dark-mode surface steps on `Theme.elevatedSurfaces`. `STATE_LAYER_OPACITY` holds press/focus scrims.
|
|
41
|
+
|
|
42
|
+
Legacy shadow-prop documentation below is superseded for native — kept for web context only.
|
|
43
|
+
|
|
44
|
+
### Elevation uses the legacy shadow props on web only
|
|
33
45
|
|
|
34
46
|
`boxShadow` is **New-Architecture-only**. Our peer range (RN >= 0.79) still allows
|
|
35
47
|
`newArchEnabled=false`, where `boxShadow` renders **nothing**. The legacy props map straight to the
|
|
@@ -1,60 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { Platform } from 'react-native';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The style props an elevation resolves to. A `Pick` rather than `ViewStyle` so a future RN
|
|
7
|
-
* shadow prop cannot silently widen what this function is allowed to emit.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Resolve an elevation token to RN style props.
|
|
12
|
-
*
|
|
13
|
-
* Uses the legacy shadow props over `boxShadow` because `boxShadow` is New-Architecture-only, and
|
|
14
|
-
* our peer range (RN >= 0.79) still lets a consumer ship `newArchEnabled=false` — on which
|
|
15
|
-
* `boxShadow` renders nothing at all. The legacy props map straight to the platform APIs and are
|
|
16
|
-
* not deprecated, so they are the only path that works on both architectures. react-native-web's
|
|
17
|
-
* style preprocessor converts these same legacy props into a real CSS `box-shadow`, so the `web`
|
|
18
|
-
* branch below rides that conversion rather than emitting `boxShadow` itself.
|
|
19
|
-
*
|
|
20
|
-
* An elevation token is a STACK of layers (web needs both an ambient and a contact shadow per
|
|
21
|
-
* step), but legacy RN shadow props can only express one. This renders `layers[0]` — the dominant
|
|
22
|
-
* layer — and drops the rest. That is an honest limit of the legacy path, not a token compromise:
|
|
23
|
-
* a future `boxShadow`-only resolver (new-arch-only consumers) can render every layer.
|
|
24
|
-
*
|
|
25
|
-
* `layer.spread` is dropped — neither legacy platform API exposes it (RN implements it by
|
|
26
|
-
* insetting a custom shadowPath). The ramp's `md`/`lg` carry a negative spread to tighten the
|
|
27
|
-
* shadow on web, so those two steps read marginally wider here. Accepted: honouring it would mean
|
|
28
|
-
* hand-drawing a shadow layer per view.
|
|
29
|
-
*
|
|
30
|
-
* Returns one of three shapes: `ios`, `android` (RN's `default` branch — Android reads the numeric
|
|
31
|
-
* `elevation` prop and ignores offset/opacity/radius), and `web`. `web` MUST stay its own explicit
|
|
32
|
-
* key: without it, react-native-web falls through to `default` (the Android shape), whose only
|
|
33
|
-
* meaningful field — `elevation` — react-native-web silently ignores (it is Android-only), so the
|
|
34
|
-
* shadow renders as nothing at all.
|
|
35
|
-
*/
|
|
36
4
|
export function elevation(token) {
|
|
37
5
|
const layer = token.layers[0];
|
|
38
6
|
return Platform.select({
|
|
39
7
|
ios: {
|
|
40
8
|
shadowColor: layer.color,
|
|
41
|
-
// Always explicit: iOS defaults shadowOffset to (0, -3), not (0, 0).
|
|
42
9
|
shadowOffset: {
|
|
43
10
|
width: layer.x,
|
|
44
11
|
height: layer.y
|
|
45
12
|
},
|
|
46
|
-
// iOS multiplies shadowOpacity by the colour's own alpha, so 1 lets #rrggbbaa carry the
|
|
47
|
-
// translucency by itself — and keeps one colour value correct on both platforms.
|
|
48
13
|
shadowOpacity: 1,
|
|
49
|
-
// Halved because iOS renders a given shadowRadius heavier than the same CSS blur, so an
|
|
50
|
-
// unhalved radius reads darker and wider than the web token this mirrors.
|
|
51
14
|
shadowRadius: layer.blur / 2
|
|
52
15
|
},
|
|
53
|
-
// Same legacy shadow-prop shape as iOS, but WITHOUT the halving above: that halving corrects
|
|
54
|
-
// for iOS rendering a given shadowRadius heavier than the same CSS blur, which is an iOS
|
|
55
|
-
// quirk, not a web one. The token's `blur` already IS the original web/CSS value (see
|
|
56
|
-
// `elevation.ts`'s doc comment), so it passes straight through as `shadowRadius` and
|
|
57
|
-
// react-native-web's preprocessor turns the whole set into a real CSS `box-shadow`.
|
|
58
16
|
web: {
|
|
59
17
|
shadowColor: layer.color,
|
|
60
18
|
shadowOffset: {
|
|
@@ -64,8 +22,6 @@ export function elevation(token) {
|
|
|
64
22
|
shadowOpacity: 1,
|
|
65
23
|
shadowRadius: layer.blur
|
|
66
24
|
},
|
|
67
|
-
// Android draws the shadow from `elevation` alone; it ignores offset/opacity/radius and tints
|
|
68
|
-
// with shadowColor only on API 28+. Below that the shadow is the platform's default black.
|
|
69
25
|
default: {
|
|
70
26
|
shadowColor: layer.color,
|
|
71
27
|
elevation: token.android
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Platform } from 'react-native';
|
|
4
|
+
import { hexToHsl, withLightness } from "../tokens/builders/color.js";
|
|
5
|
+
import { elevation as renderElevation } from "./elevation.native.js";
|
|
6
|
+
import { elevation as elevationTokens } from "../tokens/primitives/index.js";
|
|
7
|
+
import { composeBoxShadow, highlight } from "./highlight.native.js";
|
|
8
|
+
const MIN_DARK_STEP = 4;
|
|
9
|
+
function darkStep(base, floorLightness) {
|
|
10
|
+
const bumped = floorLightness + MIN_DARK_STEP + 0.15;
|
|
11
|
+
return withLightness(base, Math.max(hexToHsl(base).l, bumped));
|
|
12
|
+
}
|
|
13
|
+
function darkFloatingBackground(theme, level) {
|
|
14
|
+
const canvasL = hexToHsl(theme.colors.bg.canvas).l;
|
|
15
|
+
switch (level) {
|
|
16
|
+
case 'sm':
|
|
17
|
+
return darkStep(theme.colors.bg.surface, canvasL);
|
|
18
|
+
case 'md':
|
|
19
|
+
{
|
|
20
|
+
const sm = darkFloatingBackground(theme, 'sm');
|
|
21
|
+
return darkStep(theme.colors.bg.raised, hexToHsl(sm).l);
|
|
22
|
+
}
|
|
23
|
+
case 'lg':
|
|
24
|
+
{
|
|
25
|
+
const md = darkFloatingBackground(theme, 'md');
|
|
26
|
+
return darkStep(theme.colors.bg.raised, hexToHsl(md).l);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const DARK_AMBIENT = [{
|
|
31
|
+
offsetX: 0,
|
|
32
|
+
offsetY: 8,
|
|
33
|
+
blurRadius: 24,
|
|
34
|
+
spreadDistance: 0,
|
|
35
|
+
color: 'rgba(0,0,0,0.4)'
|
|
36
|
+
}];
|
|
37
|
+
export function tokenBoxShadow(token) {
|
|
38
|
+
return token.layers.map(layer => ({
|
|
39
|
+
offsetX: layer.x,
|
|
40
|
+
offsetY: layer.y,
|
|
41
|
+
blurRadius: layer.blur,
|
|
42
|
+
spreadDistance: layer.spread,
|
|
43
|
+
color: layer.color
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
export function floatingBackground(theme, level) {
|
|
47
|
+
if (theme.mode === 'light') {
|
|
48
|
+
return level === 'sm' ? theme.colors.bg.raised : theme.colors.bg.surface;
|
|
49
|
+
}
|
|
50
|
+
return darkFloatingBackground(theme, level);
|
|
51
|
+
}
|
|
52
|
+
export function floatingSurfaceStyle(theme, level) {
|
|
53
|
+
const token = elevationTokens[level];
|
|
54
|
+
const legacy = renderElevation(token);
|
|
55
|
+
const style = {
|
|
56
|
+
...legacy,
|
|
57
|
+
borderCurve: 'continuous'
|
|
58
|
+
};
|
|
59
|
+
if (Platform.OS === 'android') {
|
|
60
|
+
return style;
|
|
61
|
+
}
|
|
62
|
+
if (theme.mode === 'dark') {
|
|
63
|
+
const inset = level === 'lg' ? highlight('subtle', theme.mode) : [];
|
|
64
|
+
style.boxShadow = composeBoxShadow(DARK_AMBIENT, inset);
|
|
65
|
+
if (level === 'lg') {
|
|
66
|
+
style.borderTopWidth = 1;
|
|
67
|
+
style.borderTopColor = 'rgba(255,255,255,0.06)';
|
|
68
|
+
}
|
|
69
|
+
return style;
|
|
70
|
+
}
|
|
71
|
+
const inset = highlight('subtle', theme.mode);
|
|
72
|
+
style.boxShadow = composeBoxShadow(tokenBoxShadow(token), inset);
|
|
73
|
+
return style;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=floatingSurface.native.js.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const LIGHT = {
|
|
4
|
+
subtle: 'rgba(255,255,255,0.05)',
|
|
5
|
+
raised: 'rgba(255,255,255,0.85)'
|
|
6
|
+
};
|
|
7
|
+
const DARK = {
|
|
8
|
+
subtle: 'rgba(255,255,255,0.10)',
|
|
9
|
+
raised: 'rgba(255,255,255,1.0)'
|
|
10
|
+
};
|
|
11
|
+
function layerKey(layer) {
|
|
12
|
+
return [layer.offsetX, layer.offsetY, layer.blurRadius ?? 0, layer.spreadDistance ?? 0, layer.inset ? 1 : 0, layer.color ?? ''].join('|');
|
|
13
|
+
}
|
|
14
|
+
function dedupeLayers(layers) {
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
const out = [];
|
|
17
|
+
for (const layer of layers) {
|
|
18
|
+
const key = layerKey(layer);
|
|
19
|
+
if (seen.has(key)) continue;
|
|
20
|
+
seen.add(key);
|
|
21
|
+
out.push(layer);
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
export function highlightLevels(level, mode) {
|
|
26
|
+
return highlight(level, mode);
|
|
27
|
+
}
|
|
28
|
+
export function highlight(level, mode) {
|
|
29
|
+
if (level === 'none') return [];
|
|
30
|
+
const palette = mode === 'dark' ? DARK : LIGHT;
|
|
31
|
+
const color = palette[level];
|
|
32
|
+
if (level === 'subtle') {
|
|
33
|
+
return [{
|
|
34
|
+
offsetX: 0,
|
|
35
|
+
offsetY: 1,
|
|
36
|
+
blurRadius: 0,
|
|
37
|
+
spreadDistance: 0,
|
|
38
|
+
inset: true,
|
|
39
|
+
color
|
|
40
|
+
}];
|
|
41
|
+
}
|
|
42
|
+
return [{
|
|
43
|
+
offsetX: 0,
|
|
44
|
+
offsetY: 1,
|
|
45
|
+
blurRadius: 1,
|
|
46
|
+
spreadDistance: 0,
|
|
47
|
+
inset: true,
|
|
48
|
+
color
|
|
49
|
+
}];
|
|
50
|
+
}
|
|
51
|
+
export function composeBoxShadow(outset, inset) {
|
|
52
|
+
return dedupeLayers([...outset, ...inset]);
|
|
53
|
+
}
|
|
54
|
+
export function asBoxShadowArray(value) {
|
|
55
|
+
if (value === undefined) return [];
|
|
56
|
+
if (typeof value === 'string') return [];
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=highlight.native.js.map
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export { rem, hairline } from "./units.native.js";
|
|
11
11
|
export { elevation } from "./elevation.native.js";
|
|
12
|
+
export { highlight, highlightLevels, composeBoxShadow } from "./highlight.native.js";
|
|
13
|
+
export { elevatedSurfaces } from "./surfaces.native.js";
|
|
14
|
+
export { STATE_LAYER_OPACITY, rippleColor, stateLayerScrim } from "./stateLayer.native.js";
|
|
15
|
+
export { floatingBackground, floatingSurfaceStyle } from "./floatingSurface.native.js";
|
|
16
|
+
export { springs } from "./motion.native.js";
|
|
12
17
|
export { interFontFamilies, systemFontFamily, fontStyleForWeight } from "./fonts.native.js";
|
|
13
18
|
export { getSystemColorMode, subscribeToSystemColorMode } from "./colorScheme.native.js";
|
|
14
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,15 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
export const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
export const springs = {
|
|
4
|
+
spatialFast: {
|
|
5
|
+
stiffness: 800,
|
|
6
|
+
damping: 33.94,
|
|
7
|
+
mass: 1
|
|
8
|
+
},
|
|
9
|
+
spatialDefault: {
|
|
10
|
+
stiffness: 380,
|
|
11
|
+
damping: 31.19,
|
|
12
|
+
mass: 1
|
|
13
|
+
},
|
|
14
|
+
spatialSlow: {
|
|
15
|
+
stiffness: 200,
|
|
16
|
+
damping: 22.63,
|
|
17
|
+
mass: 1
|
|
18
|
+
},
|
|
19
|
+
effectsFast: {
|
|
20
|
+
stiffness: 3800,
|
|
21
|
+
damping: 123.29,
|
|
22
|
+
mass: 1
|
|
23
|
+
},
|
|
24
|
+
effectsDefault: {
|
|
25
|
+
stiffness: 1600,
|
|
26
|
+
damping: 80.0,
|
|
27
|
+
mass: 1
|
|
28
|
+
},
|
|
29
|
+
effectsSlow: {
|
|
30
|
+
stiffness: 800,
|
|
31
|
+
damping: 56.57,
|
|
32
|
+
mass: 1
|
|
33
|
+
}
|
|
14
34
|
};
|
|
15
35
|
//# sourceMappingURL=motion.native.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export const STATE_LAYER_OPACITY = {
|
|
4
|
+
pressed: 0.1,
|
|
5
|
+
focus: 0.1,
|
|
6
|
+
hover: 0.08,
|
|
7
|
+
dragged: 0.16,
|
|
8
|
+
disabled: 0.38
|
|
9
|
+
};
|
|
10
|
+
export function stateLayerScrim(mode) {
|
|
11
|
+
return mode === 'dark' ? '#ffffff' : '#000000';
|
|
12
|
+
}
|
|
13
|
+
export const rippleColor = mode => mode === 'dark' ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.10)';
|
|
14
|
+
//# sourceMappingURL=stateLayer.native.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export function elevatedSurfaces(palette, mode) {
|
|
4
|
+
if (mode === 'light') return null;
|
|
5
|
+
return {
|
|
6
|
+
elevated1: palette.background[100],
|
|
7
|
+
elevated2: palette.background[200],
|
|
8
|
+
elevated3: palette.background[300]
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=surfaces.native.js.map
|