@astryxdesign/core 0.4.5 → 0.4.6-canary.6a53e69
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/CHANGELOG.md +134 -0
- package/dist/Avatar/Avatar.d.ts +10 -5
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +139 -30
- package/dist/Avatar/AvatarStatusDot.d.ts +2 -1
- package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
- package/dist/Avatar/AvatarStatusDot.js +30 -4
- package/dist/Avatar/AvatarStatusLabelContext.d.ts +39 -0
- package/dist/Avatar/AvatarStatusLabelContext.d.ts.map +1 -0
- package/dist/Avatar/AvatarStatusLabelContext.js +41 -0
- package/dist/AvatarGroup/AvatarGroup.d.ts +3 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +15 -9
- package/dist/Blockquote/Blockquote.d.ts +4 -3
- package/dist/Blockquote/Blockquote.d.ts.map +1 -1
- package/dist/Blockquote/Blockquote.js +9 -10
- package/dist/BottomSheet/BottomSheet.d.ts +1 -0
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +37 -11
- package/dist/BottomSheet/BottomSheetEdgeTint.d.ts +6 -0
- package/dist/BottomSheet/BottomSheetEdgeTint.d.ts.map +1 -0
- package/dist/BottomSheet/BottomSheetEdgeTint.js +62 -0
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +22 -5
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts +1 -0
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +10 -4
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +23 -5
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +47 -34
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +7 -7
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +21 -12
- package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarNavigation.js +8 -4
- package/dist/Calendar/styles.d.ts +2 -2
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +5 -5
- package/dist/Center/Center.d.ts +23 -1
- package/dist/Center/Center.d.ts.map +1 -1
- package/dist/Center/Center.js +12 -6
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +3 -3
- package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
- package/dist/Chat/ChatComposerDrawer.js +2 -2
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +2 -2
- package/dist/Chat/useChatDictation.d.ts +1 -1
- package/dist/Chat/useChatDictation.d.ts.map +1 -1
- package/dist/Chat/useSpeechRecognition.d.ts +1 -1
- package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
- package/dist/Chat/useSpeechRecognition.js +4 -3
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +2 -2
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +2 -2
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +5 -5
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +4 -4
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +1 -1
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +2 -2
- package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteItem.js +3 -3
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +6 -6
- package/dist/DateInput/DateInput.d.ts +31 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +90 -22
- package/dist/DateInput/MonthScroller.d.ts +35 -0
- package/dist/DateInput/MonthScroller.d.ts.map +1 -0
- package/dist/DateInput/MonthScroller.js +658 -0
- package/dist/DateInput/MonthYearWheels.d.ts +24 -0
- package/dist/DateInput/MonthYearWheels.d.ts.map +1 -0
- package/dist/DateInput/MonthYearWheels.js +114 -0
- package/dist/DateInput/TouchDateField.d.ts +10 -0
- package/dist/DateInput/TouchDateField.d.ts.map +1 -0
- package/dist/DateInput/TouchDateField.js +810 -0
- package/dist/DateInput/Wheel.d.ts +41 -0
- package/dist/DateInput/Wheel.d.ts.map +1 -0
- package/dist/DateInput/Wheel.js +315 -0
- package/dist/DateInput/monthGeometry.d.ts +65 -0
- package/dist/DateInput/monthGeometry.d.ts.map +1 -0
- package/dist/DateInput/monthGeometry.js +98 -0
- package/dist/DateInput/tokens.stylex.d.ts +63 -0
- package/dist/DateInput/tokens.stylex.d.ts.map +1 -0
- package/dist/DateInput/tokens.stylex.js +74 -0
- package/dist/DateInput/useOwnScrollGesture.d.ts +41 -0
- package/dist/DateInput/useOwnScrollGesture.d.ts.map +1 -0
- package/dist/DateInput/useOwnScrollGesture.js +202 -0
- package/dist/DateInput/usePointerDragScroll.d.ts +15 -0
- package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -0
- package/dist/DateInput/usePointerDragScroll.js +216 -0
- package/dist/DateInput/useScrollSettle.d.ts +26 -0
- package/dist/DateInput/useScrollSettle.d.ts.map +1 -0
- package/dist/DateInput/useScrollSettle.js +149 -0
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +17 -14
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +17 -14
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +3 -3
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +2 -2
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +2 -2
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +2 -2
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +2 -2
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +4 -4
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +6 -0
- package/dist/Field/inputStyles.stylex.d.ts +1 -1
- package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
- package/dist/Field/inputStyles.stylex.js +5 -5
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +6 -6
- package/dist/HoverCard/HoverCard.d.ts +13 -3
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +2 -0
- package/dist/HoverCard/index.d.ts +1 -1
- package/dist/HoverCard/index.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.d.ts +17 -2
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +78 -9
- package/dist/InputGroup/InputGroup.js +1 -1
- package/dist/Item/Item.d.ts +9 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +52 -14
- package/dist/Layer/index.d.ts +4 -2
- package/dist/Layer/index.d.ts.map +1 -1
- package/dist/Layer/index.js +2 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +3 -2
- package/dist/Layer/useTouchTrigger.d.ts +113 -0
- package/dist/Layer/useTouchTrigger.d.ts.map +1 -0
- package/dist/Layer/useTouchTrigger.js +241 -0
- package/dist/Layout/container.stylex.d.ts +4 -2
- package/dist/Layout/container.stylex.d.ts.map +1 -1
- package/dist/Layout/container.stylex.js +19 -11
- package/dist/Layout/index.d.ts +1 -0
- package/dist/Layout/index.d.ts.map +1 -1
- package/dist/Layout/index.js +4 -0
- package/dist/Layout/padding.stylex.d.ts +315 -12
- package/dist/Layout/padding.stylex.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.js +389 -12
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +5 -4
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +6 -6
- package/dist/MetadataList/MetadataList.d.ts.map +1 -1
- package/dist/MetadataList/MetadataList.js +1 -1
- package/dist/MobileNav/MobileNav.d.ts +1 -0
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +24 -6
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +8 -8
- package/dist/NavItem/navItemStyles.stylex.d.ts +4 -4
- package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
- package/dist/NavItem/navItemStyles.stylex.js +4 -4
- package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenuItem.js +3 -3
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +36 -8
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +3 -3
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +2 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +11 -12
- package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchToken.js +3 -1
- package/dist/PowerSearch/formatFilterValue.d.ts +11 -2
- package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
- package/dist/PowerSearch/formatFilterValue.js +23 -8
- package/dist/RadioList/RadioListItem.d.ts +2 -2
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +70 -40
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +7 -7
- package/dist/Section/Section.d.ts +36 -1
- package/dist/Section/Section.d.ts.map +1 -1
- package/dist/Section/Section.js +12 -2
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +7 -2
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +3 -3
- package/dist/Selector/Selector.d.ts +26 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +93 -20
- package/dist/Selector/SelectorOption.d.ts +14 -1
- package/dist/Selector/SelectorOption.d.ts.map +1 -1
- package/dist/Selector/SelectorOption.js +6 -0
- package/dist/Selector/SelectorRowLayoutContext.d.ts +8 -0
- package/dist/Selector/SelectorRowLayoutContext.d.ts.map +1 -0
- package/dist/Selector/SelectorRowLayoutContext.js +27 -0
- package/dist/Selector/types.d.ts +1 -0
- package/dist/Selector/types.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +4 -4
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +3 -3
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +7 -7
- package/dist/Stack/Stack.d.ts +23 -1
- package/dist/Stack/Stack.d.ts.map +1 -1
- package/dist/Stack/Stack.js +12 -6
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +2 -2
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +6 -2
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +3 -3
- package/dist/Table/TableRow.js +4 -4
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.js +2 -2
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +2 -2
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +2 -2
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts +5 -3
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.js +12 -9
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.js +3 -3
- package/dist/TextArea/TextArea.js +1 -1
- package/dist/TextInput/TextInput.js +1 -1
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +3 -3
- package/dist/TimeInput/TimeInput.js +2 -2
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +6 -4
- package/dist/Timestamp/formatInstant.d.ts +3 -2
- package/dist/Timestamp/formatInstant.d.ts.map +1 -1
- package/dist/Timestamp/formatInstant.js +8 -8
- package/dist/Timestamp/tooltipEntries.d.ts +2 -1
- package/dist/Timestamp/tooltipEntries.d.ts.map +1 -1
- package/dist/Timestamp/tooltipEntries.js +5 -3
- package/dist/Toast/Toast.d.ts +4 -3
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +10 -7
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +6 -6
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +1 -1
- package/dist/Tooltip/Tooltip.d.ts +16 -3
- package/dist/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip/Tooltip.js +2 -0
- package/dist/Tooltip/index.d.ts +1 -1
- package/dist/Tooltip/index.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.d.ts +21 -2
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +71 -13
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +4 -4
- package/dist/TopNav/TopNavItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavItem.js +3 -3
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +2 -2
- package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuItem.js +2 -2
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +4 -4
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +7 -7
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +2 -2
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +1 -1
- package/dist/astryx.css +128 -62
- package/dist/hooks/containerReveal.stylex.d.ts.map +1 -1
- package/dist/hooks/containerReveal.stylex.js +18 -18
- package/dist/hooks/scrollbarGutter.d.ts +28 -0
- package/dist/hooks/scrollbarGutter.d.ts.map +1 -0
- package/dist/hooks/scrollbarGutter.js +103 -0
- package/dist/hooks/useAutoMediaMode.d.ts +31 -0
- package/dist/hooks/useAutoMediaMode.d.ts.map +1 -0
- package/dist/hooks/useAutoMediaMode.js +201 -0
- package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
- package/dist/hooks/useInputStatusIcon.js +1 -1
- package/dist/hooks/useListFocus.d.ts +5 -2
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +12 -6
- package/dist/hooks/useScrollLock.d.ts +4 -0
- package/dist/hooks/useScrollLock.d.ts.map +1 -1
- package/dist/hooks/useScrollLock.js +13 -1
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationContext.js +2 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +6 -0
- package/dist/i18n/useCollator.d.ts +12 -0
- package/dist/i18n/useCollator.d.ts.map +1 -0
- package/dist/i18n/useCollator.js +40 -0
- package/dist/i18n/useLocale.d.ts +3 -0
- package/dist/i18n/useLocale.d.ts.map +1 -0
- package/dist/i18n/useLocale.js +31 -0
- package/dist/theme/MediaTheme.d.ts +25 -5
- package/dist/theme/MediaTheme.d.ts.map +1 -1
- package/dist/theme/MediaTheme.js +31 -6
- package/dist/theme/defineTheme.d.ts +5 -0
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +5 -0
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +7 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +66 -5
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/syntax/index.d.ts +6 -0
- package/dist/theme/syntax/index.d.ts.map +1 -1
- package/dist/theme/syntax/index.js +7 -2
- package/dist/utils/dateParser.d.ts +4 -3
- package/dist/utils/dateParser.d.ts.map +1 -1
- package/dist/utils/dateParser.js +8 -8
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/plainDate.d.ts +5 -2
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +20 -4
- package/locales/en.json +28 -0
- package/locales/pseudo.json +21 -0
- package/package.json +3 -3
- package/src/Avatar/Avatar.doc.mjs +10 -6
- package/src/Avatar/Avatar.test.tsx +219 -1
- package/src/Avatar/Avatar.tsx +179 -37
- package/src/Avatar/AvatarStatusDot.tsx +30 -4
- package/src/Avatar/AvatarStatusLabelContext.ts +47 -0
- package/src/AvatarGroup/AvatarGroup.doc.mjs +10 -6
- package/src/AvatarGroup/AvatarGroup.test.tsx +62 -0
- package/src/AvatarGroup/AvatarGroup.tsx +3 -1
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +31 -8
- package/src/Banner/Banner.doc.mjs +2 -0
- package/src/Blockquote/Blockquote.doc.mjs +30 -7
- package/src/Blockquote/Blockquote.test.tsx +34 -3
- package/src/Blockquote/Blockquote.tsx +11 -9
- package/src/BottomSheet/BottomSheet.doc.mjs +3 -3
- package/src/BottomSheet/BottomSheet.test.tsx +24 -0
- package/src/BottomSheet/BottomSheet.tsx +19 -0
- package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +225 -0
- package/src/BottomSheet/BottomSheetEdgeTint.tsx +82 -0
- package/src/BottomSheet/BottomSheetPanel.test.tsx +157 -0
- package/src/BottomSheet/BottomSheetPanel.tsx +77 -3
- package/src/BottomSheet/BottomSheetSwitcher.tsx +13 -0
- package/src/BottomSheet/useSheetGestures.test.ts +27 -0
- package/src/BottomSheet/useSheetGestures.ts +25 -5
- package/src/Breadcrumbs/BreadcrumbItem.tsx +36 -23
- package/src/Breadcrumbs/Breadcrumbs.doc.mjs +26 -2
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -0
- package/src/Button/Button.tsx +12 -9
- package/src/Calendar/Calendar.tsx +15 -9
- package/src/Calendar/hooks/useCalendarNavigation.ts +6 -4
- package/src/Calendar/styles.ts +8 -5
- package/src/Center/Center.doc.mjs +48 -0
- package/src/Center/Center.test.tsx +158 -0
- package/src/Center/Center.tsx +50 -9
- package/src/Chat/ChatComposer.tsx +11 -5
- package/src/Chat/ChatComposerDrawer.tsx +4 -1
- package/src/Chat/ChatToolCalls.tsx +13 -4
- package/src/Chat/{useChatDictation.test.ts → useChatDictation.test.tsx} +29 -14
- package/src/Chat/useChatDictation.ts +1 -1
- package/src/Chat/useSpeechRecognition.ts +5 -3
- package/src/Chat/useTriggerMenu.tsx +4 -1
- package/src/CheckboxInput/CheckboxInput.tsx +5 -2
- package/src/Citation/Citation.test.tsx +6 -1
- package/src/Citation/Citation.tsx +11 -5
- package/src/ClickableCard/ClickableCard.tsx +7 -4
- package/src/CodeBlock/CodeBlock.tsx +4 -1
- package/src/Collapsible/Collapsible.tsx +5 -2
- package/src/CommandPalette/CommandPaletteItem.tsx +6 -3
- package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -0
- package/src/ComplexSelector/ComplexSelector.tsx +14 -7
- package/src/DateInput/DateInput.test.tsx +17 -1
- package/src/DateInput/DateInput.tsx +93 -21
- package/src/DateInput/DateInputTouch.test.tsx +2582 -0
- package/src/DateInput/MonthScroller.tsx +878 -0
- package/src/DateInput/MonthYearWheels.tsx +147 -0
- package/src/DateInput/TouchDateField.tsx +1223 -0
- package/src/DateInput/Wheel.tsx +473 -0
- package/src/DateInput/monthGeometry.ts +118 -0
- package/src/DateInput/tokens.stylex.ts +99 -0
- package/src/DateInput/useOwnScrollGesture.ts +227 -0
- package/src/DateInput/usePointerDragScroll.ts +220 -0
- package/src/DateInput/useScrollSettle.ts +164 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
- package/src/DateRangeInput/DateRangeInput.tsx +31 -13
- package/src/DateTimeInput/DateTimeInput.tsx +25 -9
- package/src/Dialog/Dialog.test.tsx +24 -0
- package/src/Dialog/Dialog.tsx +3 -0
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +5 -2
- package/src/DropdownMenu/DropdownMenuItem.tsx +5 -2
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +5 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +5 -2
- package/src/Field/Field.doc.mjs +2 -0
- package/src/Field/FieldLabel.tsx +9 -3
- package/src/Field/InputClearButton.test.tsx +110 -3
- package/src/Field/InputClearButton.tsx +38 -0
- package/src/Field/inputStyles.stylex.ts +17 -13
- package/src/FileInput/FileInput.tsx +15 -8
- package/src/FormLayout/FormLayout.doc.mjs +1 -1
- package/src/HoverCard/HoverCard.doc.mjs +18 -0
- package/src/HoverCard/HoverCard.test.tsx +189 -0
- package/src/HoverCard/HoverCard.tsx +22 -2
- package/src/HoverCard/index.ts +1 -0
- package/src/HoverCard/useHoverCard.doc.mjs +2 -0
- package/src/HoverCard/useHoverCard.tsx +103 -7
- package/src/InputGroup/InputGroup.tsx +1 -1
- package/src/Item/Item.doc.mjs +1 -0
- package/src/Item/Item.test.tsx +50 -0
- package/src/Item/Item.tsx +54 -6
- package/src/Layer/index.ts +10 -0
- package/src/Layer/useLayer.tsx +13 -2
- package/src/Layer/useTouchTrigger.test.ts +70 -0
- package/src/Layer/useTouchTrigger.ts +366 -0
- package/src/Layout/Layout.doc.mjs +18 -0
- package/src/Layout/container.stylex.ts +11 -3
- package/src/Layout/index.ts +4 -0
- package/src/Layout/overlayPaddingReset.test.tsx +222 -0
- package/src/Layout/padding.stylex.ts +192 -12
- package/src/Lightbox/Lightbox.tsx +11 -3
- package/src/Link/Link.tsx +9 -6
- package/src/MetadataList/MetadataList.tsx +4 -1
- package/src/MobileNav/MobileNav.tsx +61 -5
- package/src/MobileNav/MobileNavEntryAnimation.test.tsx +212 -0
- package/src/MobileNav/MobileNavScrollbarGutter.test.tsx +109 -0
- package/src/MultiSelector/MultiSelector.test.tsx +1 -1
- package/src/MultiSelector/MultiSelector.tsx +26 -10
- package/src/NavItem/navItemStyles.stylex.ts +7 -4
- package/src/NavMenu/NavHeadingMenuItem.tsx +6 -3
- package/src/NumberInput/NumberInput.doc.mjs +24 -0
- package/src/NumberInput/NumberInput.test.tsx +138 -0
- package/src/NumberInput/NumberInput.tsx +47 -8
- package/src/Outline/Outline.tsx +5 -2
- package/src/Pagination/Pagination.tsx +5 -2
- package/src/Popover/Popover.test.tsx +27 -1
- package/src/PowerSearch/PowerSearch.tsx +17 -8
- package/src/PowerSearch/PowerSearchToken.tsx +3 -0
- package/src/PowerSearch/formatFilterValue.test.ts +22 -2
- package/src/PowerSearch/formatFilterValue.ts +31 -6
- package/src/RadioList/RadioList.doc.mjs +1 -1
- package/src/RadioList/RadioList.test.tsx +170 -2
- package/src/RadioList/RadioListItem.tsx +88 -53
- package/src/Resizable/ResizeHandle.test.tsx +22 -0
- package/src/Resizable/ResizeHandle.tsx +25 -7
- package/src/Section/Section.doc.mjs +55 -0
- package/src/Section/Section.test.tsx +201 -4
- package/src/Section/Section.tsx +69 -0
- package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +15 -3
- package/src/SelectableCard/SelectableCard.tsx +6 -3
- package/src/Selector/Selector.doc.mjs +16 -2
- package/src/Selector/Selector.test.tsx +525 -1
- package/src/Selector/Selector.tsx +180 -25
- package/src/Selector/SelectorOption.doc.mjs +7 -0
- package/src/Selector/SelectorOption.tsx +21 -0
- package/src/Selector/SelectorRowLayoutContext.ts +32 -0
- package/src/Selector/types.ts +4 -4
- package/src/SideNav/SideNavHeading.tsx +14 -5
- package/src/SideNav/SideNavItem.tsx +9 -3
- package/src/Slider/Slider.tsx +25 -6
- package/src/Stack/Stack.doc.mjs +72 -0
- package/src/Stack/Stack.test.tsx +156 -0
- package/src/Stack/Stack.tsx +50 -8
- package/src/Switch/Switch.tsx +5 -2
- package/src/TabList/Tab.tsx +9 -2
- package/src/TabList/TabList.test.tsx +21 -4
- package/src/TabList/TabMenu.tsx +9 -3
- package/src/Table/TableRow.tsx +4 -4
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +6 -2
- package/src/Table/plugins/filtering/useTableFiltering.tsx +4 -1
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +10 -3
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +6 -3
- package/src/Table/plugins/sortable/useTableSortable.tsx +4 -1
- package/src/Table/plugins/sortable/useTableSortableState.test.tsx +34 -0
- package/src/Table/plugins/sortable/useTableSortableState.tsx +26 -23
- package/src/Table/plugins/tree/useTableTreeData.tsx +10 -4
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextArea/TextArea.tsx +1 -1
- package/src/TextInput/TextInput.tsx +1 -1
- package/src/Thumbnail/Thumbnail.tsx +9 -3
- package/src/TimeInput/TimeInput.tsx +1 -1
- package/src/Timestamp/Timestamp.test.tsx +27 -7
- package/src/Timestamp/Timestamp.tsx +8 -4
- package/src/Timestamp/formatInstant.ts +9 -7
- package/src/Timestamp/tooltipEntries.test.ts +11 -6
- package/src/Timestamp/tooltipEntries.ts +6 -2
- package/src/Toast/Toast.tsx +9 -7
- package/src/Token/Token.tsx +14 -5
- package/src/Tokenizer/Tokenizer.tsx +4 -1
- package/src/Tooltip/Tooltip.doc.mjs +18 -0
- package/src/Tooltip/Tooltip.test.tsx +254 -1
- package/src/Tooltip/Tooltip.tsx +22 -2
- package/src/Tooltip/index.ts +1 -0
- package/src/Tooltip/useTooltip.doc.mjs +2 -0
- package/src/Tooltip/useTooltip.tsx +99 -21
- package/src/TopNav/TopNavHeading.tsx +13 -4
- package/src/TopNav/TopNavItem.tsx +6 -3
- package/src/TopNav/TopNavMegaMenu.tsx +5 -2
- package/src/TopNav/TopNavMegaMenuItem.tsx +5 -2
- package/src/TopNav/TopNavMenu.tsx +10 -4
- package/src/TreeList/TreeListItem.tsx +22 -7
- package/src/Typeahead/BaseTypeahead.tsx +5 -2
- package/src/Typeahead/Typeahead.tsx +4 -1
- package/src/hooks/containerReveal.stylex.ts +54 -18
- package/src/hooks/scrollbarGutter.test.ts +167 -0
- package/src/hooks/scrollbarGutter.ts +121 -0
- package/src/hooks/useAutoMediaMode.test.ts +109 -0
- package/src/hooks/useAutoMediaMode.ts +233 -0
- package/src/hooks/useInputStatusIcon.tsx +4 -1
- package/src/hooks/useListFocus.doc.mjs +2 -2
- package/src/hooks/useListFocus.test.tsx +65 -3
- package/src/hooks/useListFocus.ts +15 -7
- package/src/hooks/useScrollLock.doc.mjs +4 -4
- package/src/hooks/useScrollLock.test.ts +73 -0
- package/src/hooks/useScrollLock.ts +14 -0
- package/src/i18n/InternationalizationContext.ts +2 -0
- package/src/i18n/__tests__/e2e-powersearch.test.tsx +37 -1
- package/src/i18n/__tests__/useCollator.test.tsx +115 -0
- package/src/i18n/__tests__/useLocale.test.tsx +52 -0
- package/src/i18n/index.ts +6 -0
- package/src/i18n/useCollator.doc.mjs +84 -0
- package/src/i18n/useCollator.ts +44 -0
- package/src/i18n/useLocale.doc.mjs +70 -0
- package/src/i18n/useLocale.ts +34 -0
- package/src/i18n/useTranslator.doc.mjs +1 -1
- package/src/reset.css +9 -2
- package/src/reset.test.ts +22 -0
- package/src/theme/MediaTheme.doc.mjs +23 -4
- package/src/theme/MediaTheme.dom.test.tsx +97 -0
- package/src/theme/MediaTheme.tsx +42 -7
- package/src/theme/defineTheme.test.ts +9 -3
- package/src/theme/defineTheme.ts +5 -0
- package/src/theme/derivedVarRegistry.test.ts +19 -5
- package/src/theme/derivedVarRegistry.ts +4 -0
- package/src/theme/generateThemeRules.test.ts +118 -0
- package/src/theme/generateThemeRules.ts +83 -5
- package/src/theme/index.ts +1 -1
- package/src/theme/syntax/index.ts +6 -2
- package/src/theme/syntax/serverSafeSyntax.test.ts +68 -0
- package/src/utils/dateParser.test.ts +20 -0
- package/src/utils/dateParser.ts +14 -7
- package/src/utils/index.ts +2 -0
- package/src/utils/plainDate.test.ts +6 -0
- package/src/utils/plainDate.ts +21 -4
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file BottomSheetEdgeTint.tsx
|
|
7
|
+
* @input Uses StyleX and core color tokens
|
|
8
|
+
* @output Exports BottomSheetEdgeTint, an internal decorative element
|
|
9
|
+
* @position Private helper rendered inside a non-modal BottomSheet dialog
|
|
10
|
+
*
|
|
11
|
+
* iOS 26 Safari dropped `<meta name="theme-color">` and instead derives the
|
|
12
|
+
* colour it paints behind its translucent toolbars by sampling the page: it
|
|
13
|
+
* hit tests a point just inside each viewport edge, walks up to the nearest
|
|
14
|
+
* `fixed`/`sticky` ancestor, and extends that element's declared
|
|
15
|
+
* `background-color` into the browser chrome.
|
|
16
|
+
*
|
|
17
|
+
* A modal sheet is served by that heuristic already — WebKit has a dedicated
|
|
18
|
+
* branch for a dialog's `::backdrop`. A non-modal sheet is not: the nearest
|
|
19
|
+
* fixed ancestor of the panel is the sheet's own full-viewport `<dialog>`,
|
|
20
|
+
* which is transparent and viewport-sized, and WebKit answers a viewport-sized
|
|
21
|
+
* candidate by *keeping the colour it already had* — the host page's. The page
|
|
22
|
+
* then shows through behind the address bar while the sheet covers the screen
|
|
23
|
+
* above it.
|
|
24
|
+
*
|
|
25
|
+
* This element gives the heuristic something unambiguous to sample: fixed,
|
|
26
|
+
* full width, flush with the bottom edge, taller than WebKit's 10px minimum
|
|
27
|
+
* for reading a declared colour, and painted in the sheet's own surface
|
|
28
|
+
* colour. It is masked out so it never renders for the user; Safari reads the
|
|
29
|
+
* computed style, not the painted pixels.
|
|
30
|
+
*
|
|
31
|
+
* Everywhere else it is inert decoration.
|
|
32
|
+
*
|
|
33
|
+
* SYNC: When modified, update these files to stay in sync:
|
|
34
|
+
* - /packages/core/src/BottomSheet/BottomSheet.tsx
|
|
35
|
+
* - /packages/core/src/BottomSheet/BottomSheetSwitcher.tsx
|
|
36
|
+
* - /packages/core/src/BottomSheet/BottomSheetEdgeTint.test.tsx
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
import * as stylex from '@stylexjs/stylex';
|
|
40
|
+
import {colorVars} from '../theme/tokens.stylex';
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* WebKit ignores the declared `background-color` of a sampled box thinner than
|
|
44
|
+
* 10px and falls back to sampling painted pixels, which a masked element has
|
|
45
|
+
* none of. 12px clears that floor with room to spare and is still far below
|
|
46
|
+
* the ~40px of chrome it colours.
|
|
47
|
+
*/
|
|
48
|
+
const SAMPLE_HEIGHT_PX = 12;
|
|
49
|
+
|
|
50
|
+
const styles = stylex.create({
|
|
51
|
+
tint: {
|
|
52
|
+
position: 'fixed',
|
|
53
|
+
insetInline: 0,
|
|
54
|
+
insetBlockEnd: 0,
|
|
55
|
+
height: `${SAMPLE_HEIGHT_PX}px`,
|
|
56
|
+
backgroundColor: colorVars['--color-background-surface'],
|
|
57
|
+
// Above the panel so the edge hit test lands here, and never in the way of
|
|
58
|
+
// a touch that was meant for the sheet.
|
|
59
|
+
zIndex: 2,
|
|
60
|
+
pointerEvents: 'none',
|
|
61
|
+
// Invisible to the user. WebKit's sampler checks `visibility` and
|
|
62
|
+
// `opacity` — either would disqualify the element — but not `mask`, so
|
|
63
|
+
// this hides the strip while leaving the colour readable. Without it the
|
|
64
|
+
// strip would show as a hairline under the panel as the sheet slides out.
|
|
65
|
+
maskImage: 'linear-gradient(transparent, transparent)',
|
|
66
|
+
WebkitMaskImage: 'linear-gradient(transparent, transparent)',
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Colours the iOS Safari toolbar strip below a non-modal sheet. Renders
|
|
72
|
+
* nothing visible; see the file header for why it exists.
|
|
73
|
+
*/
|
|
74
|
+
export function BottomSheetEdgeTint() {
|
|
75
|
+
return (
|
|
76
|
+
<div
|
|
77
|
+
{...stylex.props(styles.tint)}
|
|
78
|
+
data-sheet-edge-tint=""
|
|
79
|
+
aria-hidden="true"
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
@@ -237,4 +237,161 @@ describe('BottomSheetPanel', () => {
|
|
|
237
237
|
expect(panelRef).toHaveBeenLastCalledWith(null);
|
|
238
238
|
expect(panelRef).toHaveBeenCalledTimes(2);
|
|
239
239
|
});
|
|
240
|
+
|
|
241
|
+
it('floats the handle bar over content that starts at the sheet top edge', () => {
|
|
242
|
+
renderPanel({kind: 'open', entering: false});
|
|
243
|
+
|
|
244
|
+
const bar = getPanel().querySelector<HTMLElement>(
|
|
245
|
+
'div[aria-hidden="true"]',
|
|
246
|
+
);
|
|
247
|
+
if (bar == null) {
|
|
248
|
+
throw new Error('handle bar not found');
|
|
249
|
+
}
|
|
250
|
+
const body = bar.nextElementSibling as HTMLElement;
|
|
251
|
+
|
|
252
|
+
// Out of flow: the bar costs the content no layout space. That is the
|
|
253
|
+
// point of it -- the content sits closer to the sheet's top edge, and
|
|
254
|
+
// scrolled content passes beneath the pill rather than stopping at a
|
|
255
|
+
// hard edge.
|
|
256
|
+
expect(getComputedStyle(bar).position).toBe('absolute');
|
|
257
|
+
|
|
258
|
+
// So the body must not reserve room for it. A top padding here would
|
|
259
|
+
// push the content back down and undo the change.
|
|
260
|
+
expect(getComputedStyle(body).paddingTop).toBe('');
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// The pill is only legible over the content riding up beneath it because
|
|
264
|
+
// the bar carries a backdrop; without it, text runs straight through the
|
|
265
|
+
// pill. jsdom's StyleX runtime does not inject the rule, so assert on the
|
|
266
|
+
// style definition itself (same approach as AspectRatio's reset.css tests).
|
|
267
|
+
it('backs the floating handle bar with a surface gradient', async () => {
|
|
268
|
+
const fs = await import('fs');
|
|
269
|
+
const path = await import('path');
|
|
270
|
+
const source = fs.readFileSync(
|
|
271
|
+
path.resolve(__dirname, './BottomSheetPanel.tsx'),
|
|
272
|
+
'utf-8',
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
const handleBar = source.match(/handleBar: \{([\s\S]*?)\n {2}\},/);
|
|
276
|
+
expect(handleBar).not.toBeNull();
|
|
277
|
+
expect(handleBar![1]).toContain("position: 'absolute'");
|
|
278
|
+
expect(handleBar![1]).toContain('linear-gradient(to bottom');
|
|
279
|
+
expect(handleBar![1]).toContain("colorVars['--color-background-surface']");
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// In dark mode the surface fill and the scrim sit a few RGB steps apart and
|
|
283
|
+
// the drop shadow is black on near-black, so the fill alone leaves the
|
|
284
|
+
// sheet's left and right edges invisible against the scrim. A hairline on
|
|
285
|
+
// the scrim-facing edges is what draws them. Asserted on the style
|
|
286
|
+
// definition for the same reason as the test above.
|
|
287
|
+
it('draws a hairline on the three edges that face the scrim', async () => {
|
|
288
|
+
const fs = await import('fs');
|
|
289
|
+
const path = await import('path');
|
|
290
|
+
const source = fs.readFileSync(
|
|
291
|
+
path.resolve(__dirname, './BottomSheetPanel.tsx'),
|
|
292
|
+
'utf-8',
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
const sheet = source.match(/\n {2}sheet: \{([\s\S]*?)\n {2}\},/);
|
|
296
|
+
expect(sheet).not.toBeNull();
|
|
297
|
+
for (const edge of [
|
|
298
|
+
'borderBlockStart',
|
|
299
|
+
'borderInlineStart',
|
|
300
|
+
'borderInlineEnd',
|
|
301
|
+
]) {
|
|
302
|
+
expect(sheet![1]).toContain(`${edge}Width: borderVars['--border-width']`);
|
|
303
|
+
expect(sheet![1]).toContain(`${edge}Style: 'solid'`);
|
|
304
|
+
expect(sheet![1]).toContain(`${edge}Color: colorVars['--color-border']`);
|
|
305
|
+
}
|
|
306
|
+
// The block-end edge sits below the viewport, under the overscroll
|
|
307
|
+
// padding, so it carries no hairline to draw.
|
|
308
|
+
expect(sheet![1]).not.toContain('borderBlockEndWidth');
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// A theme that packs an inset ring into --shadow-high (the bundled themes all
|
|
312
|
+
// add one in dark mode) draws it just inside the sheet, where an opaque
|
|
313
|
+
// content wrapper such as Section paints over it -- so it showed only in the
|
|
314
|
+
// gap below the content and the side edges appeared to change width partway
|
|
315
|
+
// down. The scrolling body paints the surface across the whole inner box to
|
|
316
|
+
// hide the ring evenly.
|
|
317
|
+
it('paints the surface across the scrolling body so the edge stays uniform', async () => {
|
|
318
|
+
const fs = await import('fs');
|
|
319
|
+
const path = await import('path');
|
|
320
|
+
const source = fs.readFileSync(
|
|
321
|
+
path.resolve(__dirname, './BottomSheetPanel.tsx'),
|
|
322
|
+
'utf-8',
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
const body = source.match(/\n {2}body: \{([\s\S]*?)\n {2}\},/);
|
|
326
|
+
expect(body).not.toBeNull();
|
|
327
|
+
expect(body![1]).toContain(
|
|
328
|
+
"backgroundColor: colorVars['--color-background-surface']",
|
|
329
|
+
);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* The exit is not the entrance played backwards.
|
|
334
|
+
*
|
|
335
|
+
* `--ease-standard` is a decelerate curve: on it the sheet was half gone in
|
|
336
|
+
* 59ms of a 410ms transition and 90% gone in 163ms, so the close was over
|
|
337
|
+
* before it could be seen. The closing state therefore carries its own
|
|
338
|
+
* accelerating curve, and only the closing state does.
|
|
339
|
+
*/
|
|
340
|
+
it('closes on an accelerating curve of its own, not the entrance timing', () => {
|
|
341
|
+
const declarationsFor = (element: HTMLElement) => {
|
|
342
|
+
const classes = new Set(element.className.split(/\s+/));
|
|
343
|
+
const out: string[] = [];
|
|
344
|
+
for (const styleSheet of Array.from(document.styleSheets)) {
|
|
345
|
+
let rules: CSSRuleList;
|
|
346
|
+
try {
|
|
347
|
+
rules = styleSheet.cssRules;
|
|
348
|
+
} catch {
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
for (const rule of Array.from(rules)) {
|
|
352
|
+
const selector = (rule as CSSStyleRule).selectorText;
|
|
353
|
+
const owner = selector?.match(/^\.([\w-]+)/)?.[1];
|
|
354
|
+
if (owner != null && classes.has(owner)) {
|
|
355
|
+
out.push(rule.cssText);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return out.join('\n');
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
const {container: closing} = render(
|
|
363
|
+
<BottomSheetPanel
|
|
364
|
+
state={{kind: 'exiting'}}
|
|
365
|
+
height="hug"
|
|
366
|
+
onDismiss={() => {}}
|
|
367
|
+
onScrimOpacity={() => {}}>
|
|
368
|
+
Panel content
|
|
369
|
+
</BottomSheetPanel>,
|
|
370
|
+
);
|
|
371
|
+
const closingRules = declarationsFor(
|
|
372
|
+
closing.querySelector('.astryx-bottom-sheet') as HTMLElement,
|
|
373
|
+
);
|
|
374
|
+
// An accelerating curve: no vertical rise at the start (y1 = 0), so the
|
|
375
|
+
// travel lands inside the duration instead of ahead of it.
|
|
376
|
+
expect(closingRules).toContain(
|
|
377
|
+
'transition-timing-function: cubic-bezier(.3,0,.6,.6)',
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
const {container: resting} = render(
|
|
381
|
+
<BottomSheetPanel
|
|
382
|
+
state={{kind: 'open', entering: false}}
|
|
383
|
+
height="hug"
|
|
384
|
+
onDismiss={() => {}}
|
|
385
|
+
onScrimOpacity={() => {}}>
|
|
386
|
+
Panel content
|
|
387
|
+
</BottomSheetPanel>,
|
|
388
|
+
);
|
|
389
|
+
const restingRules = declarationsFor(
|
|
390
|
+
resting.querySelector('.astryx-bottom-sheet') as HTMLElement,
|
|
391
|
+
);
|
|
392
|
+
expect(restingRules).toContain(
|
|
393
|
+
'transition-timing-function: var(--ease-standard)',
|
|
394
|
+
);
|
|
395
|
+
expect(restingRules).not.toContain('cubic-bezier(.3,0,.6,.6)');
|
|
396
|
+
});
|
|
240
397
|
});
|
|
@@ -34,6 +34,7 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
34
34
|
import type {BaseProps} from '../BaseProps';
|
|
35
35
|
import {useDevWarning} from '../hooks';
|
|
36
36
|
import {
|
|
37
|
+
borderVars,
|
|
37
38
|
colorVars,
|
|
38
39
|
durationVars,
|
|
39
40
|
easeVars,
|
|
@@ -43,6 +44,7 @@ import {
|
|
|
43
44
|
spacingVars,
|
|
44
45
|
} from '../theme/tokens.stylex';
|
|
45
46
|
import {mergeProps, themeProps} from '../utils';
|
|
47
|
+
import {overlayPaddingReset} from '../Layout/padding.stylex';
|
|
46
48
|
import {
|
|
47
49
|
isValidSnapPoint,
|
|
48
50
|
resolveSnapPoints,
|
|
@@ -64,6 +66,11 @@ export type {BottomSheetSnapPoint};
|
|
|
64
66
|
const OVERSCROLL_PADDING = 48;
|
|
65
67
|
const MOBILE_KEYBOARD_BOTTOM_CLEARANCE = 48;
|
|
66
68
|
const TRANSITION_BACKSTOP_BUFFER_MS = 50;
|
|
69
|
+
// The floating handle bar's height. The bar is out of flow, so this is not
|
|
70
|
+
// layout space the content pays for -- the pill (4px, centered) lands 10-14px
|
|
71
|
+
// from the sheet's top edge, inside the space a content wrapper's own top
|
|
72
|
+
// padding already provides.
|
|
73
|
+
const HANDLE_BAR_HEIGHT = spacingVars['--spacing-6'];
|
|
67
74
|
|
|
68
75
|
// Measure the same viewport the height budgets are written against. Those are
|
|
69
76
|
// `dvh`, which the virtual keyboard does not shrink, so reading
|
|
@@ -97,12 +104,31 @@ const styles = stylex.create({
|
|
|
97
104
|
sheet: {
|
|
98
105
|
pointerEvents: 'auto',
|
|
99
106
|
boxSizing: 'border-box',
|
|
107
|
+
// Containing block for the floating handle bar, which is lifted out of
|
|
108
|
+
// flow so the scrolling body reaches the sheet's top edge.
|
|
109
|
+
position: 'relative',
|
|
100
110
|
display: 'flex',
|
|
101
111
|
flexDirection: 'column',
|
|
102
112
|
minHeight: 0,
|
|
103
113
|
width: '100%',
|
|
104
114
|
maxWidth: 640,
|
|
105
115
|
backgroundColor: colorVars['--color-background-surface'],
|
|
116
|
+
// Hairline on the three edges that face the scrim. The surface fill alone
|
|
117
|
+
// separates sheet from scrim in light mode, but not in dark: there the two
|
|
118
|
+
// sit within a few RGB steps of each other and the drop shadow is black on
|
|
119
|
+
// near-black, so the sheet's left and right edges disappear. Same
|
|
120
|
+
// treatment MobileNav gives its scrim-facing edge. The block-end edge is
|
|
121
|
+
// deliberately left bare; it sits below the viewport, under the overscroll
|
|
122
|
+
// padding.
|
|
123
|
+
borderBlockStartWidth: borderVars['--border-width'],
|
|
124
|
+
borderBlockStartStyle: 'solid',
|
|
125
|
+
borderBlockStartColor: colorVars['--color-border'],
|
|
126
|
+
borderInlineStartWidth: borderVars['--border-width'],
|
|
127
|
+
borderInlineStartStyle: 'solid',
|
|
128
|
+
borderInlineStartColor: colorVars['--color-border'],
|
|
129
|
+
borderInlineEndWidth: borderVars['--border-width'],
|
|
130
|
+
borderInlineEndStyle: 'solid',
|
|
131
|
+
borderInlineEndColor: colorVars['--color-border'],
|
|
106
132
|
borderStartStartRadius: radiusVars['--radius-container'],
|
|
107
133
|
borderStartEndRadius: radiusVars['--radius-container'],
|
|
108
134
|
boxShadow: shadowVars['--shadow-high'],
|
|
@@ -123,8 +149,27 @@ const styles = stylex.create({
|
|
|
123
149
|
transitionDuration: '0.01s',
|
|
124
150
|
},
|
|
125
151
|
},
|
|
152
|
+
/**
|
|
153
|
+
* The exit is its own motion, not the entrance played backwards.
|
|
154
|
+
*
|
|
155
|
+
* `--ease-standard` is `cubic-bezier(0.24, 1, 0.4, 1)`, a decelerate curve:
|
|
156
|
+
* it spends its speed immediately and coasts. That is right for an entrance,
|
|
157
|
+
* where the sheet arrives fast and settles, and wrong for an exit. Measured
|
|
158
|
+
* on device, it put the sheet half off-screen in 59ms of a 410ms close and
|
|
159
|
+
* 90% off in 163ms -- the travel is over before the eye has followed it, and
|
|
160
|
+
* the rest of the duration moves pixels already below the fold.
|
|
161
|
+
*
|
|
162
|
+
* An exit accelerates instead: away from rest, gathering speed, quickest as
|
|
163
|
+
* it leaves the screen. The curve is deliberately gentle rather than a hard
|
|
164
|
+
* `ease-in` -- it is moving within ~50ms, so the close reads as one
|
|
165
|
+
* departure rather than a hesitation and a snap. The duration is the
|
|
166
|
+
* entrance's own band, so only the curve differs between the two
|
|
167
|
+
* directions; a shorter band leaves too little visible travel once a theme
|
|
168
|
+
* scales the motion scale down (neutral's medium is 300ms against 410ms).
|
|
169
|
+
*/
|
|
126
170
|
sheetClosing: {
|
|
127
171
|
transform: 'translateY(100%)',
|
|
172
|
+
transitionTimingFunction: 'cubic-bezier(0.3, 0, 0.6, 0.6)',
|
|
128
173
|
},
|
|
129
174
|
sheetFading: {
|
|
130
175
|
opacity: 0,
|
|
@@ -133,13 +178,28 @@ const styles = stylex.create({
|
|
|
133
178
|
pointerEvents: 'none',
|
|
134
179
|
},
|
|
135
180
|
handleBar: {
|
|
136
|
-
|
|
181
|
+
// Floats over the body rather than taking a row in the flex column. The
|
|
182
|
+
// content starts at the sheet's top edge and rides up under the pill --
|
|
183
|
+
// both moving it closer to the top and letting scrolled content pass
|
|
184
|
+
// beneath instead of stopping at a hard edge.
|
|
185
|
+
position: 'absolute',
|
|
186
|
+
insetBlockStart: 0,
|
|
187
|
+
insetInlineStart: 0,
|
|
188
|
+
insetInlineEnd: 0,
|
|
189
|
+
zIndex: 1,
|
|
137
190
|
display: 'flex',
|
|
138
191
|
alignItems: 'center',
|
|
139
192
|
justifyContent: 'center',
|
|
140
|
-
height:
|
|
193
|
+
height: HANDLE_BAR_HEIGHT,
|
|
194
|
+
// Keeps the pill legible over whatever sits or scrolls under it: opaque
|
|
195
|
+
// surface behind the pill itself, fading out across the lower half so the
|
|
196
|
+
// content emerging below has no visible cut line.
|
|
197
|
+
backgroundImage: `linear-gradient(to bottom, ${colorVars['--color-background-surface']} 60%, transparent)`,
|
|
141
198
|
touchAction: 'none',
|
|
142
|
-
cursor:
|
|
199
|
+
cursor: {
|
|
200
|
+
default: 'grab',
|
|
201
|
+
':is(:disabled,[aria-disabled="true"])': 'default',
|
|
202
|
+
},
|
|
143
203
|
},
|
|
144
204
|
handlePill: {
|
|
145
205
|
width: sizeVars['--size-element-lg'],
|
|
@@ -154,6 +214,19 @@ const styles = stylex.create({
|
|
|
154
214
|
overflowY: 'auto',
|
|
155
215
|
overscrollBehavior: 'none',
|
|
156
216
|
touchAction: 'pan-y',
|
|
217
|
+
// The scrolling area paints the surface itself, covering the sheet's whole
|
|
218
|
+
// inner box. Without it the sheet's edge is not uniform: a theme that packs
|
|
219
|
+
// an inset ring into --shadow-high (the bundled themes all add one in dark
|
|
220
|
+
// mode) draws that ring just inside the sheet, where an opaque content
|
|
221
|
+
// wrapper such as Section paints over it -- so the ring shows only in the
|
|
222
|
+
// gap below where the content ends, and the sheet's side edges appear to
|
|
223
|
+
// change width partway down. Painting the surface here hides the ring
|
|
224
|
+
// evenly, leaving the border below as the sheet's one edge.
|
|
225
|
+
backgroundColor: colorVars['--color-background-surface'],
|
|
226
|
+
// No reserve for the handle bar: it floats, so the content starts at the
|
|
227
|
+
// sheet's top edge and rides up under the pill. The pill is 4px centered
|
|
228
|
+
// in a 24px band, so it occupies only 10-14px from the edge -- inside the
|
|
229
|
+
// space a content wrapper's own top padding already provides.
|
|
157
230
|
paddingBlockEnd: 0,
|
|
158
231
|
},
|
|
159
232
|
tallKeyboardBody: {
|
|
@@ -556,6 +629,7 @@ export function BottomSheetPanel({
|
|
|
556
629
|
themeProps('bottom-sheet'),
|
|
557
630
|
stylex.props(
|
|
558
631
|
styles.sheet,
|
|
632
|
+
overlayPaddingReset.reset,
|
|
559
633
|
height === 'hug' ? styles.hugHeight : styles.budget,
|
|
560
634
|
isClosing && styles.sheetClosing,
|
|
561
635
|
isFading && styles.sheetFading,
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*
|
|
23
23
|
* SYNC: When modified, update these files to stay in sync:
|
|
24
24
|
* - /packages/core/src/BottomSheet/BottomSheet.tsx
|
|
25
|
+
* - /packages/core/src/BottomSheet/BottomSheetEdgeTint.tsx
|
|
25
26
|
* - /packages/core/src/BottomSheet/BottomSheetSwitcher.doc.mjs
|
|
26
27
|
* - /packages/core/src/BottomSheet/BottomSheetSwitcher.test.tsx
|
|
27
28
|
* - /packages/core/src/BottomSheet/index.ts
|
|
@@ -51,6 +52,7 @@ import {
|
|
|
51
52
|
useScrollLock,
|
|
52
53
|
} from '../hooks';
|
|
53
54
|
import {composeEventHandlers, mergeProps, mergeRefs} from '../utils';
|
|
55
|
+
import {BottomSheetEdgeTint} from './BottomSheetEdgeTint';
|
|
54
56
|
import {
|
|
55
57
|
BottomSheetSwitcherContext,
|
|
56
58
|
type BottomSheetSwitcherContextValue,
|
|
@@ -103,6 +105,14 @@ const styles = stylex.create({
|
|
|
103
105
|
},
|
|
104
106
|
},
|
|
105
107
|
},
|
|
108
|
+
// The flow's dim leaves with its last panel. Same rule, same reasoning, as
|
|
109
|
+
// a standalone sheet's -- see `scrimClosing` in BottomSheet.tsx. A handoff
|
|
110
|
+
// between two sheets is not a close, and keeps the entrance curve.
|
|
111
|
+
scrimClosing: {
|
|
112
|
+
'::backdrop': {
|
|
113
|
+
transitionTimingFunction: 'linear',
|
|
114
|
+
},
|
|
115
|
+
},
|
|
106
116
|
});
|
|
107
117
|
|
|
108
118
|
type RetainedSheetPhase = 'covered' | 'aligning' | 'fading' | 'exiting';
|
|
@@ -593,6 +603,7 @@ export function BottomSheetSwitcher({
|
|
|
593
603
|
styles.dialog,
|
|
594
604
|
isFlowVisible && styles.dialogOpen,
|
|
595
605
|
hasScrim && styles.scrim,
|
|
606
|
+
hasScrim && isFlowVisible && activeSheet == null && styles.scrimClosing,
|
|
596
607
|
!hasScrim && styles.dialogNonModal,
|
|
597
608
|
xstyle,
|
|
598
609
|
);
|
|
@@ -620,6 +631,8 @@ export function BottomSheetSwitcher({
|
|
|
620
631
|
? {role: 'alertdialog'}
|
|
621
632
|
: undefined)}>
|
|
622
633
|
{children}
|
|
634
|
+
{/* A modal flow's ::backdrop already answers Safari's edge sampler. */}
|
|
635
|
+
{hasScrim ? null : <BottomSheetEdgeTint />}
|
|
623
636
|
</dialog>
|
|
624
637
|
</BottomSheetSwitcherContext>
|
|
625
638
|
);
|
|
@@ -530,6 +530,33 @@ describe('useSheetGestures', () => {
|
|
|
530
530
|
expect(hook.result.current.dragOffset).toBe(40);
|
|
531
531
|
});
|
|
532
532
|
|
|
533
|
+
/**
|
|
534
|
+
* A finger is never still. Tapping a control inside the sheet drifts a
|
|
535
|
+
* pixel or two, and with no slop that drift promoted to a sheet drag —
|
|
536
|
+
* which wrote `transition: none` onto the panel across the release, so the
|
|
537
|
+
* close the tap triggered cut instead of animating. That is the "the sheet
|
|
538
|
+
* closes with no animation" report: only on a tap, and only on a tap
|
|
539
|
+
* inside the sheet (the scrim never arms a drag).
|
|
540
|
+
*/
|
|
541
|
+
it('treats a few pixels of finger drift as a tap, not a drag', () => {
|
|
542
|
+
const {hook} = setup({snapHeights: () => [200]});
|
|
543
|
+
const body = makeBody(0); // at the top, where a pull-down would promote
|
|
544
|
+
bodyDown(hook, 0, 0, body);
|
|
545
|
+
bodyMove(hook, 3, 40, body); // the drift of a finger tapping a button
|
|
546
|
+
expect(hook.result.current.isDragging).toBe(false);
|
|
547
|
+
// and nothing suppressed the panel's transition, so a close that lands
|
|
548
|
+
// now still animates
|
|
549
|
+
expect(hook.result.current.contentProps.style.transition).toBeUndefined();
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
it('still promotes once the pull passes the tap slop', () => {
|
|
553
|
+
const {hook} = setup({snapHeights: () => [200]});
|
|
554
|
+
const body = makeBody(0);
|
|
555
|
+
bodyDown(hook, 0, 0, body);
|
|
556
|
+
bodyMove(hook, 9, 40, body); // just past the 8px slop
|
|
557
|
+
expect(hook.result.current.isDragging).toBe(true);
|
|
558
|
+
});
|
|
559
|
+
|
|
533
560
|
it('does not hijack scrolling when the body is scrolled down', () => {
|
|
534
561
|
const {hook} = setup({snapHeights: () => [200]});
|
|
535
562
|
const body = makeBody(120); // scrolled, not at the top
|
|
@@ -118,6 +118,20 @@ const OVERSCROLL_MAX = 48;
|
|
|
118
118
|
// the scroll, large enough that a swipe merely coming to rest on the last pixel
|
|
119
119
|
// doesn't start a drag on jitter.
|
|
120
120
|
const CONTENT_END_HANDOFF_SLOP = 4;
|
|
121
|
+
// How far a finger resting on the body must travel before the pull becomes a
|
|
122
|
+
// sheet drag rather than a tap.
|
|
123
|
+
//
|
|
124
|
+
// This used to be zero: any downward movement promoted. A finger is never
|
|
125
|
+
// still, so tapping a control inside the sheet drifted a pixel or two and
|
|
126
|
+
// started a drag -- which suppresses the panel's transition, correctly, for as
|
|
127
|
+
// long as the sheet is tracking the finger. The close that the tap triggered
|
|
128
|
+
// then landed inside that window and cut instead of animating. A deliberate
|
|
129
|
+
// pull was unaffected; only a tap, and only a tap inside the sheet, since the
|
|
130
|
+
// scrim is outside the body and arms nothing.
|
|
131
|
+
//
|
|
132
|
+
// 8px is the conventional tap slop, a shade over iOS's own recognizer, and
|
|
133
|
+
// well under what a real pull covers in its first frames.
|
|
134
|
+
const DRAG_PROMOTION_SLOP = 8;
|
|
121
135
|
|
|
122
136
|
// Short haptic tick on detent settle where supported. iOS Safari doesn't
|
|
123
137
|
// expose navigator.vibrate, so this is a no-op there; skipped under
|
|
@@ -1140,7 +1154,7 @@ export function useSheetGestures({
|
|
|
1140
1154
|
return;
|
|
1141
1155
|
}
|
|
1142
1156
|
const delta = event.clientY - armed.startCoord;
|
|
1143
|
-
if (delta >
|
|
1157
|
+
if (delta > DRAG_PROMOTION_SLOP && armed.scroller.scrollTop <= 0) {
|
|
1144
1158
|
// Downward pull at the top: promote to a sheet drag, anchored at the
|
|
1145
1159
|
// original pointer-down position so the pull distance carries over.
|
|
1146
1160
|
armedBodyRef.current = null;
|
|
@@ -1302,8 +1316,10 @@ export function useSheetGestures({
|
|
|
1302
1316
|
// no longer scroll that way: at the top, a downward pull (delta > 0)
|
|
1303
1317
|
// collapses; at the bottom, an upward pull (delta < 0) expands. The
|
|
1304
1318
|
// opposite direction is a real scroll, so disarm and let it through.
|
|
1305
|
-
const pullDownAtTop =
|
|
1306
|
-
|
|
1319
|
+
const pullDownAtTop =
|
|
1320
|
+
armed.top && delta > DRAG_PROMOTION_SLOP && atTop(scroller);
|
|
1321
|
+
const pullUpAtBottom =
|
|
1322
|
+
armed.bottom && delta < -DRAG_PROMOTION_SLOP && atBottom(scroller);
|
|
1307
1323
|
if (pullDownAtTop || pullUpAtBottom) {
|
|
1308
1324
|
event.preventDefault();
|
|
1309
1325
|
touchDragRef.current = null;
|
|
@@ -1433,15 +1449,19 @@ export function useSheetGestures({
|
|
|
1433
1449
|
style: {
|
|
1434
1450
|
transform:
|
|
1435
1451
|
activeOffset !== 0 ? `translateY(${activeOffset}px)` : undefined,
|
|
1452
|
+
// Gated on the sheet being up: suppression must not outlive the sheet
|
|
1453
|
+
// it was suppressing for. The host swaps the panel to its closing
|
|
1454
|
+
// state in whatever frame the dismissal lands, and a stale `none`
|
|
1455
|
+
// would apply to that transform too, cutting the exit.
|
|
1436
1456
|
transition:
|
|
1437
|
-
isDragging || isScrollAreaReconciling || reducedMotion
|
|
1457
|
+
isOpen && (isDragging || isScrollAreaReconciling || reducedMotion)
|
|
1438
1458
|
? 'none'
|
|
1439
1459
|
: undefined,
|
|
1440
1460
|
touchAction: 'none',
|
|
1441
1461
|
overscrollBehavior: 'contain',
|
|
1442
1462
|
},
|
|
1443
1463
|
}),
|
|
1444
|
-
[activeOffset, isDragging, isScrollAreaReconciling, reducedMotion],
|
|
1464
|
+
[activeOffset, isDragging, isOpen, isScrollAreaReconciling, reducedMotion],
|
|
1445
1465
|
);
|
|
1446
1466
|
|
|
1447
1467
|
const handleProps = useMemo<SheetHandleProps>(
|