@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
|
@@ -50,12 +50,17 @@ import {mergeRefs} from '../utils';
|
|
|
50
50
|
import {useSize} from '../SizeContext/SizeContext';
|
|
51
51
|
import {useInternalConfig} from './useInternalConfig';
|
|
52
52
|
import {usePowerSearchSource} from './usePowerSearchSource';
|
|
53
|
-
import {
|
|
53
|
+
import {
|
|
54
|
+
formatFilterValue,
|
|
55
|
+
formatDateAbsoluteCompact,
|
|
56
|
+
} from './formatFilterValue';
|
|
54
57
|
import {PowerSearchEditPopover} from './PowerSearchEditPopover';
|
|
55
58
|
import {resolveOperatorLabel} from './resolveOperatorLabel';
|
|
56
59
|
import {themeProps} from '../utils/themeProps';
|
|
57
60
|
import {truncateCharacters} from '../utils/characters';
|
|
58
61
|
import {useTranslator} from '../i18n';
|
|
62
|
+
import {useLocale} from '../i18n/useLocale';
|
|
63
|
+
import type {Locale} from '../i18n/types';
|
|
59
64
|
import type {
|
|
60
65
|
PowerSearchConfig,
|
|
61
66
|
PowerSearchFilter,
|
|
@@ -131,10 +136,12 @@ function PowerSearchTokenValue({
|
|
|
131
136
|
operatorValue,
|
|
132
137
|
filterValue,
|
|
133
138
|
maxLength,
|
|
139
|
+
locale,
|
|
134
140
|
}: {
|
|
135
141
|
operatorValue: OperatorValue;
|
|
136
142
|
filterValue: FilterValue;
|
|
137
143
|
maxLength: number;
|
|
144
|
+
locale: Locale;
|
|
138
145
|
}) {
|
|
139
146
|
switch (filterValue.type) {
|
|
140
147
|
case 'empty':
|
|
@@ -276,12 +283,10 @@ function PowerSearchTokenValue({
|
|
|
276
283
|
);
|
|
277
284
|
|
|
278
285
|
case 'date_absolute': {
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
day: 'numeric',
|
|
284
|
-
}).format(date);
|
|
286
|
+
const formatted = formatDateAbsoluteCompact(
|
|
287
|
+
filterValue.unixSeconds,
|
|
288
|
+
locale,
|
|
289
|
+
);
|
|
285
290
|
return (
|
|
286
291
|
<span {...stylex.props(tokenValueStyles.value)}>
|
|
287
292
|
{truncateString(formatted, maxLength)}
|
|
@@ -556,6 +561,7 @@ export function PowerSearch({
|
|
|
556
561
|
const config = useInternalConfig(configProp);
|
|
557
562
|
const searchSource = usePowerSearchSource(config);
|
|
558
563
|
const t = useTranslator();
|
|
564
|
+
const locale = useLocale();
|
|
559
565
|
const label = labelFromProps ?? t('@astryx.powersearch.label');
|
|
560
566
|
const placeholder =
|
|
561
567
|
placeholderFromProps ?? t('@astryx.powersearch.placeholder');
|
|
@@ -625,6 +631,7 @@ export function PowerSearch({
|
|
|
625
631
|
filter.value,
|
|
626
632
|
maxTokenLength,
|
|
627
633
|
t,
|
|
634
|
+
locale,
|
|
628
635
|
timezoneID,
|
|
629
636
|
)
|
|
630
637
|
: '';
|
|
@@ -644,7 +651,7 @@ export function PowerSearch({
|
|
|
644
651
|
},
|
|
645
652
|
};
|
|
646
653
|
});
|
|
647
|
-
}, [filters, config, maxTokenLength, timezoneID, t]);
|
|
654
|
+
}, [filters, config, maxTokenLength, timezoneID, t, locale]);
|
|
648
655
|
|
|
649
656
|
// Handle tokenizer onChange (field selected from typeahead)
|
|
650
657
|
const handleTokenizerChange = useCallback(
|
|
@@ -820,6 +827,7 @@ export function PowerSearch({
|
|
|
820
827
|
operatorValue={operator.value}
|
|
821
828
|
filterValue={filter.value}
|
|
822
829
|
maxLength={adjustedMaxLength}
|
|
830
|
+
locale={locale}
|
|
823
831
|
/>
|
|
824
832
|
) : undefined;
|
|
825
833
|
|
|
@@ -858,6 +866,7 @@ export function PowerSearch({
|
|
|
858
866
|
config,
|
|
859
867
|
configProp,
|
|
860
868
|
maxTokenLength,
|
|
869
|
+
locale,
|
|
861
870
|
size,
|
|
862
871
|
isReadOnly,
|
|
863
872
|
isDisabled,
|
|
@@ -13,6 +13,7 @@ import React from 'react';
|
|
|
13
13
|
import * as stylex from '@stylexjs/stylex';
|
|
14
14
|
import {Token} from '../Token';
|
|
15
15
|
import {useTranslator} from '../i18n';
|
|
16
|
+
import {useLocale} from '../i18n/useLocale';
|
|
16
17
|
import {fontWeightVars} from '../theme/tokens.stylex';
|
|
17
18
|
import {formatFilterValue} from './formatFilterValue';
|
|
18
19
|
import {resolveOperatorLabel} from './resolveOperatorLabel';
|
|
@@ -44,6 +45,7 @@ export function PowerSearchToken({
|
|
|
44
45
|
}: PowerSearchTokenProps) {
|
|
45
46
|
const config = useInternalConfig(configProp);
|
|
46
47
|
const t = useTranslator();
|
|
48
|
+
const locale = useLocale();
|
|
47
49
|
|
|
48
50
|
const fieldLabel = field.label;
|
|
49
51
|
const resolvedOperatorLabel = resolveOperatorLabel(operator, t);
|
|
@@ -63,6 +65,7 @@ export function PowerSearchToken({
|
|
|
63
65
|
filter.value,
|
|
64
66
|
adjustedMaxLength,
|
|
65
67
|
t,
|
|
68
|
+
locale,
|
|
66
69
|
);
|
|
67
70
|
|
|
68
71
|
const valueContent = valueStr ? (
|
|
@@ -31,7 +31,15 @@ const fmt = (
|
|
|
31
31
|
maxLength = 20,
|
|
32
32
|
timezoneID?: string,
|
|
33
33
|
): string =>
|
|
34
|
-
formatFilterValue(
|
|
34
|
+
formatFilterValue(
|
|
35
|
+
{} as never,
|
|
36
|
+
operator,
|
|
37
|
+
value,
|
|
38
|
+
maxLength,
|
|
39
|
+
t,
|
|
40
|
+
'en-US',
|
|
41
|
+
timezoneID,
|
|
42
|
+
);
|
|
35
43
|
|
|
36
44
|
const ELLIPSIS = '…';
|
|
37
45
|
|
|
@@ -87,8 +95,20 @@ describe('formatFilterValue', () => {
|
|
|
87
95
|
});
|
|
88
96
|
|
|
89
97
|
describe('integer / float', () => {
|
|
98
|
+
it('formats the same number differently when the locale changes', () => {
|
|
99
|
+
const args = [
|
|
100
|
+
{} as never,
|
|
101
|
+
{type: 'float'} as OperatorValue,
|
|
102
|
+
{type: 'float', value: 1234.5} as FilterValue,
|
|
103
|
+
40,
|
|
104
|
+
t,
|
|
105
|
+
] as const;
|
|
106
|
+
expect(formatFilterValue(...args, 'en-US')).toBe('1,234.5');
|
|
107
|
+
expect(formatFilterValue(...args, 'de-DE')).toBe('1.234,5');
|
|
108
|
+
});
|
|
109
|
+
|
|
90
110
|
it('formats an integer with locale grouping', () => {
|
|
91
|
-
const expected = new Intl.NumberFormat().format(1234567);
|
|
111
|
+
const expected = new Intl.NumberFormat('en-US').format(1234567);
|
|
92
112
|
expect(
|
|
93
113
|
fmt({type: 'integer'}, {type: 'integer', value: 1234567}, 40),
|
|
94
114
|
).toBe(expected);
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import type {OperatorValue, FilterValue, EnumItem} from './types';
|
|
14
14
|
import type {InternalConfig} from './useInternalConfig';
|
|
15
|
-
import type {TranslatorFn} from '../i18n';
|
|
15
|
+
import type {Locale, TranslatorFn} from '../i18n';
|
|
16
16
|
import {truncateCharacters} from '../utils/characters';
|
|
17
17
|
|
|
18
18
|
function truncate(str: string, maxLength: number): string {
|
|
@@ -27,12 +27,16 @@ function formatEnumLabel(
|
|
|
27
27
|
return item?.label ?? value;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
function formatNumber(value: number, units?: string): string {
|
|
31
|
-
const formatted = new Intl.NumberFormat().format(value);
|
|
30
|
+
function formatNumber(value: number, locale: Locale, units?: string): string {
|
|
31
|
+
const formatted = new Intl.NumberFormat(locale).format(value);
|
|
32
32
|
return units ? `${formatted} ${units}` : formatted;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
function formatDateAbsolute(
|
|
35
|
+
export function formatDateAbsolute(
|
|
36
|
+
unixSeconds: number,
|
|
37
|
+
locale: Locale,
|
|
38
|
+
timezoneID?: string,
|
|
39
|
+
): string {
|
|
36
40
|
const options: Intl.DateTimeFormatOptions = {
|
|
37
41
|
year: 'numeric',
|
|
38
42
|
month: 'short',
|
|
@@ -41,7 +45,25 @@ function formatDateAbsolute(unixSeconds: number, timezoneID?: string): string {
|
|
|
41
45
|
minute: '2-digit',
|
|
42
46
|
...(timezoneID ? {timeZone: timezoneID} : {}),
|
|
43
47
|
};
|
|
44
|
-
return new Intl.DateTimeFormat(
|
|
48
|
+
return new Intl.DateTimeFormat(locale, options).format(unixSeconds * 1000);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Compact date-only rendering (no time-of-day) for the token pill's inline
|
|
53
|
+
* value display, which has less room than the editor's full summary. Kept
|
|
54
|
+
* separate from {@link formatDateAbsolute} rather than reusing it with
|
|
55
|
+
* different options threaded through a param, since the two callers want
|
|
56
|
+
* genuinely different shapes, not a parameterization of the same one.
|
|
57
|
+
*/
|
|
58
|
+
export function formatDateAbsoluteCompact(
|
|
59
|
+
unixSeconds: number,
|
|
60
|
+
locale: Locale,
|
|
61
|
+
): string {
|
|
62
|
+
return new Intl.DateTimeFormat(locale, {
|
|
63
|
+
year: 'numeric',
|
|
64
|
+
month: 'short',
|
|
65
|
+
day: 'numeric',
|
|
66
|
+
}).format(unixSeconds * 1000);
|
|
45
67
|
}
|
|
46
68
|
|
|
47
69
|
function formatRelativeDate(value: string): string {
|
|
@@ -62,6 +84,7 @@ export function formatFilterValue(
|
|
|
62
84
|
filterValue: FilterValue,
|
|
63
85
|
maxLength: number,
|
|
64
86
|
t: TranslatorFn,
|
|
87
|
+
locale: Locale,
|
|
65
88
|
timezoneID?: string,
|
|
66
89
|
): string {
|
|
67
90
|
switch (filterValue.type) {
|
|
@@ -74,12 +97,14 @@ export function formatFilterValue(
|
|
|
74
97
|
case 'integer':
|
|
75
98
|
return formatNumber(
|
|
76
99
|
filterValue.value,
|
|
100
|
+
locale,
|
|
77
101
|
operatorValue.type === 'integer' ? operatorValue.units : undefined,
|
|
78
102
|
);
|
|
79
103
|
|
|
80
104
|
case 'float':
|
|
81
105
|
return formatNumber(
|
|
82
106
|
filterValue.value,
|
|
107
|
+
locale,
|
|
83
108
|
operatorValue.type === 'float' ? operatorValue.units : undefined,
|
|
84
109
|
);
|
|
85
110
|
|
|
@@ -157,7 +182,7 @@ export function formatFilterValue(
|
|
|
157
182
|
|
|
158
183
|
case 'date_absolute':
|
|
159
184
|
return truncate(
|
|
160
|
-
formatDateAbsolute(filterValue.unixSeconds, timezoneID),
|
|
185
|
+
formatDateAbsolute(filterValue.unixSeconds, locale, timezoneID),
|
|
161
186
|
maxLength,
|
|
162
187
|
);
|
|
163
188
|
|
|
@@ -11,7 +11,7 @@ export const docs = {
|
|
|
11
11
|
theming: {
|
|
12
12
|
targets: [
|
|
13
13
|
{className: 'astryx-radio-list', visualProps: ['orientation', 'size']},
|
|
14
|
-
{className: 'astryx-radio-list-item'},
|
|
14
|
+
{className: 'astryx-radio-list-item', visualProps: ['size'], states: ['selected', 'disabled']},
|
|
15
15
|
{className: 'astryx-radio-indicator', visualProps: ['size'], states: ['checked', 'disabled']},
|
|
16
16
|
{className: 'astryx-radio-indicator-dot', visualProps: ['size']},
|
|
17
17
|
{className: 'astryx-radio', visualProps: ['size'], states: ['checked', 'disabled'], deprecatedFor: 'radio-indicator'},
|
|
@@ -116,6 +116,22 @@ describe('RadioList', () => {
|
|
|
116
116
|
expect(handleChange).toHaveBeenCalledWith('b');
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
+
it('calls onChange when clicking the description', async () => {
|
|
120
|
+
const user = userEvent.setup();
|
|
121
|
+
const handleChange = vi.fn();
|
|
122
|
+
render(
|
|
123
|
+
<RadioList label="Preference" value="a" onChange={handleChange}>
|
|
124
|
+
<RadioListItem label="Option A" value="a" description="First option" />
|
|
125
|
+
<RadioListItem label="Option B" value="b" description="Second option" />
|
|
126
|
+
</RadioList>,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
// The whole row delegates surface clicks to the radio, so the description
|
|
130
|
+
// is a live target — not dead space as it was before.
|
|
131
|
+
await user.click(screen.getByText('Second option'));
|
|
132
|
+
expect(handleChange).toHaveBeenCalledWith('b');
|
|
133
|
+
});
|
|
134
|
+
|
|
119
135
|
it('disables all radios when group isDisabled is true', () => {
|
|
120
136
|
render(
|
|
121
137
|
<RadioList label="Preference" value="" onChange={() => {}} isDisabled>
|
|
@@ -137,7 +153,13 @@ describe('RadioList', () => {
|
|
|
137
153
|
</RadioList>,
|
|
138
154
|
);
|
|
139
155
|
|
|
140
|
-
|
|
156
|
+
// userEvent honors `pointer-events: none`, so clicking the disabled row's
|
|
157
|
+
// delegate surface is genuinely blocked (it refuses and throws) rather than
|
|
158
|
+
// merely ignored by the handler — the guarantee this PR's delegation relies
|
|
159
|
+
// on.
|
|
160
|
+
await expect(user.click(screen.getByLabelText('Option A'))).rejects.toThrow(
|
|
161
|
+
/pointer-events/i,
|
|
162
|
+
);
|
|
141
163
|
expect(handleChange).not.toHaveBeenCalled();
|
|
142
164
|
});
|
|
143
165
|
|
|
@@ -162,7 +184,13 @@ describe('RadioList', () => {
|
|
|
162
184
|
</RadioList>,
|
|
163
185
|
);
|
|
164
186
|
|
|
165
|
-
|
|
187
|
+
// userEvent honors `pointer-events: none`, so clicking the disabled row's
|
|
188
|
+
// delegate surface is genuinely blocked (it refuses and throws) rather than
|
|
189
|
+
// merely ignored by the handler — the guarantee this PR's delegation relies
|
|
190
|
+
// on.
|
|
191
|
+
await expect(user.click(screen.getByLabelText('Option A'))).rejects.toThrow(
|
|
192
|
+
/pointer-events/i,
|
|
193
|
+
);
|
|
166
194
|
expect(handleChange).not.toHaveBeenCalled();
|
|
167
195
|
});
|
|
168
196
|
|
|
@@ -647,6 +675,146 @@ describe('RadioList', () => {
|
|
|
647
675
|
expect(item).toHaveAttribute('aria-label', 'First option');
|
|
648
676
|
});
|
|
649
677
|
});
|
|
678
|
+
|
|
679
|
+
describe('radio-list-item theme target', () => {
|
|
680
|
+
it('renders astryx-radio-list-item, with its size, on every row', () => {
|
|
681
|
+
render(
|
|
682
|
+
<RadioList label="Preference" value="" onChange={() => {}} size="sm">
|
|
683
|
+
<RadioListItem label="Option A" value="a" data-testid="row-a" />
|
|
684
|
+
<RadioListItem label="Option B" value="b" data-testid="row-b" />
|
|
685
|
+
</RadioList>,
|
|
686
|
+
);
|
|
687
|
+
for (const testid of ['row-a', 'row-b']) {
|
|
688
|
+
const row = screen.getByTestId(testid);
|
|
689
|
+
expect(row).toHaveClass('astryx-radio-list-item');
|
|
690
|
+
expect(row).toHaveClass('sm');
|
|
691
|
+
expect(row).toHaveAttribute('data-size', 'sm');
|
|
692
|
+
}
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
it('carries the selected and disabled states a theme keys on', () => {
|
|
696
|
+
render(
|
|
697
|
+
<RadioList label="Preference" value="a" onChange={() => {}}>
|
|
698
|
+
<RadioListItem label="Option A" value="a" data-testid="selected" />
|
|
699
|
+
<RadioListItem label="Option B" value="b" data-testid="plain" />
|
|
700
|
+
<RadioListItem
|
|
701
|
+
label="Option C"
|
|
702
|
+
value="c"
|
|
703
|
+
isDisabled
|
|
704
|
+
data-testid="disabled"
|
|
705
|
+
/>
|
|
706
|
+
</RadioList>,
|
|
707
|
+
);
|
|
708
|
+
const selected = screen.getByTestId('selected');
|
|
709
|
+
const plain = screen.getByTestId('plain');
|
|
710
|
+
const disabled = screen.getByTestId('disabled');
|
|
711
|
+
|
|
712
|
+
expect(selected).toHaveClass('selected');
|
|
713
|
+
expect(selected).toHaveAttribute('data-selected', 'selected');
|
|
714
|
+
expect(plain).not.toHaveClass('selected');
|
|
715
|
+
expect(plain).not.toHaveAttribute('data-selected');
|
|
716
|
+
|
|
717
|
+
expect(disabled).toHaveClass('disabled');
|
|
718
|
+
expect(disabled).toHaveAttribute('data-disabled', 'disabled');
|
|
719
|
+
expect(plain).not.toHaveAttribute('data-disabled');
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
it('rides the painting row element (astryx-item), not a bare layout wrapper', () => {
|
|
723
|
+
// The row target must sit on the element Item paints — the surface that
|
|
724
|
+
// renders hover, density padding, and radius — so a theme styling
|
|
725
|
+
// `radio-list-item`'s background/padding/borderRadius (and its `:hover`)
|
|
726
|
+
// actually takes effect. Converges with how ListItem lands `list-item`
|
|
727
|
+
// on the same element as `astryx-item`. The same element also carries
|
|
728
|
+
// the reflected `data-size`, proving the variant surface moved with it.
|
|
729
|
+
const {container} = render(
|
|
730
|
+
<RadioList label="Preference" value="" onChange={() => {}}>
|
|
731
|
+
<RadioListItem label="Option A" value="a" data-testid="row" />
|
|
732
|
+
</RadioList>,
|
|
733
|
+
);
|
|
734
|
+
const row = screen.getByTestId('row');
|
|
735
|
+
// A single element carries both the paint class and the theme target.
|
|
736
|
+
expect(row).toHaveClass('astryx-item');
|
|
737
|
+
expect(row).toHaveClass('astryx-radio-list-item');
|
|
738
|
+
expect(row).toHaveAttribute('data-size');
|
|
739
|
+
// No separate layout wrapper survives outside the painting row: the
|
|
740
|
+
// target-bearing element is the same one Item renders.
|
|
741
|
+
expect(
|
|
742
|
+
container.querySelectorAll('.astryx-radio-list-item'),
|
|
743
|
+
).toHaveLength(1);
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
it('keeps the bare default row appearance: zeroed padding/radius, no default background', () => {
|
|
747
|
+
// The architectural win — the target rides the painting Item — must not
|
|
748
|
+
// change the DEFAULT look. The painting row zeroes Item's density
|
|
749
|
+
// padding, its radius, and its interactive hover/press background, so an
|
|
750
|
+
// unthemed RadioList renders as a flat surface (only the indicator tints
|
|
751
|
+
// on hover via `indicatorScope`). This matches the appearance before the
|
|
752
|
+
// target moved onto Item; a theme's `radio-list-item` overrides still win
|
|
753
|
+
// from the higher `astryx-theme` layer.
|
|
754
|
+
render(
|
|
755
|
+
<RadioList label="Preference" value="a" onChange={() => {}}>
|
|
756
|
+
<RadioListItem label="Selected" value="a" data-testid="selected" />
|
|
757
|
+
<RadioListItem label="Plain" value="b" data-testid="plain" />
|
|
758
|
+
</RadioList>,
|
|
759
|
+
);
|
|
760
|
+
const cssFor = (className: string): string => {
|
|
761
|
+
const rules: string[] = [];
|
|
762
|
+
const walk = (list: CSSRuleList) => {
|
|
763
|
+
for (const rule of Array.from(list)) {
|
|
764
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
765
|
+
const anyRule = rule as any;
|
|
766
|
+
if (anyRule.cssRules) {
|
|
767
|
+
walk(anyRule.cssRules);
|
|
768
|
+
}
|
|
769
|
+
if (
|
|
770
|
+
typeof anyRule.cssText === 'string' &&
|
|
771
|
+
anyRule.cssText.includes(`.${className}`)
|
|
772
|
+
) {
|
|
773
|
+
rules.push(anyRule.cssText);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
778
|
+
try {
|
|
779
|
+
walk(sheet.cssRules);
|
|
780
|
+
} catch {
|
|
781
|
+
// cross-origin/inaccessible sheet — skip
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return rules.join('\n');
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
const plain = screen.getByTestId('plain');
|
|
788
|
+
const atoms = plain.className
|
|
789
|
+
.split(/\s+/)
|
|
790
|
+
.filter(c => /^x[a-z0-9]+$/i.test(c));
|
|
791
|
+
const declarations = atoms.map(cssFor).join('\n');
|
|
792
|
+
|
|
793
|
+
// The bare-look declarations land on the painting row.
|
|
794
|
+
expect(declarations).toMatch(/padding-block:\s*0/);
|
|
795
|
+
expect(declarations).toMatch(/padding-inline:\s*0/);
|
|
796
|
+
expect(declarations).toMatch(/border-radius:\s*0/);
|
|
797
|
+
expect(declarations).toMatch(/background-color:\s*transparent/);
|
|
798
|
+
|
|
799
|
+
// No default full-row hover highlight: the flat transparent background
|
|
800
|
+
// replaces Item's interactive `:hover` overlay, so no hover rule paints
|
|
801
|
+
// the row's own background. (The indicator still tints via its scope.)
|
|
802
|
+
expect(declarations).not.toMatch(
|
|
803
|
+
/:hover[^{]*\{[^}]*background-color:\s*var\(--color-overlay-hover\)/,
|
|
804
|
+
);
|
|
805
|
+
|
|
806
|
+
// No default selected-row background: the selected row differs from the
|
|
807
|
+
// plain row only by state markers, not by a painted background class.
|
|
808
|
+
const selected = screen.getByTestId('selected');
|
|
809
|
+
const selectedAtoms = selected.className
|
|
810
|
+
.split(/\s+/)
|
|
811
|
+
.filter(c => /^x[a-z0-9]+$/i.test(c));
|
|
812
|
+
const selectedDecls = selectedAtoms.map(cssFor).join('\n');
|
|
813
|
+
expect(selectedDecls).not.toMatch(
|
|
814
|
+
/background-color:\s*var\(--color-accent-muted\)/,
|
|
815
|
+
);
|
|
816
|
+
});
|
|
817
|
+
});
|
|
650
818
|
});
|
|
651
819
|
|
|
652
820
|
// jsdom cannot emulate forced-colors rendering, so this asserts that the
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file RadioListItem.tsx
|
|
7
|
-
* @input Uses React use, useId, RadioListContext
|
|
7
|
+
* @input Uses React use, useId, useRef, RadioListContext, Item
|
|
8
8
|
* @output Exports RadioListItem component, RadioListItemProps
|
|
9
9
|
* @position Core implementation; consumed by index.ts, tested by RadioList.test.tsx
|
|
10
10
|
*
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
|
|
21
21
|
import React, {use, useId, useRef, type ReactNode} from 'react';
|
|
22
22
|
import * as stylex from '@stylexjs/stylex';
|
|
23
|
+
import type {StyleXStyles} from '@stylexjs/stylex';
|
|
23
24
|
import type {BaseProps} from '../BaseProps';
|
|
24
|
-
import {colorVars, spacingVars} from '../theme/tokens.stylex';
|
|
25
25
|
import {RadioListContext} from './RadioList';
|
|
26
|
-
import {mergeProps} from '../utils';
|
|
26
|
+
import {mergeProps, isRenderable} from '../utils';
|
|
27
27
|
import {indicatorScope} from '../Indicator/indicator.markers.stylex';
|
|
28
28
|
import {useIndicatorFocusRing} from '../hooks/useIndicatorFocusRing';
|
|
29
29
|
import {useIndicator} from '../Indicator';
|
|
@@ -31,11 +31,6 @@ import {Item} from '../Item';
|
|
|
31
31
|
import {themeProps} from '../utils/themeProps';
|
|
32
32
|
|
|
33
33
|
const styles = stylex.create({
|
|
34
|
-
container: {
|
|
35
|
-
display: 'flex',
|
|
36
|
-
alignItems: 'center',
|
|
37
|
-
gap: spacingVars['--spacing-2'],
|
|
38
|
-
},
|
|
39
34
|
radioWrapper: {
|
|
40
35
|
position: 'relative',
|
|
41
36
|
display: 'flex',
|
|
@@ -49,7 +44,10 @@ const styles = stylex.create({
|
|
|
49
44
|
margin: 0,
|
|
50
45
|
padding: 0,
|
|
51
46
|
opacity: 0,
|
|
52
|
-
cursor:
|
|
47
|
+
cursor: {
|
|
48
|
+
default: 'pointer',
|
|
49
|
+
':is(:disabled,[aria-disabled="true"])': 'default',
|
|
50
|
+
},
|
|
53
51
|
zIndex: 1,
|
|
54
52
|
minInlineSize: {
|
|
55
53
|
default: null,
|
|
@@ -73,16 +71,12 @@ const styles = stylex.create({
|
|
|
73
71
|
},
|
|
74
72
|
},
|
|
75
73
|
inputDisabled: {
|
|
76
|
-
cursor: '
|
|
74
|
+
cursor: 'default',
|
|
77
75
|
},
|
|
78
76
|
// Holds only the indicator, so the focus ring has one unambiguous target.
|
|
79
77
|
indicatorSlot: {
|
|
80
78
|
display: 'contents',
|
|
81
79
|
},
|
|
82
|
-
labelDisabled: {
|
|
83
|
-
color: colorVars['--color-text-disabled'],
|
|
84
|
-
cursor: 'not-allowed',
|
|
85
|
-
},
|
|
86
80
|
});
|
|
87
81
|
|
|
88
82
|
const wrapperSizeStyles = stylex.create({
|
|
@@ -96,13 +90,23 @@ const wrapperSizeStyles = stylex.create({
|
|
|
96
90
|
},
|
|
97
91
|
});
|
|
98
92
|
|
|
99
|
-
const
|
|
93
|
+
const rowStyles = stylex.create({
|
|
94
|
+
// The row's default appearance is a bare surface: no density padding, no
|
|
95
|
+
// radius, and no full-row background — only the indicator tints on hover
|
|
96
|
+
// (via `indicatorScope`). Item paints padding/radius/hover as an interactive
|
|
97
|
+
// row, so this neutralizes them at the component level. A theme's
|
|
98
|
+
// `radio-list-item` overrides still win: they land in `@layer astryx-theme`,
|
|
99
|
+
// above the component's base StyleX layer, so themes opt back into row
|
|
100
|
+
// padding/radius/hover/selected styling. `minWidth: 0` preserves label
|
|
101
|
+
// truncation now that the Item is the row's flex child.
|
|
100
102
|
root: {
|
|
101
103
|
paddingBlock: 0,
|
|
102
104
|
paddingInline: 0,
|
|
103
105
|
borderRadius: 0,
|
|
104
|
-
flex: 1,
|
|
105
106
|
minWidth: 0,
|
|
107
|
+
// Suppress Item's interactive hover/press background so the resting and
|
|
108
|
+
// hovered row look identical by default (a theme can restyle either).
|
|
109
|
+
backgroundColor: 'transparent',
|
|
106
110
|
},
|
|
107
111
|
});
|
|
108
112
|
|
|
@@ -159,6 +163,7 @@ export function RadioListItem({
|
|
|
159
163
|
xstyle,
|
|
160
164
|
className,
|
|
161
165
|
style,
|
|
166
|
+
onClick,
|
|
162
167
|
...rest
|
|
163
168
|
}: RadioListItemProps) {
|
|
164
169
|
const context = use(RadioListContext);
|
|
@@ -185,16 +190,28 @@ export function RadioListItem({
|
|
|
185
190
|
const indicatorRef = useRef<HTMLSpanElement>(null);
|
|
186
191
|
const {focusProps} = useIndicatorFocusRing(indicatorRef, isDisabled);
|
|
187
192
|
|
|
193
|
+
// The radio is the row's single keyboard control and action. The row is an
|
|
194
|
+
// enlarged click/tap target that delegates surface clicks — the description
|
|
195
|
+
// and the empty hover area, not just the control and its label — to the
|
|
196
|
+
// input via Item's `interactiveRef` (useClickableContainer). This matches
|
|
197
|
+
// CheckboxListItem so the whole row is clickable, and keeps one tab stop per
|
|
198
|
+
// option (WCAG 4.1.2). The radio carries its accessible name via `aria-label`
|
|
199
|
+
// since the visible label is now a plain (non-`<label>`) text node — a real
|
|
200
|
+
// `<label htmlFor>` would double-fire under delegation.
|
|
201
|
+
const radioRef = useRef<HTMLInputElement>(null);
|
|
202
|
+
|
|
188
203
|
const radioCircle = (
|
|
189
204
|
<div
|
|
190
205
|
{...stylex.props(styles.radioWrapper, wrapperSizeStyles[size])}
|
|
191
206
|
{...focusProps}>
|
|
192
207
|
<input
|
|
208
|
+
ref={radioRef}
|
|
193
209
|
id={id}
|
|
194
210
|
type="radio"
|
|
195
211
|
name={context.name}
|
|
196
212
|
value={value}
|
|
197
213
|
checked={isChecked}
|
|
214
|
+
aria-label={label}
|
|
198
215
|
disabled={isDisabled && !keepsFocusableForMessage}
|
|
199
216
|
aria-disabled={keepsFocusableForMessage ? 'true' : undefined}
|
|
200
217
|
// A focusable-disabled radio is not natively disabled, so detach it
|
|
@@ -208,6 +225,10 @@ export function RadioListItem({
|
|
|
208
225
|
}
|
|
209
226
|
context.onChange(value);
|
|
210
227
|
}}
|
|
228
|
+
// A consumer onClick rides on the radio input itself, so it fires for
|
|
229
|
+
// both direct control clicks and row-surface clicks the row delegates
|
|
230
|
+
// to the input — the same routing CheckboxListItem uses.
|
|
231
|
+
onClick={onClick}
|
|
211
232
|
aria-describedby={description ? descriptionID : undefined}
|
|
212
233
|
{...stylex.props(
|
|
213
234
|
styles.input,
|
|
@@ -225,50 +246,64 @@ export function RadioListItem({
|
|
|
225
246
|
</div>
|
|
226
247
|
);
|
|
227
248
|
|
|
228
|
-
const mediaContent =
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
);
|
|
249
|
+
const mediaContent = isRenderable(startContent) ? (
|
|
250
|
+
<>
|
|
251
|
+
{radioCircle}
|
|
252
|
+
{startContent}
|
|
253
|
+
</>
|
|
254
|
+
) : (
|
|
255
|
+
radioCircle
|
|
256
|
+
);
|
|
237
257
|
|
|
238
258
|
return (
|
|
239
|
-
<
|
|
259
|
+
<Item
|
|
240
260
|
ref={ref}
|
|
241
|
-
{
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
261
|
+
startContent={mediaContent}
|
|
262
|
+
// Delegate row-surface clicks (label text, description, and the empty
|
|
263
|
+
// hover area) to the radio input. The input stays the option's sole
|
|
264
|
+
// focusable control, so the row adds no second tab stop.
|
|
265
|
+
interactiveRef={radioRef}
|
|
266
|
+
isDisabled={isDisabled}
|
|
267
|
+
label={<span>{label}</span>}
|
|
268
|
+
description={
|
|
269
|
+
isRenderable(description) ? (
|
|
270
|
+
<span id={descriptionID}>{description}</span>
|
|
271
|
+
) : undefined
|
|
272
|
+
}
|
|
273
|
+
endContent={endContent}
|
|
274
|
+
xstyle={
|
|
275
|
+
[
|
|
245
276
|
// Hover reaches the radio visual through this ancestor marker rather
|
|
246
|
-
// than props, so hovering the row tints the control.
|
|
277
|
+
// than props, so hovering the row tints the control. The marker rides
|
|
278
|
+
// the painting row element (Item), the same element that carries the
|
|
279
|
+
// theme target, so a theme's hover styling stays in step with the tint.
|
|
247
280
|
!isDisabled && indicatorScope,
|
|
281
|
+
// Restore the bare default look: zero Item's padding/radius and its
|
|
282
|
+
// interactive hover/press background. Applied after Item's own base
|
|
283
|
+
// styles so it wins within the base layer; a `radio-list-item` theme
|
|
284
|
+
// still overrides it from the higher `astryx-theme` layer.
|
|
285
|
+
rowStyles.root,
|
|
248
286
|
xstyle,
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
287
|
+
] as StyleXStyles
|
|
288
|
+
}
|
|
289
|
+
{...mergeProps(
|
|
290
|
+
// One target for every row, carrying its size and runtime state so a
|
|
291
|
+
// theme can express "selected option at large" or restyle disabled
|
|
292
|
+
// rows without reaching for structural selectors. It lands on the
|
|
293
|
+
// element Item paints — the row surface — so a theme styling
|
|
294
|
+
// `radio-list-item`'s background/padding/borderRadius (and its
|
|
295
|
+
// `:hover`) actually takes effect from the `astryx-theme` layer, even
|
|
296
|
+
// though the component zeroes those by default. Converges with how
|
|
297
|
+
// ListItem lands `list-item` on the same element as `astryx-item`.
|
|
298
|
+
themeProps('radio-list-item', {
|
|
299
|
+
size,
|
|
300
|
+
selected: isChecked ? 'selected' : null,
|
|
301
|
+
disabled: isDisabled ? 'disabled' : null,
|
|
302
|
+
}),
|
|
303
|
+
{className, style},
|
|
252
304
|
)}
|
|
253
|
-
{...rest}
|
|
254
|
-
|
|
255
|
-
startContent={mediaContent}
|
|
256
|
-
label={
|
|
257
|
-
<label
|
|
258
|
-
htmlFor={id}
|
|
259
|
-
{...stylex.props(isDisabled && styles.labelDisabled)}>
|
|
260
|
-
{label}
|
|
261
|
-
</label>
|
|
262
|
-
}
|
|
263
|
-
description={
|
|
264
|
-
description != null ? (
|
|
265
|
-
<span id={descriptionID}>{description}</span>
|
|
266
|
-
) : undefined
|
|
267
|
-
}
|
|
268
|
-
endContent={endContent}
|
|
269
|
-
xstyle={embeddedStyles.root}
|
|
270
|
-
/>
|
|
271
|
-
</div>
|
|
305
|
+
{...rest}
|
|
306
|
+
/>
|
|
272
307
|
);
|
|
273
308
|
}
|
|
274
309
|
|