@astryxdesign/core 0.4.4 → 0.4.5-canary.013e728
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 +40 -0
- package/dist/AvatarGroup/AvatarGroupOverflow.js +1 -1
- package/dist/BottomSheet/BottomSheet.d.ts +11 -2
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +4 -0
- package/dist/BottomSheet/BottomSheetPanel.d.ts +5 -2
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +65 -15
- package/dist/BottomSheet/index.d.ts +1 -1
- package/dist/BottomSheet/index.d.ts.map +1 -1
- package/dist/BottomSheet/snapOffsets.d.ts +57 -20
- package/dist/BottomSheet/snapOffsets.d.ts.map +1 -1
- package/dist/BottomSheet/snapOffsets.js +106 -30
- package/dist/BottomSheet/useSheetGestures.d.ts +13 -8
- package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
- package/dist/BottomSheet/useSheetGestures.js +160 -64
- package/dist/Breadcrumbs/BreadcrumbItem.js +6 -6
- package/dist/Button/Button.js +5 -5
- package/dist/Calendar/Calendar.d.ts +17 -0
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +55 -15
- package/dist/Calendar/getStandaloneShortWeekdayNames.d.ts +14 -0
- package/dist/Calendar/getStandaloneShortWeekdayNames.d.ts.map +1 -0
- package/dist/Calendar/getStandaloneShortWeekdayNames.js +26 -0
- package/dist/Calendar/hooks/useCalendarConstraints.d.ts +22 -1
- package/dist/Calendar/hooks/useCalendarConstraints.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarConstraints.js +26 -4
- package/dist/Calendar/hooks/useCalendarDays.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarDays.js +14 -10
- package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarNavigation.js +8 -4
- package/dist/Calendar/standaloneShortWeekdayNames.generated.d.ts +47 -0
- package/dist/Calendar/standaloneShortWeekdayNames.generated.d.ts.map +1 -0
- package/dist/Calendar/standaloneShortWeekdayNames.generated.js +40 -0
- package/dist/Calendar/styles.js +3 -3
- 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 +2 -2
- package/dist/Chat/ChatToolCalls.js +1 -1
- 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/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +9 -0
- package/dist/Citation/Citation.js +3 -3
- package/dist/ClickableCard/ClickableCard.js +2 -2
- package/dist/CommandPalette/CommandPaletteItem.js +1 -1
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +8 -3
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +17 -9
- package/dist/DateRangeInput/DateRangeInput.d.ts +23 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +47 -9
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +18 -10
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +3 -3
- package/dist/Field/FieldLabel.d.ts +2 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +21 -3
- package/dist/Field/InputClearButton.d.ts +2 -1
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +12 -1
- package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
- package/dist/Field/inputStyles.stylex.js +4 -4
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +2 -2
- package/dist/FormLayout/FormLayout.d.ts +24 -2
- package/dist/FormLayout/FormLayout.d.ts.map +1 -1
- package/dist/FormLayout/FormLayout.js +7 -2
- package/dist/FormLayout/FormLayoutContext.d.ts +15 -2
- package/dist/FormLayout/FormLayoutContext.d.ts.map +1 -1
- package/dist/FormLayout/FormLayoutContext.js +19 -4
- package/dist/FormLayout/index.d.ts +1 -1
- package/dist/FormLayout/index.d.ts.map +1 -1
- 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/Item/Item.d.ts +9 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +46 -8
- 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 +2 -1
- package/dist/Link/Link.js +4 -4
- package/dist/Markdown/Markdown.d.ts +8 -0
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +31 -3
- package/dist/Markdown/parser.d.ts +14 -2
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +50 -2
- 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 -3
- package/dist/NavItem/navItemStyles.stylex.d.ts +2 -2
- package/dist/NavItem/navItemStyles.stylex.js +2 -2
- package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +38 -5
- package/dist/Outline/Outline.js +2 -2
- package/dist/Outline/parseOutlineFromMarkdown.d.ts +2 -0
- package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
- package/dist/Outline/parseOutlineFromMarkdown.js +5 -31
- 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/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +12 -1
- package/dist/RadioList/RadioListItem.d.ts +2 -2
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +68 -38
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +3 -3
- 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 +6 -1
- package/dist/SelectableCard/SelectableCard.js +1 -1
- package/dist/Selector/Selector.d.ts +26 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +95 -17
- 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.js +1 -1
- package/dist/SideNav/SideNavItem.js +1 -1
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +3 -3
- 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/StatusDot/StatusDot.d.ts +43 -3
- package/dist/StatusDot/StatusDot.d.ts.map +1 -1
- package/dist/StatusDot/StatusDot.js +42 -5
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +9 -0
- package/dist/TabList/TabMenu.js +1 -1
- 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/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
- 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.js +2 -2
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +6 -1
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +6 -1
- package/dist/Thumbnail/Thumbnail.js +1 -1
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +6 -1
- 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/Token/Token.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.js +2 -2
- package/dist/TopNav/TopNavItem.js +2 -2
- package/dist/TopNav/TopNavMegaMenu.js +1 -1
- package/dist/TopNav/TopNavMegaMenuItem.js +1 -1
- package/dist/TopNav/TopNavMenu.js +2 -2
- package/dist/TreeList/TreeListItem.js +1 -1
- package/dist/astryx.css +85 -60
- 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/useResolvedRequired.d.ts +19 -0
- package/dist/hooks/useResolvedRequired.d.ts.map +1 -0
- package/dist/hooks/useResolvedRequired.js +40 -0
- 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/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/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/plainDate.d.ts +9 -2
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +16 -4
- package/locales/af-ZA.json +958 -0
- package/locales/ar-SA.json +998 -0
- package/locales/ca-ES.json +974 -0
- package/locales/cs-CZ.json +990 -0
- package/locales/da-DK.json +966 -0
- package/locales/de-DE.json +966 -0
- package/locales/el-GR.json +990 -0
- package/locales/en.json +8 -0
- package/locales/es-ES.json +978 -0
- package/locales/fi-FI.json +990 -0
- package/locales/fr-FR.json +928 -0
- package/locales/he-IL.json +990 -0
- package/locales/hu-HU.json +990 -0
- package/locales/it-IT.json +978 -0
- package/locales/ja-JP.json +998 -0
- package/locales/ko-KR.json +990 -0
- package/locales/nl-NL.json +954 -0
- package/locales/no-NO.json +978 -0
- package/locales/pl-PL.json +982 -0
- package/locales/pseudo.json +6 -0
- package/locales/pt-BR.json +982 -0
- package/locales/pt-PT.json +982 -0
- package/locales/ro-RO.json +982 -0
- package/locales/ru-RU.json +990 -0
- package/locales/sr-SP.json +990 -0
- package/locales/sv-SE.json +986 -0
- package/locales/tr-TR.json +990 -0
- package/locales/uk-UA.json +990 -0
- package/locales/vi-VN.json +986 -0
- package/locales/zh-CN.json +998 -0
- package/locales/zh-TW.json +998 -0
- package/package.json +3 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +1 -1
- package/src/Banner/Banner.doc.mjs +2 -0
- package/src/BottomSheet/BottomSheet.doc.mjs +36 -3
- package/src/BottomSheet/BottomSheet.test.tsx +177 -2
- package/src/BottomSheet/BottomSheet.tsx +16 -2
- package/src/BottomSheet/BottomSheetPanel.test.tsx +41 -0
- package/src/BottomSheet/BottomSheetPanel.tsx +95 -15
- package/src/BottomSheet/index.ts +5 -1
- package/src/BottomSheet/snapOffsets.test.ts +114 -47
- package/src/BottomSheet/snapOffsets.ts +119 -33
- package/src/BottomSheet/useSheetGestures.test.ts +113 -15
- package/src/BottomSheet/useSheetGestures.ts +196 -100
- package/src/Breadcrumbs/BreadcrumbItem.tsx +1 -1
- package/src/Button/Button.tsx +7 -7
- package/src/Calendar/Calendar.doc.mjs +16 -0
- package/src/Calendar/Calendar.test.tsx +137 -0
- package/src/Calendar/Calendar.tsx +80 -11
- package/src/Calendar/getStandaloneShortWeekdayNames.test.ts +54 -0
- package/src/Calendar/getStandaloneShortWeekdayNames.ts +38 -0
- package/src/Calendar/hooks/useCalendarConstraints.ts +54 -3
- package/src/Calendar/hooks/useCalendarDays.ts +13 -10
- package/src/Calendar/hooks/useCalendarNavigation.ts +6 -4
- package/src/Calendar/standaloneShortWeekdayNames.generated.ts +50 -0
- package/src/Calendar/styles.ts +3 -3
- 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 +7 -4
- package/src/Chat/ChatToolCalls.tsx +1 -1
- 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/CheckboxInput/CheckboxInput.tsx +6 -0
- package/src/Citation/Citation.tsx +3 -3
- package/src/ClickableCard/ClickableCard.tsx +2 -2
- package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
- package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -0
- package/src/ComplexSelector/ComplexSelector.tsx +8 -5
- package/src/DateInput/DateInput.test.tsx +17 -1
- package/src/DateInput/DateInput.tsx +13 -9
- package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +81 -1
- package/src/DateRangeInput/DateRangeInput.tsx +88 -8
- package/src/DateTimeInput/DateTimeInput.tsx +23 -8
- package/src/Dialog/Dialog.test.tsx +24 -0
- package/src/Dialog/Dialog.tsx +3 -0
- package/src/Field/Field.doc.mjs +3 -0
- package/src/Field/FieldLabel.tsx +20 -4
- package/src/Field/InputClearButton.test.tsx +134 -2
- package/src/Field/InputClearButton.tsx +42 -1
- package/src/Field/inputStyles.stylex.ts +16 -12
- package/src/FileInput/FileInput.tsx +5 -4
- package/src/FormLayout/FormLayout.doc.mjs +13 -0
- package/src/FormLayout/FormLayout.test.tsx +181 -4
- package/src/FormLayout/FormLayout.tsx +33 -2
- package/src/FormLayout/FormLayoutContext.ts +22 -7
- package/src/FormLayout/index.ts +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/Item/Item.doc.mjs +1 -0
- package/src/Item/Item.test.tsx +50 -0
- package/src/Item/Item.tsx +41 -2
- 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 +2 -1
- package/src/Link/Link.tsx +4 -4
- package/src/Markdown/Markdown.doc.mjs +3 -0
- package/src/Markdown/Markdown.test.tsx +78 -0
- package/src/Markdown/Markdown.tsx +41 -1
- package/src/Markdown/parser.ts +60 -2
- 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 +8 -5
- package/src/NavItem/navItemStyles.stylex.ts +2 -2
- package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
- package/src/NumberInput/NumberInput.doc.mjs +24 -0
- package/src/NumberInput/NumberInput.test.tsx +138 -0
- package/src/NumberInput/NumberInput.tsx +44 -6
- package/src/Outline/Outline.doc.mjs +2 -0
- package/src/Outline/Outline.tsx +1 -1
- package/src/Outline/parseOutlineFromMarkdown.ts +10 -40
- 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/RadioList.tsx +9 -1
- package/src/RadioList/RadioListItem.tsx +83 -51
- package/src/Resizable/ResizeHandle.test.tsx +22 -0
- package/src/Resizable/ResizeHandle.tsx +9 -3
- 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 +11 -2
- package/src/SelectableCard/SelectableCard.tsx +1 -1
- package/src/Selector/Selector.doc.mjs +16 -2
- package/src/Selector/Selector.test.tsx +525 -1
- package/src/Selector/Selector.tsx +166 -21
- 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 +2 -2
- package/src/SideNav/SideNavItem.tsx +1 -1
- package/src/Slider/Slider.tsx +11 -1
- 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/StatusDot/StatusDot.doc.mjs +13 -0
- package/src/StatusDot/StatusDot.test.tsx +115 -8
- package/src/StatusDot/StatusDot.tsx +74 -9
- package/src/Switch/Switch.tsx +6 -0
- package/src/TabList/TabMenu.tsx +1 -1
- package/src/Table/TableRow.tsx +4 -4
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +2 -1
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +2 -1
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +22 -4
- 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 +2 -2
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextArea/TextArea.tsx +3 -1
- package/src/TextInput/TextInput.tsx +3 -1
- package/src/Thumbnail/Thumbnail.tsx +1 -1
- package/src/TimeInput/TimeInput.tsx +3 -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/Token/Token.tsx +1 -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 +1 -1
- package/src/TopNav/TopNavItem.tsx +2 -2
- package/src/TopNav/TopNavMegaMenu.tsx +1 -1
- package/src/TopNav/TopNavMegaMenuItem.tsx +1 -1
- package/src/TopNav/TopNavMenu.tsx +2 -2
- package/src/TreeList/TreeListItem.tsx +1 -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/useResolvedRequired.ts +42 -0
- 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/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/utils/dateParser.test.ts +20 -0
- package/src/utils/dateParser.ts +14 -7
- package/src/utils/plainDate.test.ts +56 -0
- package/src/utils/plainDate.ts +17 -4
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file useTooltip.tsx
|
|
7
|
-
* @input Uses useLayer, React hooks
|
|
8
|
-
* @output Exports useTooltip hook for hover/focus triggered tooltips
|
|
7
|
+
* @input Uses useLayer, useTouchTrigger, React hooks
|
|
8
|
+
* @output Exports useTooltip hook for hover/focus/tap triggered tooltips
|
|
9
9
|
* @position Layer hook; builds on useLayer for tooltip behavior
|
|
10
10
|
*
|
|
11
11
|
* SYNC: When modified, update:
|
|
@@ -26,6 +26,10 @@ import {
|
|
|
26
26
|
type LayerAlignment,
|
|
27
27
|
type LayerPlacement,
|
|
28
28
|
} from '../Layer/useLayer';
|
|
29
|
+
import {
|
|
30
|
+
useTouchTrigger,
|
|
31
|
+
type LayerTouchTrigger,
|
|
32
|
+
} from '../Layer/useTouchTrigger';
|
|
29
33
|
import {layerAnimations} from '../Layer/layerAnimations.stylex';
|
|
30
34
|
import {themeProps} from '../utils/themeProps';
|
|
31
35
|
import {isImeKeyEvent} from '../utils/ime';
|
|
@@ -73,6 +77,11 @@ const styles = stylex.create({
|
|
|
73
77
|
*/
|
|
74
78
|
export type TooltipFocusTrigger = 'auto' | 'always' | 'never';
|
|
75
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Touch trigger behavior for tooltips
|
|
82
|
+
*/
|
|
83
|
+
export type TooltipTouchTrigger = LayerTouchTrigger;
|
|
84
|
+
|
|
76
85
|
export interface TooltipOptions {
|
|
77
86
|
/**
|
|
78
87
|
* Position placement relative to anchor
|
|
@@ -108,6 +117,20 @@ export interface TooltipOptions {
|
|
|
108
117
|
*/
|
|
109
118
|
focusTrigger?: TooltipFocusTrigger;
|
|
110
119
|
|
|
120
|
+
/**
|
|
121
|
+
* What a tap does on a touch pointer, where there is no hover:
|
|
122
|
+
* - `auto`: tap opens the tooltip, unless the trigger performs an action of
|
|
123
|
+
* its own (a button, a link, a form control) — that tap belongs to the
|
|
124
|
+
* control, and a hint about a control the user just operated is noise
|
|
125
|
+
* - `tap`: tap always opens the tooltip. This is what an info icon rendered
|
|
126
|
+
* as a button wants: it looks like an action to the DOM, but revealing the
|
|
127
|
+
* tooltip is the only thing it does
|
|
128
|
+
* - `none`: touch never opens the tooltip
|
|
129
|
+
*
|
|
130
|
+
* @default 'auto'
|
|
131
|
+
*/
|
|
132
|
+
touchTrigger?: TooltipTouchTrigger;
|
|
133
|
+
|
|
111
134
|
/**
|
|
112
135
|
* Whether the tooltip is enabled.
|
|
113
136
|
* When false, hover/focus triggers are disabled.
|
|
@@ -218,6 +241,7 @@ function isFocusable(element: HTMLElement): boolean {
|
|
|
218
241
|
* Builds on useLayer to add:
|
|
219
242
|
* - Hover triggers with configurable delay
|
|
220
243
|
* - Focus triggers with auto-detection for focusable elements
|
|
244
|
+
* - Tap triggers on touch, where there is no hover (see useTouchTrigger)
|
|
221
245
|
* - Inverted color palette for high contrast
|
|
222
246
|
*
|
|
223
247
|
* Unlike HoverCard, tooltips:
|
|
@@ -242,6 +266,7 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
|
|
|
242
266
|
delay = 200,
|
|
243
267
|
hideDelay = 0,
|
|
244
268
|
focusTrigger = 'auto',
|
|
269
|
+
touchTrigger = 'auto',
|
|
245
270
|
isEnabled = true,
|
|
246
271
|
isOpen,
|
|
247
272
|
isDefaultOpen = false,
|
|
@@ -273,6 +298,29 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
|
|
|
273
298
|
}
|
|
274
299
|
}, []);
|
|
275
300
|
|
|
301
|
+
// Touch resolves immediately: the hover delays exist to filter out a pointer
|
|
302
|
+
// passing across the trigger, and a tap is never that.
|
|
303
|
+
const showNow = useCallback(() => {
|
|
304
|
+
clearTimeouts();
|
|
305
|
+
layer.show();
|
|
306
|
+
}, [clearTimeouts, layer]);
|
|
307
|
+
|
|
308
|
+
const hideNow = useCallback(() => {
|
|
309
|
+
clearTimeouts();
|
|
310
|
+
layer.hide();
|
|
311
|
+
}, [clearTimeouts, layer]);
|
|
312
|
+
|
|
313
|
+
const touch = useTouchTrigger({
|
|
314
|
+
touchTrigger,
|
|
315
|
+
isEnabled,
|
|
316
|
+
isControlled: isOpen !== undefined,
|
|
317
|
+
isOpen: layer.isOpen,
|
|
318
|
+
layerId: layer.id,
|
|
319
|
+
triggerRef,
|
|
320
|
+
show: showNow,
|
|
321
|
+
hide: hideNow,
|
|
322
|
+
});
|
|
323
|
+
|
|
276
324
|
// Schedule show with delay (suppressed when isOpen is false)
|
|
277
325
|
const scheduleShow = useCallback(() => {
|
|
278
326
|
if (!isEnabled || isOpen === false) {
|
|
@@ -309,26 +357,38 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
|
|
|
309
357
|
|
|
310
358
|
// Event handlers
|
|
311
359
|
const handleMouseEnter = useCallback(() => {
|
|
312
|
-
//
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
window.matchMedia('(hover: none)').matches
|
|
317
|
-
) {
|
|
360
|
+
// A tap synthesizes mouseenter. On touch the tap path owns the decision,
|
|
361
|
+
// so hover must not also fire — including the tap that just opened the
|
|
362
|
+
// tooltip, which would otherwise be double-handled.
|
|
363
|
+
if (touch.isTouchPointerRef.current) {
|
|
318
364
|
return;
|
|
319
365
|
}
|
|
320
366
|
scheduleShow();
|
|
321
|
-
}, [scheduleShow]);
|
|
367
|
+
}, [touch, scheduleShow]);
|
|
322
368
|
|
|
323
369
|
const handleMouseLeave = useCallback(() => {
|
|
370
|
+
// On touch the synthesized mouseleave arrives with the next tap elsewhere,
|
|
371
|
+
// which the outside-tap dismissal already handles — and handling it here
|
|
372
|
+
// too would close the tooltip behind the tap-open bookkeeping's back.
|
|
373
|
+
if (touch.isTouchPointerRef.current) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
324
376
|
scheduleHide();
|
|
325
|
-
}, [scheduleHide]);
|
|
377
|
+
}, [touch, scheduleHide]);
|
|
326
378
|
|
|
327
379
|
const handleFocusIn = useCallback(
|
|
328
380
|
(e: Event) => {
|
|
329
381
|
if (!isEnabled) {
|
|
330
382
|
return;
|
|
331
383
|
}
|
|
384
|
+
// A tap focuses the trigger it activates, and `:focus-visible` does not
|
|
385
|
+
// filter that out on every element: a tapped `<input>` or contenteditable
|
|
386
|
+
// matches it. Those are exactly the action triggers `auto` just decided
|
|
387
|
+
// to keep shut, so without this the focus reopens what the tap
|
|
388
|
+
// suppressed, over the field the user is trying to type into.
|
|
389
|
+
if (touch.isTouchInteraction()) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
332
392
|
// Only show tooltip for keyboard focus (:focus-visible),
|
|
333
393
|
// not programmatic focus (e.g. dialog auto-focus, touch tap)
|
|
334
394
|
const target = e.target as HTMLElement;
|
|
@@ -338,7 +398,7 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
|
|
|
338
398
|
clearTimeouts();
|
|
339
399
|
layer.show();
|
|
340
400
|
},
|
|
341
|
-
[isEnabled, clearTimeouts, layer],
|
|
401
|
+
[isEnabled, touch, clearTimeouts, layer],
|
|
342
402
|
);
|
|
343
403
|
|
|
344
404
|
const handleFocusOut = useCallback(() => {
|
|
@@ -350,15 +410,24 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
|
|
|
350
410
|
// just-pressed control reads as stale. Fires on pointerdown so it feels
|
|
351
411
|
// immediate. Uncontrolled tooltips only — a controlled tooltip's visibility
|
|
352
412
|
// is owned by the consumer. `layer.hide()` self-guards when already closed.
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
413
|
+
// A touch press is a different gesture (it may be the only way to open the
|
|
414
|
+
// tooltip at all), so the touch path answers it first.
|
|
415
|
+
const handlePointerDown = useCallback(
|
|
416
|
+
(event: PointerEvent) => {
|
|
417
|
+
if (touch.handlePointerDown(event)) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
if (isOpen !== undefined) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
clearTimeouts();
|
|
424
|
+
layer.hide();
|
|
425
|
+
},
|
|
426
|
+
[touch, isOpen, clearTimeouts, layer],
|
|
427
|
+
);
|
|
360
428
|
|
|
361
429
|
// Interaction ref that handles event listeners only
|
|
430
|
+
const {handlePointerEnter, clearTapOpen} = touch;
|
|
362
431
|
const interactionRef: RefCallback<HTMLElement> = useCallback(
|
|
363
432
|
(el: HTMLElement | null) => {
|
|
364
433
|
// Cleanup previous element
|
|
@@ -367,6 +436,10 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
|
|
|
367
436
|
triggerRef.current.removeEventListener('mouseleave', handleMouseLeave);
|
|
368
437
|
triggerRef.current.removeEventListener('focusin', handleFocusIn);
|
|
369
438
|
triggerRef.current.removeEventListener('focusout', handleFocusOut);
|
|
439
|
+
triggerRef.current.removeEventListener(
|
|
440
|
+
'pointerenter',
|
|
441
|
+
handlePointerEnter,
|
|
442
|
+
);
|
|
370
443
|
triggerRef.current.removeEventListener(
|
|
371
444
|
'pointerdown',
|
|
372
445
|
handlePointerDown,
|
|
@@ -374,10 +447,13 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
|
|
|
374
447
|
}
|
|
375
448
|
|
|
376
449
|
if (el) {
|
|
377
|
-
// Attach hover listeners
|
|
450
|
+
// Attach hover listeners. `pointerenter` runs before the synthesized
|
|
451
|
+
// `mouseenter` a tap produces, which is what lets the hover path know
|
|
452
|
+
// it is looking at a finger.
|
|
453
|
+
el.addEventListener('pointerenter', handlePointerEnter);
|
|
378
454
|
el.addEventListener('mouseenter', handleMouseEnter);
|
|
379
455
|
el.addEventListener('mouseleave', handleMouseLeave);
|
|
380
|
-
// Press-to-dismiss
|
|
456
|
+
// Press-to-dismiss on a mouse; tap-to-open on a touch pointer.
|
|
381
457
|
el.addEventListener('pointerdown', handlePointerDown);
|
|
382
458
|
|
|
383
459
|
// Attach focus listeners based on focusTrigger option
|
|
@@ -399,6 +475,7 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
|
|
|
399
475
|
handleMouseLeave,
|
|
400
476
|
handleFocusIn,
|
|
401
477
|
handleFocusOut,
|
|
478
|
+
handlePointerEnter,
|
|
402
479
|
handlePointerDown,
|
|
403
480
|
],
|
|
404
481
|
);
|
|
@@ -461,13 +538,14 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
|
|
|
461
538
|
return;
|
|
462
539
|
}
|
|
463
540
|
clearTimeouts();
|
|
541
|
+
clearTapOpen();
|
|
464
542
|
layer.hide();
|
|
465
543
|
};
|
|
466
544
|
document.addEventListener('keydown', handleKeyDown);
|
|
467
545
|
return () => {
|
|
468
546
|
document.removeEventListener('keydown', handleKeyDown);
|
|
469
547
|
};
|
|
470
|
-
}, [isOpen, layer, clearTimeouts]);
|
|
548
|
+
}, [isOpen, layer, clearTimeouts, clearTapOpen]);
|
|
471
549
|
|
|
472
550
|
// Render function that wraps layer.render with tooltip styling
|
|
473
551
|
const renderTooltip = useCallback(
|
|
@@ -72,7 +72,7 @@ const styles = stylex.create({
|
|
|
72
72
|
fontSize: 'inherit',
|
|
73
73
|
fontWeight: fontWeightVars['--font-weight-normal'],
|
|
74
74
|
textAlign: 'start',
|
|
75
|
-
':hover': {
|
|
75
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
76
76
|
'@media (hover: hover)': {
|
|
77
77
|
backgroundColor: colorVars['--color-overlay-hover'],
|
|
78
78
|
},
|
|
@@ -59,7 +59,7 @@ const styles = stylex.create({
|
|
|
59
59
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
60
60
|
backgroundColor: {
|
|
61
61
|
default: 'transparent',
|
|
62
|
-
':hover': {
|
|
62
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
63
63
|
'@media (hover: hover)': colorVars['--color-overlay-hover'],
|
|
64
64
|
},
|
|
65
65
|
':active': colorVars['--color-overlay-pressed'],
|
|
@@ -70,7 +70,7 @@ const styles = stylex.create({
|
|
|
70
70
|
fontWeight: fontWeightVars['--font-weight-semibold'],
|
|
71
71
|
backgroundColor: {
|
|
72
72
|
default: colorVars['--color-neutral'],
|
|
73
|
-
':hover': {
|
|
73
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
74
74
|
'@media (hover: hover)': colorVars['--color-neutral'],
|
|
75
75
|
},
|
|
76
76
|
':active': colorVars['--color-neutral'],
|
|
@@ -84,7 +84,7 @@ const styles = stylex.create({
|
|
|
84
84
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
85
85
|
backgroundColor: {
|
|
86
86
|
default: 'transparent',
|
|
87
|
-
':hover': {
|
|
87
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
88
88
|
'@media (hover: hover)': colorVars['--color-overlay-hover'],
|
|
89
89
|
},
|
|
90
90
|
},
|
|
@@ -56,7 +56,7 @@ const styles = stylex.create({
|
|
|
56
56
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
57
57
|
backgroundColor: {
|
|
58
58
|
default: 'transparent',
|
|
59
|
-
':hover': {
|
|
59
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
60
60
|
'@media (hover: hover)': colorVars['--color-overlay-hover'],
|
|
61
61
|
},
|
|
62
62
|
':active': colorVars['--color-overlay-pressed'],
|
|
@@ -71,7 +71,7 @@ const styles = stylex.create({
|
|
|
71
71
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
72
72
|
backgroundColor: {
|
|
73
73
|
default: 'transparent',
|
|
74
|
-
':hover': {
|
|
74
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
75
75
|
'@media (hover: hover)': colorVars['--color-overlay-hover'],
|
|
76
76
|
},
|
|
77
77
|
},
|
|
@@ -121,7 +121,7 @@ const styles = stylex.create({
|
|
|
121
121
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
122
122
|
backgroundColor: {
|
|
123
123
|
default: 'transparent',
|
|
124
|
-
':hover': {
|
|
124
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
125
125
|
'@media (hover: hover)': colorVars['--color-overlay-hover'],
|
|
126
126
|
},
|
|
127
127
|
},
|
|
@@ -101,7 +101,7 @@ const styles = stylex.create({
|
|
|
101
101
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
102
102
|
backgroundImage: {
|
|
103
103
|
default: null,
|
|
104
|
-
':hover': {
|
|
104
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
105
105
|
'@media (hover: hover)': `linear-gradient(${colorVars['--color-overlay-hover']}, ${colorVars['--color-overlay-hover']})`,
|
|
106
106
|
},
|
|
107
107
|
':active': `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`,
|
|
@@ -32,13 +32,17 @@ export const styles = stylex.create({
|
|
|
32
32
|
'--_hover-delay': '0s',
|
|
33
33
|
'--_reveal-opacity': {
|
|
34
34
|
default: 0,
|
|
35
|
-
':hover
|
|
35
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
36
|
+
'@media (hover: hover)': 1,
|
|
37
|
+
},
|
|
36
38
|
':focus-within': 1,
|
|
37
39
|
'@media (any-pointer: coarse)': 1,
|
|
38
40
|
},
|
|
39
41
|
'--_reveal-position': {
|
|
40
42
|
default: 'absolute',
|
|
41
|
-
':hover
|
|
43
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
44
|
+
'@media (hover: hover)': 'static',
|
|
45
|
+
},
|
|
42
46
|
':focus-within': 'static',
|
|
43
47
|
'@media (any-pointer: coarse)': 'static',
|
|
44
48
|
},
|
|
@@ -49,7 +53,9 @@ export const styles = stylex.create({
|
|
|
49
53
|
// content would snap out of flow at full opacity and flicker.
|
|
50
54
|
'--_reveal-delay': {
|
|
51
55
|
default: REST_DELAY,
|
|
52
|
-
':hover
|
|
56
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
57
|
+
'@media (hover: hover)': HOVER_DELAY + ', ' + HOVER_DELAY,
|
|
58
|
+
},
|
|
53
59
|
':focus-within': '0s, 0s',
|
|
54
60
|
'@media (any-pointer: coarse)': '0s, 0s',
|
|
55
61
|
},
|
|
@@ -57,7 +63,9 @@ export const styles = stylex.create({
|
|
|
57
63
|
// for) but keeps the dwell: an intent gate is timing, not motion.
|
|
58
64
|
'--_reveal-delay-reduced': {
|
|
59
65
|
default: '0s, 0s',
|
|
60
|
-
':hover
|
|
66
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
67
|
+
'@media (hover: hover)': HOVER_DELAY + ', ' + HOVER_DELAY,
|
|
68
|
+
},
|
|
61
69
|
':focus-within': '0s, 0s',
|
|
62
70
|
'@media (any-pointer: coarse)': '0s, 0s',
|
|
63
71
|
},
|
|
@@ -66,13 +74,17 @@ export const styles = stylex.create({
|
|
|
66
74
|
// coarse-pointer branch (it stays visible on touch).
|
|
67
75
|
'--_conceal-opacity': {
|
|
68
76
|
default: 1,
|
|
69
|
-
':hover
|
|
77
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
78
|
+
'@media (hover: hover)': 0,
|
|
79
|
+
},
|
|
70
80
|
},
|
|
71
81
|
// Single-value dwell for the opacity-only blocks, which have no discrete
|
|
72
82
|
// position to sequence.
|
|
73
83
|
'--_fade-delay': {
|
|
74
84
|
default: '0s',
|
|
75
|
-
':hover
|
|
85
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
86
|
+
'@media (hover: hover)': HOVER_DELAY,
|
|
87
|
+
},
|
|
76
88
|
':focus-within': '0s',
|
|
77
89
|
'@media (any-pointer: coarse)': '0s',
|
|
78
90
|
},
|
|
@@ -87,35 +99,47 @@ export const styles = stylex.create({
|
|
|
87
99
|
stateInactive: {
|
|
88
100
|
'--_reveal-opacity': {
|
|
89
101
|
default: 0,
|
|
90
|
-
':hover
|
|
102
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
103
|
+
'@media (hover: hover)': 0,
|
|
104
|
+
},
|
|
91
105
|
':focus-within': 1,
|
|
92
106
|
'@media (any-pointer: coarse)': 1,
|
|
93
107
|
},
|
|
94
108
|
'--_reveal-position': {
|
|
95
109
|
default: 'absolute',
|
|
96
|
-
':hover
|
|
110
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
111
|
+
'@media (hover: hover)': 'absolute',
|
|
112
|
+
},
|
|
97
113
|
':focus-within': 'static',
|
|
98
114
|
'@media (any-pointer: coarse)': 'static',
|
|
99
115
|
},
|
|
100
116
|
'--_reveal-delay': {
|
|
101
117
|
default: REST_DELAY,
|
|
102
|
-
':hover
|
|
118
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
119
|
+
'@media (hover: hover)': REST_DELAY,
|
|
120
|
+
},
|
|
103
121
|
':focus-within': '0s, 0s',
|
|
104
122
|
'@media (any-pointer: coarse)': '0s, 0s',
|
|
105
123
|
},
|
|
106
124
|
'--_reveal-delay-reduced': {
|
|
107
125
|
default: '0s, 0s',
|
|
108
|
-
':hover
|
|
126
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
127
|
+
'@media (hover: hover)': '0s, 0s',
|
|
128
|
+
},
|
|
109
129
|
':focus-within': '0s, 0s',
|
|
110
130
|
'@media (any-pointer: coarse)': '0s, 0s',
|
|
111
131
|
},
|
|
112
132
|
'--_conceal-opacity': {
|
|
113
133
|
default: 1,
|
|
114
|
-
':hover
|
|
134
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
135
|
+
'@media (hover: hover)': 1,
|
|
136
|
+
},
|
|
115
137
|
},
|
|
116
138
|
'--_fade-delay': {
|
|
117
139
|
default: '0s',
|
|
118
|
-
':hover
|
|
140
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
141
|
+
'@media (hover: hover)': '0s',
|
|
142
|
+
},
|
|
119
143
|
':focus-within': '0s',
|
|
120
144
|
'@media (any-pointer: coarse)': '0s',
|
|
121
145
|
},
|
|
@@ -126,35 +150,47 @@ export const styles = stylex.create({
|
|
|
126
150
|
stateActive: {
|
|
127
151
|
'--_reveal-opacity': {
|
|
128
152
|
default: 1,
|
|
129
|
-
':hover
|
|
153
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
154
|
+
'@media (hover: hover)': 1,
|
|
155
|
+
},
|
|
130
156
|
':focus-within': 1,
|
|
131
157
|
'@media (any-pointer: coarse)': 1,
|
|
132
158
|
},
|
|
133
159
|
'--_reveal-position': {
|
|
134
160
|
default: 'static',
|
|
135
|
-
':hover
|
|
161
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
162
|
+
'@media (hover: hover)': 'static',
|
|
163
|
+
},
|
|
136
164
|
':focus-within': 'static',
|
|
137
165
|
'@media (any-pointer: coarse)': 'static',
|
|
138
166
|
},
|
|
139
167
|
'--_reveal-delay': {
|
|
140
168
|
default: '0s, 0s',
|
|
141
|
-
':hover
|
|
169
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
170
|
+
'@media (hover: hover)': '0s, 0s',
|
|
171
|
+
},
|
|
142
172
|
':focus-within': '0s, 0s',
|
|
143
173
|
'@media (any-pointer: coarse)': '0s, 0s',
|
|
144
174
|
},
|
|
145
175
|
'--_reveal-delay-reduced': {
|
|
146
176
|
default: '0s, 0s',
|
|
147
|
-
':hover
|
|
177
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
178
|
+
'@media (hover: hover)': '0s, 0s',
|
|
179
|
+
},
|
|
148
180
|
':focus-within': '0s, 0s',
|
|
149
181
|
'@media (any-pointer: coarse)': '0s, 0s',
|
|
150
182
|
},
|
|
151
183
|
'--_conceal-opacity': {
|
|
152
184
|
default: 0,
|
|
153
|
-
':hover
|
|
185
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
186
|
+
'@media (hover: hover)': 0,
|
|
187
|
+
},
|
|
154
188
|
},
|
|
155
189
|
'--_fade-delay': {
|
|
156
190
|
default: '0s',
|
|
157
|
-
':hover
|
|
191
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
192
|
+
'@media (hover: hover)': '0s',
|
|
193
|
+
},
|
|
158
194
|
':focus-within': '0s',
|
|
159
195
|
'@media (any-pointer: coarse)': '0s',
|
|
160
196
|
},
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file scrollbarGutter.test.ts
|
|
5
|
+
* @input Uses vitest and a stubbed viewport + element box (jsdom does no layout)
|
|
6
|
+
* @output Unit tests for holdScrollbarGutter
|
|
7
|
+
* @position Testing; validates scrollbarGutter.ts implementation
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When scrollbarGutter.ts changes, update tests to match new behavior
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {afterEach, describe, expect, it} from 'vitest';
|
|
13
|
+
import {holdScrollbarGutter} from './scrollbarGutter';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* jsdom does no layout, so both halves of the measurement are stubbed: the
|
|
17
|
+
* viewport (`innerWidth` vs `documentElement.clientWidth`) and the element's
|
|
18
|
+
* own box, which `widths` reads from and a test flips to simulate the lock
|
|
19
|
+
* widening it.
|
|
20
|
+
*/
|
|
21
|
+
function stub({
|
|
22
|
+
innerWidth,
|
|
23
|
+
clientWidth,
|
|
24
|
+
widths,
|
|
25
|
+
}: {
|
|
26
|
+
innerWidth: number;
|
|
27
|
+
clientWidth: number;
|
|
28
|
+
widths?: () => number;
|
|
29
|
+
}) {
|
|
30
|
+
Object.defineProperty(window, 'innerWidth', {
|
|
31
|
+
value: innerWidth,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true,
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(document.documentElement, 'clientWidth', {
|
|
36
|
+
value: clientWidth,
|
|
37
|
+
configurable: true,
|
|
38
|
+
});
|
|
39
|
+
if (widths) {
|
|
40
|
+
document.body.getBoundingClientRect = () => ({width: widths()}) as DOMRect;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const rootGutter = () => document.documentElement.style.scrollbarGutter;
|
|
45
|
+
|
|
46
|
+
describe('holdScrollbarGutter', () => {
|
|
47
|
+
afterEach(() => {
|
|
48
|
+
document.body.style.cssText = '';
|
|
49
|
+
document.documentElement.style.cssText = '';
|
|
50
|
+
// @ts-expect-error -- drop the stubs so jsdom's own values come back
|
|
51
|
+
delete document.documentElement.clientWidth;
|
|
52
|
+
// @ts-expect-error -- restore the prototype's implementation
|
|
53
|
+
delete document.body.getBoundingClientRect;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('holds the gutter open when a space-taking scrollbar is about to be hidden', () => {
|
|
57
|
+
// A 1024px window over a 1009px layout viewport = a 15px classic scrollbar.
|
|
58
|
+
stub({innerWidth: 1024, clientWidth: 1009});
|
|
59
|
+
|
|
60
|
+
const hold = holdScrollbarGutter(document.body);
|
|
61
|
+
|
|
62
|
+
expect(rootGutter()).toBe('stable');
|
|
63
|
+
|
|
64
|
+
hold.settle();
|
|
65
|
+
hold.release();
|
|
66
|
+
|
|
67
|
+
expect(rootGutter()).toBe('');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('leaves an overlay scrollbar alone — there is no gutter to hold', () => {
|
|
71
|
+
stub({innerWidth: 1024, clientWidth: 1024});
|
|
72
|
+
|
|
73
|
+
const hold = holdScrollbarGutter(document.body);
|
|
74
|
+
hold.settle();
|
|
75
|
+
|
|
76
|
+
expect(rootGutter()).toBe('');
|
|
77
|
+
expect(document.body.style.paddingRight).toBe('');
|
|
78
|
+
|
|
79
|
+
hold.release();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('does not pad when holding the gutter kept the element still', () => {
|
|
83
|
+
stub({innerWidth: 1024, clientWidth: 1009, widths: () => 1009});
|
|
84
|
+
|
|
85
|
+
const hold = holdScrollbarGutter(document.body);
|
|
86
|
+
hold.settle();
|
|
87
|
+
|
|
88
|
+
expect(rootGutter()).toBe('stable');
|
|
89
|
+
expect(document.body.style.paddingRight).toBe('');
|
|
90
|
+
|
|
91
|
+
hold.release();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('falls back to padding when the element grew anyway', () => {
|
|
95
|
+
// What an engine without scrollbar-gutter support does: the gutter request
|
|
96
|
+
// is ignored, the scrollbar goes away, and the element widens by 15px.
|
|
97
|
+
let width = 1009;
|
|
98
|
+
stub({innerWidth: 1024, clientWidth: 1009, widths: () => width});
|
|
99
|
+
|
|
100
|
+
const hold = holdScrollbarGutter(document.body);
|
|
101
|
+
width = 1024;
|
|
102
|
+
hold.settle();
|
|
103
|
+
|
|
104
|
+
expect(document.body.style.paddingRight).toBe('15px');
|
|
105
|
+
|
|
106
|
+
hold.release();
|
|
107
|
+
|
|
108
|
+
expect(document.body.style.paddingRight).toBe('');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("adds to the page's own padding instead of replacing it", () => {
|
|
112
|
+
let width = 1009;
|
|
113
|
+
stub({innerWidth: 1024, clientWidth: 1009, widths: () => width});
|
|
114
|
+
document.body.style.paddingRight = '24px';
|
|
115
|
+
|
|
116
|
+
const hold = holdScrollbarGutter(document.body);
|
|
117
|
+
width = 1024;
|
|
118
|
+
hold.settle();
|
|
119
|
+
|
|
120
|
+
expect(document.body.style.paddingRight).toBe('39px');
|
|
121
|
+
|
|
122
|
+
hold.release();
|
|
123
|
+
|
|
124
|
+
expect(document.body.style.paddingRight).toBe('24px');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('restores the page\u2019s own scrollbar-gutter rather than clearing it', () => {
|
|
128
|
+
stub({innerWidth: 1024, clientWidth: 1009});
|
|
129
|
+
document.documentElement.style.scrollbarGutter = 'stable both-edges';
|
|
130
|
+
|
|
131
|
+
const hold = holdScrollbarGutter(document.body);
|
|
132
|
+
|
|
133
|
+
expect(rootGutter()).toBe('stable');
|
|
134
|
+
|
|
135
|
+
hold.settle();
|
|
136
|
+
hold.release();
|
|
137
|
+
|
|
138
|
+
expect(rootGutter()).toBe('stable both-edges');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('settles once, however many times it is called', () => {
|
|
142
|
+
let width = 1009;
|
|
143
|
+
stub({innerWidth: 1024, clientWidth: 1009, widths: () => width});
|
|
144
|
+
|
|
145
|
+
const hold = holdScrollbarGutter(document.body);
|
|
146
|
+
width = 1024;
|
|
147
|
+
hold.settle();
|
|
148
|
+
hold.settle();
|
|
149
|
+
hold.settle();
|
|
150
|
+
|
|
151
|
+
expect(document.body.style.paddingRight).toBe('15px');
|
|
152
|
+
|
|
153
|
+
hold.release();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('does nothing where there is no layout to measure', () => {
|
|
157
|
+
stub({innerWidth: 1024, clientWidth: 0});
|
|
158
|
+
|
|
159
|
+
const hold = holdScrollbarGutter(document.body);
|
|
160
|
+
hold.settle();
|
|
161
|
+
|
|
162
|
+
expect(rootGutter()).toBe('');
|
|
163
|
+
expect(document.body.style.paddingRight).toBe('');
|
|
164
|
+
|
|
165
|
+
hold.release();
|
|
166
|
+
});
|
|
167
|
+
});
|