@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
package/src/Text/Text.doc.mjs
CHANGED
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
+
/** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
|
|
4
|
+
const anatomy = [
|
|
5
|
+
{
|
|
6
|
+
name: 'Text',
|
|
7
|
+
required: true,
|
|
8
|
+
description:
|
|
9
|
+
'Polymorphic text element that renders the supplied content with themed typography.',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: 'Heading',
|
|
13
|
+
required: false,
|
|
14
|
+
description:
|
|
15
|
+
'Referenced Heading member that renders the supplied content as a semantic h1–h6 element.',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'Truncation tooltip',
|
|
19
|
+
required: false,
|
|
20
|
+
description:
|
|
21
|
+
'Tooltip-owned surface available only when Text or Heading is measured as truncated and truncation tooltips are enabled.',
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
|
|
3
25
|
/** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
|
|
4
26
|
|
|
5
27
|
export const docs = {
|
|
6
28
|
name: 'Text',
|
|
7
29
|
displayName: 'Text',
|
|
8
30
|
category: 'Content',
|
|
9
|
-
keywords: [
|
|
31
|
+
keywords: [
|
|
32
|
+
'text',
|
|
33
|
+
'typography',
|
|
34
|
+
'label',
|
|
35
|
+
'paragraph',
|
|
36
|
+
'heading',
|
|
37
|
+
'caption',
|
|
38
|
+
'font',
|
|
39
|
+
'body',
|
|
40
|
+
'subtitle',
|
|
41
|
+
],
|
|
10
42
|
playground: {
|
|
11
43
|
defaults: {
|
|
12
44
|
children: 'The quick brown fox jumps over the lazy dog.',
|
|
@@ -19,12 +51,14 @@ export const docs = {
|
|
|
19
51
|
{className: 'astryx-text', visualProps: ['type', 'size', 'color']},
|
|
20
52
|
],
|
|
21
53
|
},
|
|
22
|
-
description:
|
|
54
|
+
description:
|
|
55
|
+
'Semantic body text component that renders text with type-based styling from the theme, with optional truncation, decoration, and layout props.',
|
|
23
56
|
props: [
|
|
24
57
|
{
|
|
25
58
|
name: 'type',
|
|
26
59
|
type: "'body' | 'large' | 'label' | 'supporting' | 'code' | 'display-1' | 'display-2' | 'display-3' | 'inherit'",
|
|
27
|
-
description:
|
|
60
|
+
description:
|
|
61
|
+
"Semantic text type. Determines size, weight, and line-height from the theme. 'inherit' takes all three from the surrounding text instead. Themes may add custom types. Note: this prop is called `type`, not `variant`.",
|
|
28
62
|
default: "'body'",
|
|
29
63
|
},
|
|
30
64
|
{
|
|
@@ -36,12 +70,14 @@ export const docs = {
|
|
|
36
70
|
{
|
|
37
71
|
name: 'size',
|
|
38
72
|
type: "'4xs' | '3xs' | '2xs' | 'xsm' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl'",
|
|
39
|
-
description:
|
|
73
|
+
description:
|
|
74
|
+
'Explicit font size override. Overrides the size from `type` but preserves other type properties. Prefer using `type` alone.',
|
|
40
75
|
},
|
|
41
76
|
{
|
|
42
77
|
name: 'color',
|
|
43
78
|
type: "'primary' | 'secondary' | 'disabled' | 'placeholder' | 'accent' | 'inherit'",
|
|
44
|
-
description:
|
|
79
|
+
description:
|
|
80
|
+
"Text color. Defaults to 'secondary' for the 'supporting' type, 'primary' for all others. Themes may add custom colors.",
|
|
45
81
|
},
|
|
46
82
|
{
|
|
47
83
|
name: 'weight',
|
|
@@ -51,7 +87,8 @@ export const docs = {
|
|
|
51
87
|
{
|
|
52
88
|
name: 'display',
|
|
53
89
|
type: "'inline' | 'block'",
|
|
54
|
-
description:
|
|
90
|
+
description:
|
|
91
|
+
"Display type. Silently overridden to 'block' when maxLines > 0 or hasCapsize is true.",
|
|
55
92
|
default: "'inline'",
|
|
56
93
|
},
|
|
57
94
|
{
|
|
@@ -63,19 +100,22 @@ export const docs = {
|
|
|
63
100
|
{
|
|
64
101
|
name: 'maxLines',
|
|
65
102
|
type: 'number',
|
|
66
|
-
description:
|
|
103
|
+
description:
|
|
104
|
+
'Maximum lines before truncation. 0 means no truncation. When set, shows a tooltip on hover if content is truncated.',
|
|
67
105
|
default: '0',
|
|
68
106
|
},
|
|
69
107
|
{
|
|
70
108
|
name: 'hasTruncateTooltip',
|
|
71
109
|
type: "boolean | 'above' | 'below' | 'start' | 'end'",
|
|
72
|
-
description:
|
|
110
|
+
description:
|
|
111
|
+
"Controls tooltip behavior for truncated text. true shows the tooltip at the default position, false disables it, or a placement string ('above' | 'below' | 'start' | 'end') sets a specific position.",
|
|
73
112
|
default: 'true',
|
|
74
113
|
},
|
|
75
114
|
{
|
|
76
115
|
name: 'wordBreak',
|
|
77
116
|
type: "'break-word' | 'break-all'",
|
|
78
|
-
description:
|
|
117
|
+
description:
|
|
118
|
+
"Word break behavior when truncating. Defaults to 'break-all' for single-line truncation, 'break-word' otherwise.",
|
|
79
119
|
},
|
|
80
120
|
{
|
|
81
121
|
name: 'textWrap',
|
|
@@ -85,13 +125,15 @@ export const docs = {
|
|
|
85
125
|
{
|
|
86
126
|
name: 'justify',
|
|
87
127
|
type: "'start' | 'center' | 'end'",
|
|
88
|
-
description:
|
|
128
|
+
description:
|
|
129
|
+
'Text alignment (justification). Uses logical values (start/end) for i18n/RTL compatibility.',
|
|
89
130
|
default: "'start'",
|
|
90
131
|
},
|
|
91
132
|
{
|
|
92
133
|
name: 'hasCapsize',
|
|
93
134
|
type: 'boolean',
|
|
94
|
-
description:
|
|
135
|
+
description:
|
|
136
|
+
'Enable optical alignment using text-box-trim. Forces block display.',
|
|
95
137
|
default: 'false',
|
|
96
138
|
},
|
|
97
139
|
{
|
|
@@ -114,25 +156,61 @@ export const docs = {
|
|
|
114
156
|
{
|
|
115
157
|
name: 'xstyle',
|
|
116
158
|
type: 'StyleXStyles',
|
|
117
|
-
description:
|
|
159
|
+
description:
|
|
160
|
+
'StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}.',
|
|
118
161
|
},
|
|
119
162
|
],
|
|
120
|
-
components: [
|
|
121
|
-
{name: 'Heading'},
|
|
122
|
-
],
|
|
163
|
+
components: [{name: 'Heading'}],
|
|
123
164
|
usage: {
|
|
165
|
+
anatomy,
|
|
124
166
|
description:
|
|
125
167
|
'Text renders styled body text and headings from the theme. Use Text with a semantic type for body copy, labels, and captions, and Heading for section titles that output the correct h1\u2013h6 element.',
|
|
126
168
|
bestPractices: [
|
|
127
|
-
{
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
169
|
+
{
|
|
170
|
+
guidance: true,
|
|
171
|
+
description:
|
|
172
|
+
'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight; the theme handles the details.',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
guidance: true,
|
|
176
|
+
description:
|
|
177
|
+
'Set accessibilityLevel on Heading when the visual level differs from the document outline so screen readers announce the correct hierarchy.',
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
guidance: true,
|
|
181
|
+
description:
|
|
182
|
+
'Use maxLines with a number to truncate long content; a tooltip appears automatically on hover so no text is lost.',
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
guidance: true,
|
|
186
|
+
description:
|
|
187
|
+
'Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows.',
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
guidance: false,
|
|
191
|
+
description:
|
|
192
|
+
'Override size and weight when a semantic type already matches; extra overrides fight the theme and break when themes change.',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
guidance: false,
|
|
196
|
+
description:
|
|
197
|
+
'Skip heading levels in the document outline; go h1 then h2 then h3, never h1 then h3.',
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
guidance: false,
|
|
201
|
+
description:
|
|
202
|
+
'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text; Text and Heading apply the correct theme tokens automatically.',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
guidance: false,
|
|
206
|
+
description:
|
|
207
|
+
'Pass a `variant` prop; Text does not have a `variant` prop. Use `type` for semantic styling (body, label, large, supporting, code) or use Heading for headings.',
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
guidance: false,
|
|
211
|
+
description:
|
|
212
|
+
'Use Text for headings; use Heading with a `level` prop (1\u20136) for section titles and headings.',
|
|
213
|
+
},
|
|
136
214
|
],
|
|
137
215
|
},
|
|
138
216
|
};
|
|
@@ -143,35 +221,104 @@ export const docsZh = {
|
|
|
143
221
|
description:
|
|
144
222
|
'Text renders styled body text and headings from the theme. Use Text with a semantic type for body copy, labels, and captions, and Heading for section titles that output the correct h1\u2013h6 element.',
|
|
145
223
|
bestPractices: [
|
|
146
|
-
{
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
224
|
+
{
|
|
225
|
+
guidance: true,
|
|
226
|
+
description:
|
|
227
|
+
'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight; the theme handles the details.',
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
guidance: true,
|
|
231
|
+
description:
|
|
232
|
+
'Set accessibilityLevel on Heading when the visual level differs from the document outline so screen readers announce the correct hierarchy.',
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
guidance: true,
|
|
236
|
+
description:
|
|
237
|
+
'Use maxLines with a number to truncate long content; a tooltip appears automatically on hover so no text is lost.',
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
guidance: true,
|
|
241
|
+
description:
|
|
242
|
+
'Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows.',
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
guidance: false,
|
|
246
|
+
description:
|
|
247
|
+
'Override size and weight when a semantic type already matches; extra overrides fight the theme and break when themes change.',
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
guidance: false,
|
|
251
|
+
description:
|
|
252
|
+
'Skip heading levels in the document outline; go h1 then h2 then h3, never h1 then h3.',
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
guidance: false,
|
|
256
|
+
description:
|
|
257
|
+
'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text; Text and Heading apply the correct theme tokens automatically.',
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
guidance: false,
|
|
261
|
+
description:
|
|
262
|
+
'Pass a `variant` prop; Text does not have a `variant` prop. Use `type` for semantic styling (body, label, large, supporting, code) or use Heading for headings.',
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
guidance: false,
|
|
266
|
+
description:
|
|
267
|
+
'Use Text for headings; use Heading with a `level` prop (1\u20136) for section titles and headings.',
|
|
268
|
+
},
|
|
155
269
|
],
|
|
156
270
|
},
|
|
157
271
|
};
|
|
158
272
|
|
|
159
273
|
/** @type {import('@astryxdesign/cli/authoring').ComponentTranslationDoc} */
|
|
160
274
|
export const docsDense = {
|
|
161
|
-
description:
|
|
275
|
+
description:
|
|
276
|
+
'semantic body text + headings w/ theme-driven type scale, truncation, tabular numbers',
|
|
162
277
|
usage: {
|
|
163
278
|
description:
|
|
164
279
|
'Text renders styled body text and headings. Text for body copy with semantic types, Heading for h1\u2013h6 with theme tokens.',
|
|
165
280
|
bestPractices: [
|
|
166
|
-
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
{
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
281
|
+
{
|
|
282
|
+
guidance: true,
|
|
283
|
+
description:
|
|
284
|
+
'Semantic type (body, label, supporting, large, code) instead of manual size/weight.',
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
guidance: true,
|
|
288
|
+
description:
|
|
289
|
+
'accessibilityLevel on Heading when visual level differs from document outline.',
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
guidance: true,
|
|
293
|
+
description:
|
|
294
|
+
'maxLines for truncation; tooltip shows full text on hover.',
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
guidance: true,
|
|
298
|
+
description: 'hasTabularNumbers for aligned numeric columns.',
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
guidance: false,
|
|
302
|
+
description:
|
|
303
|
+
'Override size/weight when a semantic type already matches.',
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
guidance: false,
|
|
307
|
+
description: 'Skip heading levels; sequential h1 \u2192 h2 \u2192 h3.',
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
guidance: false,
|
|
311
|
+
description: 'Raw <p>/<h1>/<span>; use Text/Heading for theme tokens.',
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
guidance: false,
|
|
315
|
+
description:
|
|
316
|
+
'`variant` prop, which does not exist. Use `type` for text styling or Heading for headings.',
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
guidance: false,
|
|
320
|
+
description: 'Text for headings: use Heading with level (1\u20136).',
|
|
321
|
+
},
|
|
175
322
|
],
|
|
176
323
|
},
|
|
177
324
|
};
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 3
|
|
3
|
+
template_version: 3
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:Text
|
|
6
|
+
authority: draft
|
|
7
|
+
archive_reason: null
|
|
8
|
+
superseded_by: null
|
|
9
|
+
approved_by: null
|
|
10
|
+
approved_at: null
|
|
11
|
+
owners: [cixzhang]
|
|
12
|
+
review_triggers: [theming]
|
|
13
|
+
verified_by:
|
|
14
|
+
[
|
|
15
|
+
packages/core/src/Text/Text.test.tsx,
|
|
16
|
+
packages/core/src/Heading/Heading.test.tsx,
|
|
17
|
+
packages/core/src/theme/themingTargets.test.ts,
|
|
18
|
+
scripts/check-knowledge.mjs,
|
|
19
|
+
]
|
|
20
|
+
modules: []
|
|
21
|
+
families: []
|
|
22
|
+
design_specs: []
|
|
23
|
+
architecture: [architecture:component-theming-surface]
|
|
24
|
+
contributing: []
|
|
25
|
+
system_specs: []
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
# Text component contract
|
|
29
|
+
|
|
30
|
+
## Intent
|
|
31
|
+
|
|
32
|
+
Text renders themed body text through the Text component and semantic headings
|
|
33
|
+
through its referenced Heading member. This draft records their current consumer
|
|
34
|
+
anatomy, the two live root targets owned by the canonical Text documentation, and
|
|
35
|
+
the conditional Tooltip delegation used for truncated content. It does not
|
|
36
|
+
change runtime behavior, styling, targets, or public API.
|
|
37
|
+
|
|
38
|
+
## Compatibility and migration
|
|
39
|
+
|
|
40
|
+
- Released default preserved: `yes`
|
|
41
|
+
- Compatibility class: additive documentation only; runtime, DOM, styling,
|
|
42
|
+
targets, and public API remain unchanged
|
|
43
|
+
- Controlled/uncontrolled behavior: not applicable
|
|
44
|
+
- Migration decision: none
|
|
45
|
+
|
|
46
|
+
Consumer migration instructions belong in consumer docs and release notes.
|
|
47
|
+
|
|
48
|
+
## Ownership boundary
|
|
49
|
+
|
|
50
|
+
**Owns**
|
|
51
|
+
|
|
52
|
+
- The polymorphic Text element and its current `text` theming target.
|
|
53
|
+
- The referenced Heading member's semantic heading element and its current
|
|
54
|
+
`heading` theming target.
|
|
55
|
+
- Deciding from the current truncation state whether to compose Tooltip against
|
|
56
|
+
the Text or Heading element.
|
|
57
|
+
|
|
58
|
+
**Does not own / non-goals**
|
|
59
|
+
|
|
60
|
+
- The truncation tooltip surface, layer behavior, or `tooltip` target — owned by
|
|
61
|
+
Tooltip when that composed surface renders.
|
|
62
|
+
- Content supplied as Text or Heading children — owned by the caller.
|
|
63
|
+
- A separate Heading component contract; Heading remains a referenced member of
|
|
64
|
+
the canonical Text documentation and target inventory.
|
|
65
|
+
- New typography behavior, truncation behavior, semantics, styling, targets,
|
|
66
|
+
public API, or target aliases.
|
|
67
|
+
|
|
68
|
+
## Public concepts
|
|
69
|
+
|
|
70
|
+
No new public concept is introduced. Text and Heading props, defaults, and usage
|
|
71
|
+
remain documented in `Text.doc.mjs` and `Heading.doc.mjs`.
|
|
72
|
+
|
|
73
|
+
## Behavioral and layout contract
|
|
74
|
+
|
|
75
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
76
|
+
| --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ----------------------------------------------------- |
|
|
77
|
+
| FR1 | Text renders one polymorphic text element carrying the current `text` target. | Current source, docs, and tests | Verified current behavior; no new behavior decided |
|
|
78
|
+
| FR2 | Heading renders one semantic `h1`–`h6` element carrying the current `heading` target. Heading is a referenced member of Text rather than a nested Text element. | Current source, docs, tests, and target history | Verified current behavior and canonical ownership |
|
|
79
|
+
| FR3 | Text or Heading composes Tooltip only when `maxLines` is positive, truncation tooltips are enabled, and measurement reports that the rendered content is truncated. Otherwise the truncation Tooltip path does not render. | Current source, tests, and truncation history | Verified current conditional behavior |
|
|
80
|
+
| FR4 | When the conditional truncation path renders, Tooltip owns the layer surface and applies the `tooltip` target. Text and Heading retain their own root targets and do not apply or claim Tooltip's target. | Current source and owner target metadata | Verified current ownership; no target change |
|
|
81
|
+
| FR5 | Text reflects `type`, `size`, and resolved `color` on `text`; Heading reflects `level`, `color`, and an explicitly supplied `type` on `heading`. Display mode, truncation state, semantic element choice, and Tooltip open state do not become separate anatomy parts or Text-owned targets. | Current source, docs, tests, and target inventory | Verified current capabilities; no new anatomy decided |
|
|
82
|
+
|
|
83
|
+
### Observed current behavior
|
|
84
|
+
|
|
85
|
+
These observations describe the implementation; they do not establish new
|
|
86
|
+
intent:
|
|
87
|
+
|
|
88
|
+
- Text defaults to a `span` and may render another supported text element through
|
|
89
|
+
`as`. Heading maps `level` directly to `h1` through `h6`.
|
|
90
|
+
- Both members render caller content directly inside their targeted root element;
|
|
91
|
+
neither creates a separately targeted content wrapper.
|
|
92
|
+
- Both members measure truncation only when `maxLines` is positive. When the
|
|
93
|
+
measurement reports overflow and `hasTruncateTooltip` is not `false`, they
|
|
94
|
+
lazy-load Tooltip in sibling-anchor mode.
|
|
95
|
+
- Tooltip owns its layer lifecycle and applies `tooltip` only to its own rendered
|
|
96
|
+
layer. The truncated Text or Heading element remains the anchor and keeps only
|
|
97
|
+
its own target.
|
|
98
|
+
- Text and Heading no longer add a native `title` for this path; the composed
|
|
99
|
+
Tooltip is the single tooltip presentation.
|
|
100
|
+
|
|
101
|
+
### Allowed variation
|
|
102
|
+
|
|
103
|
+
- **AV1 — Text element and content.** Text may use any currently supported `as`
|
|
104
|
+
element and either member may contain caller-supplied content without changing
|
|
105
|
+
target ownership.
|
|
106
|
+
- **AV2 — Typography.** Level, type, size, color, weight, wrapping, decoration,
|
|
107
|
+
and theme or consumer styling may vary through the existing APIs and targets.
|
|
108
|
+
- **AV3 — Conditional tooltip.** Fitting content, disabled truncation tooltips,
|
|
109
|
+
and non-truncating configurations omit the delegated Tooltip path.
|
|
110
|
+
|
|
111
|
+
### Representative states
|
|
112
|
+
|
|
113
|
+
| State | Required invariant | Allowed variation |
|
|
114
|
+
| ----------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------- |
|
|
115
|
+
| Text without truncation | One Text element carries `text`; no truncation Tooltip path renders. | Supported element, content, and typography props. |
|
|
116
|
+
| Heading without truncation | One semantic heading carries `heading`; no Text target or truncation Tooltip path renders. | Heading level, accessibility level, and type. |
|
|
117
|
+
| Truncation configured but content fits | The owning Text or Heading root remains; no truncation Tooltip path renders. | Line limit and available width. |
|
|
118
|
+
| Truncated with tooltip disabled | The owning root remains clipped; no truncation Tooltip path renders. | Text or Heading owner. |
|
|
119
|
+
| Truncated with tooltip enabled and opened | The owning root anchors one Tooltip-owned surface carrying `tooltip`. | Placement and full text content. |
|
|
120
|
+
|
|
121
|
+
### Transformation and precedence order
|
|
122
|
+
|
|
123
|
+
- No new typography, truncation, element-selection, or styling precedence rule is
|
|
124
|
+
introduced.
|
|
125
|
+
|
|
126
|
+
### Performance and resources
|
|
127
|
+
|
|
128
|
+
- This draft records the current shared ResizeObserver-based truncation path and
|
|
129
|
+
lazy Tooltip composition but introduces no new measurement, observer, render,
|
|
130
|
+
or loading requirement.
|
|
131
|
+
|
|
132
|
+
## Accessibility contract
|
|
133
|
+
|
|
134
|
+
This draft does not change or extend Text's polymorphic semantics, Heading's
|
|
135
|
+
native heading level and optional `aria-level`, or Tooltip's existing
|
|
136
|
+
`aria-describedby` ownership for truncated content.
|
|
137
|
+
|
|
138
|
+
## Design relationships
|
|
139
|
+
|
|
140
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
141
|
+
| ------------------ | --------------------------------------------------------------------------------- | ------------------------------ | -------------- | ------------------ |
|
|
142
|
+
| Text | Presents caller content in the current polymorphic text element. | Current source and public docs | Prominent | FR1, FR5 |
|
|
143
|
+
| Heading | Presents caller content in the referenced semantic Heading member. | Current source and public docs | Prominent | FR2, FR5 |
|
|
144
|
+
| Truncation tooltip | Presents the full content only on the current measured-overflow and enabled path. | `component:Tooltip` | Supporting | FR3, FR4 |
|
|
145
|
+
|
|
146
|
+
Text and Heading are sibling public components represented by the canonical Text
|
|
147
|
+
documentation; Heading is not nested inside Text. The Tooltip row is conditional
|
|
148
|
+
composition rather than a Text- or Heading-owned surface.
|
|
149
|
+
|
|
150
|
+
### Theming anatomy
|
|
151
|
+
|
|
152
|
+
<!-- anatomy-theming:v1 -->
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"Text": {"target": "text"},
|
|
157
|
+
"Heading": {"target": "heading"},
|
|
158
|
+
"Truncation tooltip": {
|
|
159
|
+
"delegatesTo": {"owner": "component:Tooltip", "target": "tooltip"}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
The two local targets are the exact current targets declared by the canonical
|
|
165
|
+
Text doc. The delegated `tooltip` target applies only when the conditional
|
|
166
|
+
truncation path reaches Tooltip and Tooltip renders its layer; it is not a
|
|
167
|
+
Text- or Heading-owned target. No anatomy part requires a `none` disposition.
|
|
168
|
+
|
|
169
|
+
## Family and system relationships
|
|
170
|
+
|
|
171
|
+
- `architecture:component-theming-surface` owns anatomy qualification, aggregate
|
|
172
|
+
parent/member target ownership, exact target mapping, and delegation.
|
|
173
|
+
- Text is the canonical documentation and contract owner for both `text` and
|
|
174
|
+
`heading`; Heading remains a referenced member and does not receive a separate
|
|
175
|
+
component spec.
|
|
176
|
+
- Tooltip retains ownership of its delegated surface, interaction behavior, and
|
|
177
|
+
`tooltip` target.
|
|
178
|
+
|
|
179
|
+
## Verification map
|
|
180
|
+
|
|
181
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
182
|
+
| ------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ----------------------- |
|
|
183
|
+
| FR1, FR5 | `Text.test.tsx` and `themingTargets.test.ts` | Default, polymorphic, custom type/color, explicit size | Removing, renaming, or changing the current Text target capabilities fails focused or global target assertions. | `audit:Text/theming` |
|
|
184
|
+
| FR2, FR5 | `Heading.test.tsx`, `themingTargets.test.ts`, and target-introduction history | Levels 1–6, display type, custom color | Removing, renaming, or changing the current Heading target capabilities fails focused or global assertions. | `audit:Heading/theming` |
|
|
185
|
+
| FR3, FR4 | Text and Heading source inspection, truncation tests, Tooltip target metadata, and fix history | Fitting, overflowing, disabled, enabled | Moving the surface or target into Text/Heading, or restoring a native duplicate tooltip, violates current evidence. | `audit:Text/anatomy` |
|
|
186
|
+
| Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy, both local targets, Tooltip delegate | Missing, extra, prefixed, stale, multiply assigned, or invalid delegated mappings fail repository validation. | `audit:Text/theming` |
|
|
187
|
+
|
|
188
|
+
Current focused tests pin both local target names and Text's lack of a duplicate
|
|
189
|
+
native `title`. The conditional Tooltip path and Heading's matching no-`title`
|
|
190
|
+
behavior are established by shared source shape and history rather than a
|
|
191
|
+
separate focused assertion in each suite.
|
|
192
|
+
|
|
193
|
+
## Decision log
|
|
194
|
+
|
|
195
|
+
None. This draft records current facts and introduces no component-local design,
|
|
196
|
+
API, behavior, accessibility, or theming decision.
|
|
197
|
+
|
|
198
|
+
## Open questions
|
|
199
|
+
|
|
200
|
+
None.
|
|
201
|
+
|
|
202
|
+
## Content boundary
|
|
203
|
+
|
|
204
|
+
This file does not duplicate consumer prop tables/examples, typography token
|
|
205
|
+
values, truncation measurement mechanics, Tooltip internals, implementation
|
|
206
|
+
steps, current audit results, or system theming rules. It links to their owners.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import {useCallback, useRef, useState, type RefCallback} from 'react';
|
|
16
|
-
import {observeResize
|
|
16
|
+
import {observeResize} from '../utils/sharedResizeObserver';
|
|
17
17
|
|
|
18
18
|
export interface UseTruncationOptions {
|
|
19
19
|
/**
|
|
@@ -43,7 +43,7 @@ export interface UseTruncationReturn {
|
|
|
43
43
|
/**
|
|
44
44
|
* Hook for detecting text overflow/truncation.
|
|
45
45
|
*
|
|
46
|
-
* Uses a shared ResizeObserver singleton (via observeResize
|
|
46
|
+
* Uses a shared ResizeObserver singleton (via observeResize)
|
|
47
47
|
* for efficient detection when content or container changes. A single
|
|
48
48
|
* ResizeObserver instance is shared across all mounted useTruncation hooks,
|
|
49
49
|
* so even hundreds of table cells only create one observer.
|
|
@@ -70,6 +70,7 @@ export function useTruncation(
|
|
|
70
70
|
const [isTruncated, setIsTruncated] = useState(false);
|
|
71
71
|
const [fullText, setFullText] = useState('');
|
|
72
72
|
const elementRef = useRef<HTMLElement | null>(null);
|
|
73
|
+
const unobserveRef = useRef<(() => void) | null>(null);
|
|
73
74
|
|
|
74
75
|
const checkTruncation = useCallback(
|
|
75
76
|
(element: HTMLElement) => {
|
|
@@ -108,10 +109,10 @@ export function useTruncation(
|
|
|
108
109
|
|
|
109
110
|
const ref: RefCallback<HTMLElement> = useCallback(
|
|
110
111
|
(element: HTMLElement | null) => {
|
|
111
|
-
// Cleanup previous observation
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
// Cleanup previous observation. Unsubscribing by callback rather than
|
|
113
|
+
// by element leaves any other observer of the same node untouched.
|
|
114
|
+
unobserveRef.current?.();
|
|
115
|
+
unobserveRef.current = null;
|
|
115
116
|
|
|
116
117
|
elementRef.current = element;
|
|
117
118
|
|
|
@@ -120,7 +121,7 @@ export function useTruncation(
|
|
|
120
121
|
// observeResize fires the callback once on registration,
|
|
121
122
|
// so no separate initial check is needed.
|
|
122
123
|
if (typeof ResizeObserver !== 'undefined') {
|
|
123
|
-
observeResize(element, () => {
|
|
124
|
+
unobserveRef.current = observeResize(element, () => {
|
|
124
125
|
checkTruncation(element);
|
|
125
126
|
});
|
|
126
127
|
} else {
|