@astryxdesign/core 0.5.2-canary.2da7a39 → 0.5.2-canary.2e51213
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/dist/AppShell/AppShell.d.ts +2 -2
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +10 -7
- package/dist/Banner/Banner.d.ts +5 -0
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +7 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +3 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +22 -15
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +2 -2
- package/dist/Chat/ChatComposer.d.ts +2 -2
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +21 -2
- package/dist/Chat/ChatToolCalls.d.ts +1 -1
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +12 -34
- package/dist/Chat/useChatNewMessages.js +3 -3
- package/dist/CheckboxList/CheckboxListItem.d.ts +5 -3
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts +47 -13
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +269 -162
- package/dist/DateTimeInput/NativeDateSegment.d.ts +24 -0
- package/dist/DateTimeInput/NativeDateSegment.d.ts.map +1 -0
- package/dist/DateTimeInput/NativeDateSegment.js +235 -0
- package/dist/DateTimeInput/NativeTimeSegment.d.ts +30 -0
- package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -0
- package/dist/DateTimeInput/NativeTimeSegment.js +248 -0
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts.map +1 -1
- package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +95 -0
- package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -0
- package/dist/DateTimeInput/nativePickerSegmentStyles.js +103 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +2 -4
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +10 -4
- package/dist/Field/PanelSearchInput.d.ts.map +1 -1
- package/dist/Field/PanelSearchInput.js +3 -5
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +4 -2
- package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
- package/dist/Layer/useTouchTrigger.js +2 -4
- package/dist/Layout/Layout.d.ts +7 -8
- package/dist/Layout/Layout.d.ts.map +1 -1
- package/dist/Layout/Layout.js +7 -8
- package/dist/MultiSelector/MultiSelector.d.ts +11 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +89 -45
- package/dist/RadioList/RadioListItem.d.ts +30 -5
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +17 -4
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +102 -44
- package/dist/Resizable/index.d.ts +2 -0
- package/dist/Resizable/index.d.ts.map +1 -1
- package/dist/Resizable/index.js +1 -0
- package/dist/Resizable/useResizable.d.ts +89 -8
- package/dist/Resizable/useResizable.d.ts.map +1 -1
- package/dist/Resizable/useResizable.js +521 -38
- package/dist/Resizable/utils.d.ts +35 -0
- package/dist/Resizable/utils.d.ts.map +1 -0
- package/dist/Resizable/utils.js +27 -0
- package/dist/Selector/Selector.d.ts +10 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +105 -57
- package/dist/Selector/useSelectorPresentation.d.ts +1 -0
- package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
- package/dist/Selector/useSelectorPresentation.js +17 -2
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +3 -5
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +9 -10
- package/dist/Stepper/Step.d.ts +2 -1
- package/dist/Stepper/Step.d.ts.map +1 -1
- package/dist/Stepper/Step.js +75 -11
- package/dist/Stepper/Stepper.d.ts.map +1 -1
- package/dist/Stepper/Stepper.js +1 -0
- package/dist/TabList/TabList.d.ts.map +1 -1
- package/dist/TabList/TabList.js +2 -3
- package/dist/Table/index.d.ts +16 -1
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +4 -0
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +8 -9
- package/dist/Table/plugins/rowStatus/index.d.ts +1 -1
- package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -1
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +11 -30
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
- package/dist/Table/plugins/rowStatus/useTableRowStatus.js +108 -62
- package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +9 -1
- package/dist/Text/useTruncation.d.ts +1 -1
- package/dist/Text/useTruncation.d.ts.map +1 -1
- package/dist/Text/useTruncation.js +8 -7
- package/dist/TimeInput/TimeInput.d.ts +16 -1
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +98 -60
- package/dist/TimeInput/index.d.ts +1 -1
- package/dist/TimeInput/index.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.d.ts +2 -2
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +4 -145
- package/dist/Timestamp/formatRelativeTime.d.ts +20 -0
- package/dist/Timestamp/formatRelativeTime.d.ts.map +1 -0
- package/dist/Timestamp/formatRelativeTime.js +81 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +125 -77
- package/dist/Tokenizer/Tokenizer.d.ts +0 -38
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +94 -26
- package/dist/Tokenizer/useEndLaneReserve.d.ts +31 -0
- package/dist/Tokenizer/useEndLaneReserve.d.ts.map +1 -0
- package/dist/Tokenizer/useEndLaneReserve.js +136 -0
- package/dist/Tooltip/useTooltip.d.ts +1 -1
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +53 -42
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +85 -30
- package/dist/Typeahead/Typeahead.d.ts +0 -21
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +108 -67
- package/dist/Typeahead/busyIndicatorLane.d.ts +62 -0
- package/dist/Typeahead/busyIndicatorLane.d.ts.map +1 -0
- package/dist/Typeahead/busyIndicatorLane.js +98 -0
- package/dist/astryx.css +25 -7
- package/dist/hooks/useFocusReturnVisibility.d.ts.map +1 -1
- package/dist/hooks/useFocusReturnVisibility.js +3 -5
- package/dist/hooks/useIsomorphicLayoutEffect.d.ts +2 -2
- package/dist/hooks/useIsomorphicLayoutEffect.d.ts.map +1 -1
- package/dist/hooks/useOverflow.js +11 -11
- package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
- package/dist/hooks/useScrollOverflow.js +7 -4
- package/dist/theme/defineTheme.d.ts +13 -0
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +7 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +1 -1
- package/dist/theme/localTokens.d.ts +18 -0
- package/dist/theme/localTokens.d.ts.map +1 -0
- package/dist/theme/localTokens.js +162 -0
- package/dist/utils/interactionModality.d.ts +6 -28
- package/dist/utils/interactionModality.d.ts.map +1 -1
- package/dist/utils/interactionModality.js +72 -37
- package/dist/utils/sharedResizeObserver.d.ts +17 -9
- package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
- package/dist/utils/sharedResizeObserver.js +54 -12
- package/locales/en.json +8 -0
- package/locales/pseudo.json +6 -0
- package/package.json +7 -2
- package/src/AlertDialog/useImperativeAlertDialog.test.tsx +163 -0
- package/src/AppShell/AppShell.doc.mjs +4 -3
- package/src/AppShell/AppShell.test.tsx +21 -0
- package/src/AppShell/AppShell.tsx +12 -7
- package/src/Banner/Banner.doc.mjs +5 -1
- package/src/Banner/Banner.tsx +12 -1
- package/src/BottomSheet/BottomSheet.doc.mjs +31 -0
- package/src/BottomSheet/BottomSheet.spec.md +178 -0
- package/src/Breadcrumbs/BreadcrumbItem.tsx +18 -9
- package/src/Breadcrumbs/Breadcrumbs.doc.mjs +4 -1
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +12 -0
- package/src/Button/Button.doc.mjs +56 -0
- package/src/ButtonGroup/ButtonGroup.doc.mjs +47 -0
- package/src/Calendar/hooks/useCalendarConstraints.test.ts +153 -0
- package/src/Calendar/hooks/useCalendarDays.test.ts +265 -0
- package/src/Calendar/hooks/useCalendarNavigation.test.ts +252 -0
- package/src/Carousel/Carousel.test.tsx +83 -0
- package/src/Carousel/Carousel.tsx +8 -2
- package/src/Chat/ChatComposer.doc.mjs +7 -4
- package/src/Chat/ChatComposer.test.tsx +84 -2
- package/src/Chat/ChatComposer.tsx +45 -3
- package/src/Chat/ChatSendButton.test.tsx +189 -0
- package/src/Chat/ChatToolCalls.doc.mjs +1 -1
- package/src/Chat/ChatToolCalls.test.tsx +33 -1
- package/src/Chat/ChatToolCalls.tsx +13 -34
- package/src/Chat/useChatNewMessages.ts +3 -3
- package/src/Chat/useChatPasteAsToken.test.ts +191 -0
- package/src/CheckboxList/CheckboxList.doc.mjs +172 -31
- package/src/CheckboxList/CheckboxList.spec.md +215 -0
- package/src/CheckboxList/CheckboxList.test.tsx +45 -0
- package/src/CheckboxList/CheckboxListItem.doc.mjs +11 -9
- package/src/CheckboxList/CheckboxListItem.tsx +5 -3
- package/src/Collapsible/useCollapsible.test.tsx +236 -0
- package/src/CommandPalette/CommandPalette.doc.mjs +72 -0
- package/src/CommandPalette/CommandPalette.spec.md +224 -0
- package/src/CommandPalette/CommandPaletteEmpty.test.tsx +101 -0
- package/src/ComplexSelector/ComplexSelector.doc.mjs +42 -0
- package/src/ComplexSelector/ComplexSelector.spec.md +190 -0
- package/src/ContextMenu/ContextMenu.doc.mjs +48 -0
- package/src/ContextMenu/ContextMenu.spec.md +207 -0
- package/src/DateTimeInput/DateTimeInput.doc.mjs +43 -23
- package/src/DateTimeInput/DateTimeInput.tsx +388 -181
- package/src/DateTimeInput/DateTimeInputTouch.test.tsx +10 -2
- package/src/DateTimeInput/NativeDateSegment.tsx +308 -0
- package/src/DateTimeInput/NativePickerSegments.test.tsx +626 -0
- package/src/DateTimeInput/NativeTimeSegment.tsx +331 -0
- package/src/DateTimeInput/index.ts +1 -0
- package/src/DateTimeInput/nativePickerSegmentStyles.ts +120 -0
- package/src/Divider/Divider.doc.mjs +24 -0
- package/src/Divider/Divider.spec.md +157 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +104 -0
- package/src/DropdownMenu/DropdownMenu.spec.md +246 -0
- package/src/DropdownMenu/DropdownMenu.tsx +2 -4
- package/src/Field/Field.doc.mjs +1 -0
- package/src/Field/Field.test.tsx +39 -0
- package/src/Field/Field.tsx +18 -1
- package/src/Field/InputClearButton.test.tsx +68 -6
- package/src/Field/PanelSearchInput.tsx +3 -5
- package/src/FieldStatus/FieldStatus.doc.mjs +21 -0
- package/src/FieldStatus/FieldStatus.spec.md +213 -0
- package/src/FieldStatus/FieldStatus.test.tsx +17 -0
- package/src/FieldStatus/FieldStatus.tsx +7 -2
- package/src/Grid/Grid.doc.mjs +19 -0
- package/src/Grid/Grid.spec.md +162 -0
- package/src/Icon/Icon.doc.mjs +196 -48
- package/src/Icon/Icon.spec.md +192 -0
- package/src/IconButton/IconButton.doc.mjs +38 -0
- package/src/Kbd/Kbd.doc.mjs +18 -0
- package/src/Kbd/Kbd.spec.md +142 -0
- package/src/Layer/useTouchTrigger.ts +2 -4
- package/src/Layout/Layout.doc.mjs +57 -17
- package/src/Layout/Layout.spec.md +235 -0
- package/src/Layout/Layout.test.tsx +1 -1
- package/src/Layout/Layout.tsx +7 -8
- package/src/Layout/LayoutHeader.doc.mjs +9 -0
- package/src/Layout/LayoutPanel.doc.mjs +4 -3
- package/src/Lightbox/Lightbox.doc.mjs +149 -33
- package/src/Lightbox/Lightbox.spec.md +198 -0
- package/src/Lightbox/useLightbox.test.tsx +263 -0
- package/src/Markdown/Markdown.doc.mjs +60 -0
- package/src/Markdown/Markdown.spec.md +207 -0
- package/src/MobileNav/MobileNav.doc.mjs +140 -32
- package/src/MobileNav/MobileNav.spec.md +209 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +42 -0
- package/src/MoreMenu/MoreMenu.spec.md +222 -0
- package/src/MultiSelector/MultiSelector.doc.mjs +124 -1
- package/src/MultiSelector/MultiSelector.spec.md +293 -0
- package/src/MultiSelector/MultiSelector.test.tsx +305 -2
- package/src/MultiSelector/MultiSelector.tsx +124 -55
- package/src/NavIcon/NavIcon.doc.mjs +17 -0
- package/src/NavIcon/NavIcon.spec.md +134 -0
- package/src/NavMenu/NavHeadingMenu.spec.md +210 -0
- package/src/NavMenu/NavMenu.doc.mjs +37 -0
- package/src/Outline/Outline.doc.mjs +35 -0
- package/src/Outline/Outline.spec.md +162 -0
- package/src/OverflowList/OverflowList.doc.mjs +24 -0
- package/src/OverflowList/OverflowList.spec.md +157 -0
- package/src/Pagination/Pagination.doc.mjs +74 -0
- package/src/Pagination/Pagination.spec.md +226 -0
- package/src/Popover/Popover.doc.mjs +264 -65
- package/src/Popover/Popover.spec.md +421 -0
- package/src/Popover/usePopover.doc.mjs +208 -33
- package/src/PowerSearch/PowerSearch.spec.md +291 -0
- package/src/PowerSearch/PowerSearchFilterEditor.test.tsx +253 -0
- package/src/PowerSearch/PowerSearchToken.test.tsx +228 -0
- package/src/ProgressBar/ProgressBar.doc.mjs +198 -38
- package/src/ProgressBar/ProgressBar.spec.md +261 -0
- package/src/RadioList/RadioList.test.tsx +136 -2
- package/src/RadioList/RadioListItem.doc.mjs +30 -11
- package/src/RadioList/RadioListItem.tsx +44 -8
- package/src/Resizable/Resizable.doc.mjs +130 -24
- package/src/Resizable/Resizable.spec.md +246 -0
- package/src/Resizable/ResizeHandle.test.tsx +177 -56
- package/src/Resizable/ResizeHandle.tsx +128 -45
- package/src/Resizable/index.ts +2 -0
- package/src/Resizable/shippedDirections.test.ts +462 -0
- package/src/Resizable/useResizable.doc.mjs +124 -29
- package/src/Resizable/useResizable.test.ts +1277 -3
- package/src/Resizable/useResizable.ts +760 -48
- package/src/Resizable/utils.test.ts +74 -0
- package/src/Resizable/utils.ts +35 -0
- package/src/Section/Section.doc.mjs +17 -0
- package/src/Section/Section.spec.md +139 -0
- package/src/SegmentedControl/SegmentedControl.doc.mjs +83 -0
- package/src/SegmentedControl/SegmentedControl.spec.md +152 -0
- package/src/Selector/Selector.doc.mjs +133 -97
- package/src/Selector/Selector.spec.md +300 -0
- package/src/Selector/Selector.test.tsx +318 -1
- package/src/Selector/Selector.tsx +127 -60
- package/src/Selector/useSelectorPresentation.ts +24 -4
- package/src/SideNav/SideNav.test.tsx +3 -3
- package/src/SideNav/SideNavCollapseButton.doc.mjs +8 -0
- package/src/SideNav/SideNavItem.doc.mjs +1 -1
- package/src/Skeleton/Skeleton.doc.mjs +12 -0
- package/src/Skeleton/Skeleton.spec.md +127 -0
- package/src/Slider/Slider.doc.mjs +184 -30
- package/src/Slider/Slider.spec.md +224 -0
- package/src/Slider/Slider.tsx +2 -5
- package/src/Spinner/Spinner.doc.mjs +5 -5
- package/src/Spinner/Spinner.test.tsx +32 -7
- package/src/Spinner/Spinner.tsx +46 -14
- package/src/Stack/Stack.doc.mjs +22 -0
- package/src/Stack/Stack.spec.md +155 -0
- package/src/StatusDot/StatusDot.doc.mjs +17 -0
- package/src/StatusDot/StatusDot.spec.md +138 -0
- package/src/Stepper/Step.doc.mjs +1 -1
- package/src/Stepper/Step.tsx +118 -5
- package/src/Stepper/Stepper.doc.mjs +51 -1
- package/src/Stepper/Stepper.spec.md +245 -0
- package/src/Stepper/Stepper.test.tsx +315 -0
- package/src/Stepper/Stepper.tsx +8 -0
- package/src/Switch/Switch.doc.mjs +40 -0
- package/src/Switch/Switch.spec.md +175 -0
- package/src/TabList/TabList.tsx +2 -3
- package/src/Table/Table.doc.mjs +102 -24
- package/src/Table/Table.perf.test.tsx +51 -1
- package/src/Table/Table.spec.md +325 -0
- package/src/Table/TableHeaderCell.test.tsx +291 -0
- package/src/Table/index.ts +19 -4
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -12
- package/src/Table/plugins/filtering/useTableFilterState.test.tsx +143 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +2 -1
- package/src/Table/plugins/rowStatus/index.ts +1 -4
- package/src/Table/plugins/rowStatus/useTableRowStatus.public.test.ts +92 -0
- package/src/Table/plugins/rowStatus/useTableRowStatus.spec.md +354 -0
- package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +431 -56
- package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +155 -84
- package/src/Table/plugins/sortable/useTableSortable.test.tsx +72 -0
- package/src/Table/plugins/sortable/useTableSortable.tsx +18 -1
- package/src/Table/useTableGroupedRows.doc.mjs +2 -2
- package/src/Table/useTableRowStatus.doc.mjs +5 -5
- package/src/Text/Text.doc.mjs +190 -43
- package/src/Text/Text.spec.md +206 -0
- package/src/Text/useTruncation.ts +8 -7
- package/src/TextArea/TextArea.doc.mjs +255 -45
- package/src/TextArea/TextArea.spec.md +205 -0
- package/src/TimeInput/NativeTimeInput.test.tsx +269 -0
- package/src/TimeInput/TimeInput.doc.mjs +47 -23
- package/src/TimeInput/TimeInput.tsx +109 -50
- package/src/TimeInput/index.ts +1 -0
- package/src/Timestamp/Timestamp.doc.mjs +2 -2
- package/src/Timestamp/Timestamp.test.tsx +75 -3
- package/src/Timestamp/Timestamp.tsx +7 -153
- package/src/Timestamp/formatRelativeTime.ts +96 -0
- package/src/Toast/ToastViewport.test.tsx +194 -0
- package/src/Toast/ToastViewport.tsx +136 -58
- package/src/ToggleButton/ToggleButton.doc.mjs +56 -0
- package/src/Tokenizer/Tokenizer.doc.mjs +2 -0
- package/src/Tokenizer/Tokenizer.spec.md +293 -0
- package/src/Tokenizer/Tokenizer.test.tsx +335 -1
- package/src/Tokenizer/Tokenizer.tsx +129 -46
- package/src/Tokenizer/useEndLaneReserve.ts +146 -0
- package/src/Toolbar/Toolbar.doc.mjs +19 -0
- package/src/Toolbar/Toolbar.spec.md +174 -0
- package/src/Tooltip/Tooltip.doc.mjs +17 -0
- package/src/Tooltip/Tooltip.spec.md +142 -0
- package/src/Tooltip/Tooltip.test.tsx +21 -1
- package/src/Tooltip/useTooltip.test.tsx +318 -0
- package/src/Tooltip/useTooltip.tsx +60 -39
- package/src/TreeList/TreeList.doc.mjs +58 -0
- package/src/TreeList/TreeList.spec.md +224 -0
- package/src/Typeahead/BaseTypeahead.tsx +96 -25
- package/src/Typeahead/Typeahead.doc.mjs +89 -1
- package/src/Typeahead/Typeahead.spec.md +257 -0
- package/src/Typeahead/Typeahead.test.tsx +502 -1
- package/src/Typeahead/Typeahead.tsx +187 -69
- package/src/Typeahead/TypeaheadItem.test.tsx +93 -2
- package/src/Typeahead/busyIndicatorLane.tsx +109 -0
- package/src/__tests__/stylexDeclarations.ts +51 -0
- package/src/hooks/useFocusReturnVisibility.ts +3 -5
- package/src/hooks/useOverflow.ts +11 -11
- package/src/hooks/useScrollLock.test.ts +103 -0
- package/src/hooks/useScrollOverflow.ts +7 -4
- package/src/i18n/useTranslator.test.tsx +197 -0
- package/src/theme/defineTheme.test.ts +227 -0
- package/src/theme/defineTheme.ts +30 -0
- package/src/theme/derivedVarRegistry.test.ts +6 -0
- package/src/theme/generateThemeRules.ts +4 -1
- package/src/theme/localTokens.ts +272 -0
- package/src/theme/themingTargets.test.ts +126 -28
- package/src/utils/interactionModality.test.ts +83 -0
- package/src/utils/interactionModality.ts +88 -36
- package/src/utils/sharedResizeObserver.test.ts +124 -5
- package/src/utils/sharedResizeObserver.ts +60 -14
|
@@ -666,13 +666,147 @@ describe('RadioList', () => {
|
|
|
666
666
|
value="a"
|
|
667
667
|
data-testid="item-a"
|
|
668
668
|
id="item-a-id"
|
|
669
|
-
aria-
|
|
669
|
+
aria-describedby="help-text"
|
|
670
670
|
/>
|
|
671
671
|
</RadioList>,
|
|
672
672
|
);
|
|
673
673
|
const item = screen.getByTestId('item-a');
|
|
674
674
|
expect(item).toHaveAttribute('id', 'item-a-id');
|
|
675
|
-
expect(item).toHaveAttribute('aria-
|
|
675
|
+
expect(item).toHaveAttribute('aria-describedby', 'help-text');
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
it('routes aria-label to the radio control, not the row', () => {
|
|
679
|
+
render(
|
|
680
|
+
<RadioList label="Preference" value="" onChange={() => {}}>
|
|
681
|
+
<RadioListItem
|
|
682
|
+
label="Option A"
|
|
683
|
+
value="a"
|
|
684
|
+
data-testid="item-a"
|
|
685
|
+
aria-label="First option"
|
|
686
|
+
/>
|
|
687
|
+
</RadioList>,
|
|
688
|
+
);
|
|
689
|
+
expect(screen.getByTestId('item-a')).not.toHaveAttribute('aria-label');
|
|
690
|
+
expect(
|
|
691
|
+
screen.getByRole('radio', {name: 'First option'}),
|
|
692
|
+
).toBeInTheDocument();
|
|
693
|
+
});
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
describe('RadioListItem rich content', () => {
|
|
697
|
+
it('names the radio from the text of a ReactNode label', () => {
|
|
698
|
+
render(
|
|
699
|
+
<RadioList label="Plans" value="" onChange={() => {}}>
|
|
700
|
+
<RadioListItem
|
|
701
|
+
label={
|
|
702
|
+
<span>
|
|
703
|
+
Pro plan <em>(recommended)</em>
|
|
704
|
+
</span>
|
|
705
|
+
}
|
|
706
|
+
value="pro"
|
|
707
|
+
/>
|
|
708
|
+
</RadioList>,
|
|
709
|
+
);
|
|
710
|
+
// The radio points at its visible label, so the name is computed from
|
|
711
|
+
// the rich node's own text — unlike CheckboxListItem, whose control has
|
|
712
|
+
// a separate hidden label and needs aria-label to say anything useful.
|
|
713
|
+
expect(
|
|
714
|
+
screen.getByRole('radio', {name: 'Pro plan (recommended)'}),
|
|
715
|
+
).toBeInTheDocument();
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
it('lets aria-label override the name a ReactNode label would compute', () => {
|
|
719
|
+
render(
|
|
720
|
+
<RadioList label="Plans" value="" onChange={() => {}}>
|
|
721
|
+
<RadioListItem
|
|
722
|
+
label={
|
|
723
|
+
<span>
|
|
724
|
+
Pro plan <em>(recommended)</em>
|
|
725
|
+
</span>
|
|
726
|
+
}
|
|
727
|
+
aria-label="Pro plan"
|
|
728
|
+
value="pro"
|
|
729
|
+
/>
|
|
730
|
+
</RadioList>,
|
|
731
|
+
);
|
|
732
|
+
expect(screen.getByRole('radio', {name: 'Pro plan'})).toBeInTheDocument();
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
it('selects the option when a ReactNode label is clicked', async () => {
|
|
736
|
+
const onChange = vi.fn();
|
|
737
|
+
const user = userEvent.setup();
|
|
738
|
+
render(
|
|
739
|
+
<RadioList label="Plans" value="" onChange={onChange}>
|
|
740
|
+
<RadioListItem label={<span>Pro plan</span>} value="pro" />
|
|
741
|
+
</RadioList>,
|
|
742
|
+
);
|
|
743
|
+
await user.click(screen.getByText('Pro plan'));
|
|
744
|
+
expect(onChange).toHaveBeenCalledWith('pro');
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
it('keeps a link in a ReactNode label independent from selection', async () => {
|
|
748
|
+
const onChange = vi.fn();
|
|
749
|
+
const user = userEvent.setup();
|
|
750
|
+
render(
|
|
751
|
+
<RadioList label="Plans" value="" onChange={onChange}>
|
|
752
|
+
<RadioListItem
|
|
753
|
+
label={
|
|
754
|
+
<>
|
|
755
|
+
Pro plan <a href="#pricing">pricing details</a>
|
|
756
|
+
</>
|
|
757
|
+
}
|
|
758
|
+
aria-label="Pro plan"
|
|
759
|
+
value="pro"
|
|
760
|
+
/>
|
|
761
|
+
</RadioList>,
|
|
762
|
+
);
|
|
763
|
+
const radio = screen.getByRole('radio', {name: 'Pro plan'});
|
|
764
|
+
const link = screen.getByRole('link', {name: 'pricing details'});
|
|
765
|
+
await user.tab();
|
|
766
|
+
expect(radio).toHaveFocus();
|
|
767
|
+
await user.tab();
|
|
768
|
+
expect(link).toHaveFocus();
|
|
769
|
+
await user.click(link);
|
|
770
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
it('renders a ReactNode description and keeps it linked to the radio', async () => {
|
|
774
|
+
const onChange = vi.fn();
|
|
775
|
+
const user = userEvent.setup();
|
|
776
|
+
render(
|
|
777
|
+
<RadioList label="Plans" value="" onChange={onChange}>
|
|
778
|
+
<RadioListItem
|
|
779
|
+
label="Pro plan"
|
|
780
|
+
description={
|
|
781
|
+
<span>
|
|
782
|
+
See the <a href="#pricing">pricing page</a>
|
|
783
|
+
</span>
|
|
784
|
+
}
|
|
785
|
+
value="pro"
|
|
786
|
+
/>
|
|
787
|
+
</RadioList>,
|
|
788
|
+
);
|
|
789
|
+
const radio = screen.getByRole('radio', {name: 'Pro plan'});
|
|
790
|
+
expect(radio).toHaveAccessibleDescription('See the pricing page');
|
|
791
|
+
// The row delegates surface clicks to the radio, but a nested link is
|
|
792
|
+
// its own click target — following it must not also select the option.
|
|
793
|
+
await user.click(screen.getByRole('link', {name: 'pricing page'}));
|
|
794
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
795
|
+
});
|
|
796
|
+
|
|
797
|
+
it('leaves aria-describedby off when a conditional description renders nothing', () => {
|
|
798
|
+
const showDetails = false;
|
|
799
|
+
render(
|
|
800
|
+
<RadioList label="Plans" value="" onChange={() => {}}>
|
|
801
|
+
<RadioListItem
|
|
802
|
+
label="Pro plan"
|
|
803
|
+
// The common conditional-slot idiom yields `false`, not undefined.
|
|
804
|
+
description={showDetails && <span>Billing details</span>}
|
|
805
|
+
value="pro"
|
|
806
|
+
/>
|
|
807
|
+
</RadioList>,
|
|
808
|
+
);
|
|
809
|
+
expect(screen.getByRole('radio')).not.toHaveAttribute('aria-describedby');
|
|
676
810
|
});
|
|
677
811
|
});
|
|
678
812
|
|
|
@@ -7,7 +7,8 @@ export const docs = {
|
|
|
7
7
|
subComponentOf: 'RadioList',
|
|
8
8
|
displayName: 'Radio List Item',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
|
-
description:
|
|
10
|
+
description:
|
|
11
|
+
'Individual radio item with label, description, and content slots.',
|
|
11
12
|
// RadioListItem requires RadioList context; wrap it so the preview doesn't throw.
|
|
12
13
|
playground: {
|
|
13
14
|
defaults: {value: 'option-1', label: 'Option'},
|
|
@@ -19,10 +20,17 @@ export const docs = {
|
|
|
19
20
|
props: [
|
|
20
21
|
{
|
|
21
22
|
name: 'label',
|
|
22
|
-
type: '
|
|
23
|
-
description:
|
|
23
|
+
type: 'ReactNode',
|
|
24
|
+
description:
|
|
25
|
+
'Primary label for the radio item. Rich labels may contain links or buttons, which keep their own behavior without selecting the item. The label text names the radio; pair it with aria-label when that text does not read well on its own.',
|
|
24
26
|
required: true,
|
|
25
27
|
},
|
|
28
|
+
{
|
|
29
|
+
name: 'aria-label',
|
|
30
|
+
type: 'string',
|
|
31
|
+
description:
|
|
32
|
+
'Plain-text accessible name for the radio, applied to the control rather than the row. It overrides whatever the label element computes — a plain string label included — so reach for it when a rich label\u2019s own text is absent or reads badly.',
|
|
33
|
+
},
|
|
26
34
|
{
|
|
27
35
|
name: 'value',
|
|
28
36
|
type: 'string',
|
|
@@ -31,8 +39,9 @@ export const docs = {
|
|
|
31
39
|
},
|
|
32
40
|
{
|
|
33
41
|
name: 'description',
|
|
34
|
-
type: '
|
|
35
|
-
description:
|
|
42
|
+
type: 'ReactNode',
|
|
43
|
+
description:
|
|
44
|
+
'Secondary content displayed below the label. Links and buttons keep their own click behaviour — the row only delegates clicks from its non-interactive surface to the radio.',
|
|
36
45
|
},
|
|
37
46
|
{
|
|
38
47
|
name: 'isDisabled',
|
|
@@ -85,10 +94,17 @@ export const docsZh = {
|
|
|
85
94
|
props: [
|
|
86
95
|
{
|
|
87
96
|
name: 'label',
|
|
88
|
-
type: '
|
|
89
|
-
description:
|
|
97
|
+
type: 'ReactNode',
|
|
98
|
+
description:
|
|
99
|
+
'单选选项的主标签。富内容标签可包含链接或按钮,它们保留自身行为且不会选中该选项。标签文本用于命名单选框;若朗读效果不佳,请同时传入 aria-label。',
|
|
90
100
|
required: true,
|
|
91
101
|
},
|
|
102
|
+
{
|
|
103
|
+
name: 'aria-label',
|
|
104
|
+
type: 'string',
|
|
105
|
+
description:
|
|
106
|
+
'单选框的纯文本无障碍名称,应用于控件本身而非整行。它会覆盖标签元素计算出的名称(包括纯字符串标签),因此仅在富文本标签自身缺少文本或朗读效果不佳时使用。',
|
|
107
|
+
},
|
|
92
108
|
{
|
|
93
109
|
name: 'value',
|
|
94
110
|
type: 'string',
|
|
@@ -97,8 +113,9 @@ export const docsZh = {
|
|
|
97
113
|
},
|
|
98
114
|
{
|
|
99
115
|
name: 'description',
|
|
100
|
-
type: '
|
|
101
|
-
description:
|
|
116
|
+
type: 'ReactNode',
|
|
117
|
+
description:
|
|
118
|
+
'显示在标签下方的次要内容。链接和按钮保留自身的点击行为——整行仅将非交互区域的点击委派给单选框。',
|
|
102
119
|
},
|
|
103
120
|
{
|
|
104
121
|
name: 'isDisabled',
|
|
@@ -125,9 +142,11 @@ export const docsDense = {
|
|
|
125
142
|
displayName: 'Radio List Item',
|
|
126
143
|
description: 'Individual radio item w/ label, description, content slots.',
|
|
127
144
|
propDescriptions: {
|
|
128
|
-
label:
|
|
145
|
+
label:
|
|
146
|
+
'Primary label. String or ReactNode; nested controls keep their behavior.',
|
|
147
|
+
'aria-label': 'Plain-text radio name; overrides any label.',
|
|
129
148
|
value: 'Value of this radio item.',
|
|
130
|
-
description: '
|
|
149
|
+
description: 'Secondary content below label. String or ReactNode.',
|
|
131
150
|
isDisabled: 'Whether this individual radio item disabled.',
|
|
132
151
|
startContent: 'Content rendered before radio circle.',
|
|
133
152
|
endContent: 'Content rendered after label.',
|
|
@@ -113,17 +113,42 @@ const rowStyles = stylex.create({
|
|
|
113
113
|
export interface RadioListItemProps extends BaseProps<HTMLDivElement> {
|
|
114
114
|
ref?: React.Ref<HTMLDivElement>;
|
|
115
115
|
/**
|
|
116
|
-
*
|
|
116
|
+
* Primary label for the radio item.
|
|
117
|
+
*
|
|
118
|
+
* Accepts a plain string or a ReactNode for rich content. Links and buttons
|
|
119
|
+
* in the label keep their own behavior; only non-interactive row clicks
|
|
120
|
+
* delegate to the radio. The radio points at the rendered label for its
|
|
121
|
+
* accessible name, so a rich label still names it from its own text — pass
|
|
122
|
+
* `aria-label` when that text is absent or too noisy to announce.
|
|
117
123
|
*/
|
|
118
|
-
label:
|
|
124
|
+
label: ReactNode;
|
|
125
|
+
/**
|
|
126
|
+
* Plain-text accessible name for the radio, applied to the control rather
|
|
127
|
+
* than the row. It replaces the name the label would otherwise supply — a
|
|
128
|
+
* plain string label included — so reach for it when a rich label's own
|
|
129
|
+
* text is absent or reads badly, not as a routine addition.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```
|
|
133
|
+
* <RadioListItem
|
|
134
|
+
* label={<span>Pro plan <Badge label="Recommended" /></span>}
|
|
135
|
+
* aria-label="Pro plan"
|
|
136
|
+
* value="pro"
|
|
137
|
+
* />
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
'aria-label'?: string;
|
|
119
141
|
/**
|
|
120
142
|
* Value of this radio item.
|
|
121
143
|
*/
|
|
122
144
|
value: string;
|
|
123
145
|
/**
|
|
124
|
-
*
|
|
146
|
+
* Secondary content displayed below the label. Accepts a plain string or a
|
|
147
|
+
* ReactNode. Links and buttons anywhere in the row keep their own click
|
|
148
|
+
* behaviour — the row only delegates clicks from its non-interactive
|
|
149
|
+
* surface to the radio.
|
|
125
150
|
*/
|
|
126
|
-
description?:
|
|
151
|
+
description?: ReactNode;
|
|
127
152
|
/**
|
|
128
153
|
* Whether this individual radio item is disabled.
|
|
129
154
|
* @default false
|
|
@@ -155,6 +180,7 @@ export interface RadioListItemProps extends BaseProps<HTMLDivElement> {
|
|
|
155
180
|
export function RadioListItem({
|
|
156
181
|
ref,
|
|
157
182
|
label,
|
|
183
|
+
'aria-label': ariaLabel,
|
|
158
184
|
value,
|
|
159
185
|
description,
|
|
160
186
|
isDisabled: isItemDisabled = false,
|
|
@@ -172,6 +198,7 @@ export function RadioListItem({
|
|
|
172
198
|
}
|
|
173
199
|
|
|
174
200
|
const id = useId();
|
|
201
|
+
const labelID = useId();
|
|
175
202
|
const descriptionID = useId();
|
|
176
203
|
const isDisabled = context.isDisabled || isItemDisabled;
|
|
177
204
|
// When the whole group is disabled with a disabledMessage, radios stay
|
|
@@ -181,6 +208,10 @@ export function RadioListItem({
|
|
|
181
208
|
const keepsFocusableForMessage =
|
|
182
209
|
context.hasDisabledMessage && !isItemDisabled;
|
|
183
210
|
const isChecked = context.value === value;
|
|
211
|
+
// One predicate for both the rendered element and the aria-describedby that
|
|
212
|
+
// points at it. A ReactNode description can be `false` or `''`, which render
|
|
213
|
+
// nothing — a `!= null` check would leave the link dangling.
|
|
214
|
+
const hasDescription = isRenderable(description);
|
|
184
215
|
const size = context.size;
|
|
185
216
|
// The radio visual is an indicator: a theme can restyle it through the
|
|
186
217
|
// `radio` / `radio-dot` targets or replace the component outright.
|
|
@@ -211,7 +242,6 @@ export function RadioListItem({
|
|
|
211
242
|
name={context.name}
|
|
212
243
|
value={value}
|
|
213
244
|
checked={isChecked}
|
|
214
|
-
aria-label={label}
|
|
215
245
|
disabled={isDisabled && !keepsFocusableForMessage}
|
|
216
246
|
aria-disabled={keepsFocusableForMessage ? 'true' : undefined}
|
|
217
247
|
// A focusable-disabled radio is not natively disabled, so detach it
|
|
@@ -229,7 +259,13 @@ export function RadioListItem({
|
|
|
229
259
|
// both direct control clicks and row-surface clicks the row delegates
|
|
230
260
|
// to the input — the same routing CheckboxListItem uses.
|
|
231
261
|
onClick={onClick}
|
|
232
|
-
|
|
262
|
+
// The radio names itself from the visible label element, which works
|
|
263
|
+
// for a rich label as well as a plain string. `aria-label` replaces
|
|
264
|
+
// that name rather than adding to it, so the two are mutually
|
|
265
|
+
// exclusive — aria-labelledby would otherwise win over it.
|
|
266
|
+
aria-label={ariaLabel}
|
|
267
|
+
aria-labelledby={ariaLabel == null ? labelID : undefined}
|
|
268
|
+
aria-describedby={hasDescription ? descriptionID : undefined}
|
|
233
269
|
{...stylex.props(
|
|
234
270
|
styles.input,
|
|
235
271
|
wrapperSizeStyles[size],
|
|
@@ -264,9 +300,9 @@ export function RadioListItem({
|
|
|
264
300
|
// focusable control, so the row adds no second tab stop.
|
|
265
301
|
interactiveRef={radioRef}
|
|
266
302
|
isDisabled={isDisabled}
|
|
267
|
-
label={<span>{label}</span>}
|
|
303
|
+
label={<span id={labelID}>{label}</span>}
|
|
268
304
|
description={
|
|
269
|
-
|
|
305
|
+
hasDescription ? (
|
|
270
306
|
<span id={descriptionID}>{description}</span>
|
|
271
307
|
) : undefined
|
|
272
308
|
}
|
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
+
/** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
|
|
4
|
+
const anatomy = [
|
|
5
|
+
{
|
|
6
|
+
name: 'Handle',
|
|
7
|
+
required: true,
|
|
8
|
+
description:
|
|
9
|
+
'Focusable separator that owns pointer and keyboard resize interaction.',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: 'Grip pill',
|
|
13
|
+
required: false,
|
|
14
|
+
description:
|
|
15
|
+
'Default visible grip indicator; custom handle content can replace it.',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'Grab zone',
|
|
19
|
+
required: true,
|
|
20
|
+
description:
|
|
21
|
+
'Invisible enlarged pointer region aligned with the grip or divider.',
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
|
|
3
25
|
/** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
|
|
4
26
|
export const docs = {
|
|
5
27
|
name: 'Resizable',
|
|
@@ -19,11 +41,17 @@ export const docs = {
|
|
|
19
41
|
'grip',
|
|
20
42
|
],
|
|
21
43
|
usage: {
|
|
44
|
+
anatomy,
|
|
22
45
|
description:
|
|
23
46
|
'Hook-based resizable panel system. useResizable() manages size state ' +
|
|
24
47
|
'and ResizeHandle provides the interactive pill-grip separator. ' +
|
|
25
48
|
'Pass resize props to existing layout components via their resizable prop.',
|
|
26
49
|
bestPractices: [
|
|
50
|
+
{
|
|
51
|
+
guidance: true,
|
|
52
|
+
description:
|
|
53
|
+
'Use percent(value, {min: pixel(value)}) or percent(value, {max: pixel(value)}) when a percentage needs exactly one pixel floor or ceiling. Reuse Table’s pixel() helper; numbers, exact Npx, and pixel(value) remain pixels. State, persistence, callbacks, paint, and ARIA remain resolved pixels.',
|
|
54
|
+
},
|
|
27
55
|
{
|
|
28
56
|
guidance: true,
|
|
29
57
|
description:
|
|
@@ -57,24 +85,79 @@ export const docs = {
|
|
|
57
85
|
description:
|
|
58
86
|
'Hook that manages resize state for one or more panel regions. ' +
|
|
59
87
|
'Returns size, isCollapsed, collapse/expand/resize methods, and props to pass to handles.',
|
|
88
|
+
examples: [
|
|
89
|
+
{
|
|
90
|
+
label: 'Structured fixed pixels',
|
|
91
|
+
code: `const region = useResizable({
|
|
92
|
+
defaultSize: pixel(333),
|
|
93
|
+
containerRef,
|
|
94
|
+
});`,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
label: 'One-time structured default',
|
|
98
|
+
code: `import {useRef} from 'react';
|
|
99
|
+
import {ResizeHandle, useResizable} from '@astryxdesign/core/Resizable';
|
|
100
|
+
import {percent, pixel} from '@astryxdesign/core/Resizable/utils';
|
|
101
|
+
|
|
102
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
103
|
+
|
|
104
|
+
const region = useResizable({
|
|
105
|
+
defaultSize: percent(40, {min: pixel(333)}),
|
|
106
|
+
containerRef,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
<ResizeHandle direction="horizontal" resizable={region.props} />;`,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
label: 'Live percentage floor',
|
|
113
|
+
code: `const region = useResizable({
|
|
114
|
+
defaultSize: 0,
|
|
115
|
+
minSize: percent(40, {min: pixel(333)}),
|
|
116
|
+
containerRef,
|
|
117
|
+
});`,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
label: 'Live percentage ceiling',
|
|
121
|
+
code: `const region = useResizable({
|
|
122
|
+
defaultSize: 500,
|
|
123
|
+
maxSize: percent(10, {max: pixel(400)}),
|
|
124
|
+
containerRef,
|
|
125
|
+
});`,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
60
128
|
props: [
|
|
61
129
|
{
|
|
62
130
|
name: 'defaultSize',
|
|
63
|
-
type: '
|
|
131
|
+
type: 'SizeValue | ResizableSize',
|
|
64
132
|
description:
|
|
65
|
-
'Initial size
|
|
133
|
+
'Initial size. Numbers, exact Npx, and pixel(value) are pixels; exact N% has no additional pixel bound; percent(value, {min: pixel(value)}) or percent(value, {max: pixel(value)}) adds exactly one and resolves once.',
|
|
66
134
|
default: '250',
|
|
67
135
|
},
|
|
136
|
+
{
|
|
137
|
+
name: 'minSize',
|
|
138
|
+
type: 'ResizableSize',
|
|
139
|
+
description:
|
|
140
|
+
'Live minimum. Numbers, exact Npx, and pixel(value) remain pixels; exact N% has no additional pixel bound; percent(value, {min: pixel(value)}) or percent(value, {max: pixel(value)}) adds exactly one.',
|
|
141
|
+
default: '50',
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'maxSize',
|
|
145
|
+
type: 'ResizableSize',
|
|
146
|
+
description:
|
|
147
|
+
'Live maximum. Numbers, exact Npx, and pixel(value) remain pixels; exact N% has no additional pixel bound; percent(value, {min: pixel(value)}) or percent(value, {max: pixel(value)}) adds exactly one.',
|
|
148
|
+
default: 'Infinity',
|
|
149
|
+
},
|
|
68
150
|
{
|
|
69
151
|
name: 'minSizePx',
|
|
70
152
|
type: 'number',
|
|
71
|
-
description: '
|
|
153
|
+
description: 'Deprecated pixel-only alias for minSize.',
|
|
72
154
|
default: '50',
|
|
73
155
|
},
|
|
74
156
|
{
|
|
75
157
|
name: 'maxSizePx',
|
|
76
158
|
type: 'number',
|
|
77
|
-
description:
|
|
159
|
+
description:
|
|
160
|
+
'Deprecated pixel-only alias for maxSize. Explicit Infinity remains valid.',
|
|
78
161
|
default: 'Infinity',
|
|
79
162
|
},
|
|
80
163
|
{
|
|
@@ -86,8 +169,7 @@ export const docs = {
|
|
|
86
169
|
{
|
|
87
170
|
name: 'collapsedSize',
|
|
88
171
|
type: 'number',
|
|
89
|
-
description:
|
|
90
|
-
'Pixel threshold that triggers collapse during drag.',
|
|
172
|
+
description: 'Pixel threshold that triggers collapse during drag.',
|
|
91
173
|
default: '40',
|
|
92
174
|
},
|
|
93
175
|
{
|
|
@@ -98,13 +180,13 @@ export const docs = {
|
|
|
98
180
|
{
|
|
99
181
|
name: 'shrinkOrder',
|
|
100
182
|
type: 'number',
|
|
101
|
-
description:
|
|
102
|
-
'Cascade priority: lower number shrinks first.',
|
|
183
|
+
description: 'Cascade priority: lower number shrinks first.',
|
|
103
184
|
},
|
|
104
185
|
{
|
|
105
186
|
name: 'autoSaveId',
|
|
106
187
|
type: 'string',
|
|
107
|
-
description:
|
|
188
|
+
description:
|
|
189
|
+
'Key for persisting sizes and collapse state to localStorage.',
|
|
108
190
|
},
|
|
109
191
|
],
|
|
110
192
|
},
|
|
@@ -168,7 +250,7 @@ export const docs = {
|
|
|
168
250
|
name: 'resizable',
|
|
169
251
|
type: 'ResizableProps',
|
|
170
252
|
description:
|
|
171
|
-
|
|
253
|
+
"Resize props from useResizable: connects handle to panel. Carries the region's axis ('horizontal' | 'vertical'), which must match this handle's direction.",
|
|
172
254
|
required: true,
|
|
173
255
|
},
|
|
174
256
|
{
|
|
@@ -190,24 +272,42 @@ export const docs = {
|
|
|
190
272
|
|
|
191
273
|
/** @type {import('@astryxdesign/cli/authoring').ComponentTranslationDoc} */
|
|
192
274
|
export const docsDense = {
|
|
193
|
-
description:
|
|
275
|
+
description:
|
|
276
|
+
'Hook-based resizable panel system. useResizable() manages size state; ResizeHandle provides interactive pill-grip separator.',
|
|
194
277
|
usage: {
|
|
278
|
+
anatomy,
|
|
195
279
|
description:
|
|
196
280
|
'Hook-based resizable panel system. useResizable() manages size state; ResizeHandle provides interactive pill-grip separator. Pass resize props to existing layout components via their resizable prop.',
|
|
197
281
|
bestPractices: [
|
|
198
|
-
{
|
|
199
|
-
|
|
200
|
-
|
|
282
|
+
{
|
|
283
|
+
guidance: true,
|
|
284
|
+
description:
|
|
285
|
+
'Use useResizable() w/ existing Astryx layout components. Pass returned props to resizable prop on LayoutPanel or SideNav.',
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
guidance: true,
|
|
289
|
+
description:
|
|
290
|
+
'Provide accessible label on each ResizeHandle when multiple handles exist (e.g. "Resize sidebar", "Resize terminal").',
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
guidance: false,
|
|
294
|
+
description:
|
|
295
|
+
'Wrap panels in extra container components for resize. Hook-first architecture avoids extra DOM; use it directly on existing components.',
|
|
296
|
+
},
|
|
201
297
|
],
|
|
202
298
|
},
|
|
203
299
|
components: [
|
|
204
300
|
{
|
|
205
301
|
name: 'useResizable',
|
|
206
|
-
description:
|
|
302
|
+
description:
|
|
303
|
+
'Hook managing resize state for one or more panel regions. Returns size, isCollapsed, collapse/expand/resize methods, + props to pass to handles.',
|
|
207
304
|
propDescriptions: {
|
|
208
|
-
defaultSize:
|
|
209
|
-
|
|
210
|
-
|
|
305
|
+
defaultSize:
|
|
306
|
+
'initial pixels, exact N%, or percent(value, {min: pixel(value)}) / percent(value, {max: pixel(value)}); resolves once',
|
|
307
|
+
minSize:
|
|
308
|
+
'live minimum: pixels, exact N%, or percent(value, {min: pixel(value)}) / percent(value, {max: pixel(value)})',
|
|
309
|
+
maxSize:
|
|
310
|
+
'live maximum: pixels, exact N%, or percent(value, {min: pixel(value)}) / percent(value, {max: pixel(value)})',
|
|
211
311
|
collapsible: 'region can collapse to size 0?',
|
|
212
312
|
collapsedSize: 'px threshold triggering collapse during drag',
|
|
213
313
|
snaps: 'px values to snap to during resize',
|
|
@@ -217,14 +317,20 @@ export const docsDense = {
|
|
|
217
317
|
},
|
|
218
318
|
{
|
|
219
319
|
name: 'ResizeHandle',
|
|
220
|
-
description:
|
|
320
|
+
description:
|
|
321
|
+
'Draggable separator between panels. Pill-grip: invisible at rest, visible on hover (0.6 opacity), fully opaque during drag (1.0). Keyboard-accessible.',
|
|
221
322
|
propDescriptions: {
|
|
222
|
-
direction:
|
|
223
|
-
|
|
323
|
+
direction:
|
|
324
|
+
'layout direction: determines cursor + indicator orientation',
|
|
325
|
+
isReversed:
|
|
326
|
+
'reverse drag direction. Use when handle controls panel on end/right/bottom side',
|
|
224
327
|
isDisabled: 'handle interactive?',
|
|
225
|
-
hasDivider:
|
|
226
|
-
|
|
227
|
-
|
|
328
|
+
hasDivider:
|
|
329
|
+
'show full-length 1px divider line through handle. Use when adjacent panels share same background',
|
|
330
|
+
isAlwaysVisible:
|
|
331
|
+
'show pill grip at rest instead of only on hover. Use when discoverability important',
|
|
332
|
+
pillPlacement:
|
|
333
|
+
'which side of divider pill sits on. auto = content side (derived from isReversed), flips when collapsed; start = left/top, end = right/bottom, center = centered on divider',
|
|
228
334
|
label: 'accessible label for separator',
|
|
229
335
|
resizable: 'resize props from useResizable: connects handle to panel',
|
|
230
336
|
},
|