@astryxdesign/core 0.4.5 → 0.4.6-canary.cea9ecd
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +134 -0
- package/dist/Avatar/Avatar.d.ts +10 -5
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +139 -30
- package/dist/Avatar/AvatarStatusDot.d.ts +2 -1
- package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
- package/dist/Avatar/AvatarStatusDot.js +30 -4
- package/dist/Avatar/AvatarStatusLabelContext.d.ts +39 -0
- package/dist/Avatar/AvatarStatusLabelContext.d.ts.map +1 -0
- package/dist/Avatar/AvatarStatusLabelContext.js +41 -0
- package/dist/AvatarGroup/AvatarGroup.d.ts +3 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +15 -9
- package/dist/Blockquote/Blockquote.d.ts +4 -3
- package/dist/Blockquote/Blockquote.d.ts.map +1 -1
- package/dist/Blockquote/Blockquote.js +9 -10
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +21 -5
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +47 -34
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +7 -7
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +21 -12
- package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
- package/dist/Calendar/hooks/useCalendarNavigation.js +8 -4
- package/dist/Calendar/styles.d.ts +2 -2
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +5 -5
- package/dist/Center/Center.d.ts +23 -1
- package/dist/Center/Center.d.ts.map +1 -1
- package/dist/Center/Center.js +12 -6
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +3 -3
- package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
- package/dist/Chat/ChatComposerDrawer.js +2 -2
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +2 -2
- package/dist/Chat/useChatDictation.d.ts +1 -1
- package/dist/Chat/useChatDictation.d.ts.map +1 -1
- package/dist/Chat/useSpeechRecognition.d.ts +1 -1
- package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
- package/dist/Chat/useSpeechRecognition.js +4 -3
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +2 -2
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +2 -2
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +5 -5
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +4 -4
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +1 -1
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +2 -2
- package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteItem.js +3 -3
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +6 -6
- package/dist/DateInput/DateInput.d.ts +31 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +90 -22
- package/dist/DateInput/MonthScroller.d.ts +35 -0
- package/dist/DateInput/MonthScroller.d.ts.map +1 -0
- package/dist/DateInput/MonthScroller.js +658 -0
- package/dist/DateInput/MonthYearWheels.d.ts +24 -0
- package/dist/DateInput/MonthYearWheels.d.ts.map +1 -0
- package/dist/DateInput/MonthYearWheels.js +114 -0
- package/dist/DateInput/TouchDateField.d.ts +10 -0
- package/dist/DateInput/TouchDateField.d.ts.map +1 -0
- package/dist/DateInput/TouchDateField.js +810 -0
- package/dist/DateInput/Wheel.d.ts +41 -0
- package/dist/DateInput/Wheel.d.ts.map +1 -0
- package/dist/DateInput/Wheel.js +315 -0
- package/dist/DateInput/monthGeometry.d.ts +65 -0
- package/dist/DateInput/monthGeometry.d.ts.map +1 -0
- package/dist/DateInput/monthGeometry.js +98 -0
- package/dist/DateInput/tokens.stylex.d.ts +63 -0
- package/dist/DateInput/tokens.stylex.d.ts.map +1 -0
- package/dist/DateInput/tokens.stylex.js +74 -0
- package/dist/DateInput/useOwnScrollGesture.d.ts +41 -0
- package/dist/DateInput/useOwnScrollGesture.d.ts.map +1 -0
- package/dist/DateInput/useOwnScrollGesture.js +202 -0
- package/dist/DateInput/usePointerDragScroll.d.ts +15 -0
- package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -0
- package/dist/DateInput/usePointerDragScroll.js +216 -0
- package/dist/DateInput/useScrollSettle.d.ts +26 -0
- package/dist/DateInput/useScrollSettle.d.ts.map +1 -0
- package/dist/DateInput/useScrollSettle.js +149 -0
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +17 -14
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +17 -14
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +3 -3
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +2 -2
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +2 -2
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +2 -2
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +2 -2
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +4 -4
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +6 -0
- package/dist/Field/inputStyles.stylex.d.ts +1 -1
- package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
- package/dist/Field/inputStyles.stylex.js +5 -5
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +6 -6
- package/dist/HoverCard/HoverCard.d.ts +13 -3
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +2 -0
- package/dist/HoverCard/index.d.ts +1 -1
- package/dist/HoverCard/index.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.d.ts +17 -2
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +78 -9
- package/dist/InputGroup/InputGroup.js +1 -1
- package/dist/Item/Item.d.ts +9 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +52 -14
- package/dist/Layer/index.d.ts +4 -2
- package/dist/Layer/index.d.ts.map +1 -1
- package/dist/Layer/index.js +2 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +3 -2
- package/dist/Layer/useTouchTrigger.d.ts +113 -0
- package/dist/Layer/useTouchTrigger.d.ts.map +1 -0
- package/dist/Layer/useTouchTrigger.js +241 -0
- package/dist/Layout/container.stylex.d.ts +4 -2
- package/dist/Layout/container.stylex.d.ts.map +1 -1
- package/dist/Layout/container.stylex.js +19 -11
- package/dist/Layout/index.d.ts +1 -0
- package/dist/Layout/index.d.ts.map +1 -1
- package/dist/Layout/index.js +4 -0
- package/dist/Layout/padding.stylex.d.ts +315 -12
- package/dist/Layout/padding.stylex.d.ts.map +1 -1
- package/dist/Layout/padding.stylex.js +389 -12
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +5 -4
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +6 -6
- package/dist/MetadataList/MetadataList.d.ts.map +1 -1
- package/dist/MetadataList/MetadataList.js +1 -1
- package/dist/MobileNav/MobileNav.d.ts +1 -0
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +24 -6
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +8 -8
- package/dist/NavItem/navItemStyles.stylex.d.ts +4 -4
- package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
- package/dist/NavItem/navItemStyles.stylex.js +4 -4
- package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenuItem.js +3 -3
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +36 -8
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +3 -3
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +2 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +11 -12
- package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchToken.js +3 -1
- package/dist/PowerSearch/formatFilterValue.d.ts +11 -2
- package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
- package/dist/PowerSearch/formatFilterValue.js +23 -8
- package/dist/RadioList/RadioListItem.d.ts +2 -2
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +70 -40
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +7 -7
- package/dist/Section/Section.d.ts +36 -1
- package/dist/Section/Section.d.ts.map +1 -1
- package/dist/Section/Section.js +12 -2
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +7 -2
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +3 -3
- package/dist/Selector/Selector.d.ts +26 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +93 -20
- package/dist/Selector/SelectorOption.d.ts +14 -1
- package/dist/Selector/SelectorOption.d.ts.map +1 -1
- package/dist/Selector/SelectorOption.js +6 -0
- package/dist/Selector/SelectorRowLayoutContext.d.ts +8 -0
- package/dist/Selector/SelectorRowLayoutContext.d.ts.map +1 -0
- package/dist/Selector/SelectorRowLayoutContext.js +27 -0
- package/dist/Selector/types.d.ts +1 -0
- package/dist/Selector/types.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +4 -4
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +3 -3
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +7 -7
- package/dist/Stack/Stack.d.ts +23 -1
- package/dist/Stack/Stack.d.ts.map +1 -1
- package/dist/Stack/Stack.js +12 -6
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +2 -2
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +1 -1
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +3 -3
- package/dist/Table/TableRow.js +4 -4
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.js +2 -2
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +2 -2
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +2 -2
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts +5 -3
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.js +12 -9
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.js +3 -3
- package/dist/TextArea/TextArea.js +1 -1
- package/dist/TextInput/TextInput.js +1 -1
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +3 -3
- package/dist/TimeInput/TimeInput.js +2 -2
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +6 -4
- package/dist/Timestamp/formatInstant.d.ts +3 -2
- package/dist/Timestamp/formatInstant.d.ts.map +1 -1
- package/dist/Timestamp/formatInstant.js +8 -8
- package/dist/Timestamp/tooltipEntries.d.ts +2 -1
- package/dist/Timestamp/tooltipEntries.d.ts.map +1 -1
- package/dist/Timestamp/tooltipEntries.js +5 -3
- package/dist/Toast/Toast.d.ts +4 -3
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +10 -7
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +6 -6
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +1 -1
- package/dist/Tooltip/Tooltip.d.ts +16 -3
- package/dist/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip/Tooltip.js +2 -0
- package/dist/Tooltip/index.d.ts +1 -1
- package/dist/Tooltip/index.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.d.ts +21 -2
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +71 -13
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +4 -4
- package/dist/TopNav/TopNavItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavItem.js +3 -3
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +2 -2
- package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuItem.js +2 -2
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +4 -4
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +7 -7
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +2 -2
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +1 -1
- package/dist/astryx.css +124 -62
- package/dist/hooks/containerReveal.stylex.d.ts.map +1 -1
- package/dist/hooks/containerReveal.stylex.js +18 -18
- package/dist/hooks/scrollbarGutter.d.ts +28 -0
- package/dist/hooks/scrollbarGutter.d.ts.map +1 -0
- package/dist/hooks/scrollbarGutter.js +103 -0
- package/dist/hooks/useAutoMediaMode.d.ts +31 -0
- package/dist/hooks/useAutoMediaMode.d.ts.map +1 -0
- package/dist/hooks/useAutoMediaMode.js +201 -0
- package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
- package/dist/hooks/useInputStatusIcon.js +1 -1
- package/dist/hooks/useListFocus.d.ts +5 -2
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +12 -6
- package/dist/hooks/useScrollLock.d.ts +4 -0
- package/dist/hooks/useScrollLock.d.ts.map +1 -1
- package/dist/hooks/useScrollLock.js +13 -1
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationContext.js +2 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +6 -0
- package/dist/i18n/useCollator.d.ts +12 -0
- package/dist/i18n/useCollator.d.ts.map +1 -0
- package/dist/i18n/useCollator.js +40 -0
- package/dist/i18n/useLocale.d.ts +3 -0
- package/dist/i18n/useLocale.d.ts.map +1 -0
- package/dist/i18n/useLocale.js +31 -0
- package/dist/theme/MediaTheme.d.ts +25 -5
- package/dist/theme/MediaTheme.d.ts.map +1 -1
- package/dist/theme/MediaTheme.js +31 -6
- package/dist/theme/defineTheme.d.ts +5 -0
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +5 -0
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +7 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +66 -5
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/syntax/index.d.ts +6 -0
- package/dist/theme/syntax/index.d.ts.map +1 -1
- package/dist/theme/syntax/index.js +7 -2
- package/dist/utils/dateParser.d.ts +4 -3
- package/dist/utils/dateParser.d.ts.map +1 -1
- package/dist/utils/dateParser.js +8 -8
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/plainDate.d.ts +5 -2
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +20 -4
- package/locales/en.json +28 -0
- package/locales/pseudo.json +21 -0
- package/package.json +3 -3
- package/src/Avatar/Avatar.doc.mjs +10 -6
- package/src/Avatar/Avatar.test.tsx +219 -1
- package/src/Avatar/Avatar.tsx +179 -37
- package/src/Avatar/AvatarStatusDot.tsx +30 -4
- package/src/Avatar/AvatarStatusLabelContext.ts +47 -0
- package/src/AvatarGroup/AvatarGroup.doc.mjs +10 -6
- package/src/AvatarGroup/AvatarGroup.test.tsx +62 -0
- package/src/AvatarGroup/AvatarGroup.tsx +3 -1
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +31 -8
- package/src/Banner/Banner.doc.mjs +2 -0
- package/src/Blockquote/Blockquote.doc.mjs +30 -7
- package/src/Blockquote/Blockquote.test.tsx +34 -3
- package/src/Blockquote/Blockquote.tsx +11 -9
- package/src/BottomSheet/BottomSheet.doc.mjs +3 -3
- package/src/BottomSheet/BottomSheet.test.tsx +24 -0
- package/src/BottomSheet/BottomSheetPanel.test.tsx +91 -0
- package/src/BottomSheet/BottomSheetPanel.tsx +58 -3
- package/src/Breadcrumbs/BreadcrumbItem.tsx +36 -23
- package/src/Breadcrumbs/Breadcrumbs.doc.mjs +26 -2
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -0
- package/src/Button/Button.tsx +12 -9
- package/src/Calendar/Calendar.tsx +15 -9
- package/src/Calendar/hooks/useCalendarNavigation.ts +6 -4
- package/src/Calendar/styles.ts +8 -5
- package/src/Center/Center.doc.mjs +48 -0
- package/src/Center/Center.test.tsx +158 -0
- package/src/Center/Center.tsx +50 -9
- package/src/Chat/ChatComposer.tsx +11 -5
- package/src/Chat/ChatComposerDrawer.tsx +4 -1
- package/src/Chat/ChatToolCalls.tsx +13 -4
- package/src/Chat/{useChatDictation.test.ts → useChatDictation.test.tsx} +29 -14
- package/src/Chat/useChatDictation.ts +1 -1
- package/src/Chat/useSpeechRecognition.ts +5 -3
- package/src/Chat/useTriggerMenu.tsx +4 -1
- package/src/CheckboxInput/CheckboxInput.tsx +5 -2
- package/src/Citation/Citation.test.tsx +6 -1
- package/src/Citation/Citation.tsx +11 -5
- package/src/ClickableCard/ClickableCard.tsx +7 -4
- package/src/CodeBlock/CodeBlock.tsx +4 -1
- package/src/Collapsible/Collapsible.tsx +5 -2
- package/src/CommandPalette/CommandPaletteItem.tsx +6 -3
- package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -0
- package/src/ComplexSelector/ComplexSelector.tsx +14 -7
- package/src/DateInput/DateInput.test.tsx +17 -1
- package/src/DateInput/DateInput.tsx +93 -21
- package/src/DateInput/DateInputTouch.test.tsx +2582 -0
- package/src/DateInput/MonthScroller.tsx +878 -0
- package/src/DateInput/MonthYearWheels.tsx +147 -0
- package/src/DateInput/TouchDateField.tsx +1223 -0
- package/src/DateInput/Wheel.tsx +473 -0
- package/src/DateInput/monthGeometry.ts +118 -0
- package/src/DateInput/tokens.stylex.ts +99 -0
- package/src/DateInput/useOwnScrollGesture.ts +227 -0
- package/src/DateInput/usePointerDragScroll.ts +220 -0
- package/src/DateInput/useScrollSettle.ts +164 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
- package/src/DateRangeInput/DateRangeInput.tsx +31 -13
- package/src/DateTimeInput/DateTimeInput.tsx +25 -9
- package/src/Dialog/Dialog.test.tsx +24 -0
- package/src/Dialog/Dialog.tsx +3 -0
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +5 -2
- package/src/DropdownMenu/DropdownMenuItem.tsx +5 -2
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +5 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +5 -2
- package/src/Field/Field.doc.mjs +2 -0
- package/src/Field/FieldLabel.tsx +9 -3
- package/src/Field/InputClearButton.test.tsx +110 -3
- package/src/Field/InputClearButton.tsx +38 -0
- package/src/Field/inputStyles.stylex.ts +17 -13
- package/src/FileInput/FileInput.tsx +15 -8
- package/src/FormLayout/FormLayout.doc.mjs +1 -1
- package/src/HoverCard/HoverCard.doc.mjs +18 -0
- package/src/HoverCard/HoverCard.test.tsx +189 -0
- package/src/HoverCard/HoverCard.tsx +22 -2
- package/src/HoverCard/index.ts +1 -0
- package/src/HoverCard/useHoverCard.doc.mjs +2 -0
- package/src/HoverCard/useHoverCard.tsx +103 -7
- package/src/InputGroup/InputGroup.tsx +1 -1
- package/src/Item/Item.doc.mjs +1 -0
- package/src/Item/Item.test.tsx +50 -0
- package/src/Item/Item.tsx +54 -6
- package/src/Layer/index.ts +10 -0
- package/src/Layer/useLayer.tsx +13 -2
- package/src/Layer/useTouchTrigger.test.ts +70 -0
- package/src/Layer/useTouchTrigger.ts +366 -0
- package/src/Layout/Layout.doc.mjs +18 -0
- package/src/Layout/container.stylex.ts +11 -3
- package/src/Layout/index.ts +4 -0
- package/src/Layout/overlayPaddingReset.test.tsx +222 -0
- package/src/Layout/padding.stylex.ts +192 -12
- package/src/Lightbox/Lightbox.tsx +11 -3
- package/src/Link/Link.tsx +9 -6
- package/src/MetadataList/MetadataList.tsx +4 -1
- package/src/MobileNav/MobileNav.tsx +61 -5
- package/src/MobileNav/MobileNavEntryAnimation.test.tsx +212 -0
- package/src/MobileNav/MobileNavScrollbarGutter.test.tsx +109 -0
- package/src/MultiSelector/MultiSelector.test.tsx +1 -1
- package/src/MultiSelector/MultiSelector.tsx +26 -10
- package/src/NavItem/navItemStyles.stylex.ts +7 -4
- package/src/NavMenu/NavHeadingMenuItem.tsx +6 -3
- package/src/NumberInput/NumberInput.doc.mjs +24 -0
- package/src/NumberInput/NumberInput.test.tsx +138 -0
- package/src/NumberInput/NumberInput.tsx +47 -8
- package/src/Outline/Outline.tsx +5 -2
- package/src/Pagination/Pagination.tsx +5 -2
- package/src/Popover/Popover.test.tsx +27 -1
- package/src/PowerSearch/PowerSearch.tsx +17 -8
- package/src/PowerSearch/PowerSearchToken.tsx +3 -0
- package/src/PowerSearch/formatFilterValue.test.ts +22 -2
- package/src/PowerSearch/formatFilterValue.ts +31 -6
- package/src/RadioList/RadioList.doc.mjs +1 -1
- package/src/RadioList/RadioList.test.tsx +170 -2
- package/src/RadioList/RadioListItem.tsx +88 -53
- package/src/Resizable/ResizeHandle.test.tsx +22 -0
- package/src/Resizable/ResizeHandle.tsx +25 -7
- package/src/Section/Section.doc.mjs +55 -0
- package/src/Section/Section.test.tsx +201 -4
- package/src/Section/Section.tsx +69 -0
- package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +15 -3
- package/src/SelectableCard/SelectableCard.tsx +6 -3
- package/src/Selector/Selector.doc.mjs +16 -2
- package/src/Selector/Selector.test.tsx +525 -1
- package/src/Selector/Selector.tsx +180 -25
- package/src/Selector/SelectorOption.doc.mjs +7 -0
- package/src/Selector/SelectorOption.tsx +21 -0
- package/src/Selector/SelectorRowLayoutContext.ts +32 -0
- package/src/Selector/types.ts +4 -4
- package/src/SideNav/SideNavHeading.tsx +14 -5
- package/src/SideNav/SideNavItem.tsx +9 -3
- package/src/Slider/Slider.tsx +25 -6
- package/src/Stack/Stack.doc.mjs +72 -0
- package/src/Stack/Stack.test.tsx +156 -0
- package/src/Stack/Stack.tsx +50 -8
- package/src/Switch/Switch.tsx +5 -2
- package/src/TabList/Tab.tsx +4 -1
- package/src/TabList/TabMenu.tsx +9 -3
- package/src/Table/TableRow.tsx +4 -4
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +6 -2
- package/src/Table/plugins/filtering/useTableFiltering.tsx +4 -1
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +10 -3
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +6 -3
- package/src/Table/plugins/sortable/useTableSortable.tsx +4 -1
- package/src/Table/plugins/sortable/useTableSortableState.test.tsx +34 -0
- package/src/Table/plugins/sortable/useTableSortableState.tsx +26 -23
- package/src/Table/plugins/tree/useTableTreeData.tsx +10 -4
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextArea/TextArea.tsx +1 -1
- package/src/TextInput/TextInput.tsx +1 -1
- package/src/Thumbnail/Thumbnail.tsx +9 -3
- package/src/TimeInput/TimeInput.tsx +1 -1
- package/src/Timestamp/Timestamp.test.tsx +27 -7
- package/src/Timestamp/Timestamp.tsx +8 -4
- package/src/Timestamp/formatInstant.ts +9 -7
- package/src/Timestamp/tooltipEntries.test.ts +11 -6
- package/src/Timestamp/tooltipEntries.ts +6 -2
- package/src/Toast/Toast.tsx +9 -7
- package/src/Token/Token.tsx +14 -5
- package/src/Tokenizer/Tokenizer.tsx +4 -1
- package/src/Tooltip/Tooltip.doc.mjs +18 -0
- package/src/Tooltip/Tooltip.test.tsx +254 -1
- package/src/Tooltip/Tooltip.tsx +22 -2
- package/src/Tooltip/index.ts +1 -0
- package/src/Tooltip/useTooltip.doc.mjs +2 -0
- package/src/Tooltip/useTooltip.tsx +99 -21
- package/src/TopNav/TopNavHeading.tsx +13 -4
- package/src/TopNav/TopNavItem.tsx +6 -3
- package/src/TopNav/TopNavMegaMenu.tsx +5 -2
- package/src/TopNav/TopNavMegaMenuItem.tsx +5 -2
- package/src/TopNav/TopNavMenu.tsx +10 -4
- package/src/TreeList/TreeListItem.tsx +22 -7
- package/src/Typeahead/BaseTypeahead.tsx +5 -2
- package/src/Typeahead/Typeahead.tsx +4 -1
- package/src/hooks/containerReveal.stylex.ts +54 -18
- package/src/hooks/scrollbarGutter.test.ts +167 -0
- package/src/hooks/scrollbarGutter.ts +121 -0
- package/src/hooks/useAutoMediaMode.test.ts +109 -0
- package/src/hooks/useAutoMediaMode.ts +233 -0
- package/src/hooks/useInputStatusIcon.tsx +4 -1
- package/src/hooks/useListFocus.doc.mjs +2 -2
- package/src/hooks/useListFocus.test.tsx +65 -3
- package/src/hooks/useListFocus.ts +15 -7
- package/src/hooks/useScrollLock.doc.mjs +4 -4
- package/src/hooks/useScrollLock.test.ts +73 -0
- package/src/hooks/useScrollLock.ts +14 -0
- package/src/i18n/InternationalizationContext.ts +2 -0
- package/src/i18n/__tests__/e2e-powersearch.test.tsx +37 -1
- package/src/i18n/__tests__/useCollator.test.tsx +115 -0
- package/src/i18n/__tests__/useLocale.test.tsx +52 -0
- package/src/i18n/index.ts +6 -0
- package/src/i18n/useCollator.doc.mjs +84 -0
- package/src/i18n/useCollator.ts +44 -0
- package/src/i18n/useLocale.doc.mjs +70 -0
- package/src/i18n/useLocale.ts +34 -0
- package/src/i18n/useTranslator.doc.mjs +1 -1
- package/src/reset.css +9 -2
- package/src/reset.test.ts +22 -0
- package/src/theme/MediaTheme.doc.mjs +23 -4
- package/src/theme/MediaTheme.dom.test.tsx +97 -0
- package/src/theme/MediaTheme.tsx +42 -7
- package/src/theme/defineTheme.test.ts +9 -3
- package/src/theme/defineTheme.ts +5 -0
- package/src/theme/derivedVarRegistry.test.ts +19 -5
- package/src/theme/derivedVarRegistry.ts +4 -0
- package/src/theme/generateThemeRules.test.ts +118 -0
- package/src/theme/generateThemeRules.ts +83 -5
- package/src/theme/index.ts +1 -1
- package/src/theme/syntax/index.ts +6 -2
- package/src/theme/syntax/serverSafeSyntax.test.ts +68 -0
- package/src/utils/dateParser.test.ts +20 -0
- package/src/utils/dateParser.ts +14 -7
- package/src/utils/index.ts +2 -0
- package/src/utils/plainDate.test.ts +6 -0
- package/src/utils/plainDate.ts +21 -4
|
@@ -152,13 +152,16 @@ const styles = stylex.create({
|
|
|
152
152
|
'@media (prefers-reduced-motion: reduce)': '0s',
|
|
153
153
|
},
|
|
154
154
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
155
|
-
cursor:
|
|
155
|
+
cursor: {
|
|
156
|
+
default: 'pointer',
|
|
157
|
+
':is(:disabled,[aria-disabled="true"])': 'default',
|
|
158
|
+
},
|
|
156
159
|
outline: 'none',
|
|
157
160
|
},
|
|
158
161
|
dropzoneHover: {
|
|
159
162
|
boxShadow: {
|
|
160
163
|
default: null,
|
|
161
|
-
':hover': {
|
|
164
|
+
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
162
165
|
'@media (hover: hover)': `inset 0 0 0 2px color-mix(in srgb, ${colorVars['--color-accent']} 20%, transparent)`,
|
|
163
166
|
},
|
|
164
167
|
},
|
|
@@ -168,7 +171,7 @@ const styles = stylex.create({
|
|
|
168
171
|
backgroundColor: colorVars['--color-accent-muted'],
|
|
169
172
|
},
|
|
170
173
|
dropzoneDisabled: {
|
|
171
|
-
cursor: '
|
|
174
|
+
cursor: 'default',
|
|
172
175
|
opacity: 0.5,
|
|
173
176
|
borderColor: colorVars['--color-border-emphasized'],
|
|
174
177
|
},
|
|
@@ -197,16 +200,20 @@ const styles = stylex.create({
|
|
|
197
200
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
198
201
|
boxShadow: {
|
|
199
202
|
default: 'none',
|
|
200
|
-
':hover:not(:focus-within)':
|
|
201
|
-
|
|
202
|
-
|
|
203
|
+
':hover:not(:focus-within):where(:not(:disabled,[aria-disabled="true"]))':
|
|
204
|
+
{
|
|
205
|
+
'@media (hover: hover)': `inset 0 0 0 2px color-mix(in srgb, ${colorVars['--color-accent']} 20%, transparent)`,
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
cursor: {
|
|
209
|
+
default: 'pointer',
|
|
210
|
+
':is(:disabled,[aria-disabled="true"])': 'default',
|
|
203
211
|
},
|
|
204
|
-
cursor: 'pointer',
|
|
205
212
|
height: sizeVars['--size-element-md'],
|
|
206
213
|
outline: 'none',
|
|
207
214
|
},
|
|
208
215
|
compactDisabled: {
|
|
209
|
-
cursor: '
|
|
216
|
+
cursor: 'default',
|
|
210
217
|
opacity: 0.5,
|
|
211
218
|
borderColor: colorVars['--color-border-emphasized'],
|
|
212
219
|
},
|
|
@@ -20,7 +20,7 @@ export const docs = {
|
|
|
20
20
|
name: 'defaultOptionality',
|
|
21
21
|
type: "'optional' | 'required'",
|
|
22
22
|
description:
|
|
23
|
-
'The state the form treats as its default, so only the exception shows an optional/required indicator. With "optional", only fields marked isRequired show an indicator; with "required", only fields marked isOptional do. A field that restates the default shows nothing. Under "required" the unmarked fields also expose aria-required so screen readers match the visual default
|
|
23
|
+
'The state the form treats as its default, so only the exception shows an optional/required indicator. With "optional", only fields marked isRequired show an indicator; with "required", only fields marked isOptional do. A field that restates the default shows nothing. Under "required" the unmarked fields also expose aria-required so screen readers match the visual default; aria-required only, never the native required attribute. Leave unset for today\'s per-field behavior.',
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
name: 'children',
|
|
@@ -73,6 +73,13 @@ export const docs = {
|
|
|
73
73
|
description: 'Controls when focus events trigger the hover card.',
|
|
74
74
|
default: "'auto'",
|
|
75
75
|
},
|
|
76
|
+
{
|
|
77
|
+
name: 'touchTrigger',
|
|
78
|
+
type: "'auto' | 'tap' | 'none'",
|
|
79
|
+
description:
|
|
80
|
+
'What a tap does where there is no hover. auto opens on tap unless the trigger performs an action of its own (a button, link, or form control), whose tap belongs to the control. tap always opens. none never opens on touch. A tap-opened card is dismissed by a tap outside it.',
|
|
81
|
+
default: "'auto'",
|
|
82
|
+
},
|
|
76
83
|
{
|
|
77
84
|
name: 'isEnabled',
|
|
78
85
|
type: 'boolean',
|
|
@@ -111,6 +118,7 @@ export const docs = {
|
|
|
111
118
|
{ guidance: true, description: 'Keep content supplementary; hover cards should enhance understanding without blocking the primary workflow.' },
|
|
112
119
|
{ guidance: true, description: 'Provide a dashed underline on text triggers so users know the element is hoverable.' },
|
|
113
120
|
{ guidance: true, description: 'Use the hook API (useHoverCard) when you need more control over timing or placement.' },
|
|
121
|
+
{ guidance: true, description: 'Leave touchTrigger on auto so a tap opens the card on triggers that do nothing else, and stays out of the way on triggers that perform an action.' },
|
|
114
122
|
{ guidance: false, description: 'Place critical actions or required information inside a hover card; users may miss content that only appears on hover.' },
|
|
115
123
|
{ guidance: false, description: 'Use a hover card when a simple Tooltip or Popover would suffice.' },
|
|
116
124
|
{ guidance: false, description: 'Use a HoverCard for content the user must interact with; it disappears when the cursor leaves.' },
|
|
@@ -188,6 +196,13 @@ export const docsZh = {
|
|
|
188
196
|
description: '控制焦点事件何时触发悬浮卡片。',
|
|
189
197
|
default: "'auto'",
|
|
190
198
|
},
|
|
199
|
+
{
|
|
200
|
+
name: 'touchTrigger',
|
|
201
|
+
type: "'auto' | 'tap' | 'none'",
|
|
202
|
+
description:
|
|
203
|
+
'在没有悬停的触摸设备上,轻点的行为。auto:轻点即打开,除非触发元素本身会执行操作(按钮、链接、表单控件),此时轻点归该控件所有。tap:始终轻点打开。none:触摸永不打开。轻点打开的卡片可通过点击卡片外部关闭。',
|
|
204
|
+
default: "'auto'",
|
|
205
|
+
},
|
|
191
206
|
{
|
|
192
207
|
name: 'isEnabled',
|
|
193
208
|
type: 'boolean',
|
|
@@ -226,6 +241,7 @@ export const docsZh = {
|
|
|
226
241
|
{ guidance: true, description: 'Keep content supplementary; hover cards should enhance understanding without blocking the primary workflow.' },
|
|
227
242
|
{ guidance: true, description: 'Provide a dashed underline on text triggers so users know the element is hoverable.' },
|
|
228
243
|
{ guidance: true, description: 'Use the hook API (useHoverCard) when you need more control over timing or placement.' },
|
|
244
|
+
{ guidance: true, description: 'Leave touchTrigger on auto so a tap opens the card on triggers that do nothing else, and stays out of the way on triggers that perform an action.' },
|
|
229
245
|
{ guidance: false, description: 'Place critical actions or required information inside a hover card; users may miss content that only appears on hover.' },
|
|
230
246
|
{ guidance: false, description: 'Use a hover card when a simple Tooltip or Popover would suffice.' },
|
|
231
247
|
{ guidance: false, description: 'Use a HoverCard for content the user must interact with; it disappears when the cursor leaves.' },
|
|
@@ -244,6 +260,7 @@ export const docsDense = {
|
|
|
244
260
|
{ guidance: true, description: 'Keep content supplementary; hover cards should enhance understanding without blocking the primary workflow.' },
|
|
245
261
|
{ guidance: true, description: 'Provide a dashed underline on text triggers so users know the element is hoverable.' },
|
|
246
262
|
{ guidance: true, description: 'Use the hook API (useHoverCard) when you need more control over timing or placement.' },
|
|
263
|
+
{ guidance: true, description: 'Leave touchTrigger on auto so a tap opens the card on triggers that do nothing else, and stays out of the way on triggers that perform an action.' },
|
|
247
264
|
{ guidance: false, description: 'Place critical actions or required information inside a hover card; users may miss content that only appears on hover.' },
|
|
248
265
|
{ guidance: false, description: 'Use a hover card when a simple Tooltip or Popover would suffice.' },
|
|
249
266
|
{ guidance: false, description: 'Use a HoverCard for content the user must interact with; it disappears when the cursor leaves.' },
|
|
@@ -263,6 +280,7 @@ export const docsDense = {
|
|
|
263
280
|
delay: 'Show delay in ms.',
|
|
264
281
|
hideDelay: 'Hide delay in ms.',
|
|
265
282
|
focusTrigger: 'Controls when focus events trigger hover card.',
|
|
283
|
+
touchTrigger: 'Tap behavior where there is no hover. auto = tap opens unless the trigger acts (button/link/control); tap = always opens; none = never on touch. Tap-opened cards close on a tap outside.',
|
|
266
284
|
isEnabled: 'Enable/disable hover + focus triggers.',
|
|
267
285
|
label: 'Accessible name for the popup. With label: named role="dialog"; without: role="group".',
|
|
268
286
|
onOpenChange: 'Callback when visibility changes; true=shown, false=hidden.',
|
|
@@ -25,6 +25,7 @@ import {StrictMode} from 'react';
|
|
|
25
25
|
import {Button} from '../Button/Button';
|
|
26
26
|
import {Theme, defineTheme} from '../theme';
|
|
27
27
|
import {HoverCard} from './HoverCard';
|
|
28
|
+
import {__resetInteractionModalityForTest} from '../utils/interactionModality';
|
|
28
29
|
|
|
29
30
|
// Store original matches to restore later
|
|
30
31
|
const originalMatches = HTMLElement.prototype.matches;
|
|
@@ -804,4 +805,192 @@ describe('HoverCard', () => {
|
|
|
804
805
|
container.remove();
|
|
805
806
|
});
|
|
806
807
|
});
|
|
808
|
+
|
|
809
|
+
describe('touch', () => {
|
|
810
|
+
// The modality is document-global; a tap in one case must not decide the
|
|
811
|
+
// next one's answer.
|
|
812
|
+
beforeEach(() => {
|
|
813
|
+
__resetInteractionModalityForTest();
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
/** A tap: the pointer sequence a finger produces before hover is faked. */
|
|
817
|
+
const tap = (element: HTMLElement) => {
|
|
818
|
+
// A finger's arrival fires pointerenter too, and that is the path a pen
|
|
819
|
+
// must not take — cover it here rather than starting at pointerdown.
|
|
820
|
+
fireEvent.pointerEnter(element, {pointerType: 'touch'});
|
|
821
|
+
fireEvent.pointerDown(element, {pointerType: 'touch'});
|
|
822
|
+
fireEvent.pointerUp(element, {pointerType: 'touch'});
|
|
823
|
+
// Touch synthesizes hover after the press; the card must not act on it.
|
|
824
|
+
fireEvent.mouseEnter(element);
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
it('opens on a tap when the trigger performs no action', async () => {
|
|
828
|
+
const onOpenChange = vi.fn();
|
|
829
|
+
render(
|
|
830
|
+
<HoverCard
|
|
831
|
+
content={<span>Card content</span>}
|
|
832
|
+
onOpenChange={onOpenChange}
|
|
833
|
+
delay={300}>
|
|
834
|
+
Ruby Cheung
|
|
835
|
+
</HoverCard>,
|
|
836
|
+
);
|
|
837
|
+
|
|
838
|
+
tap(screen.getByText('Ruby Cheung'));
|
|
839
|
+
|
|
840
|
+
// Immediately: a tap is a decision, not hover intent, so no delay applies.
|
|
841
|
+
await waitFor(() => {
|
|
842
|
+
expect(onOpenChange).toHaveBeenCalledWith(true);
|
|
843
|
+
});
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
it('stays shut on a tap when the trigger performs an action', async () => {
|
|
847
|
+
const onOpenChange = vi.fn();
|
|
848
|
+
render(
|
|
849
|
+
<HoverCard
|
|
850
|
+
content={<span>Card content</span>}
|
|
851
|
+
onOpenChange={onOpenChange}
|
|
852
|
+
delay={0}>
|
|
853
|
+
<button type="button">Save</button>
|
|
854
|
+
</HoverCard>,
|
|
855
|
+
);
|
|
856
|
+
|
|
857
|
+
const trigger = screen.getByRole('button', {name: 'Save'});
|
|
858
|
+
tap(trigger);
|
|
859
|
+
// A tap focuses what it activates; that focus must not reopen the card.
|
|
860
|
+
fireEvent.focusIn(trigger);
|
|
861
|
+
|
|
862
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
863
|
+
expect(onOpenChange).not.toHaveBeenCalledWith(true);
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
it('opens on a tap of an action trigger when touchTrigger is "tap"', async () => {
|
|
867
|
+
const onOpenChange = vi.fn();
|
|
868
|
+
render(
|
|
869
|
+
<HoverCard
|
|
870
|
+
content={<span>Card content</span>}
|
|
871
|
+
onOpenChange={onOpenChange}
|
|
872
|
+
touchTrigger="tap"
|
|
873
|
+
delay={0}>
|
|
874
|
+
<button type="button">Details</button>
|
|
875
|
+
</HoverCard>,
|
|
876
|
+
);
|
|
877
|
+
|
|
878
|
+
tap(screen.getByRole('button', {name: 'Details'}));
|
|
879
|
+
|
|
880
|
+
await waitFor(() => {
|
|
881
|
+
expect(onOpenChange).toHaveBeenCalledWith(true);
|
|
882
|
+
});
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
it('survives a tap on its own content', async () => {
|
|
886
|
+
const onOpenChange = vi.fn();
|
|
887
|
+
render(
|
|
888
|
+
<HoverCard
|
|
889
|
+
content={<button type="button">Follow</button>}
|
|
890
|
+
onOpenChange={onOpenChange}
|
|
891
|
+
delay={0}
|
|
892
|
+
hideDelay={0}>
|
|
893
|
+
Ruby Cheung
|
|
894
|
+
</HoverCard>,
|
|
895
|
+
);
|
|
896
|
+
|
|
897
|
+
tap(screen.getByText('Ruby Cheung'));
|
|
898
|
+
await waitFor(() => {
|
|
899
|
+
expect(onOpenChange).toHaveBeenCalledWith(true);
|
|
900
|
+
});
|
|
901
|
+
onOpenChange.mockClear();
|
|
902
|
+
|
|
903
|
+
const action = await screen.findByRole('button', {
|
|
904
|
+
name: 'Follow',
|
|
905
|
+
hidden: true,
|
|
906
|
+
});
|
|
907
|
+
fireEvent.pointerDown(action, {pointerType: 'touch'});
|
|
908
|
+
|
|
909
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
910
|
+
expect(onOpenChange).not.toHaveBeenCalledWith(false);
|
|
911
|
+
});
|
|
912
|
+
|
|
913
|
+
it('closes on a tap outside', async () => {
|
|
914
|
+
const onOpenChange = vi.fn();
|
|
915
|
+
render(
|
|
916
|
+
<>
|
|
917
|
+
<HoverCard
|
|
918
|
+
content={<span>Card content</span>}
|
|
919
|
+
onOpenChange={onOpenChange}
|
|
920
|
+
delay={0}
|
|
921
|
+
hideDelay={0}>
|
|
922
|
+
Ruby Cheung
|
|
923
|
+
</HoverCard>
|
|
924
|
+
<button type="button">Elsewhere</button>
|
|
925
|
+
</>,
|
|
926
|
+
);
|
|
927
|
+
|
|
928
|
+
tap(screen.getByText('Ruby Cheung'));
|
|
929
|
+
await waitFor(() => {
|
|
930
|
+
expect(onOpenChange).toHaveBeenCalledWith(true);
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
fireEvent.pointerDown(screen.getByRole('button', {name: 'Elsewhere'}), {
|
|
934
|
+
pointerType: 'touch',
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
await waitFor(() => {
|
|
938
|
+
expect(onOpenChange).toHaveBeenCalledWith(false);
|
|
939
|
+
});
|
|
940
|
+
});
|
|
941
|
+
|
|
942
|
+
it('closes on a second tap of the trigger', async () => {
|
|
943
|
+
const onOpenChange = vi.fn();
|
|
944
|
+
render(
|
|
945
|
+
<HoverCard
|
|
946
|
+
content={<span>Card content</span>}
|
|
947
|
+
onOpenChange={onOpenChange}
|
|
948
|
+
delay={0}
|
|
949
|
+
hideDelay={0}>
|
|
950
|
+
Ruby Cheung
|
|
951
|
+
</HoverCard>,
|
|
952
|
+
);
|
|
953
|
+
|
|
954
|
+
const trigger = screen.getByText('Ruby Cheung');
|
|
955
|
+
tap(trigger);
|
|
956
|
+
await waitFor(() => {
|
|
957
|
+
expect(onOpenChange).toHaveBeenCalledWith(true);
|
|
958
|
+
});
|
|
959
|
+
|
|
960
|
+
tap(trigger);
|
|
961
|
+
await waitFor(() => {
|
|
962
|
+
expect(onOpenChange).toHaveBeenCalledWith(false);
|
|
963
|
+
});
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
it('ignores the focus a tap leaves behind, but not keyboard focus', async () => {
|
|
967
|
+
const onOpenChange = vi.fn();
|
|
968
|
+
render(
|
|
969
|
+
<HoverCard
|
|
970
|
+
content={<span>Card content</span>}
|
|
971
|
+
onOpenChange={onOpenChange}
|
|
972
|
+
delay={0}>
|
|
973
|
+
<button type="button">Save</button>
|
|
974
|
+
</HoverCard>,
|
|
975
|
+
);
|
|
976
|
+
|
|
977
|
+
const trigger = screen.getByRole('button', {name: 'Save'});
|
|
978
|
+
// The tap goes to the button, as `auto` decides for an action trigger —
|
|
979
|
+
// and the focus it leaves behind must not put the card over the control
|
|
980
|
+
// the user just pressed.
|
|
981
|
+
tap(trigger);
|
|
982
|
+
fireEvent.focusIn(trigger);
|
|
983
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
984
|
+
expect(onOpenChange).not.toHaveBeenCalledWith(true);
|
|
985
|
+
|
|
986
|
+
// Reaching for the keyboard ends the touch interaction: the same trigger,
|
|
987
|
+
// focused by Tab, still opens.
|
|
988
|
+
fireEvent.keyDown(document, {key: 'Tab'});
|
|
989
|
+
fireEvent.focusIn(trigger);
|
|
990
|
+
|
|
991
|
+
await waitFor(() => {
|
|
992
|
+
expect(onOpenChange).toHaveBeenCalledWith(true);
|
|
993
|
+
});
|
|
994
|
+
});
|
|
995
|
+
});
|
|
807
996
|
});
|
|
@@ -18,12 +18,19 @@
|
|
|
18
18
|
import {useCallback, useRef, type ReactElement, type ReactNode} from 'react';
|
|
19
19
|
import {useIsomorphicLayoutEffect} from '../hooks/useIsomorphicLayoutEffect';
|
|
20
20
|
import * as stylex from '@stylexjs/stylex';
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
useHoverCard,
|
|
23
|
+
type HoverCardFocusTrigger,
|
|
24
|
+
type HoverCardTouchTrigger,
|
|
25
|
+
} from './useHoverCard';
|
|
22
26
|
import type {LayerAlignment, LayerPlacement} from '../Layer/useLayer';
|
|
23
27
|
import type {BaseProps} from '../BaseProps';
|
|
24
28
|
import {colorVars, spacingVars} from '../theme/tokens.stylex';
|
|
25
29
|
|
|
26
|
-
export type {
|
|
30
|
+
export type {
|
|
31
|
+
HoverCardFocusTrigger,
|
|
32
|
+
HoverCardTouchTrigger,
|
|
33
|
+
} from './useHoverCard';
|
|
27
34
|
|
|
28
35
|
const styles = stylex.create({
|
|
29
36
|
wrapperContents: {
|
|
@@ -88,6 +95,17 @@ export interface HoverCardProps extends Pick<
|
|
|
88
95
|
*/
|
|
89
96
|
focusTrigger?: HoverCardFocusTrigger;
|
|
90
97
|
|
|
98
|
+
/**
|
|
99
|
+
* What a tap does on a touch pointer, where there is no hover:
|
|
100
|
+
* - `auto`: tap opens the card, unless the trigger performs an action of its
|
|
101
|
+
* own (a button, a link, a form control) — that tap belongs to the control
|
|
102
|
+
* - `tap`: tap always opens the card, even on a trigger that acts
|
|
103
|
+
* - `none`: touch never opens the card
|
|
104
|
+
*
|
|
105
|
+
* @default 'auto'
|
|
106
|
+
*/
|
|
107
|
+
touchTrigger?: HoverCardTouchTrigger;
|
|
108
|
+
|
|
91
109
|
/**
|
|
92
110
|
* Whether the hover card is enabled.
|
|
93
111
|
* When false, hover/focus triggers are disabled.
|
|
@@ -174,6 +192,7 @@ export function HoverCard({
|
|
|
174
192
|
delay = 300,
|
|
175
193
|
hideDelay = 200,
|
|
176
194
|
focusTrigger = 'auto',
|
|
195
|
+
touchTrigger = 'auto',
|
|
177
196
|
isEnabled = true,
|
|
178
197
|
label,
|
|
179
198
|
onOpenChange,
|
|
@@ -206,6 +225,7 @@ export function HoverCard({
|
|
|
206
225
|
delay,
|
|
207
226
|
hideDelay,
|
|
208
227
|
focusTrigger,
|
|
228
|
+
touchTrigger,
|
|
209
229
|
isEnabled,
|
|
210
230
|
label,
|
|
211
231
|
isOpen,
|
package/src/HoverCard/index.ts
CHANGED
|
@@ -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.'},
|