@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
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file useLightbox.test.tsx
|
|
5
|
+
* @input Uses vitest, @testing-library/react, useLightbox hook
|
|
6
|
+
* @output Unit tests for lightbox open/close state and trigger props
|
|
7
|
+
* @position Testing; validates useLightbox.tsx implementation
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When useLightbox.tsx changes, update tests to match new behavior
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
13
|
+
import {
|
|
14
|
+
render,
|
|
15
|
+
screen,
|
|
16
|
+
fireEvent,
|
|
17
|
+
renderHook,
|
|
18
|
+
act,
|
|
19
|
+
} from '@testing-library/react';
|
|
20
|
+
import {useLightbox} from './useLightbox';
|
|
21
|
+
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
22
|
+
|
|
23
|
+
// jsdom doesn't implement dialog.showModal/close.
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
HTMLDialogElement.prototype.showModal = vi.fn(function (
|
|
26
|
+
this: HTMLDialogElement,
|
|
27
|
+
) {
|
|
28
|
+
this.setAttribute('open', '');
|
|
29
|
+
});
|
|
30
|
+
HTMLDialogElement.prototype.close = vi.fn(function (this: HTMLDialogElement) {
|
|
31
|
+
this.removeAttribute('open');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Lightbox announces gallery navigation through the singleton live regions
|
|
36
|
+
// useAnnounce mounts on <body>; reset them so nothing leaks between tests.
|
|
37
|
+
afterEach(() => {
|
|
38
|
+
__resetLiveRegionsForTest();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Module scope so the reference stays stable across rerenders.
|
|
42
|
+
const photos = [
|
|
43
|
+
{src: '/p1.jpg', alt: 'Photo 1'},
|
|
44
|
+
{src: '/p2.jpg', alt: 'Photo 2'},
|
|
45
|
+
{src: '/p3.jpg', alt: 'Photo 3'},
|
|
46
|
+
{src: '/p4.jpg', alt: 'Photo 4'},
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
/** Renders both trigger flavors plus the lightbox element itself. */
|
|
50
|
+
function Gallery() {
|
|
51
|
+
const lightbox = useLightbox({media: photos});
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div>
|
|
55
|
+
<span data-testid="status">{lightbox.isOpen ? 'open' : 'closed'}</span>
|
|
56
|
+
<span data-testid="index">{lightbox.index}</span>
|
|
57
|
+
<span data-testid="shared" {...lightbox.triggerProps}>
|
|
58
|
+
Open gallery
|
|
59
|
+
</span>
|
|
60
|
+
{photos.map((photo, i) => (
|
|
61
|
+
<img
|
|
62
|
+
key={photo.src}
|
|
63
|
+
src={photo.src}
|
|
64
|
+
alt={`thumb ${i}`}
|
|
65
|
+
data-testid={`thumb-${i}`}
|
|
66
|
+
{...lightbox.getTriggerProps(i)}
|
|
67
|
+
/>
|
|
68
|
+
))}
|
|
69
|
+
{lightbox.element}
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
describe('useLightbox — state', () => {
|
|
75
|
+
it('starts closed at the first item', () => {
|
|
76
|
+
const {result} = renderHook(() => useLightbox({media: photos}));
|
|
77
|
+
expect(result.current.isOpen).toBe(false);
|
|
78
|
+
expect(result.current.index).toBe(0);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('opens at the first item when open() is called without an index', () => {
|
|
82
|
+
const {result} = renderHook(() => useLightbox({media: photos}));
|
|
83
|
+
|
|
84
|
+
act(() => result.current.open(2));
|
|
85
|
+
act(() => result.current.close());
|
|
86
|
+
// A bare open() resets to the start rather than reusing the last index.
|
|
87
|
+
act(() => result.current.open());
|
|
88
|
+
|
|
89
|
+
expect(result.current.isOpen).toBe(true);
|
|
90
|
+
expect(result.current.index).toBe(0);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('opens at the requested index', () => {
|
|
94
|
+
const {result} = renderHook(() => useLightbox({media: photos}));
|
|
95
|
+
|
|
96
|
+
act(() => result.current.open(2));
|
|
97
|
+
|
|
98
|
+
expect(result.current.isOpen).toBe(true);
|
|
99
|
+
expect(result.current.index).toBe(2);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('close() closes without rewinding the index', () => {
|
|
103
|
+
const {result} = renderHook(() => useLightbox({media: photos}));
|
|
104
|
+
|
|
105
|
+
act(() => result.current.open(3));
|
|
106
|
+
act(() => result.current.close());
|
|
107
|
+
|
|
108
|
+
expect(result.current.isOpen).toBe(false);
|
|
109
|
+
expect(result.current.index).toBe(3);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// The `if (!nextOpen)` guard in the hook's onOpenChange is deliberately not
|
|
113
|
+
// covered: Lightbox only ever reports `false`, so the ignored-`true` path is
|
|
114
|
+
// unreachable through the public surface. Reaching into the element's props
|
|
115
|
+
// to force it would assert a value that is already settled, and it can only
|
|
116
|
+
// be exercised for real once something emits `true`.
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe('useLightbox — trigger props', () => {
|
|
120
|
+
it('gives the trigger button semantics', () => {
|
|
121
|
+
render(<Gallery />);
|
|
122
|
+
const trigger = screen.getByTestId('shared');
|
|
123
|
+
expect(trigger).toHaveAttribute('role', 'button');
|
|
124
|
+
expect(trigger).toHaveAttribute('tabindex', '0');
|
|
125
|
+
expect(trigger).toHaveAttribute('aria-haspopup', 'dialog');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('gives every indexed trigger the same button semantics', () => {
|
|
129
|
+
render(<Gallery />);
|
|
130
|
+
const trigger = screen.getByTestId('thumb-2');
|
|
131
|
+
expect(trigger).toHaveAttribute('role', 'button');
|
|
132
|
+
expect(trigger).toHaveAttribute('tabindex', '0');
|
|
133
|
+
expect(trigger).toHaveAttribute('aria-haspopup', 'dialog');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('opens at the first item when the shared trigger is clicked', () => {
|
|
137
|
+
render(<Gallery />);
|
|
138
|
+
fireEvent.click(screen.getByTestId('shared'));
|
|
139
|
+
expect(screen.getByTestId('status').textContent).toBe('open');
|
|
140
|
+
expect(screen.getByTestId('index').textContent).toBe('0');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('opens on Enter and swallows the key press', () => {
|
|
144
|
+
render(<Gallery />);
|
|
145
|
+
const notDefaultPrevented = fireEvent.keyDown(
|
|
146
|
+
screen.getByTestId('shared'),
|
|
147
|
+
{
|
|
148
|
+
key: 'Enter',
|
|
149
|
+
},
|
|
150
|
+
);
|
|
151
|
+
expect(notDefaultPrevented).toBe(false);
|
|
152
|
+
expect(screen.getByTestId('status').textContent).toBe('open');
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('opens on Space and swallows the key press', () => {
|
|
156
|
+
render(<Gallery />);
|
|
157
|
+
const notDefaultPrevented = fireEvent.keyDown(
|
|
158
|
+
screen.getByTestId('shared'),
|
|
159
|
+
{
|
|
160
|
+
key: ' ',
|
|
161
|
+
},
|
|
162
|
+
);
|
|
163
|
+
expect(notDefaultPrevented).toBe(false);
|
|
164
|
+
expect(screen.getByTestId('status').textContent).toBe('open');
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('leaves other keys alone', () => {
|
|
168
|
+
render(<Gallery />);
|
|
169
|
+
for (const key of ['a', 'Tab', 'ArrowRight', 'Escape']) {
|
|
170
|
+
const notDefaultPrevented = fireEvent.keyDown(
|
|
171
|
+
screen.getByTestId('shared'),
|
|
172
|
+
{key},
|
|
173
|
+
);
|
|
174
|
+
expect(notDefaultPrevented).toBe(true);
|
|
175
|
+
expect(screen.getByTestId('status').textContent).toBe('closed');
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('opens at the trigger index when an indexed trigger is clicked', () => {
|
|
180
|
+
render(<Gallery />);
|
|
181
|
+
fireEvent.click(screen.getByTestId('thumb-2'));
|
|
182
|
+
expect(screen.getByTestId('status').textContent).toBe('open');
|
|
183
|
+
expect(screen.getByTestId('index').textContent).toBe('2');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('opens at the trigger index on Enter and swallows the key press', () => {
|
|
187
|
+
render(<Gallery />);
|
|
188
|
+
const notDefaultPrevented = fireEvent.keyDown(
|
|
189
|
+
screen.getByTestId('thumb-3'),
|
|
190
|
+
{key: 'Enter'},
|
|
191
|
+
);
|
|
192
|
+
expect(notDefaultPrevented).toBe(false);
|
|
193
|
+
expect(screen.getByTestId('index').textContent).toBe('3');
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('opens at the trigger index on Space and swallows the key press', () => {
|
|
197
|
+
render(<Gallery />);
|
|
198
|
+
const notDefaultPrevented = fireEvent.keyDown(
|
|
199
|
+
screen.getByTestId('thumb-1'),
|
|
200
|
+
{key: ' '},
|
|
201
|
+
);
|
|
202
|
+
expect(notDefaultPrevented).toBe(false);
|
|
203
|
+
expect(screen.getByTestId('index').textContent).toBe('1');
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('leaves other keys alone on an indexed trigger', () => {
|
|
207
|
+
render(<Gallery />);
|
|
208
|
+
const notDefaultPrevented = fireEvent.keyDown(
|
|
209
|
+
screen.getByTestId('thumb-1'),
|
|
210
|
+
{key: 'a'},
|
|
211
|
+
);
|
|
212
|
+
expect(notDefaultPrevented).toBe(true);
|
|
213
|
+
expect(screen.getByTestId('status').textContent).toBe('closed');
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe('useLightbox — element wiring', () => {
|
|
218
|
+
it('keeps the lightbox closed until a trigger fires', () => {
|
|
219
|
+
render(<Gallery />);
|
|
220
|
+
expect(document.querySelector('dialog')).not.toHaveAttribute('open');
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('shows the media for the index the trigger opened', () => {
|
|
224
|
+
render(<Gallery />);
|
|
225
|
+
fireEvent.click(screen.getByTestId('thumb-2'));
|
|
226
|
+
|
|
227
|
+
const dialog = document.querySelector('dialog')!;
|
|
228
|
+
expect(dialog).toHaveAttribute('open');
|
|
229
|
+
expect(screen.getByAltText('Photo 3')).toBeInTheDocument();
|
|
230
|
+
expect(screen.queryByAltText('Photo 1')).toBeNull();
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it('closes when the lightbox close button is pressed', () => {
|
|
234
|
+
render(<Gallery />);
|
|
235
|
+
fireEvent.click(screen.getByTestId('thumb-2'));
|
|
236
|
+
|
|
237
|
+
fireEvent.click(screen.getByRole('button', {name: 'Close'}));
|
|
238
|
+
|
|
239
|
+
expect(screen.getByTestId('status').textContent).toBe('closed');
|
|
240
|
+
expect(document.querySelector('dialog')).not.toHaveAttribute('open');
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('follows the index when the lightbox navigates', () => {
|
|
244
|
+
render(<Gallery />);
|
|
245
|
+
fireEvent.click(screen.getByTestId('thumb-2'));
|
|
246
|
+
|
|
247
|
+
fireEvent.click(screen.getByRole('button', {name: 'Next'}));
|
|
248
|
+
|
|
249
|
+
expect(screen.getByTestId('index').textContent).toBe('3');
|
|
250
|
+
expect(screen.getByAltText('Photo 4')).toBeInTheDocument();
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('reopens at a new index after closing', () => {
|
|
254
|
+
render(<Gallery />);
|
|
255
|
+
fireEvent.click(screen.getByTestId('thumb-0'));
|
|
256
|
+
fireEvent.click(screen.getByRole('button', {name: 'Close'}));
|
|
257
|
+
|
|
258
|
+
fireEvent.click(screen.getByTestId('thumb-3'));
|
|
259
|
+
|
|
260
|
+
expect(screen.getByTestId('index').textContent).toBe('3');
|
|
261
|
+
expect(screen.getByAltText('Photo 4')).toBeInTheDocument();
|
|
262
|
+
});
|
|
263
|
+
});
|
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
+
/** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
|
|
4
|
+
const anatomy = [
|
|
5
|
+
{
|
|
6
|
+
name: 'Document',
|
|
7
|
+
required: true,
|
|
8
|
+
description:
|
|
9
|
+
'Root container for block or inline Markdown content.',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: 'Heading',
|
|
13
|
+
required: false,
|
|
14
|
+
description:
|
|
15
|
+
'Rendered heading block; a custom heading renderer replaces the default part.',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'Paragraph',
|
|
19
|
+
required: false,
|
|
20
|
+
description:
|
|
21
|
+
'Rendered paragraph block; a custom paragraph renderer replaces the default part.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'List',
|
|
25
|
+
required: false,
|
|
26
|
+
description:
|
|
27
|
+
'Ordered, unordered, or task-list block rendered from Markdown items.',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Code block',
|
|
31
|
+
required: false,
|
|
32
|
+
description:
|
|
33
|
+
'Fenced code block; a custom code renderer replaces the default part.',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'Blockquote',
|
|
37
|
+
required: false,
|
|
38
|
+
description:
|
|
39
|
+
'Quoted block; a custom blockquote renderer replaces the default part.',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'Table',
|
|
43
|
+
required: false,
|
|
44
|
+
description: 'Scrollable table block rendered from Markdown rows and columns.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Divider',
|
|
48
|
+
required: false,
|
|
49
|
+
description:
|
|
50
|
+
'Horizontal rule block; a custom hr renderer replaces the default part.',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'Image',
|
|
54
|
+
required: false,
|
|
55
|
+
description:
|
|
56
|
+
'Block image or unsafe-URL fallback; a custom image renderer replaces a safe default image.',
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
3
60
|
/** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
|
|
4
61
|
|
|
5
62
|
export const docs = {
|
|
@@ -168,6 +225,7 @@ export const docs = {
|
|
|
168
225
|
],
|
|
169
226
|
},
|
|
170
227
|
usage: {
|
|
228
|
+
anatomy,
|
|
171
229
|
description:
|
|
172
230
|
'Renders a markdown string as Astryx-styled components. Use Markdown for user-generated content, AI responses, and documentation; it handles headings, lists, tables, code blocks, and citations with consistent styling.',
|
|
173
231
|
bestPractices: [
|
|
@@ -381,6 +439,7 @@ export const docsZh = {
|
|
|
381
439
|
],
|
|
382
440
|
},
|
|
383
441
|
usage: {
|
|
442
|
+
anatomy,
|
|
384
443
|
description:
|
|
385
444
|
'Renders a markdown string as Astryx-styled components. Use Markdown for user-generated content, AI responses, and documentation; it handles headings, lists, tables, code blocks, and citations with consistent styling.',
|
|
386
445
|
bestPractices: [
|
|
@@ -397,6 +456,7 @@ export const docsDense = {
|
|
|
397
456
|
description:
|
|
398
457
|
'Renders markdown string as Astryx-styled components. Use for user-generated content, AI responses, docs. Headings, lists, tables, code, citations w/ consistent styling.',
|
|
399
458
|
usage: {
|
|
459
|
+
anatomy,
|
|
400
460
|
description:
|
|
401
461
|
'Renders a markdown string as Astryx-styled components. Use Markdown for user-generated content, AI responses, and documentation; it handles headings, lists, tables, code blocks, and citations with consistent styling.',
|
|
402
462
|
bestPractices: [
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 3
|
|
3
|
+
template_version: 3
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:Markdown
|
|
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/Markdown/Markdown.test.tsx,
|
|
16
|
+
packages/core/src/theme/themingTargets.test.ts,
|
|
17
|
+
scripts/check-knowledge.mjs,
|
|
18
|
+
]
|
|
19
|
+
modules: []
|
|
20
|
+
families: [family:navigation-destinations]
|
|
21
|
+
design_specs: []
|
|
22
|
+
architecture: [architecture:component-theming-surface]
|
|
23
|
+
contributing: []
|
|
24
|
+
system_specs: [spec:AST-005/DEC-1, spec:AST-005/DEC-2]
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# Markdown component contract
|
|
28
|
+
|
|
29
|
+
## Intent
|
|
30
|
+
|
|
31
|
+
Markdown renders parsed content in a Document with stable default block parts.
|
|
32
|
+
This draft records the nine current Markdown targets and the custom-renderer
|
|
33
|
+
boundary without changing parsing, runtime behavior, styling, targets, or public
|
|
34
|
+
API.
|
|
35
|
+
|
|
36
|
+
## Compatibility and migration
|
|
37
|
+
|
|
38
|
+
- Released default preserved: `yes`
|
|
39
|
+
- Compatibility class: additive documentation only; runtime, DOM, styling,
|
|
40
|
+
targets, aliases, and public API remain unchanged
|
|
41
|
+
- Controlled/uncontrolled behavior: not applicable
|
|
42
|
+
- Migration decision: none
|
|
43
|
+
|
|
44
|
+
Consumer migration instructions belong in consumer docs and release notes.
|
|
45
|
+
|
|
46
|
+
## Ownership boundary
|
|
47
|
+
|
|
48
|
+
**Owns**
|
|
49
|
+
|
|
50
|
+
- The Document and its current `markdown` target in block and inline display.
|
|
51
|
+
- Default Heading, Paragraph, List, Code block, Blockquote, Table, Divider, and
|
|
52
|
+
Image block presentation and the eight current block targets documented below.
|
|
53
|
+
- Applying block spacing and reflected density (plus Heading level) to those
|
|
54
|
+
targets on the default render path.
|
|
55
|
+
|
|
56
|
+
**Does not own / non-goals**
|
|
57
|
+
|
|
58
|
+
- Output supplied by custom `heading`, `paragraph`, `code`, `blockquote`, `hr`,
|
|
59
|
+
or `image` renderers; the custom component owns that replacement's structure
|
|
60
|
+
and styling.
|
|
61
|
+
- Inline emphasis, link, inline-code, citation, or plugin output as additional
|
|
62
|
+
block anatomy.
|
|
63
|
+
- Nested anatomy or targets owned by CodeBlock, Blockquote, List, CheckboxList,
|
|
64
|
+
or Table.
|
|
65
|
+
- New block types, custom-renderer behavior, target names, public API, or runtime
|
|
66
|
+
behavior.
|
|
67
|
+
|
|
68
|
+
## Public concepts
|
|
69
|
+
|
|
70
|
+
No new public concept is introduced. Consumer props, renderer hooks, defaults,
|
|
71
|
+
and usage remain documented in `Markdown.doc.mjs`.
|
|
72
|
+
|
|
73
|
+
## Behavioral and layout contract
|
|
74
|
+
|
|
75
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
76
|
+
| --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------ |
|
|
77
|
+
| FR1 | Block and inline displays render one Document root carrying the current `markdown` target. Inline display renders no block anatomy. | Current source, docs, and tests | Verified current behavior; no new behavior decided |
|
|
78
|
+
| FR2 | On the default block render path, Heading, Paragraph, List, Code block, Blockquote, Table, Divider, and Image carry the eight current local block targets documented below. | Current source, docs, tests, and history | Verified current inventory and placement |
|
|
79
|
+
| FR3 | A supplied `heading`, `paragraph`, `code`, `blockquote`, `hr`, or safe-URL `image` renderer replaces the corresponding default part, so Markdown does not impose that part's local target on the replacement. | Current source, docs, and history | Verified behavior; focused absence coverage is partial |
|
|
80
|
+
| FR4 | The released Code block target is spelled `markdown-codeblock`. Although this runs together a compound name and predates the current naming rule, it is a frozen public target and this factual backfill neither renames it nor adds an alias. | Current source, docs, tests, history, and architecture | Verified compatibility constraint; no target change |
|
|
81
|
+
| FR5 | Density and Heading level remain reflected capabilities on their owning targets. Display mode, density, Heading level, streaming state, list kind, and custom-renderer selection do not become separate anatomy entries. | Current source, docs, tests, and architecture | Verified current model; no new anatomy or state target |
|
|
82
|
+
|
|
83
|
+
### Allowed variation
|
|
84
|
+
|
|
85
|
+
- **AV1 — Parsed content.** The number and ordering of block parts may vary with
|
|
86
|
+
the Markdown source without changing their ownership.
|
|
87
|
+
- **AV2 — Lists.** Ordered, unordered, and task lists share the List anatomy and
|
|
88
|
+
current `markdown-list` target.
|
|
89
|
+
- **AV3 — Custom renderers.** Supported custom block renderers may replace their
|
|
90
|
+
default part and own its styling without receiving a Markdown block target.
|
|
91
|
+
- **AV4 — Nested primitives.** Astryx primitives used inside default blocks may
|
|
92
|
+
change internal element shape while preserving their own public contracts and
|
|
93
|
+
Markdown's outer block targets.
|
|
94
|
+
|
|
95
|
+
### Representative states
|
|
96
|
+
|
|
97
|
+
| State | Required invariant | Allowed variation |
|
|
98
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
99
|
+
| Default block content | Every parsed block uses its corresponding current Markdown target. | Block count, order, density, content width, and alignment. |
|
|
100
|
+
| Custom block renderers | The replaced Heading, Paragraph, Code block, Blockquote, Divider, or Image lacks the corresponding Markdown target. | Replacement structure and styling. |
|
|
101
|
+
| Ordered/unordered list | List carries `markdown-list`. | Marker kind, start value, item count, and nested content. |
|
|
102
|
+
| Task list | The outer List part carries `markdown-list`. | Checked values and item content. |
|
|
103
|
+
| Safe block image | Default Image carries `markdown-image`, or a custom image renderer replaces it. | Source and alternative text. |
|
|
104
|
+
| Unsafe block image URL | Markdown renders its fallback Image part with `markdown-image`; no custom image renderer receives the rejected URL. | Alternative text shown by the fallback. |
|
|
105
|
+
| Inline display | Document carries `markdown`; no block target renders. | Inline text, links, code, citations, and plugin output. |
|
|
106
|
+
|
|
107
|
+
### Transformation and precedence order
|
|
108
|
+
|
|
109
|
+
- No new parsing, sanitization, heading-level, renderer-selection, spacing, or
|
|
110
|
+
styling precedence rule is introduced.
|
|
111
|
+
|
|
112
|
+
### Performance and resources
|
|
113
|
+
|
|
114
|
+
- No new parsing, streaming, render, or resource requirement is introduced.
|
|
115
|
+
|
|
116
|
+
## Accessibility contract
|
|
117
|
+
|
|
118
|
+
This draft does not change or extend Markdown's existing document semantics,
|
|
119
|
+
heading IDs, paragraph role, list semantics, scrollable Table wrapper, image
|
|
120
|
+
alternative text, or custom-renderer responsibilities.
|
|
121
|
+
|
|
122
|
+
## Design relationships
|
|
123
|
+
|
|
124
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
125
|
+
| ---------------- | -------------------------------------------------------------------------------- | ------------------------------ | -------------- | ------------------ |
|
|
126
|
+
| Document | Contains block or inline rendered Markdown content. | Current source and public docs | Supporting | FR1, FR5 |
|
|
127
|
+
| Heading | Presents one parsed heading with its resolved level and optional generated ID. | Current source and public docs | Prominent | FR2, FR3, FR5 |
|
|
128
|
+
| Paragraph | Presents one prose block using the default composition-safe paragraph structure. | Current source and public docs | Prominent | FR2, FR3 |
|
|
129
|
+
| List | Presents ordered, unordered, or task-list items as one block. | Current source and public docs | Prominent | FR2, FR5 |
|
|
130
|
+
| Code block | Presents fenced code and owns the outer spacing target on the default path. | Current source and public docs | Prominent | FR2, FR3, FR4 |
|
|
131
|
+
| Blockquote | Presents quoted block content on the default path. | Current source and public docs | Prominent | FR2, FR3 |
|
|
132
|
+
| Table | Presents parsed rows and columns in a keyboard-scrollable block wrapper. | Current source and public docs | Prominent | FR2 |
|
|
133
|
+
| Divider | Presents a horizontal separation between blocks. | Current source and public docs | Supporting | FR2, FR3 |
|
|
134
|
+
| Image | Presents a safe block image or the fallback for a rejected image URL. | Current source and public docs | Prominent | FR2, FR3 |
|
|
135
|
+
|
|
136
|
+
Custom renderers replace six default parts rather than becoming nested Markdown
|
|
137
|
+
anatomy. Lists and Tables have no corresponding custom block renderer. The
|
|
138
|
+
Document remains Markdown-owned in every display mode.
|
|
139
|
+
|
|
140
|
+
### Theming anatomy
|
|
141
|
+
|
|
142
|
+
<!-- anatomy-theming:v1 -->
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"Document": {"target": "markdown"},
|
|
147
|
+
"Heading": {"target": "markdown-heading"},
|
|
148
|
+
"Paragraph": {"target": "markdown-paragraph"},
|
|
149
|
+
"List": {"target": "markdown-list"},
|
|
150
|
+
"Code block": {"target": "markdown-codeblock"},
|
|
151
|
+
"Blockquote": {"target": "markdown-blockquote"},
|
|
152
|
+
"Table": {"target": "markdown-table"},
|
|
153
|
+
"Divider": {"target": "markdown-hr"},
|
|
154
|
+
"Image": {"target": "markdown-image"}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The map records all nine current targets on Markdown's default render paths. For
|
|
159
|
+
Heading, Paragraph, Code block, Blockquote, Divider, and safe Image, a custom
|
|
160
|
+
renderer replaces the default part and therefore replaces its local target. The
|
|
161
|
+
`markdown-codeblock` spelling is a released compatibility anomaly: the current
|
|
162
|
+
naming rule would produce `markdown-code-block`, but shipped targets are frozen
|
|
163
|
+
and this change preserves the existing spelling exactly.
|
|
164
|
+
|
|
165
|
+
## Family and system relationships
|
|
166
|
+
|
|
167
|
+
- `architecture:component-theming-surface` owns anatomy qualification, target
|
|
168
|
+
mapping, target-capability state, composition boundaries, and compatibility for
|
|
169
|
+
frozen targets.
|
|
170
|
+
- `family:navigation-destinations` owns the shared accept/block result for parsed
|
|
171
|
+
links and every Astryx-owned navigation sink. `spec:AST-005/DEC-1` requires
|
|
172
|
+
Markdown navigation to remain conformant with Core link plumbing.
|
|
173
|
+
- `spec:AST-005/DEC-2` keeps embedded-resource policy separate. Markdown may
|
|
174
|
+
reject a broader set of image/resource URLs without narrowing the shared
|
|
175
|
+
navigation contract.
|
|
176
|
+
- Nested Astryx primitives retain ownership of their own anatomy and targets;
|
|
177
|
+
Markdown owns the outer block targets listed here.
|
|
178
|
+
|
|
179
|
+
## Verification map
|
|
180
|
+
|
|
181
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
182
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------ |
|
|
183
|
+
| FR1 | `Markdown.test.tsx` root-class, block-root, inline-root, and base-prop suites | Block and inline Document | Removing or moving the root target fails focused root assertions or the global inventory. | `audit:Markdown/anatomy` |
|
|
184
|
+
| FR2, FR4, FR5 | `Markdown.test.tsx` block-spacing-target, density, Heading-level, task-list, and render suites | All eight default block types, both densities, Heading level | Removing, renaming, or moving a block target fails focused class or reflected-property assertions. | `audit:Markdown/theming` |
|
|
185
|
+
| FR3 | `Markdown.test.tsx` custom Heading and custom Image suites plus source and target-introduction history | Six replaceable default block parts | Imposing a target on a custom replacement violates the owner boundary; only Heading absence is directly pinned today. | `audit:Markdown/theming` |
|
|
186
|
+
| Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and all nine current targets | Missing, extra, prefixed, stale, or multiply assigned mappings fail repository validation. | `audit:Markdown/theming` |
|
|
187
|
+
|
|
188
|
+
Focused tests pin all nine current target names and default block placement. They
|
|
189
|
+
pin target absence only for a custom Heading; custom Paragraph, Code block,
|
|
190
|
+
Blockquote, Divider, and Image replacement paths currently rely on source and
|
|
191
|
+
history for the same ownership rule.
|
|
192
|
+
|
|
193
|
+
## Decision log
|
|
194
|
+
|
|
195
|
+
None. This draft records current facts and introduces no component-local design,
|
|
196
|
+
API, behavior, or theming decision.
|
|
197
|
+
|
|
198
|
+
## Open questions
|
|
199
|
+
|
|
200
|
+
- **OQ1 — Which focused tests should pin target absence for the five remaining
|
|
201
|
+
custom block replacement paths?** (`checkable`)
|
|
202
|
+
|
|
203
|
+
## Content boundary
|
|
204
|
+
|
|
205
|
+
This file does not duplicate consumer prop tables/examples, parser mechanics,
|
|
206
|
+
streaming implementation, nested primitive contracts, current audit results, or
|
|
207
|
+
system theming rules. It links to their owners.
|