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
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { memo, useCallback, useMemo, useRef, useState } from "react";
|
|
9
|
-
import { Animated, FlatList, Pressable, Share, StyleSheet, useWindowDimensions, View } from "react-native";
|
|
9
|
+
import { Animated, FlatList, Platform, Pressable, Share, StyleSheet, useWindowDimensions, View } from "react-native";
|
|
10
10
|
import { MediaImage } from "../../core/media/index.js";
|
|
11
11
|
import { useEnterExit, useMotion } from "../../core/motion/index.js";
|
|
12
12
|
import { useTheme } from "../../theme/hooks.js";
|
|
13
|
+
import { rippleColor } from "../../theme/platform/stateLayer.native.js";
|
|
13
14
|
import { Button } from "../button/Button.js";
|
|
14
15
|
import { Modal } from "../modal/Modal.js";
|
|
15
16
|
import { IMAGE_VIEWER_PAGE_PADDING } from "./ImageViewer.variants.js";
|
|
@@ -105,16 +106,22 @@ export const ImageViewer = /*#__PURE__*/memo(function ImageViewer({
|
|
|
105
106
|
testID: testID ? `${testID}-page-${item.id}` : undefined
|
|
106
107
|
}), [pageStyle, testID]);
|
|
107
108
|
const activeBorder = theme.colors.accent.solid;
|
|
109
|
+
const thumbCount = imageItems.length;
|
|
108
110
|
const renderThumb = useCallback(({
|
|
109
|
-
item
|
|
111
|
+
item,
|
|
112
|
+
index
|
|
110
113
|
}) => /*#__PURE__*/_jsx(ImageViewerThumb, {
|
|
111
114
|
id: item.id,
|
|
112
115
|
uri: item.thumbUri ?? item.uri,
|
|
116
|
+
label: item.label,
|
|
117
|
+
position: index + 1,
|
|
118
|
+
total: thumbCount,
|
|
113
119
|
active: item.id === currentId,
|
|
114
120
|
activeBorder: activeBorder,
|
|
121
|
+
mode: theme.mode,
|
|
115
122
|
onPress: handleThumbPress,
|
|
116
123
|
testID: testID ? `${testID}-thumb-${item.id}` : undefined
|
|
117
|
-
}), [currentId, activeBorder, handleThumbPress, testID]);
|
|
124
|
+
}), [currentId, activeBorder, theme.mode, thumbCount, handleThumbPress, testID]);
|
|
118
125
|
const bodyStyle = useMemo(() => ({
|
|
119
126
|
gap: theme.space[3]
|
|
120
127
|
}), [theme]);
|
|
@@ -180,8 +187,12 @@ const ImageViewerPage = /*#__PURE__*/memo(function ImageViewerPage({
|
|
|
180
187
|
const ImageViewerThumb = /*#__PURE__*/memo(function ImageViewerThumb({
|
|
181
188
|
id,
|
|
182
189
|
uri,
|
|
190
|
+
label,
|
|
191
|
+
position,
|
|
192
|
+
total,
|
|
183
193
|
active,
|
|
184
194
|
activeBorder,
|
|
195
|
+
mode,
|
|
185
196
|
onPress,
|
|
186
197
|
testID
|
|
187
198
|
}) {
|
|
@@ -189,9 +200,25 @@ const ImageViewerThumb = /*#__PURE__*/memo(function ImageViewerThumb({
|
|
|
189
200
|
const thumbStyle = useMemo(() => [styles.thumb, active ? {
|
|
190
201
|
borderColor: activeBorder,
|
|
191
202
|
borderWidth: 2
|
|
192
|
-
} :
|
|
203
|
+
} : styles.thumbInactive], [active, activeBorder]);
|
|
204
|
+
const androidRipple = useMemo(() => Platform.OS === "android" ? {
|
|
205
|
+
color: rippleColor(mode),
|
|
206
|
+
borderless: false
|
|
207
|
+
} : undefined, [mode]);
|
|
208
|
+
// Border colour alone isn't a reliable selection cue (colour-blind users, low-vision) — the
|
|
209
|
+
// dimmed opacity on unselected thumbs is the redundant, non-colour signal (WCAG 1.4.1).
|
|
210
|
+
const imageStyle = useMemo(() => [styles.thumbImage, {
|
|
211
|
+
opacity: active ? 1 : 0.6
|
|
212
|
+
}], [active]);
|
|
213
|
+
const accessibilityLabel = label ? `${label}, image ${position} of ${total}` : `Image ${position} of ${total}`;
|
|
193
214
|
return /*#__PURE__*/_jsx(Pressable, {
|
|
215
|
+
accessibilityRole: "button",
|
|
216
|
+
accessibilityLabel: accessibilityLabel,
|
|
217
|
+
accessibilityState: {
|
|
218
|
+
selected: active
|
|
219
|
+
},
|
|
194
220
|
onPress: handlePress,
|
|
221
|
+
android_ripple: androidRipple,
|
|
195
222
|
style: thumbStyle,
|
|
196
223
|
children: /*#__PURE__*/_jsx(MediaImage, {
|
|
197
224
|
testID: testID,
|
|
@@ -200,7 +227,7 @@ const ImageViewerThumb = /*#__PURE__*/memo(function ImageViewerThumb({
|
|
|
200
227
|
},
|
|
201
228
|
contentFit: "cover",
|
|
202
229
|
recyclingKey: uri,
|
|
203
|
-
style:
|
|
230
|
+
style: imageStyle
|
|
204
231
|
})
|
|
205
232
|
});
|
|
206
233
|
});
|
|
@@ -227,6 +254,9 @@ const styles = StyleSheet.create({
|
|
|
227
254
|
borderRadius: 8,
|
|
228
255
|
overflow: "hidden"
|
|
229
256
|
},
|
|
257
|
+
thumbInactive: {
|
|
258
|
+
borderWidth: 0
|
|
259
|
+
},
|
|
230
260
|
thumbImage: {
|
|
231
261
|
width: "100%",
|
|
232
262
|
height: "100%"
|
|
@@ -9,6 +9,12 @@ Modal image gallery with paging and thumbnails. Heavy module — subpath only.
|
|
|
9
9
|
affordance is the backdrop, so on that branch a keyboard user previously had no way to close it at
|
|
10
10
|
all. No keyboard code lives here — `__tests__/ImageViewer.keyboard.web.test.tsx` asserts the
|
|
11
11
|
inheritance.
|
|
12
|
+
- **Thumbnail strip (1.3.1 / 1.4.1 / 4.1.2)** — each `ImageViewerThumb` carries
|
|
13
|
+
`accessibilityRole="button"`, `accessibilityState={{ selected: active }}`, and an
|
|
14
|
+
`accessibilityLabel` built from the item's own `label` plus its position ("Photo, image 2 of 5"),
|
|
15
|
+
never a bare unlabelled tap target. The active thumb is also marked by a dimmed opacity on every
|
|
16
|
+
OTHER thumb, not by `activeBorder` colour alone — a colour-blind or low-vision user can tell which
|
|
17
|
+
image is open without relying on hue.
|
|
12
18
|
|
|
13
19
|
## Motion contract
|
|
14
20
|
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
* fades in and out. Both honour reduce-motion through `useMotion()`.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { memo, useCallback, useEffect, useId, useMemo, useRef } from "react";
|
|
13
|
+
import { memo, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
14
14
|
import { Animated, Platform, StyleSheet, Text, TextInput, View } from "react-native";
|
|
15
15
|
import { useAnnounce } from "../../core/a11y/index.js";
|
|
16
|
+
import { withAlpha } from "../../core/gradient/index.js";
|
|
16
17
|
import { Icon } from "../../core/icon/index.js";
|
|
17
18
|
import { useAnimatedValue, useEnterExit, useMotion } from "../../core/motion/index.js";
|
|
18
19
|
import { useTheme } from "../../theme/hooks.js";
|
|
@@ -41,6 +42,7 @@ export const Input = /*#__PURE__*/memo(function Input(props) {
|
|
|
41
42
|
} = props;
|
|
42
43
|
const theme = useTheme();
|
|
43
44
|
const motion = useMotion();
|
|
45
|
+
const [focused, setFocused] = useState(false);
|
|
44
46
|
const spec = INPUT_SIZES[size];
|
|
45
47
|
const statusColors = resolveInputStatus(theme.colors, status);
|
|
46
48
|
const a11y = resolveInputAccessibility({
|
|
@@ -78,9 +80,15 @@ export const Input = /*#__PURE__*/memo(function Input(props) {
|
|
|
78
80
|
}, [motion, ringOpacity]);
|
|
79
81
|
useEffect(() => () => ringAnimation.current?.stop(), []);
|
|
80
82
|
const handleFocus = useCallback(() => {
|
|
81
|
-
if (!disabled)
|
|
83
|
+
if (!disabled) {
|
|
84
|
+
setFocused(true);
|
|
85
|
+
setRingVisible(true);
|
|
86
|
+
}
|
|
82
87
|
}, [disabled, setRingVisible]);
|
|
83
|
-
const handleBlur = useCallback(() =>
|
|
88
|
+
const handleBlur = useCallback(() => {
|
|
89
|
+
setFocused(false);
|
|
90
|
+
setRingVisible(false);
|
|
91
|
+
}, [setRingVisible]);
|
|
84
92
|
const labelStyle = useMemo(() => [theme.fontStyleForWeight(theme.fontWeights.medium), {
|
|
85
93
|
fontSize: theme.fontSizes.sm,
|
|
86
94
|
color: theme.colors.fg.default,
|
|
@@ -88,9 +96,13 @@ export const Input = /*#__PURE__*/memo(function Input(props) {
|
|
|
88
96
|
}], [theme]);
|
|
89
97
|
const fieldStyle = useMemo(() => [inputStructure(theme, {
|
|
90
98
|
size
|
|
91
|
-
}), {
|
|
99
|
+
}), focused ? {
|
|
100
|
+
borderWidth: 2,
|
|
101
|
+
borderColor: theme.colors.accent.solid,
|
|
102
|
+
backgroundColor: withAlpha(theme.colors.accent.solid, 0.04)
|
|
103
|
+
} : {
|
|
92
104
|
borderColor: statusColors.border
|
|
93
|
-
}, disabled && styles.dimmed], [theme, size, statusColors.border, disabled]);
|
|
105
|
+
}, disabled && styles.dimmed], [theme, size, statusColors.border, disabled, focused]);
|
|
94
106
|
const focusRingStyle = useMemo(() => ({
|
|
95
107
|
position: "absolute",
|
|
96
108
|
top: -(FOCUS_RING_GAP + FOCUS_RING_WIDTH),
|
|
@@ -99,7 +111,8 @@ export const Input = /*#__PURE__*/memo(function Input(props) {
|
|
|
99
111
|
bottom: -(FOCUS_RING_GAP + FOCUS_RING_WIDTH),
|
|
100
112
|
borderWidth: FOCUS_RING_WIDTH,
|
|
101
113
|
borderColor: theme.colors.border.focus,
|
|
102
|
-
borderRadius: theme.radii.
|
|
114
|
+
borderRadius: theme.radii.md + FOCUS_RING_GAP + FOCUS_RING_WIDTH,
|
|
115
|
+
borderCurve: "continuous"
|
|
103
116
|
}), [theme]);
|
|
104
117
|
const inputTextStyle = useMemo(() => [{
|
|
105
118
|
flex: 1,
|
|
@@ -143,7 +156,7 @@ export const Input = /*#__PURE__*/memo(function Input(props) {
|
|
|
143
156
|
value: value,
|
|
144
157
|
onChangeText: onChangeText,
|
|
145
158
|
placeholder: placeholder,
|
|
146
|
-
placeholderTextColor: theme.colors.fg.
|
|
159
|
+
placeholderTextColor: theme.colors.fg.placeholder,
|
|
147
160
|
secureTextEntry: secureTextEntry,
|
|
148
161
|
autoComplete: autoComplete,
|
|
149
162
|
importantForAutofill: autoComplete === "off" ? "no" : undefined,
|
|
@@ -28,22 +28,22 @@ const slopFor = height => Math.max(0, Math.ceil((MIN_TOUCH_TARGET - height) / 2)
|
|
|
28
28
|
*/
|
|
29
29
|
export const INPUT_SIZES = {
|
|
30
30
|
sm: {
|
|
31
|
-
height:
|
|
31
|
+
height: 44,
|
|
32
32
|
fontSize: 14,
|
|
33
33
|
iconSize: 16,
|
|
34
|
-
hitSlop: slopFor(
|
|
34
|
+
hitSlop: slopFor(44)
|
|
35
35
|
},
|
|
36
36
|
md: {
|
|
37
|
-
height:
|
|
37
|
+
height: 52,
|
|
38
38
|
fontSize: 16,
|
|
39
39
|
iconSize: 18,
|
|
40
|
-
hitSlop: slopFor(
|
|
40
|
+
hitSlop: slopFor(52)
|
|
41
41
|
},
|
|
42
42
|
lg: {
|
|
43
|
-
height:
|
|
43
|
+
height: 56,
|
|
44
44
|
fontSize: 18,
|
|
45
45
|
iconSize: 20,
|
|
46
|
-
hitSlop: slopFor(
|
|
46
|
+
hitSlop: slopFor(56)
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
49
|
/**
|
|
@@ -110,7 +110,8 @@ export const inputStructure = createThemedVariants(theme => ({
|
|
|
110
110
|
flexDirection: "row",
|
|
111
111
|
alignItems: "center",
|
|
112
112
|
borderWidth: theme.borderWidths.thin,
|
|
113
|
-
borderRadius: theme.radii.
|
|
113
|
+
borderRadius: theme.radii.md,
|
|
114
|
+
borderCurve: "continuous",
|
|
114
115
|
columnGap: theme.space[2]
|
|
115
116
|
},
|
|
116
117
|
variants: {
|
|
@@ -125,3 +125,5 @@ Wrapped in `React.memo` (repo-wide re-render audit, 2026-07-17 — see root `CLA
|
|
|
125
125
|
- Theme imports decoupled to `theme/hooks`; optional peers (reanimated, gesture-handler, flash-list) load at runtime.
|
|
126
126
|
- List-heavy surfaces use `VirtualList` with device-tier window sizing where applicable.
|
|
127
127
|
- `React.memo` + stable callbacks retained; render-item/key-extractor hoisted per ESLint perf rules.
|
|
128
|
+
|
|
129
|
+
- **Round 2 visual** — radii retarget (`radii.md`/`lg`/`xl`/`full`), `borderCurve: continuous` on md+ corners; floating surfaces wire platform elevation/highlight where applicable.
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* ListItem — a row primitive.
|
|
5
|
-
* animation and no loop: the only motion is `usePressMotion`, which starts on touch and runs on the
|
|
6
|
-
* native driver. The pressable root is an animated `Pressable` rather than an `Animated.View`
|
|
7
|
-
* wrapper so a 5000-row list pays for no extra node.
|
|
4
|
+
* ListItem — a row primitive. Press feedback uses `usePressState` (scale + state-layer overlay).
|
|
8
5
|
*/
|
|
9
6
|
|
|
10
7
|
import { memo, useMemo } from "react";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
8
|
+
import { Platform, Pressable, StyleSheet, View } from "react-native";
|
|
9
|
+
import Animated, { FadeInDown, ReduceMotion } from "react-native-reanimated";
|
|
10
|
+
import { usePressState } from "../../core/motion/usePressState.js";
|
|
11
|
+
import { concentric } from "../../core/style/index.js";
|
|
12
|
+
import { rippleColor as androidRippleColor, stateLayerScrim } from "../../theme/platform/stateLayer.native.js";
|
|
13
13
|
import { useTheme } from "../../theme/hooks.js";
|
|
14
|
+
import { Text } from "../text/index.js";
|
|
14
15
|
import { listItemBodyStructure, listItemDotStructure, listItemStructure, resolveListItemAccessibility, resolveListItemColors } from "./ListItem.variants.js";
|
|
15
16
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
16
17
|
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
|
|
@@ -26,7 +27,8 @@ export const ListItem = /*#__PURE__*/memo(function ListItem({
|
|
|
26
27
|
}) {
|
|
27
28
|
const theme = useTheme();
|
|
28
29
|
const pressable = onPress !== undefined;
|
|
29
|
-
const press =
|
|
30
|
+
const press = usePressState(!pressable);
|
|
31
|
+
const leadingRadius = useMemo(() => concentric(theme.radii.lg, theme.space[4]), [theme.radii.lg, theme.space]);
|
|
30
32
|
const colors = useMemo(() => resolveListItemColors(theme.colors, unread), [theme.colors, unread]);
|
|
31
33
|
const a11y = useMemo(() => resolveListItemAccessibility({
|
|
32
34
|
title,
|
|
@@ -36,57 +38,77 @@ export const ListItem = /*#__PURE__*/memo(function ListItem({
|
|
|
36
38
|
const baseStyle = useMemo(() => [listItemStructure(theme), {
|
|
37
39
|
backgroundColor: colors.background
|
|
38
40
|
}, style], [theme, colors, style]);
|
|
39
|
-
// `style` stays last; the press style holds only opacity/transform, which `LayoutStyle` cannot name.
|
|
40
41
|
const pressableStyle = useMemo(() => [listItemStructure(theme), {
|
|
41
|
-
backgroundColor: colors.background
|
|
42
|
-
|
|
42
|
+
backgroundColor: colors.background,
|
|
43
|
+
overflow: "hidden"
|
|
44
|
+
}, press.animatedStyle, style], [theme, colors, press.animatedStyle, style]);
|
|
45
|
+
const overlayStaticStyle = useMemo(() => ({
|
|
46
|
+
backgroundColor: stateLayerScrim(theme.mode),
|
|
47
|
+
borderRadius: theme.radii.md,
|
|
48
|
+
borderCurve: "continuous"
|
|
49
|
+
}), [theme.mode, theme.radii.md]);
|
|
50
|
+
const androidRipple = useMemo(() => {
|
|
51
|
+
if (!pressable || Platform.OS !== "android") return undefined;
|
|
52
|
+
return {
|
|
53
|
+
color: androidRippleColor(theme.mode),
|
|
54
|
+
borderless: false
|
|
55
|
+
};
|
|
56
|
+
}, [pressable, theme.mode]);
|
|
43
57
|
const dotStyle = useMemo(() => [listItemDotStructure(theme), {
|
|
44
58
|
backgroundColor: colors.dot
|
|
45
59
|
}], [theme, colors]);
|
|
46
60
|
const bodyStyle = useMemo(() => listItemBodyStructure(theme), [theme]);
|
|
47
|
-
const titleStyle = useMemo(() => [theme.fontStyleForWeight(unread ? theme.fontWeights.semibold : theme.fontWeights.medium), {
|
|
48
|
-
fontSize: theme.fontSizes.md,
|
|
49
|
-
color: colors.title
|
|
50
|
-
}], [theme, unread, colors]);
|
|
51
|
-
const subtitleStyle = useMemo(() => [theme.fontStyleForWeight(theme.fontWeights.regular), {
|
|
52
|
-
fontSize: theme.fontSizes.sm,
|
|
53
|
-
color: colors.subtitle
|
|
54
|
-
}], [theme, colors]);
|
|
55
61
|
const body = /*#__PURE__*/_jsxs(_Fragment, {
|
|
56
62
|
children: [unread && /*#__PURE__*/_jsx(View, {
|
|
57
63
|
testID: testID === undefined ? undefined : `${testID}-dot`,
|
|
58
64
|
accessibilityElementsHidden: true,
|
|
59
65
|
importantForAccessibility: "no-hide-descendants",
|
|
60
66
|
style: dotStyle
|
|
61
|
-
}), leading
|
|
67
|
+
}), leading !== undefined && /*#__PURE__*/_jsx(View, {
|
|
68
|
+
style: {
|
|
69
|
+
borderRadius: leadingRadius,
|
|
70
|
+
borderCurve: "continuous",
|
|
71
|
+
overflow: "hidden"
|
|
72
|
+
},
|
|
73
|
+
children: leading
|
|
74
|
+
}), /*#__PURE__*/_jsxs(View, {
|
|
62
75
|
style: bodyStyle,
|
|
63
76
|
children: [/*#__PURE__*/_jsx(Text, {
|
|
77
|
+
variant: "body",
|
|
78
|
+
weight: unread ? "semibold" : "medium",
|
|
64
79
|
numberOfLines: 1,
|
|
65
|
-
style: titleStyle,
|
|
66
80
|
children: title
|
|
67
81
|
}), subtitle !== undefined && /*#__PURE__*/_jsx(Text, {
|
|
82
|
+
variant: "caption",
|
|
83
|
+
color: "muted",
|
|
68
84
|
numberOfLines: 2,
|
|
69
|
-
style: subtitleStyle,
|
|
70
85
|
children: subtitle
|
|
71
86
|
})]
|
|
72
87
|
}), trailing]
|
|
73
88
|
});
|
|
74
89
|
if (!pressable) {
|
|
75
|
-
return /*#__PURE__*/_jsx(View, {
|
|
90
|
+
return /*#__PURE__*/_jsx(Animated.View, {
|
|
91
|
+
entering: FadeInDown.springify().reduceMotion(ReduceMotion.System),
|
|
76
92
|
testID: testID,
|
|
77
93
|
style: baseStyle,
|
|
78
94
|
children: body
|
|
79
95
|
});
|
|
80
96
|
}
|
|
81
|
-
return /*#__PURE__*/
|
|
97
|
+
return /*#__PURE__*/_jsxs(AnimatedPressable, {
|
|
82
98
|
testID: testID,
|
|
83
99
|
accessibilityRole: "button",
|
|
84
100
|
accessibilityLabel: a11y.accessibilityLabel,
|
|
85
101
|
onPress: onPress,
|
|
86
|
-
onPressIn: press.onPressIn,
|
|
87
|
-
onPressOut: press.onPressOut,
|
|
102
|
+
onPressIn: press.handlers.onPressIn,
|
|
103
|
+
onPressOut: press.handlers.onPressOut,
|
|
104
|
+
onLayout: press.onLayout,
|
|
105
|
+
android_ripple: androidRipple,
|
|
88
106
|
style: pressableStyle,
|
|
89
|
-
children:
|
|
107
|
+
children: [/*#__PURE__*/_jsx(Animated.View, {
|
|
108
|
+
pointerEvents: "none",
|
|
109
|
+
testID: testID === undefined ? undefined : `${testID}-press-overlay`,
|
|
110
|
+
style: [StyleSheet.absoluteFill, overlayStaticStyle, press.overlayStyle]
|
|
111
|
+
}), body]
|
|
90
112
|
});
|
|
91
113
|
});
|
|
92
114
|
//# sourceMappingURL=ListItem.js.map
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
import { StyleSheet } from "react-native";
|
|
3
4
|
/**
|
|
4
5
|
* Pure resolvers for ListItem — no React, so the WCAG tests import this directly (mocking only
|
|
5
6
|
* `react-native`'s `StyleSheet`, as every sibling module's tests do).
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
import { createThemedVariants } from "../../core/style/index.js";
|
|
10
|
+
import { floatingBackground, floatingSurfaceStyle } from "../../theme/platform/floatingSurface.native.js";
|
|
9
11
|
export const LIST_ITEM_DOT_SIZE = 8;
|
|
10
|
-
export const LIST_ITEM_MIN_HEIGHT =
|
|
12
|
+
export const LIST_ITEM_MIN_HEIGHT = 56;
|
|
11
13
|
export function resolveListItemColors(colors, unread) {
|
|
12
14
|
return {
|
|
13
15
|
background: unread ? colors.bg.surface : undefined,
|
|
@@ -34,7 +36,8 @@ export const listItemStructure = createThemedVariants(theme => ({
|
|
|
34
36
|
columnGap: theme.space[3],
|
|
35
37
|
minHeight: LIST_ITEM_MIN_HEIGHT,
|
|
36
38
|
paddingVertical: theme.space[3],
|
|
37
|
-
paddingHorizontal: theme.space[4]
|
|
39
|
+
paddingHorizontal: theme.space[4],
|
|
40
|
+
borderBottomWidth: StyleSheet.hairlineWidth
|
|
38
41
|
}
|
|
39
42
|
}));
|
|
40
43
|
export const listItemBodyStructure = createThemedVariants(theme => ({
|
|
@@ -43,6 +46,12 @@ export const listItemBodyStructure = createThemedVariants(theme => ({
|
|
|
43
46
|
rowGap: theme.space[1]
|
|
44
47
|
}
|
|
45
48
|
}));
|
|
49
|
+
export function listItemRaisedStyle(theme) {
|
|
50
|
+
return {
|
|
51
|
+
backgroundColor: floatingBackground(theme, "sm"),
|
|
52
|
+
...floatingSurfaceStyle(theme, "sm")
|
|
53
|
+
};
|
|
54
|
+
}
|
|
46
55
|
export const listItemDotStructure = createThemedVariants(theme => ({
|
|
47
56
|
base: {
|
|
48
57
|
width: LIST_ITEM_DOT_SIZE,
|
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
`ListItem` renders one row for notification lists, inboxes, and settings screens: optional
|
|
4
4
|
`leading`/`trailing` nodes around a title + subtitle column. `unread` adds an `accent.solid` dot
|
|
5
5
|
and a `bg.surface` row emphasis (plus a semibold title) — `bg.surface`, not `bg.selected`, because
|
|
6
|
-
`fg.muted` is only measured AA against surface/hover. A `Pressable` when `onPress` is set
|
|
7
|
-
|
|
8
|
-
a plain `View` otherwise.
|
|
6
|
+
`fg.muted` is only measured AA against surface/hover. A `Pressable` when `onPress` is set uses
|
|
7
|
+
`usePressState` (scale + state-layer overlay on the native driver); a plain `View` otherwise.
|
|
9
8
|
|
|
10
9
|
## Files
|
|
11
10
|
|
|
@@ -16,7 +16,7 @@ unclosed fence swallows the rest of the input as code.
|
|
|
16
16
|
| `index.ts` | Public surface: `Markdown`, `MarkdownProps`, `parseMarkdown`, node types. |
|
|
17
17
|
| `__tests__/parseMarkdown.test.ts` | Pure: every block/inline form + malformed-input robustness. |
|
|
18
18
|
| `__tests__/Markdown.test.ts` | Pure: WCAG contrast for text/link/quote roles (all brands × modes). |
|
|
19
|
-
| `__tests__/Markdown.render.test.tsx` | Render: headings, lists, code, link press wiring,
|
|
19
|
+
| `__tests__/Markdown.render.test.tsx` | Render: headings, lists, code, link press wiring, every heading of a 60-section document reaching the tree (the rotor guard — see Performance), and the block/list-item safety caps (below-cap unchanged, above-cap capped + affordance reveals everything). |
|
|
20
20
|
| `__tests__/Markdown.dom.test.tsx` | Real DOM (`jest.web.config.js`): a `#`/`##`/`###` document renders real `<h1>`/`<h2>`/`<h3>` tags, not three `<h1>`s. |
|
|
21
21
|
|
|
22
22
|
## Props
|
|
@@ -64,8 +64,15 @@ The parse is `useMemo`'d on `content`; the **render tree** is the other half of
|
|
|
64
64
|
The cost is bounded by the content: blocks come from parsing one `content` string, which is a
|
|
65
65
|
chat message or a notes body, not an unbounded dataset. If a caller ever does need a virtualized
|
|
66
66
|
document, that is a different component with a different accessibility contract.
|
|
67
|
+
- **Safety caps exist for pathological/misuse input only — they do NOT contradict the above.**
|
|
68
|
+
`MAX_RENDERED_BLOCKS` (300) and `MAX_LIST_ITEMS` (50, per list block, independent of the block
|
|
69
|
+
cap) bound a degenerate `content` string; below either cap a document/list renders exactly as
|
|
70
|
+
before. Above it, a `Button` ("Show full document" / "+N more items") mounts the real, full tree
|
|
71
|
+
on press — never a re-introduction of windowing, so the rotor contract holds once expanded.
|
|
67
72
|
- Links render through a memo'd `MarkdownLink` so no per-link closure is rebuilt each render.
|
|
68
73
|
|
|
69
74
|
## Modernization (v1.0.7)
|
|
70
75
|
|
|
71
76
|
- Theme imports decoupled to `theme/hooks`; optional peers (reanimated, gesture-handler, flash-list) load at runtime.
|
|
77
|
+
|
|
78
|
+
- **Round 2 visual** — radii retarget (`radii.md`/`lg`/`xl`/`full`), `borderCurve: continuous` on md+ corners; floating surfaces wire platform elevation/highlight where applicable.
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
* VirtualizedList is an error in its own right.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { Fragment, memo, useCallback, useMemo } from "react";
|
|
10
|
+
import { Fragment, memo, useCallback, useMemo, useState } from "react";
|
|
11
11
|
import { Platform, StyleSheet, Text, View } from "react-native";
|
|
12
|
+
import { Button } from "../button/index.js";
|
|
12
13
|
import { HeadingText } from "../../core/heading/index.js";
|
|
13
14
|
import { useTheme } from "../../theme/hooks.js";
|
|
14
15
|
import { markdownBlockquoteStructure, markdownCodeBlockStructure, markdownListRowStructure, markdownListStructure, markdownStructure, resolveMarkdownColors, resolveMarkdownHeading } from "./Markdown.variants.js";
|
|
@@ -18,6 +19,17 @@ const MONO_FONT = Platform.select({
|
|
|
18
19
|
ios: "Menlo",
|
|
19
20
|
default: "monospace"
|
|
20
21
|
});
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Safety caps for pathological/misuse input, not windowing (see MODULE.md "Performance") — below
|
|
25
|
+
* these numbers a document renders exactly as before; above, an affordance mounts the real, full
|
|
26
|
+
* tree on press, so the WCAG 2.4.1 rotor contract holds once expanded.
|
|
27
|
+
*/
|
|
28
|
+
// Comfortably covers long-form docs/notes (the existing 60-heading test is a fifth of it) while
|
|
29
|
+
// bounding a document of thousands of blocks.
|
|
30
|
+
export const MAX_RENDERED_BLOCKS = 300;
|
|
31
|
+
// Covers realistic checklists/notes lists; bounds a single oversized list regardless of doc length.
|
|
32
|
+
export const MAX_LIST_ITEMS = 50;
|
|
21
33
|
const MarkdownLink = /*#__PURE__*/memo(function MarkdownLink({
|
|
22
34
|
content,
|
|
23
35
|
url,
|
|
@@ -75,6 +87,9 @@ const MarkdownBlock = /*#__PURE__*/memo(function MarkdownBlock({
|
|
|
75
87
|
colors,
|
|
76
88
|
onLinkPress
|
|
77
89
|
}) {
|
|
90
|
+
// Called unconditionally (rules of hooks) though only the "list" case below reads it.
|
|
91
|
+
const [itemsExpanded, setItemsExpanded] = useState(false);
|
|
92
|
+
const expandItems = useCallback(() => setItemsExpanded(true), []);
|
|
78
93
|
switch (block.type) {
|
|
79
94
|
case "heading":
|
|
80
95
|
{
|
|
@@ -116,25 +131,35 @@ const MarkdownBlock = /*#__PURE__*/memo(function MarkdownBlock({
|
|
|
116
131
|
})
|
|
117
132
|
});
|
|
118
133
|
case "list":
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
{
|
|
135
|
+
const visibleItems = itemsExpanded || block.items.length <= MAX_LIST_ITEMS ? block.items : block.items.slice(0, MAX_LIST_ITEMS);
|
|
136
|
+
const hiddenCount = block.items.length - visibleItems.length;
|
|
137
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
138
|
+
style: markdownListStructure(theme),
|
|
139
|
+
children: [visibleItems.map((item, itemIndex) => /*#__PURE__*/_jsxs(View, {
|
|
140
|
+
style: markdownListRowStructure(theme),
|
|
141
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
142
|
+
style: [theme.fontStyleForWeight(theme.fontWeights.regular), {
|
|
143
|
+
fontSize: theme.fontSizes.md,
|
|
144
|
+
color: colors.listMarker
|
|
145
|
+
}],
|
|
146
|
+
children: block.ordered ? `${itemIndex + 1}.` : "•"
|
|
147
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
148
|
+
style: [theme.fontStyleForWeight(theme.fontWeights.regular), styles.listContent, {
|
|
149
|
+
fontSize: theme.fontSizes.md,
|
|
150
|
+
color: colors.text
|
|
151
|
+
}],
|
|
152
|
+
children: renderInline(item, theme, colors, onLinkPress)
|
|
153
|
+
})]
|
|
154
|
+
}, itemIndex)), hiddenCount > 0 && /*#__PURE__*/_jsx(Button, {
|
|
155
|
+
variant: "link",
|
|
156
|
+
tone: "neutral",
|
|
157
|
+
size: "sm",
|
|
158
|
+
label: `+${hiddenCount} more items`,
|
|
159
|
+
onPress: expandItems
|
|
135
160
|
})]
|
|
136
|
-
}
|
|
137
|
-
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
138
163
|
default:
|
|
139
164
|
return /*#__PURE__*/_jsx(Text, {
|
|
140
165
|
style: [theme.fontStyleForWeight(theme.fontWeights.regular), {
|
|
@@ -155,15 +180,25 @@ export const Markdown = /*#__PURE__*/memo(function Markdown({
|
|
|
155
180
|
const colors = useMemo(() => resolveMarkdownColors(theme.colors), [theme.colors]);
|
|
156
181
|
const blocks = useMemo(() => parseMarkdown(content), [content]);
|
|
157
182
|
const rootStyle = useMemo(() => [markdownStructure(theme), style], [theme, style]);
|
|
158
|
-
|
|
183
|
+
const [blocksExpanded, setBlocksExpanded] = useState(false);
|
|
184
|
+
const expandBlocks = useCallback(() => setBlocksExpanded(true), []);
|
|
185
|
+
const visibleBlocks = blocksExpanded || blocks.length <= MAX_RENDERED_BLOCKS ? blocks : blocks.slice(0, MAX_RENDERED_BLOCKS);
|
|
186
|
+
const hiddenBlockCount = blocks.length - visibleBlocks.length;
|
|
187
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
159
188
|
testID: testID,
|
|
160
189
|
style: rootStyle,
|
|
161
|
-
children:
|
|
190
|
+
children: [visibleBlocks.map((block, index) => /*#__PURE__*/_jsx(MarkdownBlock, {
|
|
162
191
|
block: block,
|
|
163
192
|
theme: theme,
|
|
164
193
|
colors: colors,
|
|
165
194
|
onLinkPress: onLinkPress
|
|
166
|
-
}, `block-${index}-${block.type}`))
|
|
195
|
+
}, `block-${index}-${block.type}`)), hiddenBlockCount > 0 && /*#__PURE__*/_jsx(Button, {
|
|
196
|
+
variant: "outline",
|
|
197
|
+
tone: "neutral",
|
|
198
|
+
size: "sm",
|
|
199
|
+
label: `Show full document (${hiddenBlockCount} more)`,
|
|
200
|
+
onPress: expandBlocks
|
|
201
|
+
})]
|
|
167
202
|
});
|
|
168
203
|
});
|
|
169
204
|
const styles = StyleSheet.create({
|
|
@@ -49,7 +49,8 @@ export const markdownStructure = createThemedVariants(theme => ({
|
|
|
49
49
|
}));
|
|
50
50
|
export const markdownCodeBlockStructure = createThemedVariants(theme => ({
|
|
51
51
|
base: {
|
|
52
|
-
borderRadius: theme.radii.
|
|
52
|
+
borderRadius: theme.radii.md,
|
|
53
|
+
borderCurve: "continuous",
|
|
53
54
|
padding: theme.space[3]
|
|
54
55
|
}
|
|
55
56
|
}));
|
|
@@ -61,6 +61,7 @@ row size, since an action list's row height isn't a caller-facing choice.
|
|
|
61
61
|
menu row is never icon-only.
|
|
62
62
|
- **2.3.3** — the menu's `animationType` is `"none"` instead of `"fade"` when `useReducedMotion()`
|
|
63
63
|
is true, and the sheet's own scale/lift `setValue`s straight to rest (`Menu.motion.test.tsx`).
|
|
64
|
+
Row presses use `usePressState` (scale + state-layer overlay).
|
|
64
65
|
- Backdrop press closes the menu without calling any item's `onPress` — dismissal and selection are
|
|
65
66
|
two distinct code paths (`closeMenu` vs. `selectItem`), so a stray tap can never accidentally fire
|
|
66
67
|
an action.
|
|
@@ -127,6 +128,16 @@ supplied per row by `useSpaceActivation` (RNW's `isValidKeyPress` needs a `butto
|
|
|
127
128
|
|
|
128
129
|
Wrapped in `React.memo` (repo-wide re-render audit, 2026-07-17 — see root `CLAUDE.md`). `openMenu`/`closeMenu` are `useCallback`'d, and the inline `onPress` previously injected into the caller-supplied `trigger` via `cloneElement` on every render is extracted to `handleTriggerPress` (`useCallback`, deps `[trigger, openMenu]`) — `trigger` is a consumer-supplied child (typically this library's own `Button`), so a fresh callback there would defeat its memo. `selectItem` and the per-row `onPress` stay inline: they go to `Pressable`/`Icon` (host elements / primitive props), not a memoized child. The sheet subtree (backdrop + rows) is built only while `open` — a closed menu mounts nothing beyond the trigger. Rows are rendered with a plain `.map()` inside a `ScrollView` (not `FlatList`): action menus are short, and mounting a fresh `VirtualizedList` on the same commit as the modal fade-in was measurable open-time cost (~2× p50 in a Jest open benchmark for a 2-item list) with no windowing benefit at current call sites — `ScrollView` has no such per-open setup and still lets a list taller than the sheet's `maxHeight: 320` scroll, which a bare `.map()` with no scroll container would silently lose. Rows get `bg.sunken` press feedback (`resolveMenuRowPressedBackground`, same non-`bg.hover` reasoning as `RadioGroup`/`Accordion`), measured in `Menu.test.ts`.
|
|
129
130
|
|
|
131
|
+
## Round 5 motion
|
|
132
|
+
|
|
133
|
+
Dropped the ad hoc reanimated `FadeInDown` layer (per-row entrance, and the sheet's own former
|
|
134
|
+
entrance-only Reanimated bounce). `enter` (`core/motion`) now drives the sheet's scale/lift/opacity
|
|
135
|
+
AND the backdrop's fade together, and the web-portal path (no RN `<Modal>`) stays `mounted` through
|
|
136
|
+
a real timed exit instead of unmounting instantly — the RNModal path is unaffected, still gated on
|
|
137
|
+
`open` directly, since RN's own `animationType` already owns that surface's exit. `BACKDROP_SCRIM`'s
|
|
138
|
+
opacity now comes from the shared `MOTION_TRANSFORM.scrimOpacity` (previously a mismatched `0x99`
|
|
139
|
+
against Modal/Drawer/BottomSheet's `0x80`).
|
|
140
|
+
|
|
130
141
|
## Modernization (v1.0.7)
|
|
131
142
|
|
|
132
143
|
- Theme imports decoupled to `theme/hooks`; optional peers (reanimated, gesture-handler, flash-list) load at runtime.
|