@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
|
@@ -10,7 +10,14 @@ import {
|
|
|
10
10
|
afterAll,
|
|
11
11
|
afterEach,
|
|
12
12
|
} from 'vitest';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
render,
|
|
15
|
+
screen,
|
|
16
|
+
fireEvent,
|
|
17
|
+
act,
|
|
18
|
+
waitFor,
|
|
19
|
+
within,
|
|
20
|
+
} from '@testing-library/react';
|
|
14
21
|
import React, {useState} from 'react';
|
|
15
22
|
import * as stylex from '@stylexjs/stylex';
|
|
16
23
|
import {spacingVars} from '../theme/tokens.stylex';
|
|
@@ -170,6 +177,148 @@ describe('PowerSearch', () => {
|
|
|
170
177
|
expect(popoverText).toContain('equals');
|
|
171
178
|
});
|
|
172
179
|
|
|
180
|
+
describe('value editor identity follows the field and operator', () => {
|
|
181
|
+
// Two fields with the same value type, so an unkeyed editor would be
|
|
182
|
+
// reused across the switch and keep the first field's menu contents.
|
|
183
|
+
const sameTypeConfig: PowerSearchConfig = {
|
|
184
|
+
name: 'test-same-type',
|
|
185
|
+
fields: [
|
|
186
|
+
{
|
|
187
|
+
key: 'creator',
|
|
188
|
+
label: 'Creator',
|
|
189
|
+
operators: [
|
|
190
|
+
{
|
|
191
|
+
key: 'is_any_of',
|
|
192
|
+
label: 'is any of',
|
|
193
|
+
value: {
|
|
194
|
+
type: 'enum_list',
|
|
195
|
+
values: [{value: 'creator-1', label: 'Creator Person'}],
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
key: 'owner',
|
|
202
|
+
label: 'Owner',
|
|
203
|
+
operators: [
|
|
204
|
+
{
|
|
205
|
+
key: 'is_any_of',
|
|
206
|
+
label: 'is any of',
|
|
207
|
+
value: {
|
|
208
|
+
type: 'enum_list',
|
|
209
|
+
values: [{value: 'owner-1', label: 'Owner Person'}],
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const creatorOption = () =>
|
|
218
|
+
screen.queryByRole('option', {name: 'Creator Person', hidden: true});
|
|
219
|
+
const ownerOption = () =>
|
|
220
|
+
screen.queryByRole('option', {name: 'Owner Person', hidden: true});
|
|
221
|
+
|
|
222
|
+
it('replaces an open value menu when the field changes', async () => {
|
|
223
|
+
function Harness() {
|
|
224
|
+
const internalConfig = useInternalConfig(sameTypeConfig);
|
|
225
|
+
return (
|
|
226
|
+
<PowerSearchEditPopover
|
|
227
|
+
config={internalConfig}
|
|
228
|
+
filter={{
|
|
229
|
+
field: 'creator',
|
|
230
|
+
operator: 'is_any_of',
|
|
231
|
+
value: {type: 'enum_list', value: []},
|
|
232
|
+
}}
|
|
233
|
+
mode="edit"
|
|
234
|
+
onSave={() => {}}
|
|
235
|
+
onCancel={() => {}}
|
|
236
|
+
/>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
render(<Harness />);
|
|
241
|
+
|
|
242
|
+
// Open the Creator value menu and leave it open.
|
|
243
|
+
fireEvent.focus(screen.getByRole('combobox', {name: 'Values'}));
|
|
244
|
+
await waitFor(() => expect(creatorOption()).toBeInTheDocument());
|
|
245
|
+
|
|
246
|
+
// Switch the field underneath the open menu.
|
|
247
|
+
fireEvent.click(screen.getByRole('combobox', {name: 'Field'}));
|
|
248
|
+
fireEvent.click(
|
|
249
|
+
screen.getByRole('option', {name: 'Owner', hidden: true}),
|
|
250
|
+
);
|
|
251
|
+
act(() => flushRAF());
|
|
252
|
+
|
|
253
|
+
// The old field's options are gone, the new field's are shown.
|
|
254
|
+
expect(creatorOption()).not.toBeInTheDocument();
|
|
255
|
+
await waitFor(() => expect(ownerOption()).toBeInTheDocument());
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('replaces an open value menu on a nested sub-filter row', async () => {
|
|
259
|
+
const nestedConfig: PowerSearchConfig = {
|
|
260
|
+
name: 'test-nested-same-type',
|
|
261
|
+
fields: [
|
|
262
|
+
{
|
|
263
|
+
key: 'group',
|
|
264
|
+
label: 'Group',
|
|
265
|
+
operators: [
|
|
266
|
+
{key: 'all_of', label: 'all of', value: {type: 'nested'}},
|
|
267
|
+
],
|
|
268
|
+
},
|
|
269
|
+
...sameTypeConfig.fields,
|
|
270
|
+
],
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
function Harness() {
|
|
274
|
+
const internalConfig = useInternalConfig(nestedConfig);
|
|
275
|
+
return (
|
|
276
|
+
<PowerSearchEditPopover
|
|
277
|
+
config={internalConfig}
|
|
278
|
+
filter={{
|
|
279
|
+
field: 'group',
|
|
280
|
+
operator: 'all_of',
|
|
281
|
+
value: {
|
|
282
|
+
type: 'nested',
|
|
283
|
+
value: [
|
|
284
|
+
{
|
|
285
|
+
field: 'creator',
|
|
286
|
+
operator: 'is_any_of',
|
|
287
|
+
value: {type: 'enum_list', value: []},
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
},
|
|
291
|
+
}}
|
|
292
|
+
mode="edit"
|
|
293
|
+
onSave={() => {}}
|
|
294
|
+
onCancel={() => {}}
|
|
295
|
+
/>
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
render(<Harness />);
|
|
300
|
+
|
|
301
|
+
fireEvent.focus(screen.getByRole('combobox', {name: 'Values'}));
|
|
302
|
+
await waitFor(() => expect(creatorOption()).toBeInTheDocument());
|
|
303
|
+
|
|
304
|
+
// The nested row's own field selector is the one currently on
|
|
305
|
+
// "Creator"; the root selector stays on "Group".
|
|
306
|
+
const rowField = screen
|
|
307
|
+
.getAllByRole('combobox', {name: 'Field'})
|
|
308
|
+
.find(el => el.textContent === 'Creator');
|
|
309
|
+
expect(rowField).toBeDefined();
|
|
310
|
+
fireEvent.click(rowField!);
|
|
311
|
+
const rowListbox = document.getElementById(
|
|
312
|
+
rowField!.getAttribute('aria-controls')!,
|
|
313
|
+
)!;
|
|
314
|
+
fireEvent.click(
|
|
315
|
+
within(rowListbox).getByRole('option', {name: 'Owner', hidden: true}),
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
expect(creatorOption()).not.toBeInTheDocument();
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
|
|
173
322
|
it('edit popover shows correct filter after removing a preceding filter', () => {
|
|
174
323
|
const filters: PowerSearchFilter[] = [
|
|
175
324
|
{field: 'status', operator: 'is', value: {type: 'string', value: 'open'}},
|
|
@@ -22,7 +22,10 @@ import {TreeList, type TreeListItemData} from '../TreeList';
|
|
|
22
22
|
import {useTranslator} from '../i18n';
|
|
23
23
|
import {isImeKeyEvent} from '../utils/ime';
|
|
24
24
|
import {spacingVars, typeScaleVars} from '../theme/tokens.stylex';
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
PowerSearchValueEditor,
|
|
27
|
+
type PowerSearchValueEditorProps,
|
|
28
|
+
} from './PowerSearchValueEditor';
|
|
26
29
|
import {resolveOperatorLabel} from './resolveOperatorLabel';
|
|
27
30
|
import type {InternalConfig} from './useInternalConfig';
|
|
28
31
|
import type {
|
|
@@ -356,6 +359,7 @@ function NestedSubFilterRow({
|
|
|
356
359
|
{operatorValue && !isEmptyType && !isNestedType && (
|
|
357
360
|
<div {...stylex.props(styles.nestedRowValueEditor)}>
|
|
358
361
|
<PowerSearchValueEditor
|
|
362
|
+
key={valueEditorKey(subFilter)}
|
|
359
363
|
operatorValue={operatorValue}
|
|
360
364
|
filterValue={subFilter.value}
|
|
361
365
|
onChange={handleValueChange}
|
|
@@ -606,6 +610,42 @@ function NestedEditor({
|
|
|
606
610
|
return <TreeList items={items} density="balanced" />;
|
|
607
611
|
}
|
|
608
612
|
|
|
613
|
+
// =============================================================================
|
|
614
|
+
// Value editor cell
|
|
615
|
+
// =============================================================================
|
|
616
|
+
|
|
617
|
+
// A field switch must replace the editor, not update it in place: a reused
|
|
618
|
+
// editor keeps its open menu and old results.
|
|
619
|
+
function valueEditorKey(filter: {field: string; operator?: string}): string {
|
|
620
|
+
return `${filter.field}\u0000${filter.operator ?? ''}`;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// Keyed on field + operator, so this also mounts on a field switch, not just
|
|
624
|
+
// when the popover opens; the focus handoff below runs for both.
|
|
625
|
+
function ValueEditorCell(props: PowerSearchValueEditorProps) {
|
|
626
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
627
|
+
|
|
628
|
+
useEffect(() => {
|
|
629
|
+
const frame = requestAnimationFrame(() => {
|
|
630
|
+
const container = ref.current;
|
|
631
|
+
if (!container) {
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
const focusable = container.querySelector<HTMLElement>(
|
|
635
|
+
'input:not([disabled]), button:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])',
|
|
636
|
+
);
|
|
637
|
+
focusable?.focus();
|
|
638
|
+
});
|
|
639
|
+
return () => cancelAnimationFrame(frame);
|
|
640
|
+
}, []);
|
|
641
|
+
|
|
642
|
+
return (
|
|
643
|
+
<div ref={ref} {...stylex.props(styles.valueEditor)}>
|
|
644
|
+
<PowerSearchValueEditor {...props} />
|
|
645
|
+
</div>
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
|
|
609
649
|
// =============================================================================
|
|
610
650
|
// Main popover
|
|
611
651
|
// =============================================================================
|
|
@@ -625,22 +665,6 @@ export function PowerSearchEditPopover({
|
|
|
625
665
|
saveButtonLabelFromProps ?? t('@astryx.powersearch.editor.apply');
|
|
626
666
|
const [partialFilter, setPartialFilter] =
|
|
627
667
|
useState<PartialFilter>(initialFilter);
|
|
628
|
-
const valueEditorRef = useRef<HTMLDivElement>(null);
|
|
629
|
-
|
|
630
|
-
// Focus the first focusable element inside the value editor after mount
|
|
631
|
-
useEffect(() => {
|
|
632
|
-
const frame = requestAnimationFrame(() => {
|
|
633
|
-
const container = valueEditorRef.current;
|
|
634
|
-
if (!container) {
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
637
|
-
const focusable = container.querySelector<HTMLElement>(
|
|
638
|
-
'input:not([disabled]), button:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])',
|
|
639
|
-
);
|
|
640
|
-
focusable?.focus();
|
|
641
|
-
});
|
|
642
|
-
return () => cancelAnimationFrame(frame);
|
|
643
|
-
}, []);
|
|
644
668
|
|
|
645
669
|
const currentOperator = partialFilter.operator
|
|
646
670
|
? config.getOperator(partialFilter.field, partialFilter.operator)
|
|
@@ -854,17 +878,16 @@ export function PowerSearchEditPopover({
|
|
|
854
878
|
</div>
|
|
855
879
|
)}
|
|
856
880
|
{operatorValue && !isEmptyType && (
|
|
857
|
-
<
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
</div>
|
|
881
|
+
<ValueEditorCell
|
|
882
|
+
key={valueEditorKey(partialFilter)}
|
|
883
|
+
operatorValue={operatorValue}
|
|
884
|
+
filterValue={partialFilter.value}
|
|
885
|
+
onChange={handleValueChange}
|
|
886
|
+
onEnter={handleSave}
|
|
887
|
+
config={config}
|
|
888
|
+
maxMenuItems={maxMenuItems}
|
|
889
|
+
isDisabled={isReadOnly}
|
|
890
|
+
/>
|
|
868
891
|
)}
|
|
869
892
|
</HStack>
|
|
870
893
|
</div>
|
|
@@ -630,3 +630,54 @@ describe('maxMenuItems', () => {
|
|
|
630
630
|
await expectCapped({type: 'entity_list', searchSource: source});
|
|
631
631
|
});
|
|
632
632
|
});
|
|
633
|
+
|
|
634
|
+
// =============================================================================
|
|
635
|
+
// EnumListEditor shows the whole closed vocabulary
|
|
636
|
+
// =============================================================================
|
|
637
|
+
|
|
638
|
+
describe('EnumListEditor', () => {
|
|
639
|
+
const values = Array.from({length: 12}, (_, index) => ({
|
|
640
|
+
value: `option-${index}`,
|
|
641
|
+
label: `Option ${index}`,
|
|
642
|
+
}));
|
|
643
|
+
|
|
644
|
+
it('shows every value on focus instead of the typeahead default of 10', async () => {
|
|
645
|
+
render(
|
|
646
|
+
<PowerSearchValueEditor
|
|
647
|
+
operatorValue={{type: 'enum_list', values}}
|
|
648
|
+
filterValue={undefined}
|
|
649
|
+
onChange={vi.fn()}
|
|
650
|
+
config={stubConfig}
|
|
651
|
+
/>,
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
fireEvent.focus(screen.getByRole('combobox'));
|
|
655
|
+
await act(async () => {
|
|
656
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
expect(screen.getAllByRole('option', {hidden: true})).toHaveLength(12);
|
|
660
|
+
expect(screen.getByText('Option 11')).toBeInTheDocument();
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
it('shows every matching value when searching', async () => {
|
|
664
|
+
render(
|
|
665
|
+
<PowerSearchValueEditor
|
|
666
|
+
operatorValue={{type: 'enum_list', values}}
|
|
667
|
+
filterValue={undefined}
|
|
668
|
+
onChange={vi.fn()}
|
|
669
|
+
config={stubConfig}
|
|
670
|
+
/>,
|
|
671
|
+
);
|
|
672
|
+
|
|
673
|
+
await act(async () => {
|
|
674
|
+
fireEvent.change(screen.getByRole('combobox'), {
|
|
675
|
+
target: {value: 'Option'},
|
|
676
|
+
});
|
|
677
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
expect(screen.getAllByRole('option', {hidden: true})).toHaveLength(12);
|
|
681
|
+
expect(screen.getByText('Option 11')).toBeInTheDocument();
|
|
682
|
+
});
|
|
683
|
+
});
|
|
@@ -619,6 +619,10 @@ function EnumListEditor({
|
|
|
619
619
|
placeholder={t('@astryx.powersearch.valueEditor.selectValuesPlaceholder')}
|
|
620
620
|
hasEntriesOnFocus
|
|
621
621
|
debounceMs={0}
|
|
622
|
+
// A closed vocabulary: every value is a valid choice, so the menu shows
|
|
623
|
+
// all of them instead of BaseTypeahead's 10-suggestion default, which
|
|
624
|
+
// would silently drop valid choices with no way to reach them.
|
|
625
|
+
maxMenuItems={items.length}
|
|
622
626
|
/>
|
|
623
627
|
);
|
|
624
628
|
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @file ProgressBar.test.tsx
|
|
5
|
+
* @input Uses Vitest, Testing Library, and ProgressBar
|
|
6
|
+
* @output DOM regressions for values, labels, themes, and external mark triggers
|
|
7
|
+
* @position Colocated unit tests; mark geometry is checked in Storybook
|
|
8
|
+
*/
|
|
9
|
+
|
|
3
10
|
import {describe, it, expect, beforeAll} from 'vitest';
|
|
4
11
|
import {render, screen, waitFor} from '@testing-library/react';
|
|
5
12
|
import {ProgressBar} from './ProgressBar';
|
|
@@ -558,6 +565,21 @@ describe('ProgressBar', () => {
|
|
|
558
565
|
expect(styleClasses(accentMarks[1])).toBe(styleClasses(errorMarks[1]));
|
|
559
566
|
});
|
|
560
567
|
|
|
568
|
+
it('keeps tabbable target marks outside the progressbar subtree', () => {
|
|
569
|
+
const {container} = render(
|
|
570
|
+
<ProgressBar
|
|
571
|
+
value={50}
|
|
572
|
+
label="Progress"
|
|
573
|
+
marks={[{value: 80, label: 'Goal'}]}
|
|
574
|
+
/>,
|
|
575
|
+
);
|
|
576
|
+
const progressbar = screen.getByRole('progressbar', {name: 'Progress'});
|
|
577
|
+
const mark = container.querySelector(MARK)!;
|
|
578
|
+
expect(mark).toHaveAttribute('tabindex', '0');
|
|
579
|
+
expect(progressbar.querySelector('[tabindex="0"]')).toBeNull();
|
|
580
|
+
expect(mark.closest('[role="progressbar"]')).toBeNull();
|
|
581
|
+
});
|
|
582
|
+
|
|
561
583
|
it('renders every mark as a focusable trigger (label is required, never decorative)', () => {
|
|
562
584
|
const {container} = render(
|
|
563
585
|
<ProgressBar
|
|
@@ -605,10 +627,8 @@ describe('ProgressBar', () => {
|
|
|
605
627
|
});
|
|
606
628
|
|
|
607
629
|
it('keeps the progressbar element free of role="img"/aria-label children', () => {
|
|
608
|
-
// Marks
|
|
609
|
-
//
|
|
610
|
-
// role="img"+aria-label child, so nothing muddies what SRs announce for
|
|
611
|
-
// the bar.
|
|
630
|
+
// Marks stay outside the progressbar's presentational subtree; their
|
|
631
|
+
// Tooltip descriptions must not change the bar's own semantics.
|
|
612
632
|
const {container} = render(
|
|
613
633
|
<ProgressBar
|
|
614
634
|
value={50}
|
|
@@ -617,9 +637,7 @@ describe('ProgressBar', () => {
|
|
|
617
637
|
/>,
|
|
618
638
|
);
|
|
619
639
|
const progressbar = screen.getByRole('progressbar');
|
|
620
|
-
|
|
621
|
-
expect(progressbar.querySelector(MARK)).not.toBeNull();
|
|
622
|
-
// But it is not a labeled graphic that pollutes the a11y subtree.
|
|
640
|
+
expect(progressbar.querySelector(MARK)).toBeNull();
|
|
623
641
|
expect(progressbar.querySelector('[role="img"]')).toBeNull();
|
|
624
642
|
expect(progressbar.querySelector('[aria-label]')).toBeNull();
|
|
625
643
|
expect(container.querySelectorAll(MARK)).toHaveLength(1);
|
|
@@ -637,9 +655,9 @@ describe('ProgressBar', () => {
|
|
|
637
655
|
expect(progressbar.getAttribute('aria-valuetext')).toBe('50%');
|
|
638
656
|
});
|
|
639
657
|
|
|
640
|
-
it('
|
|
641
|
-
//
|
|
642
|
-
//
|
|
658
|
+
it('preserves the fill inside the progressbar when marks are rendered outside it', () => {
|
|
659
|
+
// Only the fill belongs to the semantic track; the focusable marks
|
|
660
|
+
// remain independently available outside its presentational subtree.
|
|
643
661
|
const {container} = render(
|
|
644
662
|
<ProgressBar
|
|
645
663
|
value={50}
|
|
@@ -652,7 +670,7 @@ describe('ProgressBar', () => {
|
|
|
652
670
|
expect(fill.style.width).toBe('50%');
|
|
653
671
|
expect(fill.classList.contains('astryx-progressbar-mark')).toBe(false);
|
|
654
672
|
const mark = container.querySelector<HTMLElement>(MARK)!;
|
|
655
|
-
expect(
|
|
673
|
+
expect(progressbar).not.toContainElement(mark);
|
|
656
674
|
expect(container.querySelectorAll(MARK)).toHaveLength(1);
|
|
657
675
|
});
|
|
658
676
|
|
|
@@ -215,26 +215,23 @@ const styles = stylex.create({
|
|
|
215
215
|
whiteSpace: 'nowrap',
|
|
216
216
|
borderWidth: 0,
|
|
217
217
|
},
|
|
218
|
-
// The
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
|
|
223
|
-
// clip via `trackClipped` (see below) — its sliding fill travels outside the
|
|
224
|
-
// track and must be clipped, and marks are ignored while indeterminate, so
|
|
225
|
-
// there is nothing to overhang.
|
|
226
|
-
track: {
|
|
218
|
+
// The in-flow track determines this containing block's actual height.
|
|
219
|
+
// Marks share its geometry without depending on the label row's height or
|
|
220
|
+
// entering the progressbar's presentational subtree. Keep it unclipped so
|
|
221
|
+
// themed tall marks can overhang the track symmetrically.
|
|
222
|
+
trackContainer: {
|
|
227
223
|
position: 'relative',
|
|
228
224
|
width: '100%',
|
|
225
|
+
},
|
|
226
|
+
// The semantic rail holds only the fill, which rounds its own corners.
|
|
227
|
+
track: {
|
|
228
|
+
width: '100%',
|
|
229
229
|
height: '8px',
|
|
230
230
|
backgroundColor: colorVars['--color-background-muted'],
|
|
231
231
|
borderRadius: radiusVars['--radius-full'],
|
|
232
232
|
},
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
// relies on the track clipping it to the visible window. Applied only when
|
|
236
|
-
// `isIndeterminate` (marks are suppressed then, so nothing needs to overhang)
|
|
237
|
-
// so it never re-clips a themed tall mark in determinate mode.
|
|
233
|
+
// The indeterminate fill overshoots the track on both sides and must be
|
|
234
|
+
// clipped to the visible rail. Marks are suppressed in this mode.
|
|
238
235
|
trackClipped: {
|
|
239
236
|
overflow: 'hidden',
|
|
240
237
|
},
|
|
@@ -260,11 +257,10 @@ const styles = stylex.create({
|
|
|
260
257
|
animationTimingFunction: 'ease-in-out',
|
|
261
258
|
animationIterationCount: 'infinite',
|
|
262
259
|
},
|
|
263
|
-
// A mark is a vertical tick centered on the track
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
// `insetInlineStart`; the translate mirrors under RTL.
|
|
260
|
+
// A mark is a vertical tick centered on the track via their shared positioning container.
|
|
261
|
+
// It stays outside role="progressbar" so it remains independently focusable.
|
|
262
|
+
// The centering translate keeps themed overhang symmetric;
|
|
263
|
+
// insetInlineStart and the mirrored translate preserve RTL.
|
|
268
264
|
//
|
|
269
265
|
// The dimensions read private vars rather than being plain declarations: a
|
|
270
266
|
// theme writes `width`/`height` on the `progressbar-mark` target as usual and
|
|
@@ -518,59 +514,50 @@ export function ProgressBar({
|
|
|
518
514
|
<VisuallyHidden id={labelId}>{label}</VisuallyHidden>
|
|
519
515
|
)}
|
|
520
516
|
|
|
521
|
-
{
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
{/* Target marks — children of the progressbar element (unchanged),
|
|
566
|
-
layered above the fill so they show whether progress is below or
|
|
567
|
-
past them. A mark's color follows what it sits on: inside the fill
|
|
568
|
-
it uses the fill variant's on-color, out on the bare track it uses
|
|
569
|
-
the emphasized divider color. Each mark is labeled, so it is a
|
|
570
|
-
focusable Tooltip trigger: the label is visible on hover/focus and
|
|
571
|
-
names the mark for assistive tech via the Tooltip's
|
|
572
|
-
aria-describedby, without adding a labeled child to the
|
|
573
|
-
progressbar's own a11y subtree. */}
|
|
517
|
+
<div {...stylex.props(styles.trackContainer)}>
|
|
518
|
+
<div
|
|
519
|
+
role="progressbar"
|
|
520
|
+
aria-valuenow={isIndeterminate ? undefined : clampedValue}
|
|
521
|
+
aria-valuemin={isIndeterminate ? undefined : 0}
|
|
522
|
+
aria-valuemax={isIndeterminate ? undefined : safeMax}
|
|
523
|
+
aria-labelledby={labelId}
|
|
524
|
+
aria-valuetext={isIndeterminate ? undefined : valueText}
|
|
525
|
+
{...mergeProps(
|
|
526
|
+
themeProps('progress-bar-track', undefined, {
|
|
527
|
+
legacyNames: ['progressbar-track'],
|
|
528
|
+
}),
|
|
529
|
+
stylex.props(styles.track, isIndeterminate && styles.trackClipped),
|
|
530
|
+
)}>
|
|
531
|
+
{isIndeterminate ? (
|
|
532
|
+
<div
|
|
533
|
+
{...mergeProps(
|
|
534
|
+
themeProps(
|
|
535
|
+
'progress-bar-fill',
|
|
536
|
+
{variant: fillVariant},
|
|
537
|
+
{legacyNames: ['progressbar-fill']},
|
|
538
|
+
),
|
|
539
|
+
stylex.props(
|
|
540
|
+
styles.indeterminateFill,
|
|
541
|
+
variantStyles[fillVariant],
|
|
542
|
+
),
|
|
543
|
+
)}
|
|
544
|
+
/>
|
|
545
|
+
) : (
|
|
546
|
+
<div
|
|
547
|
+
{...mergeProps(
|
|
548
|
+
themeProps(
|
|
549
|
+
'progress-bar-fill',
|
|
550
|
+
{variant: fillVariant},
|
|
551
|
+
{legacyNames: ['progressbar-fill']},
|
|
552
|
+
),
|
|
553
|
+
stylex.props(styles.fill, variantStyles[fillVariant]),
|
|
554
|
+
)}
|
|
555
|
+
style={{width: `${percentage}%`}}
|
|
556
|
+
/>
|
|
557
|
+
)}
|
|
558
|
+
</div>
|
|
559
|
+
{/* Marks overlay the fill but live outside the semantic progressbar.
|
|
560
|
+
Their Tooltip descriptions remain independently reachable on focus. */}
|
|
574
561
|
{resolvedMarks.map(mark => {
|
|
575
562
|
// The tick element. It is both the Tooltip's anchor and the Suspense
|
|
576
563
|
// fallback shown while the lazy Tooltip chunk loads, so the tick is
|
|
@@ -132,6 +132,17 @@ export const docs = {
|
|
|
132
132
|
{name: 'RadioListItem'},
|
|
133
133
|
],
|
|
134
134
|
usage: {
|
|
135
|
+
accessibility: [
|
|
136
|
+
{
|
|
137
|
+
name: 'Radio circle',
|
|
138
|
+
category: 'Color contrast',
|
|
139
|
+
criterion: '1.4.11 Non-text Contrast',
|
|
140
|
+
requirement: '3:1',
|
|
141
|
+
states: ['Rest', 'Hover', 'Pointer down', 'Selected'],
|
|
142
|
+
description:
|
|
143
|
+
'The circle edge (unselected) and fill (selected) must have at least 3:1 contrast with the surface behind them. For Hover and Pointer down, measure the final colors after the tint and the pressed overlay are applied.',
|
|
144
|
+
},
|
|
145
|
+
],
|
|
135
146
|
description:
|
|
136
147
|
'A group of options where only one can be selected at a time. All options are visible at once, making it easy to compare choices. Use it when users need to pick one option from a small set.',
|
|
137
148
|
bestPractices: [
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
16
16
|
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
17
17
|
import userEvent from '@testing-library/user-event';
|
|
18
|
+
import {hasPressedArm} from '../__tests__/pressState';
|
|
18
19
|
import {RadioList} from './RadioList';
|
|
19
20
|
import {RadioListItem} from './RadioListItem';
|
|
20
21
|
import {getForcedColorsRules} from '../__tests__/forcedColors';
|
|
@@ -856,3 +857,34 @@ describe('forced colors (WCAG 1.4.11)', () => {
|
|
|
856
857
|
expect(getForcedColorsRules()).toContain('background-color: canvastext;');
|
|
857
858
|
});
|
|
858
859
|
});
|
|
860
|
+
|
|
861
|
+
describe('pressed state', () => {
|
|
862
|
+
it('paints the pressed overlay over the radio indicator while the row is pressed', () => {
|
|
863
|
+
const {container} = render(
|
|
864
|
+
<RadioList label="Plan" value="a" onChange={() => {}}>
|
|
865
|
+
<RadioListItem label="Option A" value="a" />
|
|
866
|
+
<RadioListItem label="Option B" value="b" />
|
|
867
|
+
</RadioList>,
|
|
868
|
+
);
|
|
869
|
+
const circle = container.querySelector('.astryx-radio-indicator');
|
|
870
|
+
const wrapper = circle?.parentElement?.parentElement;
|
|
871
|
+
if (wrapper == null) {
|
|
872
|
+
throw new Error('the radio has no indicator wrapper to press');
|
|
873
|
+
}
|
|
874
|
+
expect(hasPressedArm(wrapper)).toBe(true);
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
it('does not expose a pressed arm on a disabled radio', () => {
|
|
878
|
+
const {container} = render(
|
|
879
|
+
<RadioList label="Plan" value="a" onChange={() => {}}>
|
|
880
|
+
<RadioListItem label="Unavailable" value="b" isDisabled />
|
|
881
|
+
</RadioList>,
|
|
882
|
+
);
|
|
883
|
+
const circle = container.querySelector('.astryx-radio-indicator');
|
|
884
|
+
const wrapper = circle?.parentElement?.parentElement;
|
|
885
|
+
if (wrapper == null) {
|
|
886
|
+
throw new Error('the radio has no indicator wrapper');
|
|
887
|
+
}
|
|
888
|
+
expect(hasPressedArm(wrapper)).toBe(false);
|
|
889
|
+
});
|
|
890
|
+
});
|