@astryxdesign/core 0.1.3 → 0.1.4-canary.01e5b29
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 +51 -0
- package/dist/AlertDialog/AlertDialog.d.ts +1 -1
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +20 -18
- package/dist/AlertDialog/useImperativeAlertDialog.js +3 -3
- package/dist/AppShell/AppShell.d.ts +1 -1
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +55 -53
- package/dist/AspectRatio/AspectRatio.js +5 -5
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +27 -25
- package/dist/Avatar/AvatarStatusDot.js +5 -5
- package/dist/AvatarGroup/AvatarGroup.js +5 -5
- package/dist/AvatarGroup/AvatarGroupOverflow.js +5 -5
- package/dist/Badge/Badge.js +3 -3
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +32 -25
- package/dist/Blockquote/Blockquote.js +7 -7
- package/dist/Breadcrumbs/BreadcrumbItem.js +17 -17
- package/dist/Breadcrumbs/Breadcrumbs.js +7 -7
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +47 -26
- package/dist/ButtonGroup/ButtonGroup.js +7 -7
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +108 -64
- package/dist/Calendar/dayCellUtils.d.ts +67 -5
- package/dist/Calendar/dayCellUtils.d.ts.map +1 -1
- package/dist/Calendar/dayCellUtils.js +139 -18
- package/dist/Calendar/styles.d.ts +2 -2
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +2 -2
- package/dist/Card/Card.d.ts +4 -2
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +18 -10
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +20 -19
- package/dist/Center/Center.js +3 -3
- package/dist/Chat/ChatComposer.js +23 -23
- package/dist/Chat/ChatComposerDrawer.js +14 -14
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +27 -15
- package/dist/Chat/ChatDictationButton.d.ts +1 -1
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +13 -11
- package/dist/Chat/ChatLayout.js +17 -17
- package/dist/Chat/ChatLayoutScrollButton.d.ts +1 -1
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +12 -10
- package/dist/Chat/ChatMessage.js +12 -12
- package/dist/Chat/ChatMessageBubble.js +7 -7
- package/dist/Chat/ChatMessageList.js +14 -14
- package/dist/Chat/ChatMessageMetadata.d.ts +1 -1
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatMessageMetadata.js +14 -12
- package/dist/Chat/ChatPastedTextToken.js +13 -13
- package/dist/Chat/ChatSendButton.js +3 -3
- package/dist/Chat/ChatSystemMessage.d.ts +1 -1
- package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
- package/dist/Chat/ChatSystemMessage.js +17 -17
- package/dist/Chat/ChatTokenizedText.d.ts +1 -1
- package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
- package/dist/Chat/ChatTokenizedText.js +24 -15
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +81 -74
- package/dist/Chat/index.d.ts +1 -1
- package/dist/Chat/index.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +15 -15
- package/dist/CheckboxInput/CheckboxInput.d.ts +6 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +32 -24
- package/dist/CheckboxList/CheckboxList.js +9 -9
- package/dist/CheckboxList/CheckboxListItem.d.ts +1 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +8 -6
- package/dist/Citation/Citation.js +10 -10
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +32 -9
- package/dist/Code/Code.d.ts +15 -1
- package/dist/Code/Code.d.ts.map +1 -1
- package/dist/Code/Code.js +35 -5
- package/dist/Code/index.d.ts +1 -1
- package/dist/Code/index.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.d.ts +10 -1
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +88 -52
- package/dist/CodeBlock/index.d.ts +1 -1
- package/dist/CodeBlock/index.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.d.ts +9 -3
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +110 -22
- package/dist/Collapsible/CollapsibleGroup.d.ts +39 -7
- package/dist/Collapsible/CollapsibleGroup.d.ts.map +1 -1
- package/dist/Collapsible/CollapsibleGroup.js +73 -12
- package/dist/Collapsible/CollapsibleGroupContext.d.ts +31 -0
- package/dist/Collapsible/CollapsibleGroupContext.d.ts.map +1 -1
- package/dist/Collapsible/CollapsibleGroupContext.js +33 -3
- package/dist/Collapsible/index.d.ts +1 -0
- package/dist/Collapsible/index.d.ts.map +1 -1
- package/dist/Collapsible/useCollapsible.d.ts +4 -1
- package/dist/Collapsible/useCollapsible.d.ts.map +1 -1
- package/dist/Collapsible/useCollapsible.js +20 -6
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +36 -34
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.js +27 -7
- package/dist/CommandPalette/CommandPaletteFooter.js +16 -16
- package/dist/CommandPalette/CommandPaletteGroup.js +5 -5
- package/dist/CommandPalette/CommandPaletteInput.js +13 -13
- package/dist/CommandPalette/CommandPaletteItem.js +3 -3
- package/dist/CommandPalette/CommandPaletteList.js +3 -3
- package/dist/ContextMenu/ContextMenu.d.ts +9 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +16 -11
- package/dist/DateInput/DateInput.js +18 -18
- package/dist/DateRangeInput/DateRangeInput.js +23 -23
- package/dist/DateTimeInput/DateTimeInput.d.ts +5 -7
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +30 -26
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +9 -9
- package/dist/Dialog/DialogHeader.js +16 -16
- package/dist/Dialog/useImperativeDialog.js +3 -3
- package/dist/Divider/Divider.d.ts +0 -22
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Divider/Divider.js +7 -7
- package/dist/DropdownMenu/DropdownMenu.js +10 -10
- package/dist/DropdownMenu/DropdownMenuItem.d.ts +2 -17
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
- package/dist/DropdownMenu/renderDropdownItems.js +10 -10
- package/dist/EmptyState/EmptyState.js +9 -9
- package/dist/Field/Field.js +17 -17
- package/dist/Field/FieldLabel.js +15 -15
- package/dist/Field/InputClearButton.js +5 -5
- package/dist/FieldStatus/FieldStatus.js +3 -3
- package/dist/FileInput/FileInput.js +29 -29
- package/dist/FormLayout/FormLayout.js +5 -5
- package/dist/Grid/Grid.d.ts +4 -3
- package/dist/Grid/Grid.d.ts.map +1 -1
- package/dist/Grid/Grid.js +29 -12
- package/dist/Grid/GridSpan.js +3 -3
- package/dist/HStack/HStack.js +3 -3
- package/dist/Heading/Heading.js +10 -10
- package/dist/HoverCard/HoverCard.js +9 -9
- package/dist/HoverCard/useHoverCard.js +3 -3
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +16 -12
- package/dist/Icon/defaultIcons.js +116 -116
- package/dist/IconButton/IconButton.js +3 -3
- package/dist/InputGroup/InputGroup.js +11 -11
- package/dist/InputGroup/InputGroupText.js +3 -3
- package/dist/Item/Item.js +18 -18
- package/dist/Kbd/Kbd.js +5 -5
- package/dist/Layer/LayerProvider.js +7 -7
- package/dist/Layer/useLayer.js +5 -5
- package/dist/Layout/Layout.js +21 -21
- package/dist/Layout/LayoutContent.js +3 -3
- package/dist/Layout/LayoutFooter.js +5 -5
- package/dist/Layout/LayoutHeader.js +5 -5
- package/dist/Layout/LayoutPanel.js +3 -3
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +55 -31
- package/dist/Lightbox/useLightbox.js +3 -3
- package/dist/Link/Link.js +15 -15
- package/dist/Link/LinkProvider.js +3 -3
- package/dist/Link/useLinkify.js +3 -3
- package/dist/List/List.js +11 -11
- package/dist/List/ListItem.js +11 -11
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +102 -102
- package/dist/Markdown/parser.d.ts +7 -0
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +300 -6
- package/dist/MetadataList/MetadataList.js +10 -10
- package/dist/MetadataList/MetadataListItem.js +15 -15
- package/dist/MobileNav/MobileNav.js +15 -15
- package/dist/MobileNav/MobileNavToggle.js +5 -5
- package/dist/MoreMenu/MoreMenu.js +3 -3
- package/dist/MultiSelector/MultiSelector.d.ts +7 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +64 -55
- package/dist/NavIcon/NavIcon.js +3 -3
- package/dist/NavMenu/NavHeadingMenu.js +5 -5
- package/dist/NavMenu/NavHeadingMenuItem.js +8 -8
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +48 -32
- package/dist/Outline/Outline.js +15 -15
- package/dist/OverflowList/OverflowList.js +8 -8
- package/dist/Overlay/Overlay.js +3 -3
- package/dist/Overlay/OverlayScrim.js +5 -5
- package/dist/Overlay/useOverlay.js +3 -3
- package/dist/Pagination/Pagination.d.ts +1 -1
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +125 -72
- package/dist/Popover/Popover.js +16 -16
- package/dist/Popover/usePopover.js +7 -7
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +110 -92
- package/dist/PowerSearch/PowerSearchEditPopover.js +84 -84
- package/dist/PowerSearch/PowerSearchFilterEditor.js +3 -3
- package/dist/PowerSearch/PowerSearchToken.js +5 -5
- package/dist/PowerSearch/PowerSearchValueEditor.js +54 -54
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +25 -18
- package/dist/RadioList/RadioList.d.ts +7 -1
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +10 -8
- package/dist/RadioList/RadioListItem.d.ts +1 -1
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +30 -22
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +28 -10
- package/dist/Section/Section.js +5 -5
- package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.js +32 -10
- package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +18 -12
- package/dist/SelectableCard/SelectableCard.js +5 -5
- package/dist/Selector/Selector.d.ts +6 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +54 -45
- package/dist/Selector/SelectorOption.js +3 -3
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +38 -34
- package/dist/SideNav/SideNavCollapseButton.d.ts +1 -1
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavCollapseButton.js +8 -6
- package/dist/SideNav/SideNavHeading.js +87 -87
- package/dist/SideNav/SideNavItem.js +42 -42
- package/dist/SideNav/SideNavSection.d.ts +1 -1
- package/dist/SideNav/SideNavSection.d.ts.map +1 -1
- package/dist/SideNav/SideNavSection.js +18 -16
- package/dist/Skeleton/Skeleton.js +3 -3
- package/dist/Slider/Slider.d.ts +6 -0
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +31 -22
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +10 -10
- package/dist/StatusDot/StatusDot.js +5 -5
- package/dist/Switch/Switch.d.ts +13 -4
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +41 -30
- package/dist/TabList/Tab.js +18 -18
- package/dist/TabList/TabList.js +5 -5
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +57 -30
- package/dist/TabList/tab.markers.stylex.d.ts +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +51 -39
- package/dist/Table/Table.js +7 -7
- package/dist/Table/TableBody.d.ts +1 -1
- package/dist/Table/TableBody.d.ts.map +1 -1
- package/dist/Table/TableBody.js +9 -5
- package/dist/Table/TableCell.d.ts.map +1 -1
- package/dist/Table/TableCell.js +76 -7
- package/dist/Table/TableFooter.d.ts +1 -1
- package/dist/Table/TableFooter.d.ts.map +1 -1
- package/dist/Table/TableFooter.js +9 -5
- package/dist/Table/TableHeader.d.ts +1 -1
- package/dist/Table/TableHeader.d.ts.map +1 -1
- package/dist/Table/TableHeader.js +9 -5
- package/dist/Table/TableHeaderCell.js +3 -3
- package/dist/Table/TableRow.js +5 -5
- package/dist/Table/index.d.ts +2 -0
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +1 -0
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +14 -11
- package/dist/Table/plugins/filtering/useTableFiltering.js +71 -71
- package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/paginateData.js +5 -1
- package/dist/Table/plugins/pagination/useTablePagination.js +7 -7
- package/dist/Table/plugins/rowExpansion/index.d.ts +3 -0
- package/dist/Table/plugins/rowExpansion/index.d.ts.map +1 -0
- package/dist/Table/plugins/rowExpansion/index.js +3 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +90 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +398 -0
- package/dist/Table/plugins/selection/useTableSelection.js +18 -18
- package/dist/Table/plugins/selection/useTableSelectionState.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelectionState.js +11 -1
- package/dist/Table/plugins/sortable/useTableSortable.js +17 -17
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.js +8 -4
- package/dist/Table/tableContextMenu.d.ts +5 -1
- package/dist/Table/tableContextMenu.d.ts.map +1 -1
- package/dist/Table/tableContextMenu.js +19 -12
- package/dist/Text/Text.d.ts +1 -1
- package/dist/Text/Text.d.ts.map +1 -1
- package/dist/Text/Text.js +14 -13
- package/dist/Text/text.stylex.d.ts +35 -0
- package/dist/Text/text.stylex.d.ts.map +1 -1
- package/dist/Text/text.stylex.js +52 -1
- package/dist/TextArea/TextArea.js +14 -14
- package/dist/TextInput/TextInput.js +15 -15
- package/dist/Thumbnail/Thumbnail.d.ts +3 -2
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +30 -29
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +26 -21
- package/dist/Timestamp/Timestamp.d.ts +1 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +37 -26
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +25 -17
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +23 -11
- package/dist/Toast/useToast.js +4 -4
- package/dist/ToggleButton/ToggleButton.js +12 -12
- package/dist/ToggleButton/ToggleButtonGroup.js +5 -5
- package/dist/Token/Token.js +21 -21
- package/dist/Tokenizer/Tokenizer.d.ts +6 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +38 -29
- package/dist/Toolbar/Toolbar.js +18 -18
- package/dist/Tooltip/Tooltip.js +11 -11
- package/dist/Tooltip/useTooltip.js +3 -3
- package/dist/TopNav/TopNav.js +32 -32
- package/dist/TopNav/TopNavHeading.js +67 -67
- package/dist/TopNav/TopNavItem.js +5 -5
- package/dist/TopNav/TopNavMegaMenu.js +30 -30
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +25 -14
- package/dist/TopNav/TopNavMegaMenuItem.js +16 -16
- package/dist/TopNav/TopNavMenu.js +32 -32
- package/dist/TreeList/TreeList.js +8 -8
- package/dist/TreeList/TreeListBranches.js +11 -11
- package/dist/TreeList/TreeListItem.js +30 -30
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +23 -20
- package/dist/Typeahead/Typeahead.js +12 -12
- package/dist/Typeahead/TypeaheadItem.js +10 -10
- package/dist/VStack/VStack.js +3 -3
- package/dist/astryx.css +23 -0
- package/dist/astryx.umd.js +60 -58
- package/dist/astryx.umd.js.map +4 -4
- package/dist/docs-types.d.ts +13 -1
- package/dist/docs-types.d.ts.map +1 -1
- package/dist/hooks/focusableSelector.d.ts +1 -1
- package/dist/hooks/focusableSelector.d.ts.map +1 -1
- package/dist/hooks/focusableSelector.js +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useFocusTrap.d.ts +3 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +38 -1
- package/dist/hooks/useHotkeys.d.ts +51 -0
- package/dist/hooks/useHotkeys.d.ts.map +1 -0
- package/dist/hooks/useHotkeys.js +160 -0
- package/dist/hooks/useInteractiveRole.d.ts +6 -2
- package/dist/hooks/useInteractiveRole.d.ts.map +1 -1
- package/dist/hooks/useInteractiveRole.js +6 -2
- package/dist/hooks/useKeyboardHint.js +9 -9
- package/dist/hooks/useStreamingText.d.ts +3 -1
- package/dist/hooks/useStreamingText.d.ts.map +1 -1
- package/dist/hooks/useStreamingText.js +14 -5
- package/dist/theme/MediaTheme.js +3 -3
- package/dist/theme/Theme.js +7 -7
- package/dist/theme/defineTheme.d.ts +1 -1
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/expandColorScale.d.ts.map +1 -1
- package/dist/theme/expandColorScale.js +10 -3
- package/dist/theme/hct.d.ts +0 -15
- package/dist/theme/hct.d.ts.map +1 -1
- package/dist/theme/hct.js +9 -9
- package/dist/theme/syntax/SyntaxTheme.js +5 -5
- package/dist/theme/tokens.d.ts +10 -2
- package/dist/theme/tokens.d.ts.map +1 -1
- package/dist/theme/tokens.js +220 -4
- package/dist/utils/color.d.ts +42 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/color.js +150 -0
- package/dist/utils/composeEventHandlers.d.ts +30 -0
- package/dist/utils/composeEventHandlers.d.ts.map +1 -0
- package/dist/utils/composeEventHandlers.js +40 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +8 -5
- package/package.json +3 -3
- package/src/AlertDialog/AlertDialog.tsx +2 -0
- package/src/AppShell/AppShell.tsx +2 -0
- package/src/AspectRatio/AspectRatio.doc.mjs +1 -1
- package/src/Avatar/Avatar.doc.mjs +13 -2
- package/src/Avatar/Avatar.test.tsx +32 -1
- package/src/Avatar/Avatar.tsx +12 -20
- package/src/Banner/Banner.doc.mjs +8 -0
- package/src/Banner/Banner.test.tsx +38 -0
- package/src/Banner/Banner.tsx +8 -1
- package/src/Button/Button.tsx +39 -6
- package/src/ButtonGroup/ButtonGroup.doc.mjs +1 -1
- package/src/Calendar/Calendar.doc.mjs +1 -1
- package/src/Calendar/Calendar.test.tsx +201 -17
- package/src/Calendar/Calendar.tsx +79 -26
- package/src/Calendar/dayCellUtils.test.ts +306 -1
- package/src/Calendar/dayCellUtils.ts +206 -13
- package/src/Calendar/styles.ts +12 -2
- package/src/Card/Card.doc.mjs +1 -1
- package/src/Card/Card.tsx +16 -6
- package/src/Carousel/Carousel.doc.mjs +12 -12
- package/src/Carousel/Carousel.test.tsx +13 -0
- package/src/Carousel/Carousel.tsx +1 -0
- package/src/Chat/Chat.doc.mjs +1 -1
- package/src/Chat/ChatComposerInput.test.tsx +24 -0
- package/src/Chat/ChatComposerInput.tsx +17 -1
- package/src/Chat/ChatDictationButton.test.tsx +43 -0
- package/src/Chat/ChatDictationButton.tsx +4 -4
- package/src/Chat/ChatLayoutScrollButton.test.tsx +33 -0
- package/src/Chat/ChatLayoutScrollButton.tsx +3 -1
- package/src/Chat/ChatMessageMetadata.test.tsx +32 -0
- package/src/Chat/ChatMessageMetadata.tsx +4 -6
- package/src/Chat/ChatSystemMessage.test.tsx +26 -11
- package/src/Chat/ChatSystemMessage.tsx +7 -7
- package/src/Chat/ChatTokenizedText.test.tsx +29 -16
- package/src/Chat/ChatTokenizedText.tsx +15 -8
- package/src/Chat/ChatToolCalls.test.tsx +55 -0
- package/src/Chat/ChatToolCalls.tsx +10 -12
- package/src/Chat/index.ts +1 -4
- package/src/Chat/useChatNewMessages.test.tsx +4 -4
- package/src/CheckboxInput/CheckboxInput.doc.mjs +12 -4
- package/src/CheckboxInput/CheckboxInput.test.tsx +103 -0
- package/src/CheckboxInput/CheckboxInput.tsx +13 -0
- package/src/CheckboxList/CheckboxList.doc.mjs +1 -1
- package/src/CheckboxList/CheckboxList.test.tsx +19 -0
- package/src/CheckboxList/CheckboxListItem.tsx +11 -2
- package/src/Citation/Citation.doc.mjs +5 -0
- package/src/ClickableCard/ClickableCard.tsx +45 -2
- package/src/Code/Code.test.tsx +54 -0
- package/src/Code/Code.tsx +48 -4
- package/src/Code/index.ts +1 -1
- package/src/CodeBlock/CodeBlock.doc.mjs +7 -2
- package/src/CodeBlock/CodeBlock.test.tsx +122 -3
- package/src/CodeBlock/CodeBlock.tsx +62 -4
- package/src/CodeBlock/index.ts +1 -1
- package/src/Collapsible/Collapsible.doc.mjs +8 -4
- package/src/Collapsible/Collapsible.test.tsx +405 -0
- package/src/Collapsible/Collapsible.tsx +86 -10
- package/src/Collapsible/CollapsibleGroup.doc.mjs +27 -3
- package/src/Collapsible/CollapsibleGroup.test.tsx +318 -0
- package/src/Collapsible/CollapsibleGroup.tsx +107 -9
- package/src/Collapsible/CollapsibleGroupContext.tsx +42 -2
- package/src/Collapsible/index.ts +4 -0
- package/src/Collapsible/useCollapsible.ts +20 -6
- package/src/CommandPalette/CommandPalette.tsx +5 -3
- package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +5 -0
- package/src/CommandPalette/CommandPaletteEmpty.tsx +15 -1
- package/src/CommandPalette/CommandPaletteGroup.doc.mjs +10 -0
- package/src/CommandPalette/CommandPaletteInput.doc.mjs +6 -0
- package/src/CommandPalette/CommandPaletteItem.doc.mjs +6 -0
- package/src/CommandPalette/CommandPaletteList.doc.mjs +9 -0
- package/src/ContextMenu/ContextMenu.doc.mjs +15 -0
- package/src/ContextMenu/ContextMenu.test.tsx +15 -0
- package/src/ContextMenu/ContextMenu.tsx +19 -1
- package/src/ContextMenu/ContextMenuItem.doc.mjs +6 -0
- package/src/DateInput/DateInput.doc.mjs +6 -1
- package/src/DateInput/DateInput.test.tsx +11 -20
- package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
- package/src/DateRangeInput/DateRangeInput.test.tsx +31 -44
- package/src/DateRangeInput/DateRangeInput.tsx +2 -2
- package/src/DateTimeInput/DateTimeInput.doc.mjs +4 -3
- package/src/DateTimeInput/DateTimeInput.test.tsx +118 -16
- package/src/DateTimeInput/DateTimeInput.tsx +9 -8
- package/src/DateTimeInput/index.ts +1 -0
- package/src/Dialog/DialogHeader.doc.mjs +45 -0
- package/src/Divider/Divider.tsx +1 -23
- package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -1
- package/src/DropdownMenu/DropdownMenu.test.tsx +5 -3
- package/src/DropdownMenu/DropdownMenuItem.tsx +5 -17
- package/src/EmptyState/EmptyState.doc.mjs +1 -1
- package/src/Field/Field.doc.mjs +1 -1
- package/src/Field/FieldLabel.test.tsx +2 -2
- package/src/FieldStatus/FieldStatus.test.tsx +282 -0
- package/src/FileInput/FileInput.doc.mjs +1 -1
- package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +0 -3
- package/src/Grid/Grid.doc.mjs +3 -3
- package/src/Grid/Grid.test.tsx +43 -18
- package/src/Grid/Grid.tsx +26 -9
- package/src/Icon/Icon.test.tsx +41 -29
- package/src/Icon/Icon.tsx +6 -2
- package/src/InputGroup/InputGroup.tsx +2 -2
- package/src/InteractiveRoleContext/InteractiveRoleContext.test.tsx +185 -0
- package/src/Item/Item.tsx +1 -1
- package/src/Layout/Layout.test.tsx +285 -0
- package/src/Layout/LayoutContent.doc.mjs +12 -0
- package/src/Layout/LayoutPanel.doc.mjs +40 -0
- package/src/Layout/LayoutSlots.test.tsx +364 -0
- package/src/Layout/__tests__/edgeCompensation.test.tsx +72 -0
- package/src/Lightbox/Lightbox.doc.mjs +5 -0
- package/src/Lightbox/Lightbox.test.tsx +123 -2
- package/src/Lightbox/Lightbox.tsx +29 -1
- package/src/Markdown/Markdown.test.tsx +23 -0
- package/src/Markdown/Markdown.tsx +9 -7
- package/src/Markdown/incremental.test.ts +36 -0
- package/src/Markdown/parser.perf.test.ts +34 -12
- package/src/Markdown/parser.test.ts +210 -0
- package/src/Markdown/parser.ts +301 -6
- package/src/MobileNav/MobileNav.doc.mjs +20 -0
- package/src/MultiSelector/MultiSelector.doc.mjs +14 -1
- package/src/MultiSelector/MultiSelector.test.tsx +33 -0
- package/src/MultiSelector/MultiSelector.tsx +20 -0
- package/src/NavMenu/NavMenu.doc.mjs +15 -0
- package/src/NumberInput/NumberInput.test.tsx +48 -3
- package/src/NumberInput/NumberInput.tsx +32 -15
- package/src/Outline/parseOutlineFromMarkdown.test.ts +80 -0
- package/src/OverflowList/OverflowList.test.tsx +416 -0
- package/src/Overlay/Overlay.doc.mjs +6 -0
- package/src/Overlay/Overlay.test.tsx +356 -0
- package/src/Pagination/Pagination.test.tsx +162 -0
- package/src/Pagination/Pagination.tsx +80 -26
- package/src/Popover/Popover.test.tsx +65 -0
- package/src/PowerSearch/PowerSearch.doc.mjs +4 -4
- package/src/PowerSearch/PowerSearch.test.tsx +109 -1
- package/src/PowerSearch/PowerSearch.tsx +37 -16
- package/src/ProgressBar/ProgressBar.test.tsx +30 -0
- package/src/ProgressBar/ProgressBar.tsx +12 -5
- package/src/RadioList/RadioList.doc.mjs +7 -1
- package/src/RadioList/RadioList.test.tsx +65 -0
- package/src/RadioList/RadioList.tsx +10 -1
- package/src/RadioList/RadioListItem.tsx +13 -4
- package/src/Resizable/ResizeHandle.test.tsx +218 -0
- package/src/Resizable/ResizeHandle.tsx +22 -4
- package/src/Section/Section.test.tsx +4 -10
- package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
- package/src/SegmentedControl/SegmentedControl.test.tsx +192 -0
- package/src/SegmentedControl/SegmentedControl.tsx +27 -5
- package/src/SegmentedControl/SegmentedControlItem.tsx +9 -4
- package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
- package/src/Selector/Selector.doc.mjs +12 -1
- package/src/Selector/Selector.test.tsx +30 -0
- package/src/Selector/Selector.tsx +18 -0
- package/src/SideNav/SideNav.doc.mjs +7 -1
- package/src/SideNav/SideNav.test.tsx +66 -0
- package/src/SideNav/SideNav.tsx +6 -2
- package/src/SideNav/SideNavCollapseButton.tsx +4 -3
- package/src/SideNav/SideNavSection.tsx +6 -4
- package/src/SizeContext/SizeContext.test.tsx +226 -0
- package/src/Slider/Slider.doc.mjs +14 -2
- package/src/Slider/Slider.test.tsx +30 -0
- package/src/Slider/Slider.tsx +20 -0
- package/src/Spinner/Spinner.tsx +1 -0
- package/src/Switch/Switch.doc.mjs +21 -9
- package/src/Switch/Switch.test.tsx +137 -0
- package/src/Switch/Switch.tsx +32 -7
- package/src/TabList/TabList.doc.mjs +3 -3
- package/src/TabList/TabList.test.tsx +185 -1
- package/src/TabList/TabMenu.tsx +45 -9
- package/src/Table/BaseTable.tsx +16 -3
- package/src/Table/Table.test.tsx +87 -0
- package/src/Table/TableBody.tsx +15 -2
- package/src/Table/TableCell.tsx +87 -8
- package/src/Table/TableFooter.tsx +15 -2
- package/src/Table/TableHeader.tsx +15 -2
- package/src/Table/index.ts +5 -0
- package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +13 -0
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +3 -1
- package/src/Table/plugins/pagination/paginateData.ts +5 -1
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +13 -0
- package/src/Table/plugins/rowExpansion/index.ts +7 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +155 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +590 -0
- package/src/Table/plugins/selection/useTableSelectionState.test.tsx +23 -0
- package/src/Table/plugins/selection/useTableSelectionState.tsx +11 -6
- package/src/Table/plugins/sortable/useTableSortableState.test.tsx +35 -1
- package/src/Table/plugins/sortable/useTableSortableState.tsx +8 -4
- package/src/Table/tableContextMenu.test.tsx +27 -3
- package/src/Table/tableContextMenu.tsx +20 -2
- package/src/Table/useTablePagination.doc.mjs +4 -1
- package/src/Table/useTableRowExpansion.doc.mjs +80 -0
- package/src/Table/useTableSortable.doc.mjs +4 -1
- package/src/Text/Text.doc.mjs +2 -2
- package/src/Text/Text.test.tsx +11 -0
- package/src/Text/Text.tsx +4 -2
- package/src/Text/text.stylex.ts +41 -0
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextArea/TextArea.test.tsx +3 -3
- package/src/TextInput/TextInput.doc.mjs +1 -1
- package/src/TextInput/TextInput.test.tsx +3 -3
- package/src/Thumbnail/Thumbnail.test.tsx +36 -2
- package/src/Thumbnail/Thumbnail.tsx +4 -2
- package/src/TimeInput/TimeInput.doc.mjs +11 -6
- package/src/TimeInput/TimeInput.test.tsx +37 -0
- package/src/TimeInput/TimeInput.tsx +11 -1
- package/src/Timestamp/Timestamp.doc.mjs +1 -1
- package/src/Timestamp/Timestamp.test.tsx +52 -0
- package/src/Timestamp/Timestamp.tsx +30 -16
- package/src/Toast/Toast.tsx +11 -3
- package/src/Toast/ToastViewport.test.tsx +64 -0
- package/src/Toast/ToastViewport.tsx +12 -0
- package/src/ToggleButton/ToggleButton.doc.mjs +1 -0
- package/src/Tokenizer/Tokenizer.doc.mjs +16 -4
- package/src/Tokenizer/Tokenizer.test.tsx +33 -0
- package/src/Tokenizer/Tokenizer.tsx +19 -0
- package/src/Toolbar/Toolbar.test.tsx +1 -1
- package/src/TopNav/TopNav.doc.mjs +1 -1
- package/src/TopNav/TopNav.test.tsx +18 -0
- package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +9 -2
- package/src/TreeList/TreeList.doc.mjs +2 -2
- package/src/Typeahead/BaseTypeahead.doc.mjs +19 -0
- package/src/Typeahead/BaseTypeahead.tsx +5 -2
- package/src/Typeahead/Typeahead.doc.mjs +7 -2
- package/src/Typeahead/Typeahead.test.tsx +45 -1
- package/src/__tests__/TestIcon.tsx +26 -0
- package/src/__tests__/fastRoleQueries.ts +66 -0
- package/src/docPropReferences.test.ts +178 -0
- package/src/docs-types.ts +14 -0
- package/src/hooks/focusableSelector.ts +1 -1
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useFocusTrap.doc.mjs +4 -2
- package/src/hooks/useFocusTrap.test.tsx +149 -1
- package/src/hooks/useFocusTrap.ts +50 -1
- package/src/hooks/useHotkeys.doc.mjs +52 -0
- package/src/hooks/useHotkeys.test.ts +245 -0
- package/src/hooks/useHotkeys.ts +203 -0
- package/src/hooks/useInteractiveRole.ts +12 -4
- package/src/hooks/useKeyboardHint.doc.mjs +6 -6
- package/src/hooks/useStreamingText.test.ts +54 -19
- package/src/hooks/useStreamingText.ts +16 -5
- package/src/theme/SyntaxTheme.doc.mjs +4 -4
- package/src/theme/defineTheme.ts +4 -13
- package/src/theme/derivedVarRegistry.test.ts +2 -2
- package/src/theme/expandColorScale.test.ts +29 -0
- package/src/theme/expandColorScale.ts +11 -6
- package/src/theme/hct.ts +9 -17
- package/src/theme/tokens.test.ts +182 -9
- package/src/theme/tokens.ts +239 -4
- package/src/theme/useTheme.test.tsx +20 -0
- package/src/utils/color.test.ts +133 -0
- package/src/utils/color.ts +148 -0
- package/src/utils/composeEventHandlers.test.ts +71 -0
- package/src/utils/composeEventHandlers.ts +44 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/mergeProps.test.ts +166 -0
- package/src/utils/sharedResizeObserver.test.ts +2 -2
- package/src/utils/timeParser.test.ts +13 -0
- package/src/utils/timeParser.ts +8 -5
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
4
|
-
import {render, screen, fireEvent} from '@testing-library/react';
|
|
3
|
+
import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
4
|
+
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
5
5
|
import {Lightbox} from './Lightbox';
|
|
6
|
+
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
6
7
|
|
|
7
8
|
// Mock showModal/close for jsdom
|
|
8
9
|
beforeEach(() => {
|
|
@@ -16,6 +17,16 @@ beforeEach(() => {
|
|
|
16
17
|
});
|
|
17
18
|
});
|
|
18
19
|
|
|
20
|
+
// useAnnounce mounts singleton live regions on <body>; reset between tests so
|
|
21
|
+
// stale announcements from one test don't leak into the next.
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
__resetLiveRegionsForTest();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
function politeRegion(): HTMLElement | null {
|
|
27
|
+
return document.querySelector('[data-astryx-live-region="polite"]');
|
|
28
|
+
}
|
|
29
|
+
|
|
19
30
|
describe('Lightbox', () => {
|
|
20
31
|
it('renders as a dialog element', () => {
|
|
21
32
|
render(
|
|
@@ -300,6 +311,116 @@ describe('Lightbox', () => {
|
|
|
300
311
|
});
|
|
301
312
|
});
|
|
302
313
|
|
|
314
|
+
describe('screen-reader announcements', () => {
|
|
315
|
+
const media = [
|
|
316
|
+
{src: '/a.jpg', alt: 'Image A', caption: 'First'},
|
|
317
|
+
{src: '/b.jpg', alt: 'Image B', caption: 'Second'},
|
|
318
|
+
{src: '/c.jpg', alt: 'Image C'},
|
|
319
|
+
];
|
|
320
|
+
|
|
321
|
+
it('announces the new image and position when navigating next via button', async () => {
|
|
322
|
+
render(
|
|
323
|
+
<Lightbox
|
|
324
|
+
isOpen={true}
|
|
325
|
+
onOpenChange={() => {}}
|
|
326
|
+
media={media}
|
|
327
|
+
defaultIndex={0}
|
|
328
|
+
/>,
|
|
329
|
+
);
|
|
330
|
+
fireEvent.click(screen.getByLabelText('Next'));
|
|
331
|
+
await waitFor(() => {
|
|
332
|
+
expect(politeRegion()).toHaveTextContent('Image B, 2 of 3');
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it('announces the new image and position when navigating via arrow keys', async () => {
|
|
337
|
+
render(
|
|
338
|
+
<Lightbox
|
|
339
|
+
isOpen={true}
|
|
340
|
+
onOpenChange={() => {}}
|
|
341
|
+
media={media}
|
|
342
|
+
defaultIndex={1}
|
|
343
|
+
/>,
|
|
344
|
+
);
|
|
345
|
+
const dialog = document.querySelector('dialog')!;
|
|
346
|
+
fireEvent.keyDown(dialog, {key: 'ArrowRight'});
|
|
347
|
+
await waitFor(() => {
|
|
348
|
+
expect(politeRegion()).toHaveTextContent('Image C, 3 of 3');
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
it('announces the new image and position when navigating prev', async () => {
|
|
353
|
+
render(
|
|
354
|
+
<Lightbox
|
|
355
|
+
isOpen={true}
|
|
356
|
+
onOpenChange={() => {}}
|
|
357
|
+
media={media}
|
|
358
|
+
defaultIndex={2}
|
|
359
|
+
/>,
|
|
360
|
+
);
|
|
361
|
+
fireEvent.click(screen.getByLabelText('Previous'));
|
|
362
|
+
await waitFor(() => {
|
|
363
|
+
expect(politeRegion()).toHaveTextContent('Image B, 2 of 3');
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it('falls back to a positional label when the image has no alt', async () => {
|
|
368
|
+
const unlabeled = [
|
|
369
|
+
{src: '/a.jpg', alt: 'Image A'},
|
|
370
|
+
{src: '/b.jpg', alt: ''},
|
|
371
|
+
];
|
|
372
|
+
render(
|
|
373
|
+
<Lightbox
|
|
374
|
+
isOpen={true}
|
|
375
|
+
onOpenChange={() => {}}
|
|
376
|
+
media={unlabeled}
|
|
377
|
+
defaultIndex={0}
|
|
378
|
+
/>,
|
|
379
|
+
);
|
|
380
|
+
fireEvent.click(screen.getByLabelText('Next'));
|
|
381
|
+
await waitFor(() => {
|
|
382
|
+
expect(politeRegion()).toHaveTextContent('Image 2 of 2');
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
it('does not announce on initial open', async () => {
|
|
387
|
+
render(
|
|
388
|
+
<Lightbox
|
|
389
|
+
isOpen={true}
|
|
390
|
+
onOpenChange={() => {}}
|
|
391
|
+
media={media}
|
|
392
|
+
defaultIndex={1}
|
|
393
|
+
/>,
|
|
394
|
+
);
|
|
395
|
+
// Allow any scheduled rAF to flush; nothing should have been announced.
|
|
396
|
+
await new Promise(resolve => requestAnimationFrame(() => resolve(null)));
|
|
397
|
+
// The dialog's aria-label already names the current image on open, so no
|
|
398
|
+
// live region is created (announce is never called).
|
|
399
|
+
expect(politeRegion()).toBeNull();
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
it('does not announce when the lightbox opens at a new index', async () => {
|
|
403
|
+
const {rerender} = render(
|
|
404
|
+
<Lightbox
|
|
405
|
+
isOpen={false}
|
|
406
|
+
onOpenChange={() => {}}
|
|
407
|
+
media={media}
|
|
408
|
+
index={0}
|
|
409
|
+
/>,
|
|
410
|
+
);
|
|
411
|
+
rerender(
|
|
412
|
+
<Lightbox
|
|
413
|
+
isOpen={true}
|
|
414
|
+
onOpenChange={() => {}}
|
|
415
|
+
media={media}
|
|
416
|
+
index={2}
|
|
417
|
+
/>,
|
|
418
|
+
);
|
|
419
|
+
await new Promise(resolve => requestAnimationFrame(() => resolve(null)));
|
|
420
|
+
expect(politeRegion()).toBeNull();
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
|
|
303
424
|
describe('video support', () => {
|
|
304
425
|
it('renders a video element when type is video', () => {
|
|
305
426
|
const {container} = render(
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import {
|
|
20
20
|
useCallback,
|
|
21
21
|
useEffect,
|
|
22
|
+
useMemo,
|
|
22
23
|
useRef,
|
|
23
24
|
useState,
|
|
24
25
|
type MouseEvent as ReactMouseEvent,
|
|
@@ -28,6 +29,7 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
28
29
|
import {colorVars, spacingVars, typeScaleVars} from '../theme/tokens.stylex';
|
|
29
30
|
import {Icon} from '../Icon';
|
|
30
31
|
import {IconButton} from '../IconButton';
|
|
32
|
+
import {useAnnounce} from '../hooks/useAnnounce';
|
|
31
33
|
import {useScrollLock} from '../hooks/useScrollLock';
|
|
32
34
|
import {useIsomorphicLayoutEffect} from '../hooks/useIsomorphicLayoutEffect';
|
|
33
35
|
import {mergeProps, mergeRefs} from '../utils';
|
|
@@ -306,7 +308,10 @@ export function Lightbox({
|
|
|
306
308
|
const dragStartRef = useRef({x: 0, y: 0, panX: 0, panY: 0});
|
|
307
309
|
|
|
308
310
|
// Resolve current media item
|
|
309
|
-
const mediaArray =
|
|
311
|
+
const mediaArray = useMemo(
|
|
312
|
+
() => (Array.isArray(media) ? media : [media]),
|
|
313
|
+
[media],
|
|
314
|
+
);
|
|
310
315
|
const isGallery = mediaArray.length > 1;
|
|
311
316
|
const currentItem =
|
|
312
317
|
mediaArray.length > 0
|
|
@@ -329,6 +334,29 @@ export function Lightbox({
|
|
|
329
334
|
setPan({x: 0, y: 0});
|
|
330
335
|
}, [index, currentItem?.src]);
|
|
331
336
|
|
|
337
|
+
// Announce gallery navigation to screen readers. Moving between images only
|
|
338
|
+
// updates the visual counter, which is silent to assistive tech, so mirror
|
|
339
|
+
// each change in a polite live region ("<alt>, 3 of 12", or "Image 3 of 12"
|
|
340
|
+
// when the image has no alt). Announce only when the image changes during an
|
|
341
|
+
// already-open session — not on mount, not when opening (even at a new
|
|
342
|
+
// index, since the dialog's aria-label already names the current image), and
|
|
343
|
+
// not on close.
|
|
344
|
+
const announce = useAnnounce();
|
|
345
|
+
const prevIndexRef = useRef(index);
|
|
346
|
+
const wasOpenRef = useRef(isOpen);
|
|
347
|
+
useEffect(() => {
|
|
348
|
+
const indexChanged = prevIndexRef.current !== index;
|
|
349
|
+
const wasOpen = wasOpenRef.current;
|
|
350
|
+
prevIndexRef.current = index;
|
|
351
|
+
wasOpenRef.current = isOpen;
|
|
352
|
+
if (!indexChanged || !isOpen || !wasOpen) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const item = mediaArray[Math.min(index, mediaArray.length - 1)];
|
|
356
|
+
const position = `${index + 1} of ${mediaArray.length}`;
|
|
357
|
+
announce(item?.alt ? `${item.alt}, ${position}` : `Image ${position}`);
|
|
358
|
+
}, [index, isOpen, announce, mediaArray]);
|
|
359
|
+
|
|
332
360
|
// Open/close dialog
|
|
333
361
|
useIsomorphicLayoutEffect(() => {
|
|
334
362
|
const dialog = dialogRef.current;
|
|
@@ -95,6 +95,29 @@ describe('Markdown', () => {
|
|
|
95
95
|
expect(link.getAttribute('rel')).toBe('noopener noreferrer');
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
+
it('renders a footer reference-style link as an anchor', () => {
|
|
99
|
+
// The XDS parser previously had no reference-definition support, so this
|
|
100
|
+
// rendered as literal `[the docs][docs]` text with the definition leaking
|
|
101
|
+
// as a paragraph. It now resolves to a real anchor.
|
|
102
|
+
render(
|
|
103
|
+
<Markdown>
|
|
104
|
+
{'See [the docs][docs] here.\n\n[docs]: https://example.com/docs\n'}
|
|
105
|
+
</Markdown>,
|
|
106
|
+
);
|
|
107
|
+
const link = screen.getByText('the docs');
|
|
108
|
+
expect(link.tagName).toBe('A');
|
|
109
|
+
expect(link.getAttribute('href')).toBe('https://example.com/docs');
|
|
110
|
+
// The definition line must not leak into the rendered output.
|
|
111
|
+
expect(screen.queryByText(/\[docs\]:/)).toBeNull();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('renders a shortcut reference-style link as an anchor', () => {
|
|
115
|
+
render(<Markdown>{'See [the docs].\n\n[the docs]: /docs'}</Markdown>);
|
|
116
|
+
const link = screen.getByText('the docs');
|
|
117
|
+
expect(link.tagName).toBe('A');
|
|
118
|
+
expect(link.getAttribute('href')).toBe('/docs');
|
|
119
|
+
});
|
|
120
|
+
|
|
98
121
|
it('does not add target="_blank" to relative links', () => {
|
|
99
122
|
render(<Markdown>{'[internal](/page)'}</Markdown>);
|
|
100
123
|
const link = screen.getByText('internal');
|
|
@@ -425,7 +425,14 @@ const streamingStyles = stylex.create({
|
|
|
425
425
|
fadeIn: {
|
|
426
426
|
opacity: 1,
|
|
427
427
|
transitionProperty: 'opacity',
|
|
428
|
-
|
|
428
|
+
// Collapse the entry fade to an instant swap under reduced motion. The
|
|
429
|
+
// 0s duration makes the @starting-style opacity jump non-animated (the
|
|
430
|
+
// media query can't nest inside @starting-style), mirroring the
|
|
431
|
+
// conditional-duration form in Spinner (Spinner.tsx).
|
|
432
|
+
transitionDuration: {
|
|
433
|
+
default: durationVars['--duration-medium'],
|
|
434
|
+
'@media (prefers-reduced-motion: reduce)': '0s',
|
|
435
|
+
},
|
|
429
436
|
transitionTimingFunction: easeVars['--ease-standard'],
|
|
430
437
|
'@starting-style': {
|
|
431
438
|
opacity: 0,
|
|
@@ -1049,12 +1056,7 @@ function renderBlock(
|
|
|
1049
1056
|
switch (node.type) {
|
|
1050
1057
|
case 'heading': {
|
|
1051
1058
|
const level = Math.min(node.level + headingLevelStart - 1, 6) as
|
|
1052
|
-
|
|
|
1053
|
-
| 2
|
|
1054
|
-
| 3
|
|
1055
|
-
| 4
|
|
1056
|
-
| 5
|
|
1057
|
-
| 6;
|
|
1059
|
+
1 | 2 | 3 | 4 | 5 | 6;
|
|
1058
1060
|
const headingChildren = node.children.map((c, i) =>
|
|
1059
1061
|
renderInline(
|
|
1060
1062
|
c,
|
|
@@ -650,3 +650,39 @@ describe('streaming end-to-end: no raw syntax visible', () => {
|
|
|
650
650
|
});
|
|
651
651
|
});
|
|
652
652
|
});
|
|
653
|
+
|
|
654
|
+
describe('parseMarkdownIncremental link reference definitions', () => {
|
|
655
|
+
function firstLinkHref(blocks: BlockNode[]): string | undefined {
|
|
656
|
+
for (const block of blocks) {
|
|
657
|
+
if (block.type === 'paragraph') {
|
|
658
|
+
for (const node of block.children) {
|
|
659
|
+
if (node.type === 'link') {
|
|
660
|
+
return node.href;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
return undefined;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
it('resolves a footer reference streamed across chunks (matches full parse)', () => {
|
|
669
|
+
const text = 'See [the docs][d] here.\n\n[d]: https://example.com/d\n';
|
|
670
|
+
const {final} = simulateStreaming(text, 5);
|
|
671
|
+
expect(final).toEqual(parseMarkdown(text));
|
|
672
|
+
expect(firstLinkHref(final)).toBe('https://example.com/d');
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
it('re-resolves an already-settled reference once its definition arrives', () => {
|
|
676
|
+
const state = createIncrementalState();
|
|
677
|
+
// The reference paragraph settles (blank line) before the definition.
|
|
678
|
+
parseMarkdownIncremental('See [d] here.\n\n', state);
|
|
679
|
+
const before = parseMarkdownIncremental('See [d] here.\n\n[d', state);
|
|
680
|
+
expect(firstLinkHref(before)).toBeUndefined();
|
|
681
|
+
// Definition completes — the settled paragraph must pick up the link.
|
|
682
|
+
const after = parseMarkdownIncremental(
|
|
683
|
+
'See [d] here.\n\n[d]: /docs\n',
|
|
684
|
+
state,
|
|
685
|
+
);
|
|
686
|
+
expect(firstLinkHref(after)).toBe('/docs');
|
|
687
|
+
});
|
|
688
|
+
});
|
|
@@ -69,6 +69,31 @@ function simulateStreamingIncremental(
|
|
|
69
69
|
return parseMarkdownIncremental(fullText, state);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// A single wall-clock measurement is flaky when the whole suite runs in
|
|
73
|
+
// parallel forks: scheduler contention can inflate a millisecond-scale
|
|
74
|
+
// sample well past a tight budget (observed 30.9ms against the 20ms Small
|
|
75
|
+
// budget). The fastest of a few runs approximates the un-contended cost —
|
|
76
|
+
// a real regression raises the minimum too — so budgets stay tight without
|
|
77
|
+
// flapping. The streaming budget tests below keep a single run: their
|
|
78
|
+
// budgets carry 10x+ headroom, which contention cannot realistically eat.
|
|
79
|
+
function measureBest<T>(
|
|
80
|
+
runs: number,
|
|
81
|
+
fn: () => T,
|
|
82
|
+
): {elapsed: number; result: T} {
|
|
83
|
+
let elapsed = Infinity;
|
|
84
|
+
let result!: T;
|
|
85
|
+
for (let i = 0; i < runs; i++) {
|
|
86
|
+
const start = performance.now();
|
|
87
|
+
const r = fn();
|
|
88
|
+
const t = performance.now() - start;
|
|
89
|
+
if (t < elapsed) {
|
|
90
|
+
elapsed = t;
|
|
91
|
+
result = r;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {elapsed, result};
|
|
95
|
+
}
|
|
96
|
+
|
|
72
97
|
describe('parseMarkdown performance', () => {
|
|
73
98
|
const sizes = [
|
|
74
99
|
{name: 'Small', paragraphs: 10, maxMs: 20},
|
|
@@ -93,9 +118,7 @@ describe('parseMarkdown performance', () => {
|
|
|
93
118
|
for (const size of sizes) {
|
|
94
119
|
it(`full re-parse ${size.name} (${size.paragraphs} paragraphs) under ${size.maxMs}ms`, () => {
|
|
95
120
|
const text = generateAIResponse(size.paragraphs);
|
|
96
|
-
const
|
|
97
|
-
const result = parseMarkdown(text);
|
|
98
|
-
const elapsed = performance.now() - start;
|
|
121
|
+
const {elapsed, result} = measureBest(3, () => parseMarkdown(text));
|
|
99
122
|
console.log(
|
|
100
123
|
` ${size.name} full parse: ${elapsed.toFixed(2)}ms → ${result.length} blocks`,
|
|
101
124
|
);
|
|
@@ -149,15 +172,14 @@ describe('parseMarkdown performance', () => {
|
|
|
149
172
|
const text = generateAIResponse(200);
|
|
150
173
|
const chunkSize = 50;
|
|
151
174
|
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const incrElapsed = performance.now() - incrStart;
|
|
175
|
+
// The assertion below compares a ratio of two measurements, so noise on
|
|
176
|
+
// either side can flip it — measure both as best-of-3.
|
|
177
|
+
const {elapsed: fullElapsed} = measureBest(3, () =>
|
|
178
|
+
simulateStreamingFullReparse(text, chunkSize),
|
|
179
|
+
);
|
|
180
|
+
const {elapsed: incrElapsed} = measureBest(3, () =>
|
|
181
|
+
simulateStreamingIncremental(text, chunkSize),
|
|
182
|
+
);
|
|
161
183
|
|
|
162
184
|
const speedup = fullElapsed / incrElapsed;
|
|
163
185
|
console.log(`\n === Incremental vs Full Re-parse Speedup ===`);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import {describe, it, expect} from 'vitest';
|
|
4
4
|
import {parseMarkdown, parseInline} from './parser';
|
|
5
|
+
import type {InlineNode} from './parser';
|
|
5
6
|
|
|
6
7
|
describe('parseInline', () => {
|
|
7
8
|
it('parses plain text', () => {
|
|
@@ -946,3 +947,212 @@ describe('citation parsing', () => {
|
|
|
946
947
|
});
|
|
947
948
|
});
|
|
948
949
|
});
|
|
950
|
+
|
|
951
|
+
// ---------------------------------------------------------------------------
|
|
952
|
+
// Link reference definitions
|
|
953
|
+
// ---------------------------------------------------------------------------
|
|
954
|
+
|
|
955
|
+
describe('link reference definitions', () => {
|
|
956
|
+
// Collect every link/image node across a block tree for concise assertions.
|
|
957
|
+
function collectLinks(
|
|
958
|
+
nodes: InlineNode[],
|
|
959
|
+
): {type: string; href?: string; src?: string; text: string}[] {
|
|
960
|
+
const out: {type: string; href?: string; src?: string; text: string}[] = [];
|
|
961
|
+
const textOf = (inlineNodes: InlineNode[]): string =>
|
|
962
|
+
inlineNodes
|
|
963
|
+
.map(inline =>
|
|
964
|
+
inline.type === 'text'
|
|
965
|
+
? inline.content
|
|
966
|
+
: 'children' in inline
|
|
967
|
+
? textOf(inline.children)
|
|
968
|
+
: '',
|
|
969
|
+
)
|
|
970
|
+
.join('');
|
|
971
|
+
for (const node of nodes) {
|
|
972
|
+
if (node.type === 'link') {
|
|
973
|
+
out.push({type: 'link', href: node.href, text: textOf(node.children)});
|
|
974
|
+
} else if (node.type === 'image') {
|
|
975
|
+
out.push({type: 'image', src: node.src, text: node.alt});
|
|
976
|
+
} else if ('children' in node) {
|
|
977
|
+
out.push(...collectLinks(node.children));
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
return out;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
function paragraphLinks(input: string) {
|
|
984
|
+
const blocks = parseMarkdown(input);
|
|
985
|
+
const links = blocks.flatMap(block =>
|
|
986
|
+
block.type === 'paragraph' ? collectLinks(block.children) : [],
|
|
987
|
+
);
|
|
988
|
+
return {blocks, links};
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
it('resolves a full reference `[text][label]` and drops the definition', () => {
|
|
992
|
+
const {blocks, links} = paragraphLinks(
|
|
993
|
+
'See [the docs][docs] here.\n\n[docs]: https://example.com/docs\n',
|
|
994
|
+
);
|
|
995
|
+
// Only the paragraph survives; the definition line produces no block.
|
|
996
|
+
expect(blocks).toHaveLength(1);
|
|
997
|
+
expect(blocks[0].type).toBe('paragraph');
|
|
998
|
+
expect(links).toEqual([
|
|
999
|
+
{type: 'link', href: 'https://example.com/docs', text: 'the docs'},
|
|
1000
|
+
]);
|
|
1001
|
+
});
|
|
1002
|
+
|
|
1003
|
+
it('resolves a collapsed reference `[text][]`', () => {
|
|
1004
|
+
const {links} = paragraphLinks(
|
|
1005
|
+
'See [the docs][].\n\n[the docs]: https://example.com/docs',
|
|
1006
|
+
);
|
|
1007
|
+
expect(links).toEqual([
|
|
1008
|
+
{type: 'link', href: 'https://example.com/docs', text: 'the docs'},
|
|
1009
|
+
]);
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
it('resolves a shortcut reference `[text]`', () => {
|
|
1013
|
+
const {links} = paragraphLinks(
|
|
1014
|
+
'See [the docs].\n\n[the docs]: https://example.com/docs',
|
|
1015
|
+
);
|
|
1016
|
+
expect(links).toEqual([
|
|
1017
|
+
{type: 'link', href: 'https://example.com/docs', text: 'the docs'},
|
|
1018
|
+
]);
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
it('resolves a reference that appears before its definition', () => {
|
|
1022
|
+
const {links} = paragraphLinks('[foo]\n\n[foo]: /bar');
|
|
1023
|
+
expect(links).toEqual([{type: 'link', href: '/bar', text: 'foo'}]);
|
|
1024
|
+
});
|
|
1025
|
+
|
|
1026
|
+
it('matches labels case-insensitively with collapsed whitespace', () => {
|
|
1027
|
+
const {links} = paragraphLinks(
|
|
1028
|
+
'See [The Docs][DOCS].\n\n[docs]: https://example.com/d',
|
|
1029
|
+
);
|
|
1030
|
+
expect(links).toEqual([
|
|
1031
|
+
{type: 'link', href: 'https://example.com/d', text: 'The Docs'},
|
|
1032
|
+
]);
|
|
1033
|
+
});
|
|
1034
|
+
|
|
1035
|
+
it('supports an angle-bracket destination and a title', () => {
|
|
1036
|
+
const {links} = paragraphLinks(
|
|
1037
|
+
'See [x].\n\n[x]: <https://example.com/x> "the title"',
|
|
1038
|
+
);
|
|
1039
|
+
expect(links).toEqual([
|
|
1040
|
+
{type: 'link', href: 'https://example.com/x', text: 'x'},
|
|
1041
|
+
]);
|
|
1042
|
+
});
|
|
1043
|
+
|
|
1044
|
+
it('absorbs a title on the line after a title-less definition', () => {
|
|
1045
|
+
const {blocks, links} = paragraphLinks(
|
|
1046
|
+
'See [x].\n\n[x]: https://example.com/x\n "the title"\n',
|
|
1047
|
+
);
|
|
1048
|
+
// The continuation title line must not leak as its own paragraph.
|
|
1049
|
+
expect(blocks).toHaveLength(1);
|
|
1050
|
+
expect(links).toEqual([
|
|
1051
|
+
{type: 'link', href: 'https://example.com/x', text: 'x'},
|
|
1052
|
+
]);
|
|
1053
|
+
});
|
|
1054
|
+
|
|
1055
|
+
it('resolves an empty angle-bracket destination to an empty href', () => {
|
|
1056
|
+
const {blocks, links} = paragraphLinks('[foo]\n\n[foo]: <>');
|
|
1057
|
+
expect(blocks).toHaveLength(1);
|
|
1058
|
+
expect(links).toEqual([{type: 'link', href: '', text: 'foo'}]);
|
|
1059
|
+
});
|
|
1060
|
+
|
|
1061
|
+
it('recognizes a definition immediately after a heading (no blank line)', () => {
|
|
1062
|
+
const {blocks, links} = paragraphLinks('# Title\n[x]: /url\n\n[x]');
|
|
1063
|
+
expect(blocks.map(block => block.type)).toEqual(['heading', 'paragraph']);
|
|
1064
|
+
expect(links).toEqual([{type: 'link', href: '/url', text: 'x'}]);
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
it('recognizes a definition immediately after a closed code fence', () => {
|
|
1068
|
+
const {blocks, links} = paragraphLinks('```\ncode\n```\n[x]: /url\n\n[x]');
|
|
1069
|
+
expect(blocks.map(block => block.type)).toEqual(['codeblock', 'paragraph']);
|
|
1070
|
+
expect(links).toEqual([{type: 'link', href: '/url', text: 'x'}]);
|
|
1071
|
+
});
|
|
1072
|
+
|
|
1073
|
+
it('uses the first definition when a label is defined twice', () => {
|
|
1074
|
+
const {links} = paragraphLinks('[a]\n\n[a]: /first\n[a]: /second');
|
|
1075
|
+
expect(links).toEqual([{type: 'link', href: '/first', text: 'a'}]);
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
it('resolves a blockquote-nested definition even with a top-level definition present', () => {
|
|
1079
|
+
const blocks = parseMarkdown('[outer]: /o\n\n> [inner]\n>\n> [inner]: /i');
|
|
1080
|
+
const quote = blocks.find(block => block.type === 'blockquote');
|
|
1081
|
+
expect(quote?.type).toBe('blockquote');
|
|
1082
|
+
if (quote != null && quote.type === 'blockquote') {
|
|
1083
|
+
const links = quote.children.flatMap(block =>
|
|
1084
|
+
block.type === 'paragraph' ? collectLinks(block.children) : [],
|
|
1085
|
+
);
|
|
1086
|
+
expect(links).toEqual([{type: 'link', href: '/i', text: 'inner'}]);
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
|
|
1090
|
+
it('resolves a reference image `![alt][label]`', () => {
|
|
1091
|
+
const {links} = paragraphLinks('![logo][l]\n\n[l]: /logo.png');
|
|
1092
|
+
expect(links).toEqual([{type: 'image', src: '/logo.png', text: 'logo'}]);
|
|
1093
|
+
});
|
|
1094
|
+
|
|
1095
|
+
it('does not treat a whitespace-only second label as collapsed', () => {
|
|
1096
|
+
// `[foo][ ]` is a full reference to the empty (normalized) label and matches
|
|
1097
|
+
// nothing; `[foo]` still resolves as a shortcut and `[ ]` stays literal.
|
|
1098
|
+
const blocks = parseMarkdown('[foo][ ]\n\n[foo]: /f');
|
|
1099
|
+
expect(blocks[0].type).toBe('paragraph');
|
|
1100
|
+
if (blocks[0].type === 'paragraph') {
|
|
1101
|
+
expect(collectLinks(blocks[0].children)).toEqual([
|
|
1102
|
+
{type: 'link', href: '/f', text: 'foo'},
|
|
1103
|
+
]);
|
|
1104
|
+
const literal = blocks[0].children
|
|
1105
|
+
.map(node => (node.type === 'text' ? node.content : ''))
|
|
1106
|
+
.join('');
|
|
1107
|
+
expect(literal).toContain('[ ]');
|
|
1108
|
+
}
|
|
1109
|
+
});
|
|
1110
|
+
|
|
1111
|
+
it('leaves an unresolved reference as literal text', () => {
|
|
1112
|
+
const {blocks, links} = paragraphLinks('See [the docs][missing].');
|
|
1113
|
+
expect(links).toEqual([]);
|
|
1114
|
+
expect(blocks[0].type).toBe('paragraph');
|
|
1115
|
+
if (blocks[0].type === 'paragraph') {
|
|
1116
|
+
expect(blocks[0].children).toContainEqual({
|
|
1117
|
+
type: 'text',
|
|
1118
|
+
content: 'See [the docs][missing].',
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
});
|
|
1122
|
+
|
|
1123
|
+
it('does not resolve a definition or reference inside a code fence', () => {
|
|
1124
|
+
const blocks = parseMarkdown('```\n[x]\n[x]: /should-not-resolve\n```');
|
|
1125
|
+
expect(blocks).toHaveLength(1);
|
|
1126
|
+
expect(blocks[0].type).toBe('codeblock');
|
|
1127
|
+
if (blocks[0].type === 'codeblock') {
|
|
1128
|
+
expect(blocks[0].content).toBe('[x]\n[x]: /should-not-resolve');
|
|
1129
|
+
}
|
|
1130
|
+
});
|
|
1131
|
+
|
|
1132
|
+
it('does not treat a definition-shaped line as a definition mid-paragraph', () => {
|
|
1133
|
+
// CommonMark: a definition cannot interrupt a paragraph.
|
|
1134
|
+
const {blocks, links} = paragraphLinks('Foo\n[bar]: /baz');
|
|
1135
|
+
expect(links).toEqual([]);
|
|
1136
|
+
expect(blocks).toHaveLength(1);
|
|
1137
|
+
expect(blocks[0].type).toBe('paragraph');
|
|
1138
|
+
});
|
|
1139
|
+
|
|
1140
|
+
it('leaves footnote markers and definitions untouched', () => {
|
|
1141
|
+
const blocks = parseMarkdown(
|
|
1142
|
+
'A claim.[^1]\n\n[^1]: https://example.com/note',
|
|
1143
|
+
);
|
|
1144
|
+
// No link nodes; the `[^1]` marker stays literal and `[^1]:` is not
|
|
1145
|
+
// treated as a link reference definition (footnotes are out of scope).
|
|
1146
|
+
const links = blocks.flatMap(block =>
|
|
1147
|
+
block.type === 'paragraph' ? collectLinks(block.children) : [],
|
|
1148
|
+
);
|
|
1149
|
+
expect(links).toEqual([]);
|
|
1150
|
+
expect(blocks).toHaveLength(2);
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
it('leaves ordinary bracketed text with no definition alone', () => {
|
|
1154
|
+
const {links, blocks} = paragraphLinks('an array like [1, 2, 3] here');
|
|
1155
|
+
expect(links).toEqual([]);
|
|
1156
|
+
expect(blocks[0].type).toBe('paragraph');
|
|
1157
|
+
});
|
|
1158
|
+
});
|