@astryxdesign/core 0.6.2 → 0.6.3-canary.01fa439
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -0
- package/dist/BottomSheet/BottomSheet.d.ts +1 -1
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +3 -1
- package/dist/BottomSheet/BottomSheetPanel.d.ts +7 -5
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +56 -19
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +10 -5
- package/dist/Chat/ChatComposerDrawer.d.ts +19 -5
- package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
- package/dist/Chat/ChatComposerDrawer.js +48 -23
- package/dist/Chat/ChatComposerInput.d.ts +11 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +63 -16
- package/dist/Chat/ChatDictationButton.d.ts +3 -2
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +6 -4
- package/dist/Chat/ChatSendButton.js +1 -1
- package/dist/Chat/index.d.ts +1 -1
- package/dist/Chat/index.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +12 -2
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +6 -1
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +1 -1
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +1 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +4 -4
- package/dist/DateInput/NativeDateField.d.ts.map +1 -1
- package/dist/DateInput/NativeDateField.js +16 -16
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +2 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +4 -4
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +8 -8
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
- package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
- package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
- package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
- package/dist/Dialog/DialogHeader.d.ts +8 -1
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +10 -1
- package/dist/Field/InputClearButton.d.ts +4 -2
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +4 -2
- package/dist/Field/PanelSearchInput.d.ts.map +1 -1
- package/dist/Field/PanelSearchInput.js +1 -1
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +7 -7
- package/dist/Kbd/Kbd.d.ts +5 -3
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +36 -42
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +6 -2
- package/dist/Markdown/Markdown.d.ts +8 -2
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
- package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
- package/dist/Markdown/Markdown.fr23.bench.js +150 -0
- package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
- package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
- package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
- package/dist/Markdown/Markdown.js +262 -109
- package/dist/Markdown/ast.d.ts +162 -0
- package/dist/Markdown/ast.d.ts.map +1 -0
- package/dist/Markdown/ast.js +74 -0
- package/dist/Markdown/index.d.ts +5 -3
- package/dist/Markdown/index.d.ts.map +1 -1
- package/dist/Markdown/index.js +3 -2
- package/dist/Markdown/parser/index.d.ts +10 -0
- package/dist/Markdown/parser/index.d.ts.map +1 -0
- package/dist/Markdown/parser/index.js +10 -0
- package/dist/Markdown/parser.d.ts +126 -58
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +716 -167
- package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
- package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
- package/dist/Markdown/plugins/frontmatter.js +132 -0
- package/dist/Markdown/plugins/index.d.ts +16 -0
- package/dist/Markdown/plugins/index.d.ts.map +1 -0
- package/dist/Markdown/plugins/index.js +13 -0
- package/dist/Markdown/plugins/protocol.d.ts +191 -0
- package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
- package/dist/Markdown/plugins/protocol.js +957 -0
- package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
- package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
- package/dist/Markdown/plugins/semanticFence.js +213 -0
- package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
- package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
- package/dist/Markdown/plugins/sourceDecoration.js +393 -0
- package/dist/Markdown/plugins/textTransform.d.ts +30 -0
- package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
- package/dist/Markdown/plugins/textTransform.js +374 -0
- package/dist/Markdown/remark.d.ts +196 -0
- package/dist/Markdown/remark.d.ts.map +1 -0
- package/dist/Markdown/remark.js +1062 -0
- package/dist/Markdown/url.d.ts +4 -0
- package/dist/Markdown/url.d.ts.map +1 -0
- package/dist/Markdown/url.js +25 -0
- package/dist/Markdown/utils.d.ts +4 -2
- package/dist/Markdown/utils.d.ts.map +1 -1
- package/dist/Markdown/utils.js +2 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +4 -4
- package/dist/Outline/index.d.ts +1 -0
- package/dist/Outline/index.d.ts.map +1 -1
- package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
- package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
- package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
- package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
- package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
- package/dist/Outline/useOutlineFromMarkdown.js +8 -3
- package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +36 -31
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +13 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
- package/dist/Selector/Selector.d.ts +9 -7
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +7 -5
- package/dist/SideNav/SideNav.d.ts +2 -1
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +9 -3
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +28 -12
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +23 -7
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +11 -0
- package/dist/TabList/Tab.d.ts +1 -1
- package/dist/TabList/Tab.d.ts.map +1 -1
- package/dist/TabList/Tab.js +20 -7
- package/dist/Table/Table.d.ts +1 -0
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +29 -13
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +1 -1
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +2 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +4 -4
- package/dist/ToggleButton/ToggleButton.d.ts +9 -6
- package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButton.js +15 -27
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +3 -0
- package/dist/TreeList/TreeListItem.d.ts +6 -1
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +12 -2
- package/dist/TreeList/TreeListTypes.d.ts +8 -1
- package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +16 -7
- package/dist/astryx.css +18 -7
- package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
- package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
- package/dist/hooks/scrollKeyboardDelegation.js +146 -0
- package/dist/hooks/useScrollableArea.d.ts +6 -2
- package/dist/hooks/useScrollableArea.d.ts.map +1 -1
- package/dist/hooks/useScrollableArea.js +17 -5
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +10 -0
- package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +9 -0
- package/locales/af-ZA.json +530 -1
- package/locales/ar-SA.json +490 -1
- package/locales/ca-ES.json +514 -1
- package/locales/cs-CZ.json +498 -1
- package/locales/da-DK.json +522 -1
- package/locales/de-DE.json +522 -1
- package/locales/el-GR.json +498 -1
- package/locales/es-ES.json +510 -1
- package/locales/fi-FI.json +498 -1
- package/locales/fr-FR.json +534 -1
- package/locales/he-IL.json +498 -1
- package/locales/hu-HU.json +498 -1
- package/locales/it-IT.json +510 -1
- package/locales/ja-JP.json +490 -1
- package/locales/ko-KR.json +498 -1
- package/locales/nl-NL.json +534 -1
- package/locales/no-NO.json +510 -1
- package/locales/pl-PL.json +506 -1
- package/locales/pt-BR.json +506 -1
- package/locales/pt-PT.json +506 -1
- package/locales/ro-RO.json +506 -1
- package/locales/ru-RU.json +498 -1
- package/locales/sr-SP.json +498 -1
- package/locales/sv-SE.json +502 -1
- package/locales/tr-TR.json +498 -1
- package/locales/uk-UA.json +498 -1
- package/locales/vi-VN.json +502 -1
- package/locales/zh-CN.json +490 -1
- package/locales/zh-TW.json +490 -1
- package/package.json +19 -4
- package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
- package/src/BottomSheet/BottomSheet.spec.md +46 -20
- package/src/BottomSheet/BottomSheet.test.tsx +6 -3
- package/src/BottomSheet/BottomSheet.tsx +3 -1
- package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
- package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
- package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
- package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
- package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
- package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
- package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
- package/src/Button/__tests__/Button.a11y.states.ts +9 -0
- package/src/Chat/ChatComposer.doc.mjs +14 -0
- package/src/Chat/ChatComposer.spec.md +230 -0
- package/src/Chat/ChatComposer.test.tsx +57 -0
- package/src/Chat/ChatComposer.tsx +21 -9
- package/src/Chat/ChatComposerDrawer.doc.mjs +63 -5
- package/src/Chat/ChatComposerDrawer.spec.md +267 -0
- package/src/Chat/ChatComposerDrawer.test.tsx +81 -12
- package/src/Chat/ChatComposerDrawer.tsx +38 -9
- package/src/Chat/ChatComposerInput.doc.mjs +114 -26
- package/src/Chat/ChatComposerInput.spec.md +185 -0
- package/src/Chat/ChatComposerInput.test.tsx +113 -3
- package/src/Chat/ChatComposerInput.tsx +78 -13
- package/src/Chat/ChatComposerTokenElement.spec.md +152 -0
- package/src/Chat/ChatComposerTokenElement.test.tsx +85 -0
- package/src/Chat/ChatDictationButton.doc.mjs +3 -3
- package/src/Chat/ChatDictationButton.spec.md +160 -0
- package/src/Chat/ChatDictationButton.test.tsx +92 -27
- package/src/Chat/ChatDictationButton.tsx +8 -6
- package/src/Chat/ChatSendButton.test.tsx +1 -4
- package/src/Chat/ChatSendButton.tsx +1 -1
- package/src/Chat/index.ts +1 -0
- package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
- package/src/CheckboxInput/CheckboxInput.tsx +21 -1
- package/src/ClickableCard/ClickableCard.test.tsx +102 -5
- package/src/Collapsible/Collapsible.doc.mjs +11 -0
- package/src/Collapsible/Collapsible.test.tsx +21 -0
- package/src/Collapsible/Collapsible.tsx +5 -0
- package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
- package/src/ComplexSelector/ComplexSelector.tsx +6 -1
- package/src/DateInput/DateInput.tsx +6 -1
- package/src/DateInput/NativeDateField.tsx +24 -8
- package/src/DateInput/TouchDateField.tsx +6 -2
- package/src/DateRangeInput/DateRangeInput.tsx +6 -1
- package/src/DateTimeInput/DateTimeInput.tsx +6 -1
- package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
- package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
- package/src/Dialog/DialogHeader.doc.mjs +12 -0
- package/src/Dialog/DialogHeader.test.tsx +97 -0
- package/src/Dialog/DialogHeader.tsx +25 -3
- package/src/Dialog/modules/DialogHeader.spec.md +75 -38
- package/src/Field/InputClearButton.test.tsx +17 -3
- package/src/Field/InputClearButton.tsx +5 -2
- package/src/Field/PanelSearchInput.tsx +5 -2
- package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
- package/src/FileInput/FileInput.tsx +11 -2
- package/src/Kbd/Kbd.doc.mjs +3 -3
- package/src/Kbd/Kbd.test.tsx +57 -1
- package/src/Kbd/Kbd.tsx +57 -37
- package/src/Layout/LayoutFooter.doc.mjs +17 -0
- package/src/Link/Link.doc.mjs +11 -0
- package/src/Link/Link.test.tsx +24 -0
- package/src/Link/Link.tsx +5 -0
- package/src/List/List.spec.md +200 -0
- package/src/Markdown/Markdown.doc.mjs +272 -0
- package/src/Markdown/Markdown.fr23.bench.ts +174 -0
- package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
- package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
- package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
- package/src/Markdown/Markdown.public.test.ts +126 -3
- package/src/Markdown/Markdown.spec.md +197 -44
- package/src/Markdown/Markdown.test.tsx +11 -0
- package/src/Markdown/Markdown.tsx +414 -135
- package/src/Markdown/ast.test.ts +307 -0
- package/src/Markdown/ast.ts +337 -0
- package/src/Markdown/incremental.test.ts +12 -0
- package/src/Markdown/index.ts +37 -1
- package/src/Markdown/modules/remark.spec.md +269 -0
- package/src/Markdown/parser/index.ts +64 -0
- package/src/Markdown/parser.public.test.ts +103 -0
- package/src/Markdown/parser.ts +1180 -235
- package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
- package/src/Markdown/plugins/frontmatter.ts +198 -0
- package/src/Markdown/plugins/index.ts +53 -0
- package/src/Markdown/plugins/protocol.test.tsx +1022 -0
- package/src/Markdown/plugins/protocol.ts +1618 -0
- package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
- package/src/Markdown/plugins/semanticFence.ts +424 -0
- package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
- package/src/Markdown/plugins/sourceDecoration.ts +539 -0
- package/src/Markdown/plugins/textTransform.test.ts +467 -0
- package/src/Markdown/plugins/textTransform.ts +554 -0
- package/src/Markdown/remark.test.tsx +1877 -0
- package/src/Markdown/remark.ts +1574 -0
- package/src/Markdown/url.ts +30 -0
- package/src/Markdown/utils.ts +13 -1
- package/src/MultiSelector/MultiSelector.test.tsx +1 -35
- package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
- package/src/NumberInput/NumberInput.tsx +6 -1
- package/src/Outline/Outline.doc.mjs +7 -5
- package/src/Outline/Outline.spec.md +1 -1
- package/src/Outline/index.ts +1 -0
- package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
- package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
- package/src/Outline/useOutlineFromMarkdown.ts +15 -3
- package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
- package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
- package/src/ProgressBar/ProgressBar.test.tsx +29 -11
- package/src/ProgressBar/ProgressBar.tsx +59 -72
- package/src/RadioList/RadioList.doc.mjs +11 -0
- package/src/RadioList/RadioList.test.tsx +32 -0
- package/src/RadioList/RadioListItem.tsx +25 -1
- package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
- package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
- package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
- package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
- package/src/Selector/Selector.doc.mjs +2 -2
- package/src/Selector/Selector.spec.md +51 -49
- package/src/Selector/Selector.test.tsx +61 -55
- package/src/Selector/Selector.tsx +23 -14
- package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
- package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
- package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
- package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
- package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
- package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
- package/src/SideNav/SideNav.doc.mjs +1 -1
- package/src/SideNav/SideNav.test.tsx +10 -0
- package/src/SideNav/SideNav.tsx +14 -2
- package/src/Slider/Slider.doc.mjs +17 -3
- package/src/Slider/Slider.test.tsx +221 -0
- package/src/Slider/Slider.tsx +40 -9
- package/src/Spinner/Spinner.test.tsx +4 -0
- package/src/Spinner/Spinner.tsx +31 -18
- package/src/Switch/Switch.doc.mjs +11 -0
- package/src/Switch/Switch.test.tsx +16 -0
- package/src/Switch/Switch.tsx +28 -0
- package/src/TabList/Tab.tsx +35 -7
- package/src/TabList/TabList.doc.mjs +11 -0
- package/src/TabList/TabList.spec.md +204 -0
- package/src/TabList/TabList.test.tsx +66 -0
- package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
- package/src/Table/Table.doc.mjs +1 -1
- package/src/Table/Table.spec.md +54 -40
- package/src/Table/Table.test.tsx +83 -10
- package/src/Table/Table.tsx +30 -22
- package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +137 -0
- package/src/TextArea/TextArea.tsx +6 -1
- package/src/TextInput/TextInput.test.tsx +20 -1
- package/src/TextInput/TextInput.tsx +6 -1
- package/src/TimeInput/TimeInput.tsx +6 -1
- package/src/ToggleButton/ToggleButton.doc.mjs +3 -3
- package/src/ToggleButton/ToggleButton.test.tsx +299 -4
- package/src/ToggleButton/ToggleButton.tsx +26 -33
- package/src/ToggleButton/ToggleButtonGroup.doc.mjs +3 -3
- package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
- package/src/Tokenizer/Tokenizer.spec.md +142 -75
- package/src/TreeList/TreeList.doc.mjs +3 -3
- package/src/TreeList/TreeList.spec.md +123 -75
- package/src/TreeList/TreeList.test.tsx +29 -0
- package/src/TreeList/TreeList.tsx +3 -0
- package/src/TreeList/TreeListItem.tsx +15 -1
- package/src/TreeList/TreeListTypes.ts +11 -1
- package/src/Typeahead/BaseTypeahead.spec.md +4 -3
- package/src/Typeahead/BaseTypeahead.tsx +21 -7
- package/src/Typeahead/Typeahead.test.tsx +53 -0
- package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
- package/src/__tests__/pressState.ts +93 -0
- package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
- package/src/hooks/scrollKeyboardDelegation.ts +233 -0
- package/src/hooks/useScrollableArea.doc.mjs +15 -3
- package/src/hooks/useScrollableArea.test.tsx +59 -1
- package/src/hooks/useScrollableArea.ts +34 -10
- package/src/inputFontFloor.test.ts +106 -0
- package/src/tailwind-theme.css +0 -6
- package/src/theme/generateThemeRules.test.ts +30 -0
- package/src/theme/generateThemeRules.ts +10 -0
- package/src/utils/interactionOverlay.stylex.ts +20 -0
|
@@ -7,7 +7,7 @@ authority: current
|
|
|
7
7
|
archive_reason: null
|
|
8
8
|
superseded_by: null
|
|
9
9
|
approved_by: cixzhang
|
|
10
|
-
approved_at: 2026-09-
|
|
10
|
+
approved_at: 2026-09-19
|
|
11
11
|
owners: [cixzhang]
|
|
12
12
|
review_triggers: [api, theming]
|
|
13
13
|
verified_by:
|
|
@@ -16,10 +16,12 @@ verified_by:
|
|
|
16
16
|
packages/core/src/Markdown/Markdown.public.test.ts,
|
|
17
17
|
packages/core/src/Markdown/parser.test.ts,
|
|
18
18
|
packages/core/src/Markdown/incremental.test.ts,
|
|
19
|
+
packages/core/src/Markdown/remark.test.tsx,
|
|
20
|
+
packages/core/src/Outline/parseOutlineFromMarkdown.test.ts,
|
|
19
21
|
packages/core/src/theme/themingTargets.test.ts,
|
|
20
22
|
scripts/check-knowledge.mjs,
|
|
21
23
|
]
|
|
22
|
-
modules: []
|
|
24
|
+
modules: [module:Markdown/remark]
|
|
23
25
|
families: [family:navigation-destinations]
|
|
24
26
|
design_specs: []
|
|
25
27
|
architecture:
|
|
@@ -31,6 +33,10 @@ system_specs:
|
|
|
31
33
|
spec:AST-002/DEC-5,
|
|
32
34
|
spec:AST-005/DEC-1,
|
|
33
35
|
spec:AST-005/DEC-2,
|
|
36
|
+
spec:AST-036/DEC-1,
|
|
37
|
+
spec:AST-036/DEC-2,
|
|
38
|
+
spec:AST-036/DEC-3,
|
|
39
|
+
spec:AST-036/DEC-4,
|
|
34
40
|
]
|
|
35
41
|
---
|
|
36
42
|
|
|
@@ -39,18 +45,20 @@ system_specs:
|
|
|
39
45
|
## Intent
|
|
40
46
|
|
|
41
47
|
Markdown renders parsed content in a Document with stable default block parts and
|
|
42
|
-
constrained renderer seams.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
rendering, styling, and streaming behavior
|
|
48
|
+
constrained renderer seams. Callers may opt into the canonical plugin protocol for
|
|
49
|
+
bounded source syntax, immutable document transformation, typed extension
|
|
50
|
+
rendering, and native typed document-start frontmatter. They may separately opt into dollar-delimited math by supplying one typed
|
|
51
|
+
renderer for both inline and display expressions. The parser accepts matching
|
|
52
|
+
explicit options. Existing parsing, rendering, styling, and streaming behavior
|
|
53
|
+
remain unchanged when plugins and math are absent.
|
|
47
54
|
|
|
48
55
|
## Compatibility and migration
|
|
49
56
|
|
|
50
57
|
- Released default preserved: `yes`
|
|
51
58
|
- Compatibility class: additive, opt-in public API; existing parser nodes, DOM,
|
|
52
|
-
styling, targets,
|
|
53
|
-
|
|
59
|
+
styling, targets, dollar-delimited text, `components`, and `inlinePlugins` remain
|
|
60
|
+
unchanged unless the caller supplies `plugins`, supplies `components.math`, or
|
|
61
|
+
passes the matching explicit parser option.
|
|
54
62
|
- Controlled/uncontrolled behavior: not applicable
|
|
55
63
|
- Migration decision: none
|
|
56
64
|
|
|
@@ -69,6 +77,16 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
69
77
|
delimiter boundaries, escape behavior, parser nodes, and streaming parity.
|
|
70
78
|
- Passing each recognized expression as inert text to the caller's one math
|
|
71
79
|
renderer with an `inline` or `block` display value.
|
|
80
|
+
- Applying the canonical `plugins` protocol in the fixed syntax → immutable
|
|
81
|
+
transform → render order while preserving built-in lexical shields, Core-owned
|
|
82
|
+
semantics, and local readable fallback.
|
|
83
|
+
- Validating and freezing replacement document roots before later transforms or
|
|
84
|
+
rendering observe them.
|
|
85
|
+
- Sharing plugin-enabled parse configuration, transformed heading projection, and
|
|
86
|
+
collision-safe heading IDs with Markdown-derived Outline utilities.
|
|
87
|
+
- Decoding an optional document-start frontmatter block into caller-defined typed
|
|
88
|
+
metadata, withholding unfinished frontmatter while streaming, and excluding
|
|
89
|
+
completed frontmatter syntax from rendered content.
|
|
72
90
|
|
|
73
91
|
**Does not own / non-goals**
|
|
74
92
|
|
|
@@ -78,11 +96,43 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
78
96
|
additional default block anatomy.
|
|
79
97
|
- Nested anatomy or targets owned by CodeBlock, Blockquote, List, CheckboxList,
|
|
80
98
|
or Table.
|
|
81
|
-
- Executing or sanitizing a renderer's math
|
|
82
|
-
|
|
99
|
+
- Executing or sanitizing a renderer's math or plugin output, raw HTML parsing,
|
|
100
|
+
mutable or unrestricted AST plugins, package discovery, or new
|
|
101
|
+
list/table/inline-style override slots.
|
|
83
102
|
|
|
84
103
|
## Public concepts
|
|
85
104
|
|
|
105
|
+
`plugins` is one optional ordered list of opaque entries created by
|
|
106
|
+
`createMarkdownPlugin()`. A plugin declares only the `syntax`, `transform`, and
|
|
107
|
+
`renderers` capabilities it uses. Syntax-bearing entries supply stable parse
|
|
108
|
+
identity. Parsing, transforms, rendering, and Outline use one stable, strictly typed,
|
|
109
|
+
MDAST-aligned canonical tree; `parseMarkdownAst()` and `parseInlineAst()` expose
|
|
110
|
+
that tree from the server-safe `@astryxdesign/core/Markdown/parser` subpath while
|
|
111
|
+
`@astryxdesign/core/Markdown/plugins` remains server-safe for constructing and
|
|
112
|
+
running plugins in server or RSC code. The rendered `Markdown` component remains a
|
|
113
|
+
client entry: function-bearing plugin entries are not serializable props and cannot
|
|
114
|
+
cross an RSC boundary. `MarkdownAstNodeMap` and `visitMarkdownNodes` provide
|
|
115
|
+
node-kind narrowing. Released parser functions preserve their existing result shape
|
|
116
|
+
through a compatibility projection. Transforms return validated replacement roots
|
|
117
|
+
without entering parse identity. Every extension node introduced
|
|
118
|
+
by syntax or transformation has complete renderer ownership and a deterministic
|
|
119
|
+
text projection. Text matching, semantic fences, source decoration, and native
|
|
120
|
+
frontmatter are helpers that compile to transforms rather than separate protocol
|
|
121
|
+
phases. Frontmatter is document metadata: it has no renderer, uses a bounded
|
|
122
|
+
first-party key/value grammar rather than Remark compatibility, and exposes typed
|
|
123
|
+
metadata through the helper that created it. `spec:AST-036`
|
|
124
|
+
owns the shared protocol and limited Remark compatibility profile,
|
|
125
|
+
`module:Markdown/remark` owns that profile's adapter, and this component owns
|
|
126
|
+
aggregate application and fallback.
|
|
127
|
+
|
|
128
|
+
### Acceptance and implementation state
|
|
129
|
+
|
|
130
|
+
The plugin clauses below are the accepted target contract for the AST-036 rollout,
|
|
131
|
+
not a claim that the APIs already ship. Until every clause's implementation and
|
|
132
|
+
verification land, the currently released no-plugin, parser, `components`, and
|
|
133
|
+
`inlinePlugins` behavior remains the only available contract. Each implementation PR
|
|
134
|
+
must identify the clauses it completes without weakening the zero-breaking baseline.
|
|
135
|
+
|
|
86
136
|
`MarkdownComponents.math` is one optional renderer with the signature
|
|
87
137
|
`({value: string, display: 'inline' | 'block'}) => ReactNode`. Supplying it opts
|
|
88
138
|
the component into math parsing because the caller owns both whether dollar
|
|
@@ -97,19 +147,33 @@ unions. Enabled calls return the explicit `InlineNodeWithMath` and
|
|
|
97
147
|
|
|
98
148
|
## Behavioral and layout contract
|
|
99
149
|
|
|
100
|
-
| ID | Invariant
|
|
101
|
-
| ---- |
|
|
102
|
-
| FR1 | Block and inline displays render one Document root carrying the current `markdown` target. Inline display renders no block anatomy.
|
|
103
|
-
| 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.
|
|
104
|
-
| 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.
|
|
105
|
-
| FR4 | The released Code block target remains `markdown-codeblock`; this compatibility anomaly is not renamed or aliased.
|
|
106
|
-
| FR5 | Density and Heading level remain reflected capabilities on their owning targets. Display mode, streaming state, and renderer selection do not become separate anatomy entries.
|
|
107
|
-
| FR6 | Without `components.math`, Markdown does not recognize math syntax. Default, legacy-set, `math: false`, and `ParseOptions`-annotated parser calls retain the released `InlineNode` / `BlockNode` result unions; only `MathParseOptions` returns the explicit math-enabled unions.
|
|
108
|
-
| FR7 | With math enabled, `$…$` produces an inline `math` node and `$$…$$` produces a block `math` node. The renderer receives the delimiter-free source as `value` and its placement as `display`.
|
|
109
|
-
| FR8 | Inline math stays on one line, cannot have whitespace touching either delimiter, and cannot open immediately after a digit or close immediately before one. `$$` is reserved for display math. These boundaries keep paired currency amounts literal.
|
|
110
|
-
| FR9 | A backslash-escaped dollar is literal outside math and does not close math inside it. An unmatched inline or display delimiter remains literal in non-streaming output.
|
|
111
|
-
| FR10 | Code spans and fenced code blocks are opaque to math parsing. Link destinations are opaque; link labels may contain inline math. Inline plugins run only on prose text and never inside math.
|
|
112
|
-
| FR11 | Streaming converges to the same nodes as a full parse at every chunk boundary, including display math nested in ordinary lists, task lists, blockquotes, and their supported combinations, with LF or CRLF and with or without source ranges. Incomplete math is withheld only while its exact owning container remains open; a list/quote exit or quote-depth change restores literal parsing. Math-enabled incremental calls require `IncrementalParseState<true>`, so the cache and returned union share one contract.
|
|
150
|
+
| ID | Invariant |
|
|
151
|
+
| ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
152
|
+
| FR1 | Block and inline displays render one Document root carrying the current `markdown` target. Inline display renders no block anatomy. |
|
|
153
|
+
| 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. |
|
|
154
|
+
| 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. |
|
|
155
|
+
| FR4 | The released Code block target remains `markdown-codeblock`; this compatibility anomaly is not renamed or aliased. |
|
|
156
|
+
| FR5 | Density and Heading level remain reflected capabilities on their owning targets. Display mode, streaming state, and renderer selection do not become separate anatomy entries. |
|
|
157
|
+
| FR6 | Without `components.math`, Markdown does not recognize math syntax. Default, legacy-set, `math: false`, and `ParseOptions`-annotated parser calls retain the released `InlineNode` / `BlockNode` result unions; only `MathParseOptions` returns the explicit math-enabled unions. |
|
|
158
|
+
| FR7 | With math enabled, `$…$` produces an inline `math` node and `$$…$$` produces a block `math` node. The renderer receives the delimiter-free source as `value` and its placement as `display`. |
|
|
159
|
+
| FR8 | Inline math stays on one line, cannot have whitespace touching either delimiter, and cannot open immediately after a digit or close immediately before one. `$$` is reserved for display math. These boundaries keep paired currency amounts literal. |
|
|
160
|
+
| FR9 | A backslash-escaped dollar is literal outside math and does not close math inside it. An unmatched inline or display delimiter remains literal in non-streaming output. |
|
|
161
|
+
| FR10 | Code spans and fenced code blocks are opaque to math parsing. Link destinations are opaque; link labels may contain inline math. Inline plugins run only on prose text and never inside math. |
|
|
162
|
+
| FR11 | Streaming converges to the same nodes as a full parse at every chunk boundary, including display math nested in ordinary lists, task lists, blockquotes, and their supported combinations, with LF or CRLF and with or without source ranges. Incomplete math is withheld only while its exact owning container remains open; a list/quote exit or quote-depth change restores literal parsing. Math-enabled incremental calls require `IncrementalParseState<true>`, so the cache and returned union share one contract. |
|
|
163
|
+
| FR12 | Omitting `plugins` and passing an empty list are one semantic empty pipeline with identical parser unions, AST, DOM, styling, targets, IDs, and streaming behavior. Core may skip empty preparation and allocation without creating a separate behavior model. `components`, `inlinePlugins`, citations, autolinking, sources, and math retain their released meaning. |
|
|
164
|
+
| FR13 | Plugin-enabled parsing follows built-in lexical shields and ordered syntax claims, then uses one stable, strictly typed, MDAST-aligned canonical tree for transforms, rendering, and Outline. `MarkdownAstNodeMap` and `visitMarkdownNodes` narrow callbacks by node kind. Released parser functions preserve their existing result shape through a compatibility projection. Every returned root is finite, acyclic, representable, validated, and frozen before later plugins or rendering observe it. |
|
|
165
|
+
| FR14 | Plugin failures preserve the last valid document and readable authored source. Core retains heading, navigation, image, list, table, and document semantics and exposes no raw-markup parser channel, registry, package discovery, mutable shared AST, or unrestricted DOM hook. URL-like plugin data remains untrusted; Astryx-owned sinks follow `family:navigation-destinations`. |
|
|
166
|
+
| FR15 | Incremental parse identity contains every parse-affecting Markdown option and only ordered syntax-bearing plugin name, protocol version, and `parseKey`. Transform or renderer changes reuse settled parse output, rerun transformation, and do not remount unaffected extension output. |
|
|
167
|
+
| FR16 | Plugin-enabled Markdown and Markdown-derived Outline use the same parse options, ordered transforms, extension text projection, slugger, and collision allocator so every visible heading, Outline label, heading ID, and target agree. A limited Remark adapter may run only synchronous transform plugins whose input and output round-trip through the documented supported MDAST subset. |
|
|
168
|
+
| FR17 | An extension node declares `content` as `'none'`, `'phrasing'`, `'flow'`, or an explicit `{allow, min?, max?}` allowlist that narrows the category its `display` implies. Markdown parses every container's inner source span under the same grammar and shields, validates children at each transform boundary, renders children through the same built-in renderers and `components` seams, counts nesting toward the built-in depth bound, leaves FR16 heading traversal unchanged, and renders children in place when a container renderer fails. |
|
|
169
|
+
| FR18 | A transform may read and remove another plugin's extension nodes, including a subtree containing them, and may insert or remove headings; it may not create, edit, internally reorder, or duplicate another plugin's nodes, change a source heading's depth, or forge or duplicate heading identity. `dependsOn` is validated at preparation; an unmet or misordered dependency skips only that plugin's transform. Every rejection names the rule and owning plugin. |
|
|
170
|
+
| FR19 | `onPluginDiagnostic` is available on the component and parser options and receives one source-free event — plugin, phase, stable code, severity — per failure, advisory, or silent degradation, in development and production, rate-limited with a suppression code. Admission, duplicate-name, and protocol-version failures behave identically through the component and every parser entrypoint: the call succeeds with the last valid configuration and never throws into the caller. |
|
|
171
|
+
| FR20 | `parseMarkdownAst()` and `parseInlineAst()` return the canonical tree and accept the same options and plugin list as the component; `@astryxdesign/core/Markdown/parser` exposes parsing, canonical AST types, and plugin admission with no client boundary. `createMarkdownPlugin()` infers the extension-node union, so no callsite needs explicit type arguments, and a declaration that yields no usable extension type is a type error rather than a silent `never`. |
|
|
172
|
+
| FR21 | A transform runs again for every streamed update and must be idempotent and convergent; transforms whose effect requires complete input use the final-input signal. Semantically equal plugin lists reuse prepared work whether or not the array reference is stable, and development reports one diagnostic when a recreated list prevents reuse. |
|
|
173
|
+
| FR22 | An extension renderer may opt into the Markdown-owned extension theme target so themes reach plugin output. Opting out leaves output untargeted. The target adds no default styling or anatomy beyond the block spacing and content width Core already applies. |
|
|
174
|
+
| FR23 | Markdown owns an explicit supported dialect rather than claiming full CommonMark or GFM conformance. Adjacent compatible ordered or unordered items remain one list regardless of task-marker presence; each item independently preserves its checked state or ordinary list-item semantics, including at nested levels. The default grammar keeps its released task-list and table support, while `autolink: 'gfm'` adds only the documented autolink behavior and does not toggle any other syntax. |
|
|
175
|
+
| FR24 | `createMarkdownFrontmatter()` recognizes only a leading `---` block of unique `key: value` lines, decodes it through the caller's typed parser, stores finite JSON-like metadata on the canonical document, and removes the syntax from rendered content. An unfinished leading block yields no visible Markdown while streaming; malformed or unfinished final input remains ordinary Markdown. Frontmatter has no renderer and requires no Remark compatibility. |
|
|
176
|
+
| FR25 | The canonical parser and plugin-construction subpaths remain server-safe and can run function-bearing plugins entirely within server or RSC code. The client-owned `Markdown` component supports traditional and streaming SSR, but plugin entries containing functions cannot be serialized from a Server Component into that client boundary; direct RSC rendering requires a future additive server renderer rather than weakening the plugin protocol. |
|
|
113
177
|
|
|
114
178
|
### Allowed variation
|
|
115
179
|
|
|
@@ -125,21 +189,28 @@ unions. Enabled calls return the explicit `InlineNodeWithMath` and
|
|
|
125
189
|
- **AV5 — Math renderer.** The caller may use any renderer that accepts the raw
|
|
126
190
|
expression and display value. Its DOM, styles, typesetting engine, error UI,
|
|
127
191
|
and accessibility representation are outside Markdown's ownership.
|
|
192
|
+
- **AV6 — Installed plugins.** A host may supply any ordered set of compatible
|
|
193
|
+
opaque plugin entries. Syntax, immutable transform behavior, renderer-owned
|
|
194
|
+
output, and helper implementation may vary while validation, readable fallback,
|
|
195
|
+
Core semantics, and heading identity stay fixed.
|
|
128
196
|
|
|
129
197
|
### Representative states
|
|
130
198
|
|
|
131
|
-
| State | Required invariant
|
|
132
|
-
| ---------------------- |
|
|
133
|
-
| Default block content | Every parsed block uses its corresponding current Markdown target.
|
|
134
|
-
| Custom block renderers | The replaced Heading, Paragraph, Code block, Blockquote, Divider, or Image lacks the corresponding Markdown target.
|
|
135
|
-
| Ordered/unordered list | List carries `markdown-list`.
|
|
136
|
-
| Task list |
|
|
137
|
-
| Safe block image | Default Image carries `markdown-image`, or a custom image renderer replaces it.
|
|
138
|
-
| Unsafe block image URL | Markdown renders its fallback Image part with `markdown-image`; no custom image renderer receives the rejected URL.
|
|
139
|
-
| Inline display | Document carries `markdown`; no block target renders.
|
|
140
|
-
| Math renderer absent | Dollar-delimited source follows the released Markdown grammar and no `math` node or renderer output exists.
|
|
141
|
-
| Math renderer present | Complete supported delimiters are opaque to Markdown formatting and are passed to the renderer as inert text.
|
|
142
|
-
| Streaming math | Incomplete math is withheld; once complete, the streamed nodes equal the full-parse nodes at top level and inside list/blockquote containers.
|
|
199
|
+
| State | Required invariant | Allowed variation |
|
|
200
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
201
|
+
| Default block content | Every parsed block uses its corresponding current Markdown target. | Block count, order, density, content width, and alignment. |
|
|
202
|
+
| Custom block renderers | The replaced Heading, Paragraph, Code block, Blockquote, Divider, or Image lacks the corresponding Markdown target. | Replacement structure and styling. |
|
|
203
|
+
| Ordered/unordered list | List carries `markdown-list`. | Marker kind, start value, item count, and nested content. |
|
|
204
|
+
| Task list | Each task-marked item carries its own checked state; mixed task/plain items stay in one compatible list and preserve document order and nesting. | Checked values, item content, and adjacent plain items. |
|
|
205
|
+
| Safe block image | Default Image carries `markdown-image`, or a custom image renderer replaces it. | Source and alternative text. |
|
|
206
|
+
| 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. |
|
|
207
|
+
| Inline display | Document carries `markdown`; no block target renders. | Inline text, links, code, citations, plugins, and opt-in inline math. |
|
|
208
|
+
| Math renderer absent | Dollar-delimited source follows the released Markdown grammar and no `math` node or renderer output exists. | Currency, unmatched delimiters, and ordinary prose. |
|
|
209
|
+
| Math renderer present | Complete supported delimiters are opaque to Markdown formatting and are passed to the renderer as inert text. | Inline or block display and any renderer-owned output. |
|
|
210
|
+
| Streaming math | Incomplete math is withheld; once complete, the streamed nodes equal the full-parse nodes at top level and inside list/blockquote containers. | Delimiters and expression text may arrive in separate chunks; source ranges remain optional. |
|
|
211
|
+
| Plugins omitted | Released parser unions, AST, DOM, targets, heading IDs, and performance remain unchanged. | Omitted or empty list; both are one empty transform pipeline. |
|
|
212
|
+
| Plugins enabled | Fixed syntax → immutable transform → render order, validated roots, readable fallback, and matching Markdown/Outline heading identity remain invariant. | Syntax, transforms, renderers, helper execution plans, plugin order, and live post-parse state. |
|
|
213
|
+
| Native frontmatter | A complete leading block is absent from rendered content and yields typed metadata; unfinished streaming input is withheld. | Metadata schema and values are caller-defined finite data. |
|
|
143
214
|
|
|
144
215
|
### Transformation and precedence order
|
|
145
216
|
|
|
@@ -151,6 +222,16 @@ unions. Enabled calls return the explicit `InlineNodeWithMath` and
|
|
|
151
222
|
display value. Markdown never turns it into HTML or executes it.
|
|
152
223
|
- Existing URL sanitization remains in force for links and images; math adds no
|
|
153
224
|
navigation or raw-HTML sink.
|
|
225
|
+
- Built-in syntax and protected contexts claim first; extension syntax claims only
|
|
226
|
+
eligible source; ordered transforms then receive deeply readonly document roots;
|
|
227
|
+
Core validates each returned root before rendering.
|
|
228
|
+
- A configured native frontmatter helper claims only the document-start delimiter.
|
|
229
|
+
It withholds an unfinished block during streaming, removes a completed block
|
|
230
|
+
before later transforms render the document, and makes typed metadata available
|
|
231
|
+
to those later transforms and to callers of that helper.
|
|
232
|
+
- Text matching, semantic fences, and source decorations use transform helpers. Core
|
|
233
|
+
may compile those helpers into indexed internal plans without exposing additional
|
|
234
|
+
public phases.
|
|
154
235
|
|
|
155
236
|
### Performance and resources
|
|
156
237
|
|
|
@@ -162,6 +243,8 @@ unions. Enabled calls return the explicit `InlineNodeWithMath` and
|
|
|
162
243
|
container depth so an indented closer cannot become a new opener and a depth
|
|
163
244
|
transition cannot swallow literal content. The factory-created state carries
|
|
164
245
|
the same legacy or math-enabled node contract as the parser call.
|
|
246
|
+
- Stable and semantically equal plugin lists reuse prepared syntax and transform plans. Only syntax enters parse identity; transform and renderer changes reuse parsed output. Zero-work and representative transforms remain within `spec:AST-036` FR21–FR23 budgets, including the plugin-authored and streaming paths.
|
|
247
|
+
- Remark compatibility adapters, the conformance kit, and optional renderers stay outside Core bundles unless explicitly imported.
|
|
165
248
|
|
|
166
249
|
## Accessibility contract
|
|
167
250
|
|
|
@@ -170,7 +253,10 @@ scrollable Table wrapper, and image alternative text remain unchanged. Math has
|
|
|
170
253
|
no Astryx-owned default output: the caller's renderer owns an accessible
|
|
171
254
|
representation appropriate to its typesetting engine (for example MathML or a
|
|
172
255
|
labelled `role="math"` element). Markdown adds no wrapper, ARIA attributes, or
|
|
173
|
-
HTML injection around renderer output.
|
|
256
|
+
HTML injection around renderer output. Plugin renderers likewise own their
|
|
257
|
+
complete documented semantic pattern, while Core preserves its own document,
|
|
258
|
+
heading, navigation, image, list, and table semantics. Transforms cannot erase
|
|
259
|
+
required accessible meaning or make meaning color-only.
|
|
174
260
|
|
|
175
261
|
## Design relationships
|
|
176
262
|
|
|
@@ -234,18 +320,32 @@ and this change preserves the existing spelling exactly.
|
|
|
234
320
|
- `spec:AST-005/DEC-2` keeps embedded-resource policy separate. Markdown may
|
|
235
321
|
reject a broader set of image/resource URLs without narrowing the shared
|
|
236
322
|
navigation contract.
|
|
323
|
+
- `spec:AST-036` owns the opaque syntax/transform/renderer protocol, immutable AST
|
|
324
|
+
validation, limited Remark compatibility, performance, and resource boundaries.
|
|
325
|
+
This record owns aggregate Markdown behavior in FR12–FR22;
|
|
326
|
+
`module:Markdown/remark` owns the separately imported Remark adapter's
|
|
327
|
+
supported subset, rejections, and diagnostics; and
|
|
328
|
+
`module:Outline/parseOutlineFromMarkdown` owns the corresponding Outline
|
|
329
|
+
projection.
|
|
237
330
|
- Nested Astryx primitives retain ownership of their own anatomy and targets;
|
|
238
331
|
Markdown owns the outer block targets listed here.
|
|
239
332
|
|
|
240
333
|
## Verification map
|
|
241
334
|
|
|
242
|
-
| Contract | Verification | Representative states
|
|
243
|
-
| ---------------------- | -------------------------------------------------------------------------- |
|
|
244
|
-
| FR1–FR5 | `Markdown.test.tsx`, theme-target tests, and `scripts/check-knowledge.mjs` | Default block/inline output and all current targets
|
|
245
|
-
| FR6–FR10 | `parser.test.ts` and `Markdown.test.tsx` | Opt-out, inline/display math, escapes, currency, code, links, plugins
|
|
246
|
-
| FR11 | `incremental.test.ts` and `Markdown.test.tsx` | Every-character top-level/list/task-list/blockquote splits, CRLF, source ranges
|
|
247
|
-
|
|
|
248
|
-
|
|
|
335
|
+
| Contract | Verification | Representative states | Failure signal |
|
|
336
|
+
| ---------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
337
|
+
| FR1–FR5 | `Markdown.test.tsx`, theme-target tests, and `scripts/check-knowledge.mjs` | Default block/inline output and all current targets | Existing DOM, target, spacing, or renderer behavior changes. |
|
|
338
|
+
| FR6–FR10 | `parser.test.ts` and `Markdown.test.tsx` | Opt-out, inline/display math, escapes, currency, code, links, plugins | A delimiter is claimed without opt-in, TeX is formatted as Markdown, or opaque contexts leak. |
|
|
339
|
+
| FR11 | `incremental.test.ts` and `Markdown.test.tsx` | Every-character top-level/list/task-list/blockquote splits, CRLF, source ranges | Streaming diverges from a full parse, shows partial syntax, mistakes a nested closer for an opener, or crosses a closed container. |
|
|
340
|
+
| FR12–FR16 | plugin, transform, adapter, performance, and Outline parser tests | omitted/empty lists, immutable transforms, invalid outputs, live updates, one compatible Remark plugin, duplicate headings | Empty behavior forks, input mutates, invalid structure escapes, transforms reparse, adapter loses content, budgets fail, or heading targets diverge. |
|
|
341
|
+
| FR17–FR18 | container parse/validation, ownership, and dependency tests | leaf/container declarations, nested containers, foreign read/remove/mint/edit, unmet/misordered dependencies | Plugin-built parsed children, invalid content, lost fallback children, foreign mint/edit, or generic ownership codes. |
|
|
342
|
+
| FR19 | diagnostic-channel tests in development and production | every phase, advisory reports, rate suppression, no handler, malformed list, duplicate Core, version skew | A silent production failure, document content in a diagnostic, or one entrypoint throwing where another recovers. |
|
|
343
|
+
| FR20–FR22 | canonical/server imports, inference, streaming, preparation, theming tests | server imports, no explicit type args, chunk boundaries, recreated lists, themed/unthemed extensions | Client references, explicit-type workarounds, oscillation, per-render re-preparation, or unreachable opted-in output. |
|
|
344
|
+
| FR23 | parser, renderer, nesting, and public option tests | task-only, plain-only, and mixed ordered/unordered lists at top level and nested; autolink omitted/enabled | A mixed list splits or loses order/state, a plain item becomes a checkbox, or `autolink: 'gfm'` changes non-autolink syntax. |
|
|
345
|
+
| FR24 | `plugins/frontmatter.test.tsx`, Storybook, and server rendering | complete, malformed, non-leading, LF/CRLF, unfinished streaming, full plugin stack | Metadata syntax renders after completion, unfinished syntax leaks while streaming, typing is lost, or later plugins stop composing. |
|
|
346
|
+
| FR25 | `parser.public.test.ts`, plugin SSR tests, and package export checks | server/RSC parsing with plugins, synchronous SSR, suspending renderer streaming boundary | A server import gains `use client`, plugin execution needs serialization, SSR loses fallback, or direct RSC rendering is misrepresented as supported. |
|
|
347
|
+
| Public syntax/types | `Markdown.public.test.ts`, core typecheck, and `Markdown.doc.mjs` | Legacy exhaustive switches, math opt-ins, inferred extension-node unions | A released union widens, an enabled union loses nodes, or docs drift from declarations. |
|
|
348
|
+
| Security/accessibility | `parser.test.ts`, `Markdown.test.tsx`, and renderer guidance | Inert expression strings and renderer-owned semantics | Astryx executes math as HTML or silently claims renderer-owned accessibility. |
|
|
249
349
|
|
|
250
350
|
Focused tests continue to pin all nine current target names and default block
|
|
251
351
|
placement. Math intentionally adds no target and no default anatomy.
|
|
@@ -274,6 +374,59 @@ Rejected: a generic AST/plugin escape hatch, raw HTML rendering, new list/table
|
|
|
274
374
|
slots without consumer evidence, or a separate boolean on the component that
|
|
275
375
|
could enable math without a renderer.
|
|
276
376
|
|
|
377
|
+
### DEC-2 — Immutable transformation is the canonical Markdown extension seam
|
|
378
|
+
|
|
379
|
+
**Reference:** `component:Markdown/DEC-2`
|
|
380
|
+
**Decider:** `cixzhang`, `2026-09-15`
|
|
381
|
+
|
|
382
|
+
Markdown accepts one ordered `plugins` list whose opaque entries are created by
|
|
383
|
+
`createMarkdownPlugin()`. The public protocol exposes only bounded `syntax`,
|
|
384
|
+
immutable `transform`, and typed `renderers`. Core owns deep-readonly input,
|
|
385
|
+
validation and freezing of replacement roots, readable fallback, syntax-only parse
|
|
386
|
+
identity, preparation reuse, shared heading identity, containers, diagnostics, canonical/server parsing, and theming in FR12–FR22. Existing
|
|
387
|
+
`components`, `inlinePlugins`, math, citations, autolinking, and parser calls remain
|
|
388
|
+
compatible.
|
|
389
|
+
|
|
390
|
+
Text matching, semantic fences, and source decoration are transform helpers rather
|
|
391
|
+
than separate protocol phases. A tree-shakeable adapter may run only synchronous
|
|
392
|
+
transform-only Remark plugins over the documented MDAST subset; unsupported behavior
|
|
393
|
+
fails closed rather than being approximated.
|
|
394
|
+
|
|
395
|
+
This projects `spec:AST-036/DEC-1` through `DEC-4` into the component owner. It rejects a registry, package discovery, mutable shared AST, raw markup, a second plugin prop, or an unrestricted Unified runtime.
|
|
396
|
+
|
|
397
|
+
### DEC-3 — Containers, diagnostics, and canonical APIs are Markdown-owned
|
|
398
|
+
|
|
399
|
+
**Reference:** `component:Markdown/DEC-3`
|
|
400
|
+
**Decider:** `cixzhang`, `2026-09-16`
|
|
401
|
+
|
|
402
|
+
Markdown parses every extension container's inner span itself and validates children against the plugin's declared content shape, so a callout holds real Markdown while heading identity, protected contexts, navigation policy, and Outline scope stay Core-owned. Containers change what a document can express, not which headings have identity: the released top-level traversal shared by heading IDs and Outline is untouched. A failed container renderer shows its children rather than literal source. Ownership rejections name the rule and owner; removal of another plugin's nodes is permitted and only minting, editing, internal reordering, duplication, and identity forgery are not.
|
|
403
|
+
|
|
404
|
+
Markdown also owns the protocol's observability and entry surface: `onPluginDiagnostic` makes every failure visible in production without carrying document content, admission failures degrade instead of throwing at any entrypoint, canonical parse entrypoints and a server-safe parser entry exist beside the released projection, extension types are inferred, and extension output may opt into one theme target without becoming default anatomy.
|
|
405
|
+
|
|
406
|
+
This projects `spec:AST-036/DEC-5` through `DEC-11` into the component owner in FR17–FR22. It rejects leaf-only extensions, plugin-authored parsed children, independent document shells, development-only or free-text diagnostics, parsers reachable only through a client barrel, required hand-written extension aliases, and default anatomy for plugin output.
|
|
407
|
+
|
|
408
|
+
### DEC-4 — Own an explicit Markdown dialect, not a profile switch
|
|
409
|
+
|
|
410
|
+
**Reference:** `component:Markdown/DEC-4`
|
|
411
|
+
**Decider:** `cixzhang`, `2026-09-19`
|
|
412
|
+
|
|
413
|
+
Markdown's released grammar is an explicit Astryx-owned subset. Task-list markers are item semantics inside the ordinary ordered or unordered list structure, so mixed task and plain items stay in one compatible list and each item retains its own state at every nesting level. Released table and task-list syntax remains enabled by default. The optional `autolink: 'gfm'` value adds only the documented autolink behavior; it neither enables another syntax feature nor changes list structure.
|
|
414
|
+
|
|
415
|
+
This keeps documents stable as Astryx adds or declines individual ecosystem features. It rejects a blanket CommonMark or GFM conformance claim, aggregate all-task/all-plain classification, an implicit whole-grammar mode switch, and silently enabling future GFM features under the existing autolink option.
|
|
416
|
+
|
|
417
|
+
### DEC-5 — Frontmatter is typed document metadata
|
|
418
|
+
|
|
419
|
+
**Reference:** `component:Markdown/DEC-5`
|
|
420
|
+
**Decider:** `cixzhang`, `2026-09-19`
|
|
421
|
+
|
|
422
|
+
Native frontmatter is a first-party helper in the ordered plugin pipeline. It
|
|
423
|
+
recognizes only a leading delimited block, parses a deliberately small key/value
|
|
424
|
+
grammar through a caller-provided typed decoder, and removes the syntax from the
|
|
425
|
+
rendered document. It does not create a visual extension node or require Remark's
|
|
426
|
+
frontmatter format. During streaming, incomplete frontmatter is withheld so raw
|
|
427
|
+
metadata never flashes as content; once closed, later plugins can consume the
|
|
428
|
+
metadata and the remaining document normally.
|
|
429
|
+
|
|
277
430
|
## Open questions
|
|
278
431
|
|
|
279
432
|
- **OQ1 — Which focused tests should pin target absence for the five remaining
|
|
@@ -80,6 +80,17 @@ describe('Markdown', () => {
|
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
+
it('keeps citation markers out of released heading ids', () => {
|
|
84
|
+
render(
|
|
85
|
+
<Markdown sources={{cite: {title: 'Citation'}}}>
|
|
86
|
+
{'# Before [cite] after'}
|
|
87
|
+
</Markdown>,
|
|
88
|
+
);
|
|
89
|
+
expect(
|
|
90
|
+
screen.getByRole('heading', {name: /Before.*after/}),
|
|
91
|
+
).toHaveAttribute('id', 'before-after');
|
|
92
|
+
});
|
|
93
|
+
|
|
83
94
|
it('passes the generated id to a custom heading component', () => {
|
|
84
95
|
const received: (string | undefined)[] = [];
|
|
85
96
|
render(
|