@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
|
@@ -12,6 +12,7 @@ export const docs = {
|
|
|
12
12
|
{name: 'delay', type: 'number', description: 'Delay before showing the hover card on hover, in milliseconds.', default: '300'},
|
|
13
13
|
{name: 'hideDelay', type: 'number', description: 'Delay before hiding after mouse or focus leaves, in milliseconds.', default: '200'},
|
|
14
14
|
{name: 'focusTrigger', type: "'auto' | 'always' | 'never'", description: 'When focus should open the hover card. auto only attaches focus listeners to naturally focusable elements.', default: "'auto'"},
|
|
15
|
+
{name: 'touchTrigger', type: "'auto' | 'tap' | 'none'", description: 'What a tap does where there is no hover. auto opens on tap unless the trigger performs an action of its own; tap always opens; none never opens on touch.', default: "'auto'"},
|
|
15
16
|
{name: 'isEnabled', type: 'boolean', description: 'Whether hover and focus triggers are enabled.', default: 'true'},
|
|
16
17
|
{name: 'label', type: 'string', description: 'Accessible name for the hover card popup. When provided, the popup is exposed as a named role="dialog"; when omitted, it falls back to role="group" (a group may validly be unnamed).'},
|
|
17
18
|
{name: 'isOpen', type: 'boolean', description: 'Controlled open state. true force-shows, false force-hides, undefined lets hover/focus manage visibility.'},
|
|
@@ -52,6 +53,7 @@ export const docsDense = {
|
|
|
52
53
|
delay: 'show delay in ms.',
|
|
53
54
|
hideDelay: 'hide delay after mouse/focus leave in ms.',
|
|
54
55
|
focusTrigger: 'when focus opens hover card; auto = naturally focusable elements only.',
|
|
56
|
+
touchTrigger: 'tap behavior with no hover; auto = tap unless trigger acts, tap = always, none = never.',
|
|
55
57
|
isEnabled: 'whether hover/focus triggers are enabled.',
|
|
56
58
|
label: 'accessible name for popup. with label: named role="dialog"; without: role="group".',
|
|
57
59
|
isOpen: 'controlled open state: true force-show, false force-hide, undefined unmanaged.',
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file useHoverCard.ts
|
|
7
|
-
* @input Uses useLayer, React hooks
|
|
8
|
-
* @output Exports useHoverCard hook for hover/focus triggered layers
|
|
7
|
+
* @input Uses useLayer, useTouchTrigger, React hooks
|
|
8
|
+
* @output Exports useHoverCard hook for hover/focus/tap triggered layers
|
|
9
9
|
* @position Layer hook; builds on useLayer for hover card 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 {
|
|
31
35
|
colorVars,
|
|
@@ -58,6 +62,11 @@ const styles = stylex.create({
|
|
|
58
62
|
*/
|
|
59
63
|
export type HoverCardFocusTrigger = 'auto' | 'always' | 'never';
|
|
60
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Touch trigger behavior for hover cards
|
|
67
|
+
*/
|
|
68
|
+
export type HoverCardTouchTrigger = LayerTouchTrigger;
|
|
69
|
+
|
|
61
70
|
export interface HoverCardOptions {
|
|
62
71
|
/**
|
|
63
72
|
* Position placement relative to anchor
|
|
@@ -93,6 +102,17 @@ export interface HoverCardOptions {
|
|
|
93
102
|
*/
|
|
94
103
|
focusTrigger?: HoverCardFocusTrigger;
|
|
95
104
|
|
|
105
|
+
/**
|
|
106
|
+
* What a tap does on a touch pointer, where there is no hover:
|
|
107
|
+
* - `auto`: tap opens the card, unless the trigger performs an action of its
|
|
108
|
+
* own (a button, a link, a form control) — that tap belongs to the control
|
|
109
|
+
* - `tap`: tap always opens the card, even on a trigger that acts
|
|
110
|
+
* - `none`: touch never opens the card
|
|
111
|
+
*
|
|
112
|
+
* @default 'auto'
|
|
113
|
+
*/
|
|
114
|
+
touchTrigger?: HoverCardTouchTrigger;
|
|
115
|
+
|
|
96
116
|
/**
|
|
97
117
|
* Whether the hover card is enabled.
|
|
98
118
|
* When false, hover/focus triggers are disabled.
|
|
@@ -240,6 +260,7 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
240
260
|
delay = 300,
|
|
241
261
|
hideDelay = 200,
|
|
242
262
|
focusTrigger = 'auto',
|
|
263
|
+
touchTrigger = 'auto',
|
|
243
264
|
isEnabled = true,
|
|
244
265
|
label,
|
|
245
266
|
isOpen,
|
|
@@ -276,6 +297,30 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
276
297
|
}
|
|
277
298
|
}, []);
|
|
278
299
|
|
|
300
|
+
// Touch resolves immediately: the hover delays exist to filter out a pointer
|
|
301
|
+
// passing across the trigger, and a tap is never that.
|
|
302
|
+
const showNow = useCallback(() => {
|
|
303
|
+
clearTimeouts();
|
|
304
|
+
layer.show();
|
|
305
|
+
}, [clearTimeouts, layer]);
|
|
306
|
+
|
|
307
|
+
const hideNow = useCallback(() => {
|
|
308
|
+
clearTimeouts();
|
|
309
|
+
isHoveringContentRef.current = false;
|
|
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
|
+
|
|
279
324
|
// Schedule show with delay (suppressed when isOpen is false)
|
|
280
325
|
const scheduleShow = useCallback(() => {
|
|
281
326
|
if (!isEnabled || isOpen === false) {
|
|
@@ -303,17 +348,42 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
303
348
|
|
|
304
349
|
// Event handlers
|
|
305
350
|
const handleMouseEnter = useCallback(() => {
|
|
351
|
+
// A tap synthesizes mouseenter. On touch the tap path owns the decision,
|
|
352
|
+
// so hover must not also fire — without this a hover card opens on every
|
|
353
|
+
// tap of its trigger and has nothing to close it.
|
|
354
|
+
if (touch.isTouchPointerRef.current) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
306
357
|
scheduleShow();
|
|
307
|
-
}, [scheduleShow]);
|
|
358
|
+
}, [touch, scheduleShow]);
|
|
308
359
|
|
|
309
360
|
const handleMouseLeave = useCallback(() => {
|
|
361
|
+
// On touch the synthesized mouseleave arrives with the next tap elsewhere,
|
|
362
|
+
// which the outside-tap dismissal already handles.
|
|
363
|
+
if (touch.isTouchPointerRef.current) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
310
366
|
scheduleHide();
|
|
311
|
-
}, [scheduleHide]);
|
|
367
|
+
}, [touch, scheduleHide]);
|
|
368
|
+
|
|
369
|
+
// Tap-to-open on touch; on a mouse this does nothing and hover still rules.
|
|
370
|
+
const handlePointerDown = useCallback(
|
|
371
|
+
(event: PointerEvent) => {
|
|
372
|
+
touch.handlePointerDown(event);
|
|
373
|
+
},
|
|
374
|
+
[touch],
|
|
375
|
+
);
|
|
312
376
|
|
|
313
377
|
const handleFocusIn = useCallback(() => {
|
|
314
378
|
if (!isEnabled) {
|
|
315
379
|
return;
|
|
316
380
|
}
|
|
381
|
+
// A tap focuses the trigger it activates. Opening on that focus would
|
|
382
|
+
// reinstate exactly the behavior the touch path just decided against —
|
|
383
|
+
// and on an action trigger it covers the thing the user tapped.
|
|
384
|
+
if (touch.isTouchInteraction()) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
317
387
|
// Skip showing if we're in the middle of an Escape dismiss
|
|
318
388
|
if (isEscapeDismissingRef.current) {
|
|
319
389
|
isEscapeDismissingRef.current = false;
|
|
@@ -321,7 +391,7 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
321
391
|
}
|
|
322
392
|
clearTimeouts();
|
|
323
393
|
layer.show();
|
|
324
|
-
}, [isEnabled, clearTimeouts, layer]);
|
|
394
|
+
}, [isEnabled, touch, clearTimeouts, layer]);
|
|
325
395
|
|
|
326
396
|
const handleFocusOut = useCallback(
|
|
327
397
|
(e: FocusEvent) => {
|
|
@@ -346,13 +416,15 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
346
416
|
e.stopPropagation();
|
|
347
417
|
// Hide immediately without refocusing (we're already on trigger)
|
|
348
418
|
clearTimeouts();
|
|
419
|
+
touch.clearTapOpen();
|
|
349
420
|
layer.hide();
|
|
350
421
|
}
|
|
351
422
|
},
|
|
352
|
-
[clearTimeouts, layer],
|
|
423
|
+
[touch, clearTimeouts, layer],
|
|
353
424
|
);
|
|
354
425
|
|
|
355
426
|
// Interaction ref that handles event listeners only
|
|
427
|
+
const {handlePointerEnter} = touch;
|
|
356
428
|
const interactionRef: RefCallback<HTMLElement> = useCallback(
|
|
357
429
|
(el: HTMLElement | null) => {
|
|
358
430
|
// Cleanup previous element
|
|
@@ -365,12 +437,24 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
365
437
|
handleFocusOut as EventListener,
|
|
366
438
|
);
|
|
367
439
|
triggerRef.current.removeEventListener('keydown', handleKeyDown);
|
|
440
|
+
triggerRef.current.removeEventListener(
|
|
441
|
+
'pointerenter',
|
|
442
|
+
handlePointerEnter,
|
|
443
|
+
);
|
|
444
|
+
triggerRef.current.removeEventListener(
|
|
445
|
+
'pointerdown',
|
|
446
|
+
handlePointerDown,
|
|
447
|
+
);
|
|
368
448
|
}
|
|
369
449
|
|
|
370
450
|
if (el) {
|
|
371
|
-
// Attach hover listeners
|
|
451
|
+
// Attach hover listeners. `pointerenter` runs before the synthesized
|
|
452
|
+
// `mouseenter` a tap produces, which is what lets the hover path know
|
|
453
|
+
// it is looking at a finger.
|
|
454
|
+
el.addEventListener('pointerenter', handlePointerEnter);
|
|
372
455
|
el.addEventListener('mouseenter', handleMouseEnter);
|
|
373
456
|
el.addEventListener('mouseleave', handleMouseLeave);
|
|
457
|
+
el.addEventListener('pointerdown', handlePointerDown);
|
|
374
458
|
|
|
375
459
|
// Attach focus listeners based on focusTrigger option
|
|
376
460
|
const shouldAttachFocus =
|
|
@@ -395,6 +479,8 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
395
479
|
handleFocusIn,
|
|
396
480
|
handleFocusOut,
|
|
397
481
|
handleKeyDown,
|
|
482
|
+
handlePointerEnter,
|
|
483
|
+
handlePointerDown,
|
|
398
484
|
],
|
|
399
485
|
);
|
|
400
486
|
|
|
@@ -475,10 +561,18 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
475
561
|
<div
|
|
476
562
|
{...stylex.props(styles.content)}
|
|
477
563
|
onMouseEnter={() => {
|
|
564
|
+
// Touch synthesizes these over the card too; letting a tap inside
|
|
565
|
+
// register as "hovering content" would block every later hide.
|
|
566
|
+
if (touch.isTouchPointerRef.current) {
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
478
569
|
isHoveringContentRef.current = true;
|
|
479
570
|
clearTimeouts();
|
|
480
571
|
}}
|
|
481
572
|
onMouseLeave={() => {
|
|
573
|
+
if (touch.isTouchPointerRef.current) {
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
482
576
|
isHoveringContentRef.current = false;
|
|
483
577
|
scheduleHide();
|
|
484
578
|
}}
|
|
@@ -490,6 +584,7 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
490
584
|
isEscapeDismissingRef.current = true;
|
|
491
585
|
// Hide immediately
|
|
492
586
|
clearTimeouts();
|
|
587
|
+
touch.clearTapOpen();
|
|
493
588
|
layer.hide();
|
|
494
589
|
// Refocus the trigger
|
|
495
590
|
triggerRef.current?.focus();
|
|
@@ -526,6 +621,7 @@ export function useHoverCard(options: HoverCardOptions = {}): HoverCardReturn {
|
|
|
526
621
|
clearTimeouts,
|
|
527
622
|
scheduleHide,
|
|
528
623
|
popoverXstyle,
|
|
624
|
+
touch,
|
|
529
625
|
],
|
|
530
626
|
);
|
|
531
627
|
|
package/src/Item/Item.doc.mjs
CHANGED
|
@@ -40,6 +40,7 @@ export const docs = {
|
|
|
40
40
|
{name: 'density', type: "'compact' | 'balanced' | 'spacious'", description: 'Spacing density. "compact" uses 4px block padding, "balanced" uses 8px, and "spacious" uses 12px block and inline padding.', default: "'balanced'"},
|
|
41
41
|
{name: 'labelLines', type: 'number', description: 'Max lines before label truncates with ellipsis.'},
|
|
42
42
|
{name: 'descriptionLines', type: 'number', description: 'Max lines before description truncates with ellipsis.'},
|
|
43
|
+
{name: 'layout', type: "'stacked' | 'inline'", description: 'How the label and description sit together. stacked puts the description on its own line below the label; inline keeps both on one line, description ellipsizing first, so the row fits a fixed-height host.', default: "'stacked'"},
|
|
43
44
|
{name: 'onClick', type: '(event: MouseEvent) => void', description: 'Click handler. Makes the item clickable with button semantics.'},
|
|
44
45
|
{name: 'interactiveRef', type: 'RefObject<HTMLElement | null>', description: 'Ref to a nested control (e.g. a checkbox in startContent) that owns the item\'s keyboard access and action. The row becomes an enlarged click/tap target that delegates surface clicks to it (useClickableContainer) and renders no invisible button/anchor, so the row adds no second tab stop (WCAG 4.1.2). Mutually exclusive with onClick/href; those are ignored when set.'},
|
|
45
46
|
{name: 'href', type: 'string', description: 'Link URL. Makes the item a link via an invisible anchor element.'},
|
package/src/Item/Item.test.tsx
CHANGED
|
@@ -508,4 +508,54 @@ describe('Item', () => {
|
|
|
508
508
|
expect(screen.getByText('Alice')).toBeInTheDocument();
|
|
509
509
|
expect(screen.getByText(/commented/)).toBeInTheDocument();
|
|
510
510
|
});
|
|
511
|
+
it('puts the label and description in one row when layout is inline', () => {
|
|
512
|
+
const stacked = render(
|
|
513
|
+
<Item label="Private" description="Only members can access" />,
|
|
514
|
+
);
|
|
515
|
+
const stackedRow = screen.getByText('Private').parentElement;
|
|
516
|
+
stacked.unmount();
|
|
517
|
+
|
|
518
|
+
render(
|
|
519
|
+
<Item
|
|
520
|
+
label="Private"
|
|
521
|
+
description="Only members can access"
|
|
522
|
+
layout="inline"
|
|
523
|
+
/>,
|
|
524
|
+
);
|
|
525
|
+
const inlineRow = screen.getByText('Private').parentElement;
|
|
526
|
+
|
|
527
|
+
// Same container, different styling: the shared content box switches from
|
|
528
|
+
// a column to a row, so its class list must differ from the stacked one.
|
|
529
|
+
expect(inlineRow?.className).not.toBe(stackedRow?.className);
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
it('ellipsizes a ReactNode description when layout is inline', () => {
|
|
533
|
+
// A stacked ReactNode description is left alone (it may wrap); an inline
|
|
534
|
+
// one is one line by definition, so it truncates like a string does.
|
|
535
|
+
const stacked = render(
|
|
536
|
+
<Item
|
|
537
|
+
label="Private"
|
|
538
|
+
description={<span>Only members can access</span>}
|
|
539
|
+
/>,
|
|
540
|
+
);
|
|
541
|
+
const stackedDescription = screen.getByText('Only members can access')
|
|
542
|
+
.parentElement?.className;
|
|
543
|
+
stacked.unmount();
|
|
544
|
+
|
|
545
|
+
render(
|
|
546
|
+
<Item
|
|
547
|
+
label="Private"
|
|
548
|
+
description={<span>Only members can access</span>}
|
|
549
|
+
layout="inline"
|
|
550
|
+
/>,
|
|
551
|
+
);
|
|
552
|
+
expect(
|
|
553
|
+
screen.getByText('Only members can access').parentElement?.className,
|
|
554
|
+
).not.toBe(stackedDescription);
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it('ignores inline layout when there is no description', () => {
|
|
558
|
+
render(<Item label="Private" layout="inline" />);
|
|
559
|
+
expect(screen.getByText('Private')).toBeInTheDocument();
|
|
560
|
+
});
|
|
511
561
|
});
|
package/src/Item/Item.tsx
CHANGED
|
@@ -106,6 +106,15 @@ export interface ItemProps extends BaseProps<HTMLElement> {
|
|
|
106
106
|
*/
|
|
107
107
|
descriptionLines?: number;
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* How the label and description sit together. `stacked` puts the description
|
|
111
|
+
* on its own line below the label; `inline` keeps both on one line, with the
|
|
112
|
+
* description ellipsizing first, so the row fits a fixed-height host.
|
|
113
|
+
*
|
|
114
|
+
* @default 'stacked'
|
|
115
|
+
*/
|
|
116
|
+
layout?: 'stacked' | 'inline';
|
|
117
|
+
|
|
109
118
|
/**
|
|
110
119
|
* Click handler. Makes the item clickable with button semantics.
|
|
111
120
|
*/
|
|
@@ -213,7 +222,7 @@ const styles = stylex.create({
|
|
|
213
222
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
214
223
|
backgroundColor: {
|
|
215
224
|
default: 'transparent',
|
|
216
|
-
':hover': {
|
|
225
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
217
226
|
'@media (hover: hover)': colorVars['--color-overlay-hover'],
|
|
218
227
|
},
|
|
219
228
|
':active': colorVars['--color-overlay-pressed'],
|
|
@@ -264,6 +273,25 @@ const styles = stylex.create({
|
|
|
264
273
|
minWidth: 0,
|
|
265
274
|
textAlign: 'start',
|
|
266
275
|
},
|
|
276
|
+
// `layout="inline"`: label and description share one line, so the row fits a
|
|
277
|
+
// fixed-height host such as a Selector trigger inside an InputGroup.
|
|
278
|
+
inlineContent: {
|
|
279
|
+
flexDirection: 'row',
|
|
280
|
+
// Centered, not baseline-aligned: two different font sizes on a shared
|
|
281
|
+
// baseline make a line box taller than either line, which would push a
|
|
282
|
+
// fixed-height host (a Selector trigger) a pixel off its size token.
|
|
283
|
+
alignItems: 'center',
|
|
284
|
+
columnGap: spacingVars['--spacing-1'],
|
|
285
|
+
},
|
|
286
|
+
inlineLabel: {
|
|
287
|
+
flexShrink: 0,
|
|
288
|
+
},
|
|
289
|
+
// The description yields width first, so the label — the part that identifies
|
|
290
|
+
// the item — is the last thing to ellipsize.
|
|
291
|
+
inlineDescription: {
|
|
292
|
+
flexShrink: 1,
|
|
293
|
+
minWidth: 0,
|
|
294
|
+
},
|
|
267
295
|
label: {
|
|
268
296
|
// Falls back to the primary text token; a parent (e.g. a destructive menu
|
|
269
297
|
// item) can recolor the label by setting --_item-label-color.
|
|
@@ -358,6 +386,7 @@ export function Item({
|
|
|
358
386
|
density = 'balanced',
|
|
359
387
|
labelLines,
|
|
360
388
|
descriptionLines,
|
|
389
|
+
layout = 'stacked',
|
|
361
390
|
onClick,
|
|
362
391
|
interactiveRef,
|
|
363
392
|
href,
|
|
@@ -420,12 +449,16 @@ export function Item({
|
|
|
420
449
|
? styles.labelSingleTruncate
|
|
421
450
|
: null;
|
|
422
451
|
|
|
452
|
+
// Inline rows are one line by definition, so the description always
|
|
453
|
+
// ellipsizes there — a ReactNode description cannot wrap the row open.
|
|
454
|
+
const isInline = layout === 'inline' && description != null;
|
|
455
|
+
|
|
423
456
|
const descriptionTruncateStyle =
|
|
424
457
|
descriptionLines != null
|
|
425
458
|
? descriptionLines === 1
|
|
426
459
|
? styles.descriptionSingleTruncate
|
|
427
460
|
: styles.descriptionMultiTruncate
|
|
428
|
-
: isStringDescription
|
|
461
|
+
: isStringDescription || isInline
|
|
429
462
|
? styles.descriptionSingleTruncate
|
|
430
463
|
: null;
|
|
431
464
|
|
|
@@ -434,6 +467,7 @@ export function Item({
|
|
|
434
467
|
<span
|
|
435
468
|
{...stylex.props(
|
|
436
469
|
styles.label,
|
|
470
|
+
isInline && styles.inlineLabel,
|
|
437
471
|
labelTruncateStyle,
|
|
438
472
|
labelLines != null &&
|
|
439
473
|
labelLines > 1 &&
|
|
@@ -445,6 +479,7 @@ export function Item({
|
|
|
445
479
|
<span
|
|
446
480
|
{...stylex.props(
|
|
447
481
|
styles.description,
|
|
482
|
+
isInline && styles.inlineDescription,
|
|
448
483
|
descriptionTruncateStyle,
|
|
449
484
|
descriptionLines != null &&
|
|
450
485
|
descriptionLines > 1 &&
|
|
@@ -481,6 +516,7 @@ export function Item({
|
|
|
481
516
|
<span
|
|
482
517
|
{...stylex.props(
|
|
483
518
|
styles.content,
|
|
519
|
+
isInline && styles.inlineContent,
|
|
484
520
|
isDisabled && styles.disabledContent,
|
|
485
521
|
)}>
|
|
486
522
|
{labelAndDescription}
|
|
@@ -494,6 +530,7 @@ export function Item({
|
|
|
494
530
|
tabIndex={isDisabled ? -1 : undefined}
|
|
495
531
|
{...stylex.props(
|
|
496
532
|
styles.invisibleAnchor,
|
|
533
|
+
isInline && styles.inlineContent,
|
|
497
534
|
isDisabled && styles.disabledContent,
|
|
498
535
|
)}>
|
|
499
536
|
{labelAndDescription}
|
|
@@ -505,6 +542,7 @@ export function Item({
|
|
|
505
542
|
disabled={isDisabled}
|
|
506
543
|
{...stylex.props(
|
|
507
544
|
styles.invisibleButton,
|
|
545
|
+
isInline && styles.inlineContent,
|
|
508
546
|
isDisabled && styles.disabledContent,
|
|
509
547
|
)}>
|
|
510
548
|
{labelAndDescription}
|
|
@@ -513,6 +551,7 @@ export function Item({
|
|
|
513
551
|
<span
|
|
514
552
|
{...stylex.props(
|
|
515
553
|
styles.content,
|
|
554
|
+
isInline && styles.inlineContent,
|
|
516
555
|
isDisabled && styles.disabledContent,
|
|
517
556
|
)}>
|
|
518
557
|
{labelAndDescription}
|
package/src/Layer/index.ts
CHANGED
|
@@ -29,6 +29,14 @@ export type {
|
|
|
29
29
|
FixedLayerReturn,
|
|
30
30
|
} from './useLayer';
|
|
31
31
|
|
|
32
|
+
// Shared touch behavior for the hover layers
|
|
33
|
+
export {useTouchTrigger, isActionTrigger} from './useTouchTrigger';
|
|
34
|
+
export type {
|
|
35
|
+
LayerTouchTrigger,
|
|
36
|
+
UseTouchTriggerOptions,
|
|
37
|
+
UseTouchTriggerReturn,
|
|
38
|
+
} from './useTouchTrigger';
|
|
39
|
+
|
|
32
40
|
// Layer provider
|
|
33
41
|
export {LayerProvider} from './LayerProvider';
|
|
34
42
|
export type {LayerProviderProps} from './LayerProvider';
|
|
@@ -50,6 +58,7 @@ export type {
|
|
|
50
58
|
export {useHoverCard, HoverCard} from '../HoverCard';
|
|
51
59
|
export type {
|
|
52
60
|
HoverCardFocusTrigger,
|
|
61
|
+
HoverCardTouchTrigger,
|
|
53
62
|
HoverCardOptions,
|
|
54
63
|
HoverCardReturn,
|
|
55
64
|
HoverCardProps,
|
|
@@ -59,6 +68,7 @@ export type {
|
|
|
59
68
|
export {useTooltip, Tooltip} from '../Tooltip';
|
|
60
69
|
export type {
|
|
61
70
|
TooltipFocusTrigger,
|
|
71
|
+
TooltipTouchTrigger,
|
|
62
72
|
TooltipOptions,
|
|
63
73
|
TooltipReturn,
|
|
64
74
|
TooltipProps,
|
package/src/Layer/useLayer.tsx
CHANGED
|
@@ -29,6 +29,7 @@ import {createPortal} from 'react-dom';
|
|
|
29
29
|
import {addAnchorName, removeAnchorName} from './anchorName';
|
|
30
30
|
import {resolveLayerPortalTarget} from './layerHost';
|
|
31
31
|
import {typeScaleVars, typographyVars} from '../theme/tokens.stylex';
|
|
32
|
+
import {overlayPaddingReset} from '../Layout/padding.stylex';
|
|
32
33
|
|
|
33
34
|
const styles = stylex.create({
|
|
34
35
|
// Base reset for all layers
|
|
@@ -771,7 +772,12 @@ export function useLayer(
|
|
|
771
772
|
: styles.offsetInline(toCssLength(offset))
|
|
772
773
|
: null;
|
|
773
774
|
|
|
774
|
-
const stylexResult = stylex.props(
|
|
775
|
+
const stylexResult = stylex.props(
|
|
776
|
+
styles.base,
|
|
777
|
+
overlayPaddingReset.reset,
|
|
778
|
+
offsetStyle,
|
|
779
|
+
xstyle,
|
|
780
|
+
);
|
|
775
781
|
const combinedClassName = extraClassName
|
|
776
782
|
? `${extraClassName} ${stylexResult.className ?? ''}`
|
|
777
783
|
: stylexResult.className;
|
|
@@ -835,7 +841,12 @@ export function useLayer(
|
|
|
835
841
|
left: x,
|
|
836
842
|
};
|
|
837
843
|
|
|
838
|
-
const stylexResult = stylex.props(
|
|
844
|
+
const stylexResult = stylex.props(
|
|
845
|
+
styles.base,
|
|
846
|
+
overlayPaddingReset.reset,
|
|
847
|
+
styles.fixed,
|
|
848
|
+
xstyle,
|
|
849
|
+
);
|
|
839
850
|
const combinedClassName = extraClassName
|
|
840
851
|
? `${extraClassName} ${stylexResult.className ?? ''}`
|
|
841
852
|
: stylexResult.className;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file useTouchTrigger.test.ts
|
|
5
|
+
* @input Uses vitest, isActionTrigger
|
|
6
|
+
* @output Unit tests for the action-trigger rule behind touchTrigger="auto"
|
|
7
|
+
* @position Testing; validates useTouchTrigger.ts implementation
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When useTouchTrigger.ts changes, update tests to match new behavior
|
|
10
|
+
*
|
|
11
|
+
* The tap-versus-suppress decision rests entirely on this predicate, and it is
|
|
12
|
+
* the part a new element type silently falls through. The per-component tests
|
|
13
|
+
* (Tooltip.test.tsx, HoverCard.test.tsx) cover the gestures it feeds.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import {describe, it, expect} from 'vitest';
|
|
17
|
+
import {isActionTrigger} from './useTouchTrigger';
|
|
18
|
+
|
|
19
|
+
function element(html: string): HTMLElement {
|
|
20
|
+
const host = document.createElement('div');
|
|
21
|
+
host.innerHTML = html;
|
|
22
|
+
return host.firstElementChild as HTMLElement;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe('isActionTrigger', () => {
|
|
26
|
+
it.each([
|
|
27
|
+
['<button type="button">Save</button>'],
|
|
28
|
+
['<input type="text" />'],
|
|
29
|
+
['<select></select>'],
|
|
30
|
+
['<textarea></textarea>'],
|
|
31
|
+
['<summary>More</summary>'],
|
|
32
|
+
['<label>Name</label>'],
|
|
33
|
+
['<a href="/somewhere">Link</a>'],
|
|
34
|
+
])('treats %s as an action', html => {
|
|
35
|
+
expect(isActionTrigger(element(html))).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it.each([
|
|
39
|
+
['<span>Plain text</span>'],
|
|
40
|
+
['<svg></svg>'],
|
|
41
|
+
['<abbr title="what">WCAG</abbr>'],
|
|
42
|
+
// An anchor without href is a link that goes nowhere.
|
|
43
|
+
['<a>Not a link</a>'],
|
|
44
|
+
])('treats %s as inert', html => {
|
|
45
|
+
expect(isActionTrigger(element(html))).toBe(false);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('reads an explicit role over the tag it sits on', () => {
|
|
49
|
+
expect(isActionTrigger(element('<span role="button">Go</span>'))).toBe(
|
|
50
|
+
true,
|
|
51
|
+
);
|
|
52
|
+
// Scenery: the role says this button is not the control it looks like.
|
|
53
|
+
expect(
|
|
54
|
+
isActionTrigger(element('<button role="presentation">x</button>')),
|
|
55
|
+
).toBe(false);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('does not treat mere focusability as an action', () => {
|
|
59
|
+
// The wrapper a text-only Tooltip renders: reachable by keyboard so the
|
|
60
|
+
// hint is not mouse-only, and it still does nothing when activated.
|
|
61
|
+
expect(isActionTrigger(element('<span tabindex="0">Term</span>'))).toBe(
|
|
62
|
+
false,
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('treats a contenteditable surface as an action', () => {
|
|
67
|
+
const editable = element('<div contenteditable="true"></div>');
|
|
68
|
+
expect(isActionTrigger(editable)).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
});
|