@astryxdesign/core 0.6.2 → 0.6.3-canary.0899f21
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/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +13 -28
- 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/ChatLayout.d.ts +19 -0
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +19 -0
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +44 -34
- package/dist/Chat/ChatMessageBubble.d.ts +2 -0
- package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
- package/dist/Chat/ChatMessageBubble.js +5 -3
- package/dist/Chat/ChatMessageList.d.ts +2 -1
- package/dist/Chat/ChatMessageList.d.ts.map +1 -1
- package/dist/Chat/ChatMessageList.js +4 -3
- package/dist/Chat/ChatMessageMetadata.d.ts +5 -4
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatMessageMetadata.js +12 -9
- 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/Citation/Citation.d.ts +1 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +3 -2
- package/dist/CodeBlock/highlightRanges.d.ts.map +1 -1
- package/dist/CodeBlock/highlightRanges.js +14 -3
- 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 +13 -4
- 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/Icon/Icon.d.ts +6 -31
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +8 -71
- package/dist/Icon/IconDefaultSizeContext.d.ts +4 -0
- package/dist/Icon/IconDefaultSizeContext.d.ts.map +1 -0
- package/dist/Icon/IconDefaultSizeContext.js +18 -0
- package/dist/Icon/IconSize.stylex.d.ts +65 -0
- package/dist/Icon/IconSize.stylex.d.ts.map +1 -0
- package/dist/Icon/IconSize.stylex.js +75 -0
- package/dist/Item/Item.d.ts +1 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +4 -3
- 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/Link/useLinkComponent.d.ts +5 -15
- package/dist/Link/useLinkComponent.d.ts.map +1 -1
- package/dist/Link/useLinkComponent.js +34 -51
- package/dist/List/List.d.ts +19 -1
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +9 -2
- package/dist/List/ListContext.d.ts +1 -0
- package/dist/List/ListContext.d.ts.map +1 -1
- package/dist/List/ListContext.js +2 -1
- package/dist/List/ListItem.d.ts +1 -1
- package/dist/List/ListItem.d.ts.map +1 -1
- package/dist/List/ListItem.js +9 -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 +17 -0
- package/dist/Markdown/plugins/index.d.ts.map +1 -0
- package/dist/Markdown/plugins/index.js +14 -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/softBreaks.d.ts +3 -0
- package/dist/Markdown/plugins/softBreaks.d.ts.map +1 -0
- package/dist/Markdown/plugins/softBreaks.js +172 -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 +6 -0
- package/dist/Markdown/url.d.ts.map +1 -0
- package/dist/Markdown/url.js +31 -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/MetadataList/MetadataList.js +3 -3
- 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/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchValueEditor.js +5 -0
- 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/ScrollableArea/ScrollableArea.d.ts +1 -0
- package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
- package/dist/ScrollableArea/ScrollableArea.js +1 -0
- 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 +16 -7
- 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/Timer/Timer.d.ts +49 -0
- package/dist/Timer/Timer.d.ts.map +1 -0
- package/dist/Timer/Timer.js +158 -0
- package/dist/Timer/index.d.ts +9 -0
- package/dist/Timer/index.d.ts.map +1 -0
- package/dist/Timer/index.js +10 -0
- 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/TopNav/TopNavMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +3 -2
- 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 +27 -11
- 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/useClickableContainer.d.ts +10 -1
- package/dist/hooks/useClickableContainer.d.ts.map +1 -1
- package/dist/hooks/useClickableContainer.js +15 -4
- 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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/theme/declarationBoundary.d.ts +17 -0
- package/dist/theme/declarationBoundary.d.ts.map +1 -0
- package/dist/theme/declarationBoundary.js +343 -0
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +4 -0
- package/dist/theme/generateThemeRules.d.ts +13 -7
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +140 -34
- 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/dist/utils/safeUrl.d.ts +11 -0
- package/dist/utils/safeUrl.d.ts.map +1 -0
- package/dist/utils/safeUrl.js +78 -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 +24 -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/Button.doc.mjs +5 -5
- package/src/Button/Button.tsx +15 -13
- 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/ChatLayout.doc.mjs +12 -4
- package/src/Chat/ChatLayout.spec.md +271 -0
- package/src/Chat/ChatLayout.test.tsx +28 -0
- package/src/Chat/ChatLayout.tsx +19 -0
- package/src/Chat/ChatLayoutScrollButton.spec.md +338 -0
- package/src/Chat/ChatLayoutScrollButton.test.tsx +31 -0
- package/src/Chat/ChatLayoutScrollButton.tsx +31 -14
- package/src/Chat/ChatMessageBubble.doc.mjs +28 -15
- package/src/Chat/ChatMessageBubble.spec.md +263 -0
- package/src/Chat/ChatMessageBubble.test.tsx +93 -0
- package/src/Chat/ChatMessageBubble.tsx +8 -3
- package/src/Chat/ChatMessageList.spec.md +222 -0
- package/src/Chat/ChatMessageList.test.tsx +64 -2
- package/src/Chat/ChatMessageList.tsx +4 -3
- package/src/Chat/ChatMessageMetadata.doc.mjs +57 -3
- package/src/Chat/ChatMessageMetadata.spec.md +220 -0
- package/src/Chat/ChatMessageMetadata.test.tsx +34 -0
- package/src/Chat/ChatMessageMetadata.tsx +13 -13
- package/src/Chat/ChatSendButton.test.tsx +1 -4
- package/src/Chat/ChatSendButton.tsx +1 -1
- package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +514 -0
- package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +740 -0
- package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +457 -0
- package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +91 -0
- package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +91 -0
- package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +456 -0
- package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +413 -0
- 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/Citation/Citation.doc.mjs +2 -2
- package/src/Citation/Citation.test.tsx +17 -0
- package/src/Citation/Citation.tsx +4 -2
- package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
- package/src/ClickableCard/ClickableCard.test.tsx +102 -5
- package/src/CodeBlock/highlightRanges.test.ts +143 -1
- package/src/CodeBlock/highlightRanges.ts +15 -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/Dialog.doc.mjs +2 -0
- package/src/Dialog/DialogHeader.doc.mjs +22 -0
- package/src/Dialog/DialogHeader.test.tsx +167 -3
- package/src/Dialog/DialogHeader.tsx +37 -6
- package/src/Dialog/modules/DialogHeader.spec.md +101 -42
- package/src/DropdownMenu/DropdownMenu.test.tsx +5 -2
- 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/Icon/Icon.doc.mjs +7 -5
- package/src/Icon/Icon.spec.md +81 -40
- package/src/Icon/Icon.test.tsx +6 -3
- package/src/Icon/Icon.tsx +20 -68
- package/src/Icon/IconDefaultSizeContext.ts +23 -0
- package/src/Icon/IconSize.stylex.ts +70 -0
- package/src/IconButton/IconButton.doc.mjs +3 -3
- package/src/IconButton/IconButton.test.tsx +40 -0
- package/src/Item/Item.doc.mjs +6 -2
- package/src/Item/Item.tsx +9 -3
- 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 +17 -4
- package/src/Link/Link.test.tsx +24 -0
- package/src/Link/Link.tsx +5 -0
- package/src/Link/LinkProvider.doc.mjs +2 -2
- package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +261 -0
- package/src/Link/useLinkComponent.test.tsx +333 -0
- package/src/Link/useLinkComponent.ts +29 -57
- package/src/List/List.doc.mjs +6 -0
- package/src/List/List.spec.md +200 -0
- package/src/List/List.test.tsx +117 -1
- package/src/List/List.tsx +22 -2
- package/src/List/ListContext.tsx +3 -1
- package/src/List/ListItem.doc.mjs +2 -2
- package/src/List/ListItem.source-build.test.mjs +41 -0
- package/src/List/ListItem.tsx +26 -2
- package/src/Markdown/Markdown.doc.mjs +300 -2
- 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 +130 -3
- package/src/Markdown/Markdown.renderBoundary.test.tsx +72 -0
- package/src/Markdown/Markdown.spec.md +203 -45
- package/src/Markdown/Markdown.test.tsx +63 -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/modules/softBreaks.spec.md +137 -0
- package/src/Markdown/parser/index.ts +64 -0
- package/src/Markdown/parser.public.test.ts +103 -0
- package/src/Markdown/parser.test.ts +20 -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 +54 -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/softBreaks.test.tsx +172 -0
- package/src/Markdown/plugins/softBreaks.ts +169 -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 +36 -0
- package/src/Markdown/utils.ts +13 -1
- package/src/MetadataList/MetadataList.test.tsx +4 -2
- package/src/MetadataList/MetadataList.tsx +3 -3
- 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/PowerSearch/PowerSearchValueEditor.test.tsx +51 -0
- package/src/PowerSearch/PowerSearchValueEditor.tsx +4 -0
- 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/ScrollableArea.tsx +1 -0
- 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 +34 -15
- 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.a11y.chromium.spec.ts +45 -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/Timer/Timer.doc.mjs +183 -0
- package/src/Timer/Timer.spec.md +215 -0
- package/src/Timer/Timer.test.tsx +302 -0
- package/src/Timer/Timer.tsx +258 -0
- package/src/Timer/index.ts +11 -0
- 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/Token/Token.doc.mjs +2 -2
- package/src/Tokenizer/Tokenizer.spec.md +142 -75
- package/src/TopNav/TopNavMenu.doc.mjs +2 -2
- package/src/TopNav/TopNavMenu.test.tsx +30 -0
- package/src/TopNav/TopNavMenu.tsx +7 -2
- 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/useClickableContainer.test.tsx +236 -0
- package/src/hooks/useClickableContainer.ts +20 -4
- 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/index.ts +3 -0
- package/src/inputFontFloor.test.ts +106 -0
- package/src/tailwind-theme.css +0 -6
- package/src/theme/Theme.test.tsx +32 -0
- package/src/theme/declarationBoundary.test.ts +126 -0
- package/src/theme/declarationBoundary.ts +347 -0
- package/src/theme/derivedVarRegistry.test.ts +7 -0
- package/src/theme/derivedVarRegistry.ts +1 -0
- package/src/theme/generateThemeRules.test.ts +526 -1
- package/src/theme/generateThemeRules.ts +228 -50
- package/src/theme/tokenValueCompat.test.ts +4 -1
- package/src/utils/interactionOverlay.stylex.ts +20 -0
- package/src/utils/safeUrl.test.ts +88 -0
- package/src/utils/safeUrl.ts +85 -0
|
@@ -20,9 +20,9 @@ export const docs = {
|
|
|
20
20
|
{
|
|
21
21
|
name: 'icon',
|
|
22
22
|
type: 'ReactNode',
|
|
23
|
-
description: 'Icon element rendered inside the button.',
|
|
23
|
+
description: 'Icon element rendered inside the button. An Astryx Icon with no explicit size defaults to sm for sm/md buttons and md for lg buttons.',
|
|
24
24
|
required: true,
|
|
25
|
-
slotElements: [{__element: 'Icon', props: {icon: 'check'
|
|
25
|
+
slotElements: [{__element: 'Icon', props: {icon: 'check'}}],
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
name: 'variant',
|
|
@@ -137,7 +137,7 @@ export const docsDense = {
|
|
|
137
137
|
},
|
|
138
138
|
propDescriptions: {
|
|
139
139
|
label: 'accessible label; used as aria-label, not rendered as visible text',
|
|
140
|
-
icon: 'icon element rendered inside button',
|
|
140
|
+
icon: 'icon element rendered inside button; unsized Astryx Icon defaults to sm for sm/md buttons and md for lg',
|
|
141
141
|
variant: 'visual style variant',
|
|
142
142
|
size: 'size variant',
|
|
143
143
|
elevation: 'resting shadow depth: none|low|med|high; raise for a floating action button (FAB)',
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import {describe, it, expect, vi} from 'vitest';
|
|
13
13
|
import {render, screen} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
|
+
import {Icon} from '../Icon/Icon';
|
|
15
16
|
import {IconButton} from './IconButton';
|
|
16
17
|
|
|
17
18
|
describe('IconButton', () => {
|
|
@@ -52,6 +53,45 @@ describe('IconButton', () => {
|
|
|
52
53
|
expect(screen.getByRole('button', {name: 'Add'})).toBeInTheDocument();
|
|
53
54
|
});
|
|
54
55
|
|
|
56
|
+
it.each([
|
|
57
|
+
['sm', 'sm', '1rem'],
|
|
58
|
+
['md', 'sm', '1rem'],
|
|
59
|
+
['lg', 'md', '1.25rem'],
|
|
60
|
+
] as const)(
|
|
61
|
+
'renders the %s button wrapper and inherited Icon at the same size',
|
|
62
|
+
(buttonSize, iconSize, renderedSize) => {
|
|
63
|
+
render(
|
|
64
|
+
<IconButton
|
|
65
|
+
label="Add"
|
|
66
|
+
icon={<Icon icon="check" data-testid="icon" />}
|
|
67
|
+
size={buttonSize}
|
|
68
|
+
/>,
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const icon = screen.getByTestId('icon');
|
|
72
|
+
const wrapper = icon.parentElement;
|
|
73
|
+
expect(wrapper).not.toBeNull();
|
|
74
|
+
|
|
75
|
+
expect(icon).toHaveAttribute('data-size', iconSize);
|
|
76
|
+
expect(getComputedStyle(icon).width).toBe(renderedSize);
|
|
77
|
+
expect(getComputedStyle(icon).height).toBe(renderedSize);
|
|
78
|
+
expect(getComputedStyle(wrapper!).width).toBe(renderedSize);
|
|
79
|
+
expect(getComputedStyle(wrapper!).height).toBe(renderedSize);
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
it('preserves an explicit Astryx Icon size', () => {
|
|
84
|
+
render(
|
|
85
|
+
<IconButton
|
|
86
|
+
label="Add"
|
|
87
|
+
icon={<Icon icon="check" size="lg" data-testid="icon" />}
|
|
88
|
+
size="sm"
|
|
89
|
+
/>,
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
expect(screen.getByTestId('icon')).toHaveAttribute('data-size', 'lg');
|
|
93
|
+
});
|
|
94
|
+
|
|
55
95
|
it('handles click events', async () => {
|
|
56
96
|
const user = userEvent.setup();
|
|
57
97
|
const handleClick = vi.fn();
|
package/src/Item/Item.doc.mjs
CHANGED
|
@@ -22,6 +22,10 @@ export const docs = {
|
|
|
22
22
|
vars: [
|
|
23
23
|
{name: '--_item-label-color', description: 'Color of the label line. Unset by default (the label uses the primary text token); a parent sets it to recolor the label it renders, as the destructive dropdown/context menu item does.', default: 'var(--color-text-primary)', private: true},
|
|
24
24
|
{name: '--_item-description-color', description: 'Companion to --_item-label-color for the secondary description line.', default: 'var(--color-text-secondary)', private: true},
|
|
25
|
+
{name: '--_item-inset-inline', description: 'Inline inset of the row. Item derives its paddingInline from this variable, and List reads it to cancel the inset when edgeCompensation="inline". Set paddingInline on `item` in a theme and both stay in sync.', default: 'var(--spacing-2) (var(--spacing-3) for density="spacious")', private: true},
|
|
26
|
+
],
|
|
27
|
+
derived: [
|
|
28
|
+
{property: 'paddingInline', vars: ['--_item-inset-inline']},
|
|
25
29
|
],
|
|
26
30
|
},
|
|
27
31
|
components: [
|
|
@@ -43,7 +47,7 @@ export const docs = {
|
|
|
43
47
|
{name: 'layout', type: "'stacked' | 'inline'", description: 'How the label and description sit together. stacked puts the description on its own line below the label; inline keeps both on one line, description ellipsizing first, so the row fits a fixed-height host.', default: "'stacked'"},
|
|
44
48
|
{name: 'onClick', type: '(event: MouseEvent) => void', description: 'Click handler. Makes the item clickable with button semantics.'},
|
|
45
49
|
{name: 'interactiveRef', type: 'RefObject<HTMLElement | null>', description: 'Ref to a nested control (e.g. a checkbox in startContent) that owns the item\'s keyboard access and action. The row becomes an enlarged click/tap target that delegates surface clicks to it (useClickableContainer) and renders no invisible button/anchor, so the row adds no second tab stop (WCAG 4.1.2). Mutually exclusive with onClick/href; those are ignored when set.'},
|
|
46
|
-
{name: 'href', type: 'string', description: 'Link URL. Makes the item a link via an invisible anchor element.'},
|
|
50
|
+
{name: 'href', type: 'string', description: 'Link URL. Makes the item a link via an invisible anchor element. The destination follows the shared navigation rule described on the Link `href` prop.'},
|
|
47
51
|
{name: 'target', type: "'_blank' | '_self'", description: 'Link target. Only used with href. target="_blank" automatically adds noopener noreferrer.'},
|
|
48
52
|
{name: 'rel', type: 'string', description: 'Link relationship tokens. noopener noreferrer are merged automatically for target="_blank".'},
|
|
49
53
|
{name: 'isHighlighted', type: 'boolean', description: 'Highlighted state (hover/keyboard focus appearance).', default: 'false'},
|
|
@@ -167,7 +171,7 @@ export const docsDense = {
|
|
|
167
171
|
onClick: 'Click handler; enables button semantics.',
|
|
168
172
|
interactiveRef:
|
|
169
173
|
'Ref to a nested control that owns the item\'s keyboard access/action; row delegates surface clicks to it (useClickableContainer), no invisible button/anchor, no second tab stop (WCAG 4.1.2). Mutually exclusive with onClick/href.',
|
|
170
|
-
href: 'Link URL; enables anchor semantics.',
|
|
174
|
+
href: 'Link URL; enables anchor semantics. Follows the shared navigation rule (see Link href).',
|
|
171
175
|
target:
|
|
172
176
|
'Link target, only with href. target="_blank" auto-adds noopener noreferrer.',
|
|
173
177
|
rel: 'Link relationship tokens. noopener noreferrer are merged for target="_blank".',
|
package/src/Item/Item.tsx
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @file Item.tsx
|
|
7
7
|
* @input Uses React, ReactNode, StyleXStyles, theme tokens, useClickableContainer
|
|
8
|
-
* @output Exports Item component, ItemProps type
|
|
8
|
+
* @output Exports Item component, ItemProps type; publishes the shared inline inset
|
|
9
9
|
* @position Core layout primitive; consumed by index.ts, tested by Item.test.tsx
|
|
10
10
|
*
|
|
11
11
|
* SYNC: When modified, update these files to stay in sync:
|
|
@@ -209,7 +209,13 @@ const styles = stylex.create({
|
|
|
209
209
|
display: 'flex',
|
|
210
210
|
alignItems: 'center',
|
|
211
211
|
gap: spacingVars['--spacing-2'],
|
|
212
|
-
|
|
212
|
+
// The inline inset is published as --_item-inset-inline and the padding
|
|
213
|
+
// derives from it, so consumers that need to compensate for the inset
|
|
214
|
+
// (List's edgeCompensation) read the var instead of mirroring the values.
|
|
215
|
+
// Themes that set paddingInline on `item` also feed this var via the
|
|
216
|
+
// derived var registry, keeping padding and compensation in sync.
|
|
217
|
+
'--_item-inset-inline': spacingVars['--spacing-2'],
|
|
218
|
+
paddingInline: 'var(--_item-inset-inline)',
|
|
213
219
|
position: 'relative',
|
|
214
220
|
boxSizing: 'border-box',
|
|
215
221
|
textAlign: 'start',
|
|
@@ -356,7 +362,7 @@ const densityStyles = stylex.create({
|
|
|
356
362
|
},
|
|
357
363
|
spacious: {
|
|
358
364
|
paddingBlock: spacingVars['--spacing-3'],
|
|
359
|
-
|
|
365
|
+
'--_item-inset-inline': spacingVars['--spacing-3'],
|
|
360
366
|
},
|
|
361
367
|
});
|
|
362
368
|
|
package/src/Kbd/Kbd.doc.mjs
CHANGED
|
@@ -27,7 +27,7 @@ export const docs = {
|
|
|
27
27
|
name: 'keys',
|
|
28
28
|
type: 'string',
|
|
29
29
|
description:
|
|
30
|
-
'Keyboard shortcut string. Use "+" to separate keys. Special keys: mod (Cmd on Mac), ctrl, alt, shift, enter, backspace, escape, tab, up, down, left, right.',
|
|
30
|
+
'Keyboard shortcut string. Use "+" to separate keys. Special keys: mod (Cmd on Mac), ctrl, alt, shift, enter, backspace, escape, tab, up, down, left, right, plus. Aliases: esc for escape and return for enter.',
|
|
31
31
|
required: true,
|
|
32
32
|
},
|
|
33
33
|
{
|
|
@@ -72,7 +72,7 @@ export const docsZh = {
|
|
|
72
72
|
name: 'keys',
|
|
73
73
|
type: 'string',
|
|
74
74
|
description:
|
|
75
|
-
'键盘快捷键字符串。使用 "+" 分隔各按键。特殊按键:mod(Mac 上为 Cmd)、ctrl、alt、shift、enter、backspace、escape、tab、up、down、left、right。',
|
|
75
|
+
'键盘快捷键字符串。使用 "+" 分隔各按键。特殊按键:mod(Mac 上为 Cmd)、ctrl、alt、shift、enter、backspace、escape、tab、up、down、left、right、plus。别名:esc 等同于 escape,return 等同于 enter。',
|
|
76
76
|
required: true,
|
|
77
77
|
},
|
|
78
78
|
{
|
|
@@ -122,7 +122,7 @@ export const docsDense = {
|
|
|
122
122
|
],
|
|
123
123
|
},
|
|
124
124
|
propDescriptions: {
|
|
125
|
-
keys: 'Shortcut string. "+" separates keys. Special: mod (Cmd on Mac), ctrl, alt, shift, enter, backspace, escape, tab, up, down, left, right.',
|
|
125
|
+
keys: 'Shortcut string. "+" separates keys. Special: mod (Cmd on Mac), ctrl, alt, shift, enter, backspace, escape, tab, up, down, left, right, plus. Aliases: esc for escape, return for enter.',
|
|
126
126
|
xstyle: 'StyleX styles for layout customization. Must be stylex.create() value.',
|
|
127
127
|
className: 'CSS class for root element. Prefer xstyle; className for non-StyleX integration.',
|
|
128
128
|
style: 'Inline styles for root element. Prefer xstyle; inline styles bypass StyleX optimization.',
|
package/src/Kbd/Kbd.test.tsx
CHANGED
|
@@ -10,13 +10,14 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import {render, screen} from '@testing-library/react';
|
|
13
|
-
import {describe, it, expect, afterEach} from 'vitest';
|
|
13
|
+
import {describe, it, expect, afterEach, vi} from 'vitest';
|
|
14
14
|
import {Kbd} from './Kbd';
|
|
15
15
|
|
|
16
16
|
describe('Kbd', () => {
|
|
17
17
|
const originalPlatform = navigator.platform;
|
|
18
18
|
|
|
19
19
|
afterEach(() => {
|
|
20
|
+
vi.restoreAllMocks();
|
|
20
21
|
// Restore platform after any test that spoofs it \u2014 ensures no
|
|
21
22
|
// test pollution even if an assertion fails mid-test.
|
|
22
23
|
Object.defineProperty(navigator, 'platform', {
|
|
@@ -72,6 +73,61 @@ describe('Kbd', () => {
|
|
|
72
73
|
expect(screen.getByText('Esc')).toBeInTheDocument();
|
|
73
74
|
});
|
|
74
75
|
|
|
76
|
+
it.each([
|
|
77
|
+
{alias: 'esc', display: 'Esc', label: 'Escape'},
|
|
78
|
+
{alias: 'return', display: '\u21B5', label: 'Enter'},
|
|
79
|
+
])('normalizes the $alias key alias', ({alias, display, label}) => {
|
|
80
|
+
render(<Kbd keys={alias} />);
|
|
81
|
+
expect(screen.getByText(display)).toBeInTheDocument();
|
|
82
|
+
expect(screen.getByRole('img')).toHaveAttribute('aria-label', label);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it.each([
|
|
86
|
+
{alias: 'esc', canonical: 'escape'},
|
|
87
|
+
{alias: 'return', canonical: 'enter'},
|
|
88
|
+
])('$alias renders identically to $canonical', ({alias, canonical}) => {
|
|
89
|
+
const {container, rerender} = render(<Kbd keys={canonical} />);
|
|
90
|
+
const text = container.textContent;
|
|
91
|
+
const label = screen.getByRole('img').getAttribute('aria-label');
|
|
92
|
+
rerender(<Kbd keys={alias} />);
|
|
93
|
+
expect(container.textContent).toBe(text);
|
|
94
|
+
expect(screen.getByRole('img').getAttribute('aria-label')).toBe(label);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it.each([
|
|
98
|
+
{keys: 'ctrl + ESC', display: 'Esc', label: 'Control + Escape'},
|
|
99
|
+
{keys: 'shift + RETURN', display: '\u21B5', label: 'Shift + Enter'},
|
|
100
|
+
])('normalizes aliases inside the $keys combo', ({keys, display, label}) => {
|
|
101
|
+
render(<Kbd keys={keys} />);
|
|
102
|
+
expect(screen.getByText(display)).toBeInTheDocument();
|
|
103
|
+
expect(screen.getByRole('img')).toHaveAttribute('aria-label', label);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('keeps child keys unique after alias normalization', () => {
|
|
107
|
+
const consoleError = vi
|
|
108
|
+
.spyOn(console, 'error')
|
|
109
|
+
.mockImplementation(() => {});
|
|
110
|
+
const {container} = render(
|
|
111
|
+
<Kbd keys="escape+esc+ESC+enter+return+return" />,
|
|
112
|
+
);
|
|
113
|
+
expect(consoleError).not.toHaveBeenCalled();
|
|
114
|
+
expect(
|
|
115
|
+
Array.from(container.querySelectorAll('kbd'), key => key.textContent),
|
|
116
|
+
).toEqual(['Esc', 'Esc', 'Esc', '↵', '↵', '↵']);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it.each(['constructor', '__proto__'])(
|
|
120
|
+
'renders the unknown %s key without consulting object prototypes',
|
|
121
|
+
key => {
|
|
122
|
+
render(<Kbd keys={key} />);
|
|
123
|
+
expect(screen.getByText(key.toUpperCase())).toBeInTheDocument();
|
|
124
|
+
expect(screen.getByRole('img')).toHaveAttribute(
|
|
125
|
+
'aria-label',
|
|
126
|
+
key.toUpperCase(),
|
|
127
|
+
);
|
|
128
|
+
},
|
|
129
|
+
);
|
|
130
|
+
|
|
75
131
|
it('exposes a spoken accessible name and hides the glyphs (obs-1)', () => {
|
|
76
132
|
render(<Kbd keys="mod+shift+k" />);
|
|
77
133
|
// The wrapper carries a screen-reader name built from spoken key labels
|
package/src/Kbd/Kbd.tsx
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file Kbd.tsx
|
|
7
|
-
* @input Uses React, StyleX, theme tokens
|
|
8
|
-
* @output Exports Kbd component and KbdProps
|
|
7
|
+
* @input Uses React, StyleX, theme tokens, shortcut key names and aliases
|
|
8
|
+
* @output Exports Kbd component and KbdProps with canonical shortcut labels
|
|
9
9
|
* @position Core implementation; renders styled keyboard shortcut indicators
|
|
10
10
|
*
|
|
11
11
|
* SYNC: When modified, update:
|
|
@@ -61,20 +61,25 @@ const styles = stylex.create({
|
|
|
61
61
|
* Note: `mod` is not in this map — it resolves dynamically via platform
|
|
62
62
|
* detection inside the component.
|
|
63
63
|
*/
|
|
64
|
-
const KEY_DISPLAY
|
|
65
|
-
ctrl
|
|
66
|
-
alt
|
|
67
|
-
shift
|
|
68
|
-
enter
|
|
69
|
-
backspace
|
|
70
|
-
escape
|
|
71
|
-
tab
|
|
72
|
-
up
|
|
73
|
-
down
|
|
74
|
-
left
|
|
75
|
-
right
|
|
76
|
-
plus
|
|
77
|
-
|
|
64
|
+
const KEY_DISPLAY = new Map<string, string>([
|
|
65
|
+
['ctrl', '\u2303'], // ⌃
|
|
66
|
+
['alt', '\u2325'], // ⌥
|
|
67
|
+
['shift', '\u21E7'], // ⇧
|
|
68
|
+
['enter', '\u21B5'], // ↵
|
|
69
|
+
['backspace', '\u232B'], // ⌫
|
|
70
|
+
['escape', 'Esc'],
|
|
71
|
+
['tab', '\u21E5'], // ⇥
|
|
72
|
+
['up', '\u2191'],
|
|
73
|
+
['down', '\u2193'],
|
|
74
|
+
['left', '\u2190'],
|
|
75
|
+
['right', '\u2192'],
|
|
76
|
+
['plus', '+'],
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
const KBD_KEY_ALIASES = new Map<string, string>([
|
|
80
|
+
['esc', 'escape'],
|
|
81
|
+
['return', 'enter'],
|
|
82
|
+
]);
|
|
78
83
|
|
|
79
84
|
/**
|
|
80
85
|
* Resolves a key name to its display string. Handles the platform-aware
|
|
@@ -85,7 +90,7 @@ function getKeyDisplay(key: string, isMac: boolean): string {
|
|
|
85
90
|
if (key === 'mod') {
|
|
86
91
|
return isMac ? '\u2318' : 'Ctrl';
|
|
87
92
|
}
|
|
88
|
-
return KEY_DISPLAY
|
|
93
|
+
return KEY_DISPLAY.get(key) ?? key.toUpperCase();
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
/**
|
|
@@ -93,26 +98,26 @@ function getKeyDisplay(key: string, isMac: boolean): string {
|
|
|
93
98
|
* (⌘, ⇧, ↵, …) that assistive tech cannot announce meaningfully, so the
|
|
94
99
|
* accessible name for the shortcut is built from these words instead.
|
|
95
100
|
*/
|
|
96
|
-
const KEY_LABEL
|
|
97
|
-
ctrl
|
|
98
|
-
alt
|
|
99
|
-
shift
|
|
100
|
-
enter
|
|
101
|
-
backspace
|
|
102
|
-
escape
|
|
103
|
-
tab
|
|
104
|
-
up
|
|
105
|
-
down
|
|
106
|
-
left
|
|
107
|
-
right
|
|
108
|
-
plus
|
|
109
|
-
|
|
101
|
+
const KEY_LABEL = new Map<string, string>([
|
|
102
|
+
['ctrl', 'Control'],
|
|
103
|
+
['alt', 'Alt'],
|
|
104
|
+
['shift', 'Shift'],
|
|
105
|
+
['enter', 'Enter'],
|
|
106
|
+
['backspace', 'Backspace'],
|
|
107
|
+
['escape', 'Escape'],
|
|
108
|
+
['tab', 'Tab'],
|
|
109
|
+
['up', 'Up arrow'],
|
|
110
|
+
['down', 'Down arrow'],
|
|
111
|
+
['left', 'Left arrow'],
|
|
112
|
+
['right', 'Right arrow'],
|
|
113
|
+
['plus', 'Plus'],
|
|
114
|
+
]);
|
|
110
115
|
|
|
111
116
|
function getKeyLabel(key: string, isMac: boolean): string {
|
|
112
117
|
if (key === 'mod') {
|
|
113
118
|
return isMac ? 'Command' : 'Control';
|
|
114
119
|
}
|
|
115
|
-
return KEY_LABEL
|
|
120
|
+
return KEY_LABEL.get(key) ?? key.toUpperCase();
|
|
116
121
|
}
|
|
117
122
|
|
|
118
123
|
function subscribeToPlatformChanges(): () => void {
|
|
@@ -127,7 +132,9 @@ export interface KbdProps extends BaseProps<HTMLSpanElement> {
|
|
|
127
132
|
ref?: React.Ref<HTMLSpanElement>;
|
|
128
133
|
/**
|
|
129
134
|
* Keyboard shortcut string. Use "+" to separate keys.
|
|
130
|
-
* Special keys: mod (Cmd on Mac), ctrl, alt, shift, enter, backspace, escape
|
|
135
|
+
* Special keys: mod (Cmd on Mac), ctrl, alt, shift, enter, backspace, escape,
|
|
136
|
+
* tab, up, down, left, and right.
|
|
137
|
+
* Aliases: "esc" for "escape" and "return" for "enter".
|
|
131
138
|
* Use "plus" to render a literal "+" key (e.g. "shift+plus").
|
|
132
139
|
*
|
|
133
140
|
* @example
|
|
@@ -163,11 +170,24 @@ export function Kbd({keys, ref, xstyle, className, style, ...rest}: KbdProps) {
|
|
|
163
170
|
getServerPlatformSnapshot,
|
|
164
171
|
);
|
|
165
172
|
|
|
166
|
-
const
|
|
173
|
+
const keyOccurrences = new Map<string, number>();
|
|
174
|
+
const parts = keys
|
|
175
|
+
.split('+')
|
|
176
|
+
.map(key => key.trim().toLowerCase())
|
|
177
|
+
.map(sourceKey => {
|
|
178
|
+
const occurrence = keyOccurrences.get(sourceKey) ?? 0;
|
|
179
|
+
keyOccurrences.set(sourceKey, occurrence + 1);
|
|
180
|
+
return {
|
|
181
|
+
key: KBD_KEY_ALIASES.get(sourceKey) ?? sourceKey,
|
|
182
|
+
reactKey: `${sourceKey}:${occurrence}`,
|
|
183
|
+
};
|
|
184
|
+
});
|
|
167
185
|
|
|
168
186
|
// Screen-reader name: the joined spoken labels (e.g. "Command + K"), since
|
|
169
187
|
// the visual glyphs below are announced meaninglessly by assistive tech.
|
|
170
|
-
const accessibleName = parts
|
|
188
|
+
const accessibleName = parts
|
|
189
|
+
.map(({key}) => getKeyLabel(key, isMac))
|
|
190
|
+
.join(' + ');
|
|
171
191
|
|
|
172
192
|
return (
|
|
173
193
|
<span
|
|
@@ -181,8 +201,8 @@ export function Kbd({keys, ref, xstyle, className, style, ...rest}: KbdProps) {
|
|
|
181
201
|
className,
|
|
182
202
|
style,
|
|
183
203
|
)}>
|
|
184
|
-
{parts.map(key => (
|
|
185
|
-
<kbd key={
|
|
204
|
+
{parts.map(({key, reactKey}) => (
|
|
205
|
+
<kbd key={reactKey} aria-hidden="true" {...stylex.props(styles.kbd)}>
|
|
186
206
|
{getKeyDisplay(key, isMac)}
|
|
187
207
|
</kbd>
|
|
188
208
|
))}
|
|
@@ -8,6 +8,23 @@ export const docs = {
|
|
|
8
8
|
displayName: 'Layout Footer',
|
|
9
9
|
isHiddenFromOverview: true,
|
|
10
10
|
description: 'Bottom bar for action bars, pagination, and status bars.',
|
|
11
|
+
playground: {
|
|
12
|
+
defaults: {
|
|
13
|
+
children: 'Footer content: status bar or actions',
|
|
14
|
+
hasDivider: true,
|
|
15
|
+
},
|
|
16
|
+
wrapper: {
|
|
17
|
+
component: 'Layout',
|
|
18
|
+
slotProp: 'footer',
|
|
19
|
+
props: {
|
|
20
|
+
content: {
|
|
21
|
+
__element: 'LayoutContent',
|
|
22
|
+
props: {},
|
|
23
|
+
children: 'Main content area',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
11
28
|
props: [
|
|
12
29
|
{
|
|
13
30
|
name: 'children',
|
package/src/Link/Link.doc.mjs
CHANGED
|
@@ -38,7 +38,8 @@ export const docs = {
|
|
|
38
38
|
{
|
|
39
39
|
name: 'href',
|
|
40
40
|
type: 'string',
|
|
41
|
-
description:
|
|
41
|
+
description:
|
|
42
|
+
'Link destination URL. Astryx-owned links and clickable surfaces block javascript:, vbscript:, and data:text/html after control-character removal, outer-whitespace trimming, and case-insensitive scheme inspection. The same rule covers native anchors, custom routers, Markdown links, and every activation method. Relative paths, fragments, protocol-relative URLs, HTTP(S), mailto, tel, safe custom schemes, and accepted downloads keep their existing behavior. A rejected destination renders inertly without invoking a custom router. There is no bypass prop; exceptional behavior requires caller-owned custom rendering outside this guarantee. Images and other resource URLs have separate policies.',
|
|
42
43
|
},
|
|
43
44
|
{
|
|
44
45
|
name: 'hasUnderline',
|
|
@@ -151,7 +152,8 @@ export const docs = {
|
|
|
151
152
|
{
|
|
152
153
|
name: 'component',
|
|
153
154
|
type: 'LinkComponentType',
|
|
154
|
-
description:
|
|
155
|
+
description:
|
|
156
|
+
'Component to use for all link elements. It receives accepted `href` and `to` values under the shared navigation rule described on the Link `href` prop. Supported structured destinations, including their `protocol`, are checked without changing object identity. If either supplied destination is rejected, Astryx renders inert content without invoking this component; it does not pass undefined or fall back to the other destination.',
|
|
155
157
|
required: true,
|
|
156
158
|
},
|
|
157
159
|
{
|
|
@@ -164,6 +166,17 @@ export const docs = {
|
|
|
164
166
|
},
|
|
165
167
|
],
|
|
166
168
|
usage: {
|
|
169
|
+
accessibility: [
|
|
170
|
+
{
|
|
171
|
+
name: 'Link text',
|
|
172
|
+
category: 'Color contrast',
|
|
173
|
+
criterion: '1.4.3 Contrast (Minimum)',
|
|
174
|
+
requirement: '4.5:1',
|
|
175
|
+
states: ['Rest', 'Hover', 'Pointer down'],
|
|
176
|
+
description:
|
|
177
|
+
'Link text must have at least 4.5:1 contrast with the background behind it. For Pointer down, measure against the pressed overlay the link paints behind its text.',
|
|
178
|
+
},
|
|
179
|
+
],
|
|
167
180
|
description:
|
|
168
181
|
'A styled anchor for inline and standalone text navigation. Supports external links, underline variants, tooltips, and custom link components for router integration. Use it for navigating between pages or to external URLs.',
|
|
169
182
|
bestPractices: [
|
|
@@ -344,7 +357,7 @@ export const docsDense = {
|
|
|
344
357
|
propDescriptions: {
|
|
345
358
|
as: 'Custom component to render instead of <a>',
|
|
346
359
|
label: 'Accessible label (aria-label). Only for non-text content like icon-only links.',
|
|
347
|
-
href: 'Link destination URL',
|
|
360
|
+
href: 'Link destination URL. Shared rule blocks javascript:, vbscript:, data:text/html after scheme normalization on every Astryx-owned navigation path. Ordinary URLs, fragments, safe custom schemes, and accepted downloads are preserved. Rejected => inert, no custom router. No bypass prop; exceptional caller-owned rendering is outside the guarantee. Image/resource policy is separate.',
|
|
348
361
|
hasUnderline: 'Always show underline',
|
|
349
362
|
isDisabled: 'Disables link',
|
|
350
363
|
isExternalLink: 'Opens new tab w/ external icon and safe rel tokens',
|
|
@@ -365,7 +378,7 @@ export const docsDense = {
|
|
|
365
378
|
description:
|
|
366
379
|
'Provider setting default link component for all Astryx links in subtree.',
|
|
367
380
|
propDescriptions: {
|
|
368
|
-
component: 'Component for all link elements',
|
|
381
|
+
component: 'Component for all link elements. Accepted href/to follow the Link href rule; structured fields including protocol are checked, preserving identity. Either rejected => inert content, no router invocation or fallback.',
|
|
369
382
|
children: 'Subtree',
|
|
370
383
|
},
|
|
371
384
|
},
|
package/src/Link/Link.test.tsx
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import {describe, it, expect, vi} from 'vitest';
|
|
13
13
|
import {fireEvent, render, screen} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
|
+
import {hasPressedArm} from '../__tests__/pressState';
|
|
15
16
|
import {Link} from './Link';
|
|
16
17
|
import {LinkProvider} from './LinkProvider';
|
|
17
18
|
|
|
@@ -417,3 +418,26 @@ describe('Link', () => {
|
|
|
417
418
|
expect(link).toHaveAttribute('data-color', 'secondary');
|
|
418
419
|
});
|
|
419
420
|
});
|
|
421
|
+
|
|
422
|
+
describe('pressed state', () => {
|
|
423
|
+
it('paints the pressed overlay behind a link while it is pressed', () => {
|
|
424
|
+
render(<Link href="/docs">Docs</Link>);
|
|
425
|
+
expect(hasPressedArm(screen.getByRole('link', {name: 'Docs'}))).toBe(true);
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it('paints it on the button form too', () => {
|
|
429
|
+
render(<Link onClick={() => {}}>Open</Link>);
|
|
430
|
+
expect(hasPressedArm(screen.getByRole('button', {name: 'Open'}))).toBe(
|
|
431
|
+
true,
|
|
432
|
+
);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
it('does not press a disabled link', () => {
|
|
436
|
+
render(
|
|
437
|
+
<Link href="/docs" isDisabled>
|
|
438
|
+
Docs
|
|
439
|
+
</Link>,
|
|
440
|
+
);
|
|
441
|
+
expect(hasPressedArm(screen.getByText('Docs').closest('a')!)).toBe(false);
|
|
442
|
+
});
|
|
443
|
+
});
|
package/src/Link/Link.tsx
CHANGED
|
@@ -45,6 +45,7 @@ import {computeTargetAndRel} from './computeTargetAndRel';
|
|
|
45
45
|
import {useInteractiveRole} from '../hooks/useInteractiveRole';
|
|
46
46
|
import {themeProps} from '../utils/themeProps';
|
|
47
47
|
import {focusOutlineProps} from '../utils/focusOutline.stylex';
|
|
48
|
+
import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
|
|
48
49
|
import {useTranslator} from '../i18n';
|
|
49
50
|
|
|
50
51
|
/**
|
|
@@ -368,6 +369,9 @@ export function Link({
|
|
|
368
369
|
styles.base,
|
|
369
370
|
styles.buttonReset,
|
|
370
371
|
linkColorStyles[color],
|
|
372
|
+
// The system's pressed overlay behind the text; the hover stays the
|
|
373
|
+
// colour change above, so a press is the one background it paints.
|
|
374
|
+
!isDisabled && interactionOverlayStyles.pressedBackgroundColor,
|
|
371
375
|
hasUnderline && styles.hasUnderline,
|
|
372
376
|
isStandalone && styles.standalone,
|
|
373
377
|
isDisabled && styles.disabled,
|
|
@@ -427,6 +431,7 @@ export function Link({
|
|
|
427
431
|
focusOutlineProps.focusVisible(
|
|
428
432
|
styles.base,
|
|
429
433
|
linkColorStyles[color],
|
|
434
|
+
!isDisabled && interactionOverlayStyles.pressedBackgroundColor,
|
|
430
435
|
hasUnderline && styles.hasUnderline,
|
|
431
436
|
isStandalone && styles.standalone,
|
|
432
437
|
isDisabled && styles.disabled,
|
|
@@ -13,7 +13,7 @@ export const docs = {
|
|
|
13
13
|
description: 'Wraps your app to replace the default <a> tag with a framework-specific link component (e.g. Next.js Link) for client-side routing across all Astryx components.',
|
|
14
14
|
},
|
|
15
15
|
props: [
|
|
16
|
-
{name: 'component', type: 'LinkComponentType', required: true, description: 'Link component to use for all link elements in the subtree (e.g. Next.js Link).'},
|
|
16
|
+
{name: 'component', type: 'LinkComponentType', required: true, description: 'Link component to use for all link elements in the subtree (e.g. Next.js Link). It receives accepted `href` and `to` values under the shared navigation rule described on the Link `href` prop. Supported structured destinations, including their `protocol`, are checked without changing object identity. If either supplied destination is rejected, Astryx renders inert content without invoking this component; it does not pass undefined or fall back to the other destination.'},
|
|
17
17
|
{name: 'children', type: 'ReactNode', required: true, description: 'Content to render with the link provider.'},
|
|
18
18
|
],
|
|
19
19
|
};
|
|
@@ -25,6 +25,6 @@ export const docsDense = {
|
|
|
25
25
|
description: 'Wraps app to replace default <a> tag w/ framework-specific link component (e.g. Next.js Link) for client-side routing across all Astryx components.',
|
|
26
26
|
},
|
|
27
27
|
propDescriptions: {
|
|
28
|
-
component: 'link component for all link elements in subtree (e.g. Next.js Link)',
|
|
28
|
+
component: 'link component for all link elements in subtree (e.g. Next.js Link). Accepted href/to follow the Link href rule; structured fields including protocol are checked, preserving identity. Either rejected => inert content, no router invocation or fallback.',
|
|
29
29
|
},
|
|
30
30
|
};
|