@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
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
import {describe, expect, it} from 'vitest';
|
|
4
|
+
import {
|
|
5
|
+
createIncrementalState,
|
|
6
|
+
parseMarkdown,
|
|
7
|
+
parseMarkdownAst,
|
|
8
|
+
} from './parser';
|
|
9
|
+
import {createMarkdownPlugin} from './plugins';
|
|
10
|
+
import type {
|
|
11
|
+
MarkdownExtensionNode,
|
|
12
|
+
MarkdownSyntaxPluginDefinition,
|
|
13
|
+
} from './plugins';
|
|
14
|
+
|
|
15
|
+
type DemoNoteNode = MarkdownExtensionNode<
|
|
16
|
+
'demo-notes',
|
|
17
|
+
'note',
|
|
18
|
+
{readonly body: string},
|
|
19
|
+
'block'
|
|
20
|
+
>;
|
|
21
|
+
|
|
22
|
+
const demoNotes = createMarkdownPlugin<'demo-notes', DemoNoteNode>({
|
|
23
|
+
name: 'demo-notes',
|
|
24
|
+
apiVersion: 1,
|
|
25
|
+
parseKey: 'v1',
|
|
26
|
+
syntax: {
|
|
27
|
+
block: [
|
|
28
|
+
{
|
|
29
|
+
startsWith: [':::note'],
|
|
30
|
+
maxSpan: 200,
|
|
31
|
+
tokenize({source, offset, end, isFinal}) {
|
|
32
|
+
const close = source.indexOf('\n:::', offset + 7);
|
|
33
|
+
if (close < 0 || close + 4 > end) {
|
|
34
|
+
return isFinal ? {status: 'no-match'} : {status: 'defer'};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
status: 'match',
|
|
38
|
+
end: close + 4,
|
|
39
|
+
node: {
|
|
40
|
+
type: 'extension',
|
|
41
|
+
plugin: 'demo-notes',
|
|
42
|
+
name: 'note',
|
|
43
|
+
display: 'block',
|
|
44
|
+
data: {body: source.slice(offset + 7, close).trim()},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
renderers: {
|
|
52
|
+
note: {
|
|
53
|
+
render: ({node}) => node.data.body,
|
|
54
|
+
toText: node => node.data.body,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
} satisfies MarkdownSyntaxPluginDefinition<'demo-notes', DemoNoteNode>);
|
|
58
|
+
|
|
59
|
+
describe('canonical Markdown AST', () => {
|
|
60
|
+
it('uses MDAST-aligned names and fields for every built-in structure', () => {
|
|
61
|
+
const ast = parseMarkdownAst(
|
|
62
|
+
'# Title\n\n**bold** and *emphasis* with `code` and [link](/docs).\n\n- item\n\n| A | B |\n| - | - |\n| 1 | 2 |\n\n```ts\nconst value = 1;\n```\n\n---',
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
expect(ast).toMatchObject({
|
|
66
|
+
type: 'root',
|
|
67
|
+
children: [
|
|
68
|
+
{
|
|
69
|
+
type: 'heading',
|
|
70
|
+
depth: 1,
|
|
71
|
+
children: [{type: 'text', value: 'Title'}],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
type: 'paragraph',
|
|
75
|
+
children: [
|
|
76
|
+
{type: 'strong'},
|
|
77
|
+
{type: 'text'},
|
|
78
|
+
{type: 'emphasis'},
|
|
79
|
+
{type: 'text'},
|
|
80
|
+
{type: 'inlineCode', value: 'code'},
|
|
81
|
+
{type: 'text'},
|
|
82
|
+
{type: 'link', url: '/docs'},
|
|
83
|
+
{type: 'text', value: '.'},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
type: 'list',
|
|
88
|
+
ordered: false,
|
|
89
|
+
children: [{type: 'listItem'}],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
type: 'table',
|
|
93
|
+
align: [null, null],
|
|
94
|
+
children: [
|
|
95
|
+
{
|
|
96
|
+
type: 'tableRow',
|
|
97
|
+
children: [{type: 'tableCell'}, {type: 'tableCell'}],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
type: 'tableRow',
|
|
101
|
+
children: [{type: 'tableCell'}, {type: 'tableCell'}],
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
{type: 'code', lang: 'ts', value: 'const value = 1;'},
|
|
106
|
+
{type: 'thematicBreak'},
|
|
107
|
+
],
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('represents remaining built-ins without legacy aliases', () => {
|
|
112
|
+
const ast = parseMarkdownAst(
|
|
113
|
+
'> quote\n\n\n\nParagraph  [src] $x$ \nnext\n\n$$\ny\n$$',
|
|
114
|
+
{math: true, sourceIds: new Set(['src'])},
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
expect(ast.children).toMatchObject([
|
|
118
|
+
{
|
|
119
|
+
type: 'blockquote',
|
|
120
|
+
children: [
|
|
121
|
+
{type: 'paragraph', children: [{type: 'text', value: 'quote'}]},
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
{type: 'image', url: '/block.png', alt: 'Block'},
|
|
125
|
+
{
|
|
126
|
+
type: 'paragraph',
|
|
127
|
+
children: [
|
|
128
|
+
{type: 'text', value: 'Paragraph '},
|
|
129
|
+
{type: 'image', url: '/inline.png', alt: 'Inline'},
|
|
130
|
+
{type: 'text', value: ' '},
|
|
131
|
+
{type: 'citation', sourceId: 'src'},
|
|
132
|
+
{type: 'text', value: ' '},
|
|
133
|
+
{type: 'inlineMath', value: 'x'},
|
|
134
|
+
{type: 'break'},
|
|
135
|
+
{type: 'text', value: 'next'},
|
|
136
|
+
],
|
|
137
|
+
},
|
|
138
|
+
{type: 'math', value: 'y'},
|
|
139
|
+
]);
|
|
140
|
+
expect(parseMarkdownAst('```\nplain\n```').children[0]).toMatchObject({
|
|
141
|
+
type: 'code',
|
|
142
|
+
lang: null,
|
|
143
|
+
value: 'plain',
|
|
144
|
+
});
|
|
145
|
+
expect(parseMarkdown('```\nplain\n```')[0]).toEqual({
|
|
146
|
+
type: 'codeblock',
|
|
147
|
+
language: 'plaintext',
|
|
148
|
+
content: 'plain',
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('keeps source provenance canonical while projecting the released range', () => {
|
|
153
|
+
const source = '# Heading\n\nParagraph';
|
|
154
|
+
const ast = parseMarkdownAst(source, {sourceRanges: true});
|
|
155
|
+
const legacy = parseMarkdown(source, {sourceRanges: true});
|
|
156
|
+
|
|
157
|
+
expect(ast.children[0].position).toEqual({
|
|
158
|
+
start: {offset: 0},
|
|
159
|
+
end: {offset: 9},
|
|
160
|
+
});
|
|
161
|
+
expect(legacy[0]).toEqual({
|
|
162
|
+
type: 'heading',
|
|
163
|
+
level: 1,
|
|
164
|
+
children: [{type: 'text', content: 'Heading'}],
|
|
165
|
+
range: {start: 0, end: 9},
|
|
166
|
+
});
|
|
167
|
+
expect('position' in legacy[0]).toBe(false);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('authors canonical positions without the sourceRanges option', () => {
|
|
171
|
+
const source = '# Heading\n\nParagraph\n\n> Quoted';
|
|
172
|
+
const ast = parseMarkdownAst(source);
|
|
173
|
+
|
|
174
|
+
// Transforms observe provenance on every top-level block whether or not
|
|
175
|
+
// the caller opted into the released `range` projection.
|
|
176
|
+
expect(ast.children.map(block => block.position)).toEqual([
|
|
177
|
+
{start: {offset: 0}, end: {offset: 9}},
|
|
178
|
+
{start: {offset: 11}, end: {offset: 20}},
|
|
179
|
+
{start: {offset: 22}, end: {offset: 30}},
|
|
180
|
+
]);
|
|
181
|
+
expect(
|
|
182
|
+
parseMarkdownAst(source, {sourceRanges: true}).children.map(
|
|
183
|
+
block => block.position,
|
|
184
|
+
),
|
|
185
|
+
).toEqual(ast.children.map(block => block.position));
|
|
186
|
+
|
|
187
|
+
// Nested blocks remain a top-level-only contract.
|
|
188
|
+
const quote = ast.children[2];
|
|
189
|
+
if (quote.type !== 'blockquote') {
|
|
190
|
+
throw new Error('Expected blockquote');
|
|
191
|
+
}
|
|
192
|
+
expect(quote.children[0].position).toBeUndefined();
|
|
193
|
+
|
|
194
|
+
// The released projection is unchanged: no `range` unless asked for.
|
|
195
|
+
expect(parseMarkdown(source)).toEqual([
|
|
196
|
+
{
|
|
197
|
+
type: 'heading',
|
|
198
|
+
level: 1,
|
|
199
|
+
children: [{type: 'text', content: 'Heading'}],
|
|
200
|
+
},
|
|
201
|
+
{type: 'paragraph', children: [{type: 'text', content: 'Paragraph'}]},
|
|
202
|
+
{
|
|
203
|
+
type: 'blockquote',
|
|
204
|
+
children: [
|
|
205
|
+
{type: 'paragraph', children: [{type: 'text', content: 'Quoted'}]},
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
]);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('keeps canonical positions off released extension nodes', () => {
|
|
212
|
+
const source = ':::note\nBody\n:::\n\nTail prose.';
|
|
213
|
+
const plugins = [demoNotes];
|
|
214
|
+
|
|
215
|
+
// The projection rebuilds every built-in block field by field, but passes
|
|
216
|
+
// an extension node through — so it is the one kind that could carry a
|
|
217
|
+
// canonical position out. Without the option the released node is exactly
|
|
218
|
+
// what it has always been.
|
|
219
|
+
const released = parseMarkdown(source, {plugins});
|
|
220
|
+
expect(released[0]).toEqual({
|
|
221
|
+
type: 'extension',
|
|
222
|
+
plugin: 'demo-notes',
|
|
223
|
+
name: 'note',
|
|
224
|
+
display: 'block',
|
|
225
|
+
data: {body: 'Body'},
|
|
226
|
+
source: ':::note\nBody\n:::',
|
|
227
|
+
});
|
|
228
|
+
expect('position' in released[0]).toBe(false);
|
|
229
|
+
expect(Object.keys(released[0])).toEqual([
|
|
230
|
+
'type',
|
|
231
|
+
'plugin',
|
|
232
|
+
'name',
|
|
233
|
+
'display',
|
|
234
|
+
'data',
|
|
235
|
+
'source',
|
|
236
|
+
]);
|
|
237
|
+
|
|
238
|
+
// With the option the node keeps the exact provenance it has always
|
|
239
|
+
// exposed: `position` with offsets, and no `range`.
|
|
240
|
+
const withRanges = parseMarkdown(source, {sourceRanges: true, plugins});
|
|
241
|
+
expect(withRanges[0]).toEqual({
|
|
242
|
+
type: 'extension',
|
|
243
|
+
plugin: 'demo-notes',
|
|
244
|
+
name: 'note',
|
|
245
|
+
display: 'block',
|
|
246
|
+
data: {body: 'Body'},
|
|
247
|
+
source: ':::note\nBody\n:::',
|
|
248
|
+
position: {start: {offset: 0}, end: {offset: 16}},
|
|
249
|
+
});
|
|
250
|
+
expect('range' in withRanges[0]).toBe(false);
|
|
251
|
+
|
|
252
|
+
// The canonical tree carries provenance either way.
|
|
253
|
+
expect(parseMarkdownAst(source, {plugins}).children[0].position).toEqual({
|
|
254
|
+
start: {offset: 0},
|
|
255
|
+
end: {offset: 16},
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('preserves optional legacy keys and insertion order exactly', () => {
|
|
260
|
+
const [image, list] = parseMarkdown('\n\n- item');
|
|
261
|
+
|
|
262
|
+
expect(Object.keys(image)).toEqual(['type', 'alt', 'src']);
|
|
263
|
+
expect(Object.keys(list)).toEqual([
|
|
264
|
+
'type',
|
|
265
|
+
'ordered',
|
|
266
|
+
'start',
|
|
267
|
+
'delimiter',
|
|
268
|
+
'loose',
|
|
269
|
+
'items',
|
|
270
|
+
]);
|
|
271
|
+
if (list.type !== 'list') {
|
|
272
|
+
throw new Error('Expected list');
|
|
273
|
+
}
|
|
274
|
+
expect(Object.keys(list.items[0])).toEqual(['checked', 'children']);
|
|
275
|
+
expect(list).toStrictEqual({
|
|
276
|
+
type: 'list',
|
|
277
|
+
ordered: false,
|
|
278
|
+
start: undefined,
|
|
279
|
+
delimiter: undefined,
|
|
280
|
+
loose: undefined,
|
|
281
|
+
items: [
|
|
282
|
+
{
|
|
283
|
+
checked: undefined,
|
|
284
|
+
children: [
|
|
285
|
+
{
|
|
286
|
+
type: 'paragraph',
|
|
287
|
+
children: [{type: 'text', content: 'item'}],
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
},
|
|
291
|
+
],
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('does not expose canonical fields through released parser results', () => {
|
|
296
|
+
const state = createIncrementalState();
|
|
297
|
+
const blocks = parseMarkdown('# Heading\n\nParagraph');
|
|
298
|
+
|
|
299
|
+
expect(blocks[0]).toEqual({
|
|
300
|
+
type: 'heading',
|
|
301
|
+
level: 1,
|
|
302
|
+
children: [{type: 'text', content: 'Heading'}],
|
|
303
|
+
});
|
|
304
|
+
expect('depth' in blocks[0]).toBe(false);
|
|
305
|
+
expect(state.settledBlocks).toEqual([]);
|
|
306
|
+
});
|
|
307
|
+
});
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file ast.ts
|
|
5
|
+
* @input Parsed Markdown structure and optional Astryx extension nodes
|
|
6
|
+
* @output Canonical immutable MDAST-aligned Markdown node types and text projection
|
|
7
|
+
* @position Public canonical Markdown tree shared by parsing, transforms, rendering, and Outline
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type MarkdownAstDataValue =
|
|
11
|
+
| null
|
|
12
|
+
| boolean
|
|
13
|
+
| number
|
|
14
|
+
| string
|
|
15
|
+
| ReadonlyArray<MarkdownAstDataValue>
|
|
16
|
+
| {readonly [key: string]: MarkdownAstDataValue};
|
|
17
|
+
|
|
18
|
+
export interface MarkdownAstPoint {
|
|
19
|
+
readonly line?: number;
|
|
20
|
+
readonly column?: number;
|
|
21
|
+
readonly offset?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface MarkdownAstPosition {
|
|
25
|
+
readonly start: MarkdownAstPoint;
|
|
26
|
+
readonly end: MarkdownAstPoint;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface MarkdownAstNodeBase {
|
|
30
|
+
readonly position?: MarkdownAstPosition;
|
|
31
|
+
readonly data?: MarkdownAstDataValue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface MarkdownAstExtensionNode<
|
|
35
|
+
Plugin extends string = string,
|
|
36
|
+
Name extends string = string,
|
|
37
|
+
Data extends MarkdownAstDataValue = MarkdownAstDataValue,
|
|
38
|
+
Display extends 'inline' | 'block' = 'inline' | 'block',
|
|
39
|
+
> extends MarkdownAstNodeBase {
|
|
40
|
+
readonly type: 'extension';
|
|
41
|
+
readonly plugin: Plugin;
|
|
42
|
+
readonly name: Name;
|
|
43
|
+
readonly data: Data;
|
|
44
|
+
readonly display: Display;
|
|
45
|
+
readonly source?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface MarkdownAstText extends MarkdownAstNodeBase {
|
|
49
|
+
readonly type: 'text';
|
|
50
|
+
readonly value: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface MarkdownAstParent<
|
|
54
|
+
Type extends 'strong' | 'emphasis' | 'delete',
|
|
55
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
56
|
+
> extends MarkdownAstNodeBase {
|
|
57
|
+
readonly type: Type;
|
|
58
|
+
readonly children: ReadonlyArray<MarkdownAstPhrasingContent<Extension>>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface MarkdownAstInlineCode extends MarkdownAstNodeBase {
|
|
62
|
+
readonly type: 'inlineCode';
|
|
63
|
+
readonly value: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface MarkdownAstInlineMath extends MarkdownAstNodeBase {
|
|
67
|
+
readonly type: 'inlineMath';
|
|
68
|
+
readonly value: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface MarkdownAstLink<
|
|
72
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
73
|
+
> extends MarkdownAstNodeBase {
|
|
74
|
+
readonly type: 'link';
|
|
75
|
+
readonly url: string;
|
|
76
|
+
readonly children: ReadonlyArray<MarkdownAstPhrasingContent<Extension>>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface MarkdownAstImage extends MarkdownAstNodeBase {
|
|
80
|
+
readonly type: 'image';
|
|
81
|
+
readonly url: string;
|
|
82
|
+
readonly alt: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface MarkdownAstCitation extends MarkdownAstNodeBase {
|
|
86
|
+
readonly type: 'citation';
|
|
87
|
+
readonly sourceId: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface MarkdownAstBreak extends MarkdownAstNodeBase {
|
|
91
|
+
readonly type: 'break';
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type MarkdownAstPhrasingContent<
|
|
95
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
96
|
+
> =
|
|
97
|
+
| MarkdownAstText
|
|
98
|
+
| MarkdownAstParent<'strong', Extension>
|
|
99
|
+
| MarkdownAstParent<'emphasis', Extension>
|
|
100
|
+
| MarkdownAstParent<'delete', Extension>
|
|
101
|
+
| MarkdownAstInlineCode
|
|
102
|
+
| MarkdownAstInlineMath
|
|
103
|
+
| MarkdownAstLink<Extension>
|
|
104
|
+
| MarkdownAstImage
|
|
105
|
+
| MarkdownAstCitation
|
|
106
|
+
| MarkdownAstBreak
|
|
107
|
+
| (Extension & {readonly display: 'inline'});
|
|
108
|
+
|
|
109
|
+
export interface MarkdownAstHeading<
|
|
110
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
111
|
+
> extends MarkdownAstNodeBase {
|
|
112
|
+
readonly type: 'heading';
|
|
113
|
+
readonly depth: 1 | 2 | 3 | 4 | 5 | 6;
|
|
114
|
+
readonly children: ReadonlyArray<MarkdownAstPhrasingContent<Extension>>;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface MarkdownAstParagraph<
|
|
118
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
119
|
+
> extends MarkdownAstNodeBase {
|
|
120
|
+
readonly type: 'paragraph';
|
|
121
|
+
readonly children: ReadonlyArray<MarkdownAstPhrasingContent<Extension>>;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const markdownAstLegacyCodeLanguage = Symbol('MarkdownAstLegacyCodeLanguage');
|
|
125
|
+
|
|
126
|
+
export interface MarkdownAstCode extends MarkdownAstNodeBase {
|
|
127
|
+
readonly type: 'code';
|
|
128
|
+
readonly lang: string | null;
|
|
129
|
+
readonly meta?: string;
|
|
130
|
+
readonly value: string;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
type MarkdownAstCodeWithLegacyLanguage = MarkdownAstCode & {
|
|
134
|
+
readonly [markdownAstLegacyCodeLanguage]?: string | null;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/** @internal Preserves the released parser/renderer language projection. */
|
|
138
|
+
export function markMarkdownAstLegacyCodeLanguage<Node extends MarkdownAstCode>(
|
|
139
|
+
node: Node,
|
|
140
|
+
language: string | null,
|
|
141
|
+
): Node {
|
|
142
|
+
if (language === node.lang) {
|
|
143
|
+
return node;
|
|
144
|
+
}
|
|
145
|
+
Object.defineProperty(node, markdownAstLegacyCodeLanguage, {
|
|
146
|
+
configurable: false,
|
|
147
|
+
enumerable: true,
|
|
148
|
+
value: language,
|
|
149
|
+
writable: false,
|
|
150
|
+
});
|
|
151
|
+
return node;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** @internal Reads the released language projection for a canonical code node. */
|
|
155
|
+
export function getMarkdownAstLegacyCodeLanguage(
|
|
156
|
+
node: MarkdownAstCode,
|
|
157
|
+
): string | null {
|
|
158
|
+
const legacyLanguage = (node as MarkdownAstCodeWithLegacyLanguage)[
|
|
159
|
+
markdownAstLegacyCodeLanguage
|
|
160
|
+
];
|
|
161
|
+
return legacyLanguage === undefined ? node.lang : legacyLanguage;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface MarkdownAstMath extends MarkdownAstNodeBase {
|
|
165
|
+
readonly type: 'math';
|
|
166
|
+
readonly value: string;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface MarkdownAstBlockquote<
|
|
170
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
171
|
+
> extends MarkdownAstNodeBase {
|
|
172
|
+
readonly type: 'blockquote';
|
|
173
|
+
readonly children: ReadonlyArray<MarkdownAstBlockContent<Extension>>;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface MarkdownAstListItem<
|
|
177
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
178
|
+
> extends MarkdownAstNodeBase {
|
|
179
|
+
readonly type: 'listItem';
|
|
180
|
+
readonly checked?: boolean;
|
|
181
|
+
readonly children: ReadonlyArray<MarkdownAstBlockContent<Extension>>;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export interface MarkdownAstList<
|
|
185
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
186
|
+
> extends MarkdownAstNodeBase {
|
|
187
|
+
readonly type: 'list';
|
|
188
|
+
readonly ordered: boolean;
|
|
189
|
+
readonly start?: number;
|
|
190
|
+
readonly spread?: boolean;
|
|
191
|
+
/** Astryx-preserved ordered-list marker delimiter. */
|
|
192
|
+
readonly delimiter?: '.' | ')';
|
|
193
|
+
readonly children: ReadonlyArray<MarkdownAstListItem<Extension>>;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export type MarkdownAstTableAlignment = 'left' | 'center' | 'right' | null;
|
|
197
|
+
|
|
198
|
+
export interface MarkdownAstTableCell<
|
|
199
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
200
|
+
> extends MarkdownAstNodeBase {
|
|
201
|
+
readonly type: 'tableCell';
|
|
202
|
+
readonly children: ReadonlyArray<MarkdownAstPhrasingContent<Extension>>;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface MarkdownAstTableRow<
|
|
206
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
207
|
+
> extends MarkdownAstNodeBase {
|
|
208
|
+
readonly type: 'tableRow';
|
|
209
|
+
readonly children: ReadonlyArray<MarkdownAstTableCell<Extension>>;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface MarkdownAstTable<
|
|
213
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
214
|
+
> extends MarkdownAstNodeBase {
|
|
215
|
+
readonly type: 'table';
|
|
216
|
+
readonly align: ReadonlyArray<MarkdownAstTableAlignment>;
|
|
217
|
+
readonly children: ReadonlyArray<MarkdownAstTableRow<Extension>>;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface MarkdownAstThematicBreak extends MarkdownAstNodeBase {
|
|
221
|
+
readonly type: 'thematicBreak';
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export type MarkdownAstBlockContent<
|
|
225
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
226
|
+
> =
|
|
227
|
+
| MarkdownAstHeading<Extension>
|
|
228
|
+
| MarkdownAstParagraph<Extension>
|
|
229
|
+
| MarkdownAstCode
|
|
230
|
+
| MarkdownAstMath
|
|
231
|
+
| MarkdownAstBlockquote<Extension>
|
|
232
|
+
| MarkdownAstList<Extension>
|
|
233
|
+
| MarkdownAstTable<Extension>
|
|
234
|
+
| MarkdownAstThematicBreak
|
|
235
|
+
| MarkdownAstImage
|
|
236
|
+
| (Extension & {readonly display: 'block'});
|
|
237
|
+
|
|
238
|
+
export interface MarkdownAstRoot<
|
|
239
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
240
|
+
> extends MarkdownAstNodeBase {
|
|
241
|
+
readonly type: 'root';
|
|
242
|
+
readonly children: ReadonlyArray<MarkdownAstBlockContent<Extension>>;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export interface MarkdownAstNodeMap<
|
|
246
|
+
Extension extends MarkdownAstExtensionNode = MarkdownAstExtensionNode,
|
|
247
|
+
> {
|
|
248
|
+
readonly root: MarkdownAstRoot<Extension>;
|
|
249
|
+
readonly text: MarkdownAstText;
|
|
250
|
+
readonly strong: MarkdownAstParent<'strong', Extension>;
|
|
251
|
+
readonly emphasis: MarkdownAstParent<'emphasis', Extension>;
|
|
252
|
+
readonly delete: MarkdownAstParent<'delete', Extension>;
|
|
253
|
+
readonly inlineCode: MarkdownAstInlineCode;
|
|
254
|
+
readonly inlineMath: MarkdownAstInlineMath;
|
|
255
|
+
readonly break: MarkdownAstBreak;
|
|
256
|
+
readonly link: MarkdownAstLink<Extension>;
|
|
257
|
+
readonly image: MarkdownAstImage;
|
|
258
|
+
readonly citation: MarkdownAstCitation;
|
|
259
|
+
readonly heading: MarkdownAstHeading<Extension>;
|
|
260
|
+
readonly paragraph: MarkdownAstParagraph<Extension>;
|
|
261
|
+
readonly code: MarkdownAstCode;
|
|
262
|
+
readonly math: MarkdownAstMath;
|
|
263
|
+
readonly blockquote: MarkdownAstBlockquote<Extension>;
|
|
264
|
+
readonly list: MarkdownAstList<Extension>;
|
|
265
|
+
readonly listItem: MarkdownAstListItem<Extension>;
|
|
266
|
+
readonly table: MarkdownAstTable<Extension>;
|
|
267
|
+
readonly tableRow: MarkdownAstTableRow<Extension>;
|
|
268
|
+
readonly tableCell: MarkdownAstTableCell<Extension>;
|
|
269
|
+
readonly thematicBreak: MarkdownAstThematicBreak;
|
|
270
|
+
readonly extension: Extension;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export type MarkdownAstNode<
|
|
274
|
+
Extension extends MarkdownAstExtensionNode = MarkdownAstExtensionNode,
|
|
275
|
+
Type extends keyof MarkdownAstNodeMap<Extension> =
|
|
276
|
+
keyof MarkdownAstNodeMap<Extension>,
|
|
277
|
+
> = MarkdownAstNodeMap<Extension>[Type];
|
|
278
|
+
|
|
279
|
+
export function visitMarkdownNodes<
|
|
280
|
+
Extension extends MarkdownAstExtensionNode,
|
|
281
|
+
Type extends keyof MarkdownAstNodeMap<Extension>,
|
|
282
|
+
>(
|
|
283
|
+
root: MarkdownAstRoot<Extension>,
|
|
284
|
+
type: Type,
|
|
285
|
+
visitor: (node: MarkdownAstNodeMap<Extension>[Type]) => void,
|
|
286
|
+
): void {
|
|
287
|
+
const visit = (node: MarkdownAstNode<Extension>): void => {
|
|
288
|
+
if (node.type === type) {
|
|
289
|
+
visitor(node as MarkdownAstNodeMap<Extension>[Type]);
|
|
290
|
+
}
|
|
291
|
+
if ('children' in node) {
|
|
292
|
+
for (const child of node.children) {
|
|
293
|
+
visit(child);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
visit(root);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function markdownAstText<
|
|
301
|
+
Extension extends MarkdownAstExtensionNode = never,
|
|
302
|
+
>(
|
|
303
|
+
nodes: ReadonlyArray<MarkdownAstPhrasingContent<Extension>>,
|
|
304
|
+
extensionText: (
|
|
305
|
+
node: Extension & {readonly display: 'inline'},
|
|
306
|
+
) => string = node => node.source ?? '',
|
|
307
|
+
): string {
|
|
308
|
+
let text = '';
|
|
309
|
+
for (const node of nodes) {
|
|
310
|
+
switch (node.type) {
|
|
311
|
+
case 'text':
|
|
312
|
+
case 'inlineCode':
|
|
313
|
+
case 'inlineMath':
|
|
314
|
+
text += node.value;
|
|
315
|
+
break;
|
|
316
|
+
case 'strong':
|
|
317
|
+
case 'emphasis':
|
|
318
|
+
case 'delete':
|
|
319
|
+
case 'link':
|
|
320
|
+
text += markdownAstText(node.children, extensionText);
|
|
321
|
+
break;
|
|
322
|
+
case 'image':
|
|
323
|
+
text += node.alt;
|
|
324
|
+
break;
|
|
325
|
+
case 'citation':
|
|
326
|
+
case 'break':
|
|
327
|
+
break;
|
|
328
|
+
case 'extension':
|
|
329
|
+
text += extensionText(node);
|
|
330
|
+
break;
|
|
331
|
+
default: {
|
|
332
|
+
node satisfies never;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return text;
|
|
337
|
+
}
|
|
@@ -47,6 +47,18 @@ describe('parseMarkdownIncremental', () => {
|
|
|
47
47
|
}
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
+
it('keeps projected settled-list identity when a following block settles too', () => {
|
|
51
|
+
const state = createIncrementalState();
|
|
52
|
+
parseMarkdownIncremental('1. a\n\nTail', state);
|
|
53
|
+
const result = parseMarkdownIncremental(
|
|
54
|
+
'1. a\n\n1. b\n\nAfter\n\nTail',
|
|
55
|
+
state,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
expect(state.settledBlocks).toEqual(parseMarkdown(state.settledText));
|
|
59
|
+
expect(result[0]).toBe(state.settledBlocks[0]);
|
|
60
|
+
});
|
|
61
|
+
|
|
50
62
|
it('joins loose ) ordered list across streamed chunks', () => {
|
|
51
63
|
const text = '1) apple\n\n1) banana\n\n1) cherry\n';
|
|
52
64
|
const {final} = simulateStreaming(text, 5);
|