@astryxdesign/core 0.6.2 → 0.6.3-canary.039a67e
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/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +33 -12
- 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.d.ts +2 -1
- package/dist/Chat/ChatSendButton.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.js +6 -4
- package/dist/Chat/ChatSystemMessage.d.ts +3 -3
- package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
- package/dist/Chat/ChatSystemMessage.js +2 -2
- package/dist/Chat/ChatTokenizedText.d.ts +6 -6
- package/dist/Chat/ChatTokenizedText.js +10 -6
- package/dist/Chat/ChatToolCalls.d.ts +7 -9
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +43 -26
- 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 +25 -5
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +29 -17
- 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/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +4 -4
- package/dist/DateTimeInput/DateTimeInput.d.ts +32 -15
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +55 -30
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
- package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.d.ts.map +1 -1
- 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 +726 -177
- 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/SegmentedControl.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControl.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 +30 -14
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +61 -13
- package/dist/TimeInput/TouchTimeField.d.ts +11 -0
- package/dist/TimeInput/TouchTimeField.d.ts.map +1 -0
- package/dist/TimeInput/TouchTimeField.js +417 -0
- package/dist/TimeInput/index.d.ts +1 -1
- package/dist/TimeInput/index.d.ts.map +1 -1
- 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/defineTheme.d.ts +3 -0
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +4 -1
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +4 -0
- package/dist/theme/generateThemeRules.d.ts +15 -7
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +143 -35
- package/dist/theme/themeAdaptations.d.ts +5 -3
- package/dist/theme/themeAdaptations.d.ts.map +1 -1
- package/dist/theme/themeAdaptations.js +33 -5
- package/dist/utils/inputPresentation.d.ts +55 -0
- package/dist/utils/inputPresentation.d.ts.map +1 -0
- package/dist/utils/inputPresentation.js +108 -0
- package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
- package/dist/utils/interactionOverlay.stylex.js +9 -0
- package/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/Avatar/Avatar.doc.mjs +1 -1
- package/src/Avatar/Avatar.test.tsx +30 -0
- package/src/Avatar/Avatar.tsx +38 -14
- 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.doc.mjs +32 -0
- package/src/Chat/ChatSendButton.spec.md +227 -0
- package/src/Chat/ChatSendButton.test.tsx +128 -8
- package/src/Chat/ChatSendButton.tsx +6 -4
- package/src/Chat/ChatSystemMessage.doc.mjs +115 -12
- package/src/Chat/ChatSystemMessage.spec.md +225 -0
- package/src/Chat/ChatSystemMessage.test.tsx +112 -20
- package/src/Chat/ChatSystemMessage.tsx +4 -6
- package/src/Chat/ChatTokenizedText.doc.mjs +96 -9
- package/src/Chat/ChatTokenizedText.spec.md +190 -0
- package/src/Chat/ChatTokenizedText.test.tsx +60 -1
- package/src/Chat/ChatTokenizedText.tsx +14 -8
- package/src/Chat/ChatToolCalls.doc.mjs +4 -1
- package/src/Chat/ChatToolCalls.spec.md +194 -0
- package/src/Chat/ChatToolCalls.test.tsx +83 -0
- package/src/Chat/ChatToolCalls.tsx +46 -21
- 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/__tests__/ChatSendButton.a11y.chromium.spec.ts +1522 -0
- package/src/Chat/__tests__/ChatSystemMessage.a11y.chromium.spec.ts +1004 -0
- package/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts +573 -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.doc.mjs +38 -9
- package/src/DateInput/DateInput.tsx +59 -17
- package/src/DateInput/NativeDateField.tsx +24 -8
- package/src/DateInput/Presentation.test.tsx +121 -0
- package/src/DateInput/TouchDateField.tsx +6 -2
- package/src/DateInput/index.ts +1 -0
- package/src/DateRangeInput/DateRangeInput.tsx +6 -1
- package/src/DateTimeInput/DateTimeInput.doc.mjs +28 -12
- package/src/DateTimeInput/DateTimeInput.tsx +93 -37
- package/src/DateTimeInput/Presentation.test.tsx +89 -0
- package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
- package/src/DateTimeInput/index.ts +1 -0
- 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 +210 -45
- package/src/Markdown/Markdown.test.tsx +87 -3
- 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 +43 -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 +38 -6
- package/src/Markdown/parser.ts +1221 -242
- 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 +61 -0
- package/src/SegmentedControl/SegmentedControl.tsx +2 -1
- package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
- package/src/Selector/Selector.doc.mjs +3 -3
- 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/NativeTimeInput.test.tsx +36 -3
- package/src/TimeInput/Presentation.test.tsx +148 -0
- package/src/TimeInput/TimeInput.doc.mjs +21 -5
- package/src/TimeInput/TimeInput.tsx +102 -11
- package/src/TimeInput/TouchTimeField.tsx +572 -0
- package/src/TimeInput/index.ts +1 -0
- 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/defineTheme.ts +4 -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 +231 -50
- package/src/theme/themeAdaptations.test.ts +211 -1
- package/src/theme/themeAdaptations.ts +50 -4
- package/src/theme/tokenValueCompat.test.ts +4 -1
- package/src/utils/inputPresentation.ts +143 -0
- package/src/utils/interactionOverlay.stylex.ts +20 -0
- package/src/utils/safeUrl.test.ts +88 -0
- package/src/utils/safeUrl.ts +85 -0
|
@@ -6,14 +6,22 @@
|
|
|
6
6
|
* Shared logic for generating CSS rules from a resolved theme definition,
|
|
7
7
|
* including one component-leaf lowering path for root, adaptation, and
|
|
8
8
|
* media-surface values plus condition-correct Heading weight precedence guards.
|
|
9
|
+
* Built adaptation metadata resolves against the same root component defaults
|
|
10
|
+
* as defineTheme, so scale-only rules do not reset authored component styles.
|
|
9
11
|
* Used by both the runtime path (Theme injects <style>) and the build
|
|
10
12
|
* path (`astryx theme build` pre-compiles to CSS files).
|
|
11
13
|
*
|
|
14
|
+
* Every consumer-supplied declaration is checked by declarationBoundary.ts
|
|
15
|
+
* before it is emitted, so a value can never end its declaration or rule
|
|
16
|
+
* early. A refused declaration is dropped and reported in the supplied
|
|
17
|
+
* warnings array (build receipts), or through `console.warn` (runtime).
|
|
18
|
+
*
|
|
12
19
|
* Extracted from defineTheme.ts to reduce cyclomatic complexity and provide
|
|
13
20
|
* a clear single-responsibility module for CSS generation.
|
|
14
21
|
*
|
|
15
|
-
* @input DefinedTheme (resolved theme object from defineTheme)
|
|
16
|
-
* @output CSS rule strings, split by layer (component vs prose)
|
|
22
|
+
* @input DefinedTheme (resolved theme object from defineTheme), optional warnings array
|
|
23
|
+
* @output CSS rule strings, split by layer (component vs prose), and warning text
|
|
24
|
+
* for each dropped declaration
|
|
17
25
|
* @position packages/core/src/theme/generateThemeRules.ts
|
|
18
26
|
*/
|
|
19
27
|
|
|
@@ -26,6 +34,10 @@ import {parseStyleKey} from '../utils/parseStyleKey';
|
|
|
26
34
|
import {getDerivedVars} from './derivedVarRegistry';
|
|
27
35
|
import {dataTokenDefaults} from './domainTokens/dataTokens';
|
|
28
36
|
import {cssVar, classPrefix, dataAttrNamespace} from '../naming';
|
|
37
|
+
import {
|
|
38
|
+
checkDeclarationName,
|
|
39
|
+
checkDeclarationValue,
|
|
40
|
+
} from './declarationBoundary';
|
|
29
41
|
|
|
30
42
|
/**
|
|
31
43
|
* Theme @scope selectors.
|
|
@@ -366,6 +378,117 @@ function expandContainerPadding(
|
|
|
366
378
|
return tokens;
|
|
367
379
|
}
|
|
368
380
|
|
|
381
|
+
// =============================================================================
|
|
382
|
+
// Declaration assembly: a declaration always stays one declaration
|
|
383
|
+
// =============================================================================
|
|
384
|
+
|
|
385
|
+
type DiagnosticSink = (message: string) => void;
|
|
386
|
+
|
|
387
|
+
const warnToConsole: DiagnosticSink = message => {
|
|
388
|
+
console.warn(`[astryx theme] ${message}`);
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
/** Build receipts collect warning text; runtime callers warn by default. */
|
|
392
|
+
function diagnosticSink(warnings: string[] | undefined): DiagnosticSink {
|
|
393
|
+
return warnings ? message => warnings.push(message) : warnToConsole;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Shorten an authored value for a one-line message. */
|
|
397
|
+
function previewValue(value: string): string {
|
|
398
|
+
const oneLine = JSON.stringify(value);
|
|
399
|
+
return oneLine.length > 80 ? `${oneLine.slice(0, 77)}..."` : oneLine;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function reportDrop(
|
|
403
|
+
sink: DiagnosticSink,
|
|
404
|
+
property: string,
|
|
405
|
+
value: string,
|
|
406
|
+
location: string,
|
|
407
|
+
reason: string,
|
|
408
|
+
): void {
|
|
409
|
+
sink(
|
|
410
|
+
`dropped "${property}" in ${location}: ${reason} (value: ${previewValue(value)})`,
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* True when `name: value;` stays exactly one declaration; otherwise reports
|
|
416
|
+
* the drop and returns false. Both checks follow CSS syntax, so valid CSS a
|
|
417
|
+
* browser keeps inside one declaration (a `data:` URI, `Gill\ Sans`, a closed
|
|
418
|
+
* comment, a vendor-prefixed property) is never refused; see
|
|
419
|
+
* declarationBoundary.ts for the rules.
|
|
420
|
+
*/
|
|
421
|
+
function acceptDeclaration(
|
|
422
|
+
property: string,
|
|
423
|
+
value: string,
|
|
424
|
+
location: string,
|
|
425
|
+
sink: DiagnosticSink,
|
|
426
|
+
): boolean {
|
|
427
|
+
const reason = checkDeclarationName(property) ?? checkDeclarationValue(value);
|
|
428
|
+
if (reason === null) {
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
431
|
+
reportDrop(sink, property, value, location, reason);
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Assemble `prop: value;` lines, dropping (and reporting) any entry whose
|
|
437
|
+
* property or value could not stay a single declaration. Theme definitions
|
|
438
|
+
* are code, but apps do assemble them from stored input (brand colors,
|
|
439
|
+
* white-labeling), so the generated stylesheet must never extend beyond the
|
|
440
|
+
* declarations it means to emit.
|
|
441
|
+
*/
|
|
442
|
+
function joinDeclarations(
|
|
443
|
+
entries: [string, string][],
|
|
444
|
+
location: string,
|
|
445
|
+
sink: DiagnosticSink,
|
|
446
|
+
mapProp: (prop: string) => string = p => p,
|
|
447
|
+
): string {
|
|
448
|
+
const lines: string[] = [];
|
|
449
|
+
for (const [rawProp, rawValue] of entries) {
|
|
450
|
+
// Legacy unenrolled tokens retain non-string values. Scan the same text
|
|
451
|
+
// interpolation has always emitted, without changing the normalized theme.
|
|
452
|
+
const value = `${rawValue}`;
|
|
453
|
+
const prop = mapProp(rawProp);
|
|
454
|
+
if (acceptDeclaration(prop, value, location, sink)) {
|
|
455
|
+
lines.push(` ${prop}: ${value};`);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return lines.join('\n');
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/** The `:scope` token block for portable and theme-local token values. */
|
|
462
|
+
function tokenBlock(
|
|
463
|
+
source: ThemeRuleSource,
|
|
464
|
+
location: string,
|
|
465
|
+
sink: DiagnosticSink,
|
|
466
|
+
): string | null {
|
|
467
|
+
const declarations = [
|
|
468
|
+
joinDeclarations(Object.entries(source.tokens), `${location}tokens`, sink),
|
|
469
|
+
joinDeclarations(
|
|
470
|
+
Object.entries(source.localTokens ?? {}),
|
|
471
|
+
`${location}localTokens`,
|
|
472
|
+
sink,
|
|
473
|
+
),
|
|
474
|
+
]
|
|
475
|
+
.filter(block => block.length > 0)
|
|
476
|
+
.join('\n');
|
|
477
|
+
const hasEntries =
|
|
478
|
+
Object.keys(source.tokens).length > 0 ||
|
|
479
|
+
Object.keys(source.localTokens ?? {}).length > 0;
|
|
480
|
+
return hasEntries ? ` :scope {\n${declarations}\n }` : null;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/** `components.button["variant:secondary"]`-style location for a rule. */
|
|
484
|
+
function componentLocation(
|
|
485
|
+
prefix: string,
|
|
486
|
+
component: string,
|
|
487
|
+
key: string,
|
|
488
|
+
): string {
|
|
489
|
+
return `${prefix}components.${component}[${JSON.stringify(key)}]`;
|
|
490
|
+
}
|
|
491
|
+
|
|
369
492
|
// =============================================================================
|
|
370
493
|
// Public API
|
|
371
494
|
// =============================================================================
|
|
@@ -393,9 +516,12 @@ export interface ThemeRuleSource {
|
|
|
393
516
|
components?: ComponentStyleMap;
|
|
394
517
|
}
|
|
395
518
|
|
|
396
|
-
export function generateThemeRules(
|
|
519
|
+
export function generateThemeRules(
|
|
520
|
+
theme: ThemeRuleSource,
|
|
521
|
+
warnings?: string[],
|
|
522
|
+
): string[] {
|
|
397
523
|
const parts: string[] = [];
|
|
398
|
-
const
|
|
524
|
+
const sink = diagnosticSink(warnings);
|
|
399
525
|
|
|
400
526
|
// Bare prose rules reference semantic variables instead of baking the root
|
|
401
527
|
// value. That lets adaptation token writes take effect through CSS alone
|
|
@@ -403,21 +529,25 @@ export function generateThemeRules(theme: ThemeRuleSource): string[] {
|
|
|
403
529
|
const val = (key: string): string => `var(${key})`;
|
|
404
530
|
|
|
405
531
|
// 1. Token block — CSS custom properties on :scope
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
532
|
+
const tokenRules = tokenBlock(theme, '', sink);
|
|
533
|
+
if (tokenRules !== null) {
|
|
534
|
+
parts.push(tokenRules);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// 1b. Base font — apply the theme's declared body font to the scope root.
|
|
538
|
+
// Components styled with `font-family: inherit` (SideNav items, Buttons)
|
|
539
|
+
// otherwise resolve against the browser default serif, since nothing else
|
|
540
|
+
// sets a page font. `font-family` inherits, so one rule on :scope covers
|
|
541
|
+
// the tree. Only emitted when the theme declares a body font, so a bare
|
|
542
|
+
// theme still contributes no scope rules of its own.
|
|
543
|
+
if (theme.tokens['--font-family-body']) {
|
|
544
|
+
parts.push(` :scope {\n font-family: var(--font-family-body);\n }`);
|
|
415
545
|
}
|
|
416
546
|
|
|
417
547
|
// 2. Component overrides: stable .astryx-* target classes combined with
|
|
418
548
|
// reflected data-* selectors for visual props and runtime states.
|
|
419
549
|
if (theme.components) {
|
|
420
|
-
generateComponentRules(theme.components, parts);
|
|
550
|
+
generateComponentRules(theme.components, parts, {sink});
|
|
421
551
|
}
|
|
422
552
|
|
|
423
553
|
// 3. Prose HTML element rules (h1-h6, p, small, code, hr)
|
|
@@ -513,6 +643,13 @@ function generateHeadingWeightOverrides(
|
|
|
513
643
|
}
|
|
514
644
|
}
|
|
515
645
|
|
|
646
|
+
/**
|
|
647
|
+
* The `fontWeight` a heading rule authors for `styleKey`, or undefined when
|
|
648
|
+
* it has none. A value that cannot stay one declaration is treated as not
|
|
649
|
+
* authored, so the override falls back to the inherited or token weight
|
|
650
|
+
* instead of interpolating it; the drop itself is reported where that same
|
|
651
|
+
* rule's declarations are emitted, so it is not reported twice here.
|
|
652
|
+
*/
|
|
516
653
|
function getAuthoredHeadingWeight(
|
|
517
654
|
headingRuleMap: Record<string, unknown>,
|
|
518
655
|
styleKey: string,
|
|
@@ -522,13 +659,20 @@ function getAuthoredHeadingWeight(
|
|
|
522
659
|
return undefined;
|
|
523
660
|
}
|
|
524
661
|
const fontWeight = (rule as Record<string, unknown>).fontWeight;
|
|
525
|
-
return typeof fontWeight === 'string'
|
|
662
|
+
return typeof fontWeight === 'string' &&
|
|
663
|
+
checkDeclarationValue(fontWeight) === null
|
|
664
|
+
? fontWeight
|
|
665
|
+
: undefined;
|
|
526
666
|
}
|
|
527
667
|
|
|
528
668
|
/** Options shared by root, adaptation, and media-surface component lowering. */
|
|
529
669
|
interface ComponentRuleOptions {
|
|
530
670
|
resetInheritedPaddingSpecificity?: boolean;
|
|
531
671
|
surface?: MediaSurface;
|
|
672
|
+
/** Receives dropped declarations; defaults to `console.warn`. */
|
|
673
|
+
sink?: DiagnosticSink;
|
|
674
|
+
/** Location prefix for diagnostics, e.g. `onDark.` or `adaptations[0].`. */
|
|
675
|
+
location?: string;
|
|
532
676
|
}
|
|
533
677
|
|
|
534
678
|
/**
|
|
@@ -545,6 +689,8 @@ function generateComponentRules(
|
|
|
545
689
|
{
|
|
546
690
|
resetInheritedPaddingSpecificity = false,
|
|
547
691
|
surface,
|
|
692
|
+
sink = warnToConsole,
|
|
693
|
+
location: locationPrefix = '',
|
|
548
694
|
}: ComponentRuleOptions = {},
|
|
549
695
|
): void {
|
|
550
696
|
for (const [component, rules] of Object.entries(components)) {
|
|
@@ -556,6 +702,7 @@ function generateComponentRules(
|
|
|
556
702
|
|
|
557
703
|
const suffix = parseStyleKey(key);
|
|
558
704
|
const baseSelector = componentSelector(component, suffix, surface);
|
|
705
|
+
const location = componentLocation(locationPrefix, component, key);
|
|
559
706
|
|
|
560
707
|
// Separate regular properties from pseudo-class overrides
|
|
561
708
|
const props: [string, string][] = [];
|
|
@@ -564,7 +711,14 @@ function generateComponentRules(
|
|
|
564
711
|
for (const [prop, value] of entries) {
|
|
565
712
|
if (prop.startsWith(':') && typeof value === 'object') {
|
|
566
713
|
pseudos.push([prop, value]);
|
|
567
|
-
} else
|
|
714
|
+
} else if (
|
|
715
|
+
acceptDeclaration(
|
|
716
|
+
toKebabCase(prop),
|
|
717
|
+
`${value as string}`,
|
|
718
|
+
location,
|
|
719
|
+
sink,
|
|
720
|
+
)
|
|
721
|
+
) {
|
|
568
722
|
props.push([prop, value as string]);
|
|
569
723
|
}
|
|
570
724
|
}
|
|
@@ -644,9 +798,12 @@ function generateComponentRules(
|
|
|
644
798
|
|
|
645
799
|
// Emit base rule
|
|
646
800
|
if (finalProps.length > 0) {
|
|
647
|
-
const declarations =
|
|
648
|
-
|
|
649
|
-
|
|
801
|
+
const declarations = joinDeclarations(
|
|
802
|
+
finalProps,
|
|
803
|
+
location,
|
|
804
|
+
sink,
|
|
805
|
+
toKebabCase,
|
|
806
|
+
);
|
|
650
807
|
parts.push(` ${baseSelector} {\n${declarations}\n }`);
|
|
651
808
|
}
|
|
652
809
|
|
|
@@ -654,9 +811,12 @@ function generateComponentRules(
|
|
|
654
811
|
for (const [pseudo, pseudoStyles] of pseudos) {
|
|
655
812
|
const pseudoEntries = Object.entries(pseudoStyles);
|
|
656
813
|
if (pseudoEntries.length > 0) {
|
|
657
|
-
const declarations =
|
|
658
|
-
|
|
659
|
-
.
|
|
814
|
+
const declarations = joinDeclarations(
|
|
815
|
+
pseudoEntries,
|
|
816
|
+
`${location}[${JSON.stringify(pseudo)}]`,
|
|
817
|
+
sink,
|
|
818
|
+
toKebabCase,
|
|
819
|
+
);
|
|
660
820
|
parts.push(
|
|
661
821
|
` ${appendPseudoToSelectorList(baseSelector, pseudo)} {\n${declarations}\n }`,
|
|
662
822
|
);
|
|
@@ -822,8 +982,11 @@ function generateSizeOverrides(
|
|
|
822
982
|
* Component rules (tokens, stable .astryx-* targets plus data-* selectors) are
|
|
823
983
|
* that need to beat StyleX — they stay in astryx-theme (above StyleX layers).
|
|
824
984
|
*/
|
|
825
|
-
export function generateThemeRulesSplit(
|
|
826
|
-
|
|
985
|
+
export function generateThemeRulesSplit(
|
|
986
|
+
theme: DefinedTheme,
|
|
987
|
+
warnings?: string[],
|
|
988
|
+
): ThemeRulesSplit {
|
|
989
|
+
const allRules = generateThemeRules(theme, warnings);
|
|
827
990
|
|
|
828
991
|
const prose: string[] = [];
|
|
829
992
|
const component: string[] = [];
|
|
@@ -847,22 +1010,29 @@ export function generateThemeRulesSplit(theme: DefinedTheme): ThemeRulesSplit {
|
|
|
847
1010
|
* to media contexts — only tokens change. Themes can further customize
|
|
848
1011
|
* via onDark.components / onLight.components.
|
|
849
1012
|
*/
|
|
850
|
-
export function generateOnMediaCSS(
|
|
1013
|
+
export function generateOnMediaCSS(
|
|
1014
|
+
theme: DefinedTheme,
|
|
1015
|
+
warnings?: string[],
|
|
1016
|
+
): string {
|
|
851
1017
|
const parts: string[] = [];
|
|
852
1018
|
const scopeSelector = themeScopeStart(theme.name);
|
|
1019
|
+
const sink = diagnosticSink(warnings);
|
|
853
1020
|
|
|
854
1021
|
for (const surface of ['dark', 'light'] as const) {
|
|
855
1022
|
const onMedia = surface === 'dark' ? theme.__onDark : theme.__onLight;
|
|
856
1023
|
if (!onMedia) {
|
|
857
1024
|
continue;
|
|
858
1025
|
}
|
|
1026
|
+
const location = surface === 'dark' ? 'onDark.' : 'onLight.';
|
|
859
1027
|
|
|
860
1028
|
// Token overrides
|
|
861
1029
|
const tokenEntries = Object.entries(onMedia.tokens);
|
|
862
1030
|
if (tokenEntries.length > 0) {
|
|
863
|
-
const declarations =
|
|
864
|
-
|
|
865
|
-
|
|
1031
|
+
const declarations = joinDeclarations(
|
|
1032
|
+
tokenEntries,
|
|
1033
|
+
`${location}tokens`,
|
|
1034
|
+
sink,
|
|
1035
|
+
);
|
|
866
1036
|
parts.push(` ${mediaSelector(surface)} {\n${declarations}\n }`);
|
|
867
1037
|
}
|
|
868
1038
|
|
|
@@ -872,6 +1042,8 @@ export function generateOnMediaCSS(theme: DefinedTheme): string {
|
|
|
872
1042
|
generateComponentRules(onMedia.components, parts, {
|
|
873
1043
|
resetInheritedPaddingSpecificity: true,
|
|
874
1044
|
surface,
|
|
1045
|
+
sink,
|
|
1046
|
+
location,
|
|
875
1047
|
});
|
|
876
1048
|
generateColorOverrides(onMedia.components, parts, surface);
|
|
877
1049
|
generateSizeOverrides(onMedia.components, parts, surface);
|
|
@@ -895,22 +1067,22 @@ export function generateOnMediaCSS(theme: DefinedTheme): string {
|
|
|
895
1067
|
}
|
|
896
1068
|
|
|
897
1069
|
/** Generate only the declarations one adaptation rule writes. */
|
|
898
|
-
function generateAdaptationRuleRules(
|
|
1070
|
+
function generateAdaptationRuleRules(
|
|
1071
|
+
rule: ThemeRuleSource,
|
|
1072
|
+
location: string,
|
|
1073
|
+
sink: DiagnosticSink,
|
|
1074
|
+
): string[] {
|
|
899
1075
|
const parts: string[] = [];
|
|
900
|
-
const
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
];
|
|
904
|
-
if (tokenEntries.length > 0) {
|
|
905
|
-
const declarations = tokenEntries
|
|
906
|
-
.map(([prop, value]) => ` ${prop}: ${value};`)
|
|
907
|
-
.join('\n');
|
|
908
|
-
parts.push(` :scope {\n${declarations}\n }`);
|
|
1076
|
+
const tokens = tokenBlock(rule, location, sink);
|
|
1077
|
+
if (tokens !== null) {
|
|
1078
|
+
parts.push(tokens);
|
|
909
1079
|
}
|
|
910
1080
|
|
|
911
1081
|
if (rule.components) {
|
|
912
1082
|
generateComponentRules(rule.components, parts, {
|
|
913
1083
|
resetInheritedPaddingSpecificity: true,
|
|
1084
|
+
sink,
|
|
1085
|
+
location,
|
|
914
1086
|
});
|
|
915
1087
|
generateColorOverrides(rule.components, parts);
|
|
916
1088
|
generateSizeOverrides(rule.components, parts);
|
|
@@ -948,7 +1120,11 @@ function generateAdaptationMediaBlock(
|
|
|
948
1120
|
* rule. Bare prose follows semantic variables, so token writes need no duplicate
|
|
949
1121
|
* prose selectors here.
|
|
950
1122
|
*/
|
|
951
|
-
export function generateAdaptationCSS(
|
|
1123
|
+
export function generateAdaptationCSS(
|
|
1124
|
+
theme: DefinedTheme,
|
|
1125
|
+
warnings?: string[],
|
|
1126
|
+
): ThemeCSSOutput {
|
|
1127
|
+
const sink = diagnosticSink(warnings);
|
|
952
1128
|
// Built themes can reach this compiler without passing through defineTheme.
|
|
953
1129
|
// Validate retained metadata even when it has no rules (and therefore emits
|
|
954
1130
|
// no CSS): width points remain observable through AppShell and inheritance.
|
|
@@ -965,6 +1141,7 @@ export function generateAdaptationCSS(theme: DefinedTheme): ThemeCSSOutput {
|
|
|
965
1141
|
theme.__axes ?? {},
|
|
966
1142
|
theme.tokens,
|
|
967
1143
|
theme.localTokens,
|
|
1144
|
+
theme.components,
|
|
968
1145
|
)
|
|
969
1146
|
: undefined);
|
|
970
1147
|
if (!rules || rules.length === 0) {
|
|
@@ -982,8 +1159,12 @@ export function generateAdaptationCSS(theme: DefinedTheme): ThemeCSSOutput {
|
|
|
982
1159
|
// active whenever the later condition matches, even if the earlier condition
|
|
983
1160
|
// does not. Pairwise merging cannot repair that: multiple mutually exclusive
|
|
984
1161
|
// earlier rules can each overlap one broad later rule.
|
|
985
|
-
for (const rule of rules) {
|
|
986
|
-
const parts = generateAdaptationRuleRules(
|
|
1162
|
+
for (const [index, rule] of rules.entries()) {
|
|
1163
|
+
const parts = generateAdaptationRuleRules(
|
|
1164
|
+
rule,
|
|
1165
|
+
`adaptations[${index}].`,
|
|
1166
|
+
sink,
|
|
1167
|
+
);
|
|
987
1168
|
if (parts.length === 0) {
|
|
988
1169
|
continue;
|
|
989
1170
|
}
|
|
@@ -1029,12 +1210,9 @@ export function generateAdaptationCSS(theme: DefinedTheme): ThemeCSSOutput {
|
|
|
1029
1210
|
return {prose: '', component: blocks.join('\n\n')};
|
|
1030
1211
|
}
|
|
1031
1212
|
|
|
1032
|
-
/** Indent
|
|
1213
|
+
/** Indent the rule start without rewriting newlines inside authored values. */
|
|
1033
1214
|
function indentRule(rule: string): string {
|
|
1034
|
-
return rule
|
|
1035
|
-
.split('\n')
|
|
1036
|
-
.map(line => (line.length > 0 ? ` ${line}` : line))
|
|
1037
|
-
.join('\n');
|
|
1215
|
+
return ` ${rule}`;
|
|
1038
1216
|
}
|
|
1039
1217
|
|
|
1040
1218
|
/**
|
|
@@ -1075,8 +1253,11 @@ export function generateDataTokenDefaultsCSS(): string {
|
|
|
1075
1253
|
* The theme-independent `--color-data-*` defaults are not part of this output:
|
|
1076
1254
|
* see `generateDataTokenDefaultsCSS`.
|
|
1077
1255
|
*/
|
|
1078
|
-
export function generateThemeCSS(
|
|
1079
|
-
|
|
1256
|
+
export function generateThemeCSS(
|
|
1257
|
+
theme: DefinedTheme,
|
|
1258
|
+
warnings?: string[],
|
|
1259
|
+
): ThemeCSSOutput {
|
|
1260
|
+
const {component, prose} = generateThemeRulesSplit(theme, warnings);
|
|
1080
1261
|
const scopeSelector = themeScopeStart(theme.name);
|
|
1081
1262
|
const scopeTo = THEME_SCOPE_TO;
|
|
1082
1263
|
|
|
@@ -1096,14 +1277,14 @@ export function generateThemeCSS(theme: DefinedTheme): ThemeCSSOutput {
|
|
|
1096
1277
|
|
|
1097
1278
|
// Adaptations follow the root theme in authored order. Media-surface rules
|
|
1098
1279
|
// follow adaptations so onDark/onLight keep their specified precedence.
|
|
1099
|
-
const adaptationCss = generateAdaptationCSS(theme);
|
|
1280
|
+
const adaptationCss = generateAdaptationCSS(theme, warnings);
|
|
1100
1281
|
if (adaptationCss.component) {
|
|
1101
1282
|
componentCss = componentCss
|
|
1102
1283
|
? `${componentCss}\n\n${adaptationCss.component}`
|
|
1103
1284
|
: adaptationCss.component;
|
|
1104
1285
|
}
|
|
1105
1286
|
|
|
1106
|
-
const onMediaCss = generateOnMediaCSS(theme);
|
|
1287
|
+
const onMediaCss = generateOnMediaCSS(theme, warnings);
|
|
1107
1288
|
if (onMediaCss) {
|
|
1108
1289
|
componentCss = componentCss
|
|
1109
1290
|
? `${componentCss}\n\n${onMediaCss}`
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @file themeAdaptations.test.ts
|
|
5
5
|
* Tests AST-012's ordered, closed, CSS-first theme adaptation contract,
|
|
6
|
-
* including normalization and final
|
|
6
|
+
* including normalization, root-dependent type-scale component writes, and final
|
|
7
|
+
* reachable-cascade validation.
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
import {describe, expect, it} from 'vitest';
|
|
@@ -378,6 +379,215 @@ describe('rule order and writes', () => {
|
|
|
378
379
|
});
|
|
379
380
|
});
|
|
380
381
|
|
|
382
|
+
describe('adapted type-scale component defaults', () => {
|
|
383
|
+
const displayFamily = 'Sarina, "Brush Script MT", "Snell Roundhand", cursive';
|
|
384
|
+
const butterShapedInput: DefineThemeInput = {
|
|
385
|
+
name: 'butter-shaped',
|
|
386
|
+
typography: {
|
|
387
|
+
scale: {base: 16, ratio: 1.25},
|
|
388
|
+
body: {family: 'Outfit', fallbacks: 'sans-serif'},
|
|
389
|
+
},
|
|
390
|
+
components: {
|
|
391
|
+
text: Object.fromEntries(
|
|
392
|
+
['display-1', 'display-2', 'display-3'].map(type => [
|
|
393
|
+
`type:${type}`,
|
|
394
|
+
{fontFamily: displayFamily},
|
|
395
|
+
]),
|
|
396
|
+
),
|
|
397
|
+
button: {base: {borderRadius: '12px'}},
|
|
398
|
+
},
|
|
399
|
+
adaptations: {
|
|
400
|
+
rules: [
|
|
401
|
+
{
|
|
402
|
+
when: {width: {below: 'md'}, pointer: 'coarse'},
|
|
403
|
+
value: {typography: {scale: {base: 14, ratio: 1.2}}},
|
|
404
|
+
},
|
|
405
|
+
],
|
|
406
|
+
},
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
it('keeps butter-shaped display families while adapting scale tokens only', () => {
|
|
410
|
+
const theme = defineTheme(butterShapedInput);
|
|
411
|
+
const rule = theme.__adaptationRules![0];
|
|
412
|
+
const css = generateThemeCSS(theme).component;
|
|
413
|
+
const adaptiveCSS = generateAdaptationCSS(theme).component;
|
|
414
|
+
|
|
415
|
+
expect(rule.query).toBe('(width < 768px) and (pointer: coarse)');
|
|
416
|
+
expect(theme.tokens['--font-size-base']).toBe('1rem');
|
|
417
|
+
expect(rule.tokens['--font-size-base']).toBe('0.875rem');
|
|
418
|
+
expect(rule.tokens['--font-size-5xl']).not.toBe(
|
|
419
|
+
theme.tokens['--font-size-5xl'],
|
|
420
|
+
);
|
|
421
|
+
expect(adaptiveCSS).toContain('--font-size-base: 0.875rem');
|
|
422
|
+
// The root owns the var() wiring and its authored overrides. Re-emitting
|
|
423
|
+
// either would turn an unrelated scale change into a component write.
|
|
424
|
+
expect(rule.components).toBeUndefined();
|
|
425
|
+
expect(adaptiveCSS).not.toContain('.astryx-text');
|
|
426
|
+
expect(adaptiveCSS).not.toContain('.astryx-heading');
|
|
427
|
+
expect(adaptiveCSS).not.toContain('.astryx-button');
|
|
428
|
+
for (const type of ['display-1', 'display-2', 'display-3']) {
|
|
429
|
+
expect(theme.components?.text[`type:${type}`].fontFamily).toBe(
|
|
430
|
+
displayFamily,
|
|
431
|
+
);
|
|
432
|
+
expect(count(css, `.astryx-text[data-type="${type}"] {`)).toBe(1);
|
|
433
|
+
}
|
|
434
|
+
expect(count(css, `font-family: ${displayFamily};`)).toBe(3);
|
|
435
|
+
// Built modules retain root components + intent, not resolved rule layers.
|
|
436
|
+
expect(generateThemeCSS({...theme, __adaptationRules: undefined})).toEqual(
|
|
437
|
+
generateThemeCSS(theme),
|
|
438
|
+
);
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
it('fills only missing generated leaves when the root has no scale', () => {
|
|
442
|
+
const components = {
|
|
443
|
+
heading: {
|
|
444
|
+
'level:1': {fontFamily: 'serif', fontWeight: '900'},
|
|
445
|
+
'type:display-1': {fontSize: '5rem'},
|
|
446
|
+
},
|
|
447
|
+
text: {
|
|
448
|
+
'type:display-1': {fontFamily: displayFamily, lineHeight: '1.1'},
|
|
449
|
+
'type:body': {fontSize: '18px'},
|
|
450
|
+
'type:custom': {fontFamily: 'monospace'},
|
|
451
|
+
},
|
|
452
|
+
button: {base: {borderRadius: '12px'}},
|
|
453
|
+
};
|
|
454
|
+
const before = structuredClone(components);
|
|
455
|
+
const theme = defineTheme({
|
|
456
|
+
...butterShapedInput,
|
|
457
|
+
typography: undefined,
|
|
458
|
+
components,
|
|
459
|
+
});
|
|
460
|
+
const generated = theme.__adaptationRules![0].components!;
|
|
461
|
+
|
|
462
|
+
expect(generated.heading['level:1']).toEqual({
|
|
463
|
+
fontSize: 'var(--text-heading-1-size)',
|
|
464
|
+
lineHeight: 'var(--text-heading-1-leading)',
|
|
465
|
+
});
|
|
466
|
+
expect(generated.heading['type:display-1']).toEqual({
|
|
467
|
+
fontFamily: 'var(--font-family-heading)',
|
|
468
|
+
lineHeight: 'var(--text-display-1-leading)',
|
|
469
|
+
});
|
|
470
|
+
expect(generated.text['type:display-1']).toEqual({
|
|
471
|
+
fontSize: 'var(--text-display-1-size)',
|
|
472
|
+
});
|
|
473
|
+
expect(generated.text['type:body']).toEqual({
|
|
474
|
+
fontFamily: 'var(--font-family-body)',
|
|
475
|
+
lineHeight: 'var(--text-body-leading)',
|
|
476
|
+
});
|
|
477
|
+
expect(generated.text['type:custom']).toBeUndefined();
|
|
478
|
+
expect(generated.button).toBeUndefined();
|
|
479
|
+
expect(components).toEqual(before);
|
|
480
|
+
expect(theme.components).toEqual(before);
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
it('preserves explicit rule writes, including a later root-restoring value', () => {
|
|
484
|
+
const theme = defineTheme({
|
|
485
|
+
...butterShapedInput,
|
|
486
|
+
adaptations: {
|
|
487
|
+
rules: [
|
|
488
|
+
{
|
|
489
|
+
when: {pointer: 'coarse'},
|
|
490
|
+
value: {
|
|
491
|
+
typography: {scale: {base: 15}},
|
|
492
|
+
components: {
|
|
493
|
+
text: {'type:display-1': {fontFamily: 'monospace'}},
|
|
494
|
+
heading: {'level:1': {fontWeight: '300'}},
|
|
495
|
+
},
|
|
496
|
+
},
|
|
497
|
+
},
|
|
498
|
+
...butterShapedInput.adaptations!.rules!,
|
|
499
|
+
{
|
|
500
|
+
when: {contrast: 'more'},
|
|
501
|
+
value: {
|
|
502
|
+
typography: {scale: {base: 14}},
|
|
503
|
+
components: {
|
|
504
|
+
text: {'type:display-1': {fontFamily: displayFamily}},
|
|
505
|
+
},
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
],
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
const [first, scaleOnly, restore] = theme.__adaptationRules!;
|
|
512
|
+
expect(first.components).toEqual({
|
|
513
|
+
text: {'type:display-1': {fontFamily: 'monospace'}},
|
|
514
|
+
heading: {'level:1': {fontWeight: '300'}},
|
|
515
|
+
});
|
|
516
|
+
expect(scaleOnly.components).toBeUndefined();
|
|
517
|
+
expect(restore.components).toEqual({
|
|
518
|
+
text: {'type:display-1': {fontFamily: displayFamily}},
|
|
519
|
+
});
|
|
520
|
+
const css = generateAdaptationCSS(theme).component;
|
|
521
|
+
expect(css.indexOf('font-family: monospace')).toBeLessThan(
|
|
522
|
+
css.indexOf(`font-family: ${displayFamily}`),
|
|
523
|
+
);
|
|
524
|
+
// Explicit heading defaults still trigger the public weight-prop guard.
|
|
525
|
+
expect(css).toContain(
|
|
526
|
+
'.astryx-heading[data-weight="bold"] { font-weight: var(--font-weight-bold); }',
|
|
527
|
+
);
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
it('lets a later generated component leaf win when its root path is absent', () => {
|
|
531
|
+
const theme = defineTheme(
|
|
532
|
+
adaptationInput([
|
|
533
|
+
{
|
|
534
|
+
when: {pointer: 'coarse'},
|
|
535
|
+
value: {components: {text: {'type:body': {fontSize: '2rem'}}}},
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
when: {pointer: 'coarse'},
|
|
539
|
+
value: {typography: {scale: {base: 14, ratio: 1.2}}},
|
|
540
|
+
},
|
|
541
|
+
]),
|
|
542
|
+
);
|
|
543
|
+
expect(theme.__axes.typography).toBeUndefined();
|
|
544
|
+
expect(theme.components).toBeUndefined();
|
|
545
|
+
const [authored, generated] = theme.__adaptationRules!;
|
|
546
|
+
expect(authored.components?.text['type:body'].fontSize).toBe('2rem');
|
|
547
|
+
expect(generated.components?.text['type:body'].fontSize).toBe(
|
|
548
|
+
'var(--text-body-size)',
|
|
549
|
+
);
|
|
550
|
+
|
|
551
|
+
// FR4/FR6: only existing root paths suppress generated defaults. Without
|
|
552
|
+
// root wiring, the later scale produces a component write, so it beats the
|
|
553
|
+
// earlier authored leaf when both conditions match (unlike the case above).
|
|
554
|
+
const css = generateAdaptationCSS(theme).component;
|
|
555
|
+
const bodyRules = [
|
|
556
|
+
...css.matchAll(/\.astryx-text\[data-type="body"\] \{([^}]+)\}/g),
|
|
557
|
+
].map(match => match[1]);
|
|
558
|
+
expect(bodyRules).toHaveLength(2);
|
|
559
|
+
expect(bodyRules[0]).toContain('font-size: 2rem;');
|
|
560
|
+
expect(bodyRules[1]).toContain('font-size: var(--text-body-size);');
|
|
561
|
+
expect(mediaPreludes(css)).toEqual([
|
|
562
|
+
'(pointer: coarse)',
|
|
563
|
+
'(pointer: coarse)',
|
|
564
|
+
]);
|
|
565
|
+
expect(generateThemeCSS({...theme, __adaptationRules: undefined})).toEqual(
|
|
566
|
+
generateThemeCSS(theme),
|
|
567
|
+
);
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
it('uses the effective child root without mutating inherited components', () => {
|
|
571
|
+
const base = defineTheme(butterShapedInput);
|
|
572
|
+
const before = structuredClone(base.components);
|
|
573
|
+
const child = defineTheme({
|
|
574
|
+
name: 'child-display',
|
|
575
|
+
extends: base,
|
|
576
|
+
components: {
|
|
577
|
+
text: {'type:display-2': {fontFamily: 'serif'}},
|
|
578
|
+
heading: {'level:2': {fontFamily: 'monospace'}},
|
|
579
|
+
},
|
|
580
|
+
});
|
|
581
|
+
expect(child.__adaptationRules![0].components).toBeUndefined();
|
|
582
|
+
expect(child.components?.text['type:display-1'].fontFamily).toBe(
|
|
583
|
+
displayFamily,
|
|
584
|
+
);
|
|
585
|
+
expect(child.components?.text['type:display-2'].fontFamily).toBe('serif');
|
|
586
|
+
expect(child.components?.heading['level:2'].fontFamily).toBe('monospace');
|
|
587
|
+
expect(base.components).toEqual(before);
|
|
588
|
+
});
|
|
589
|
+
});
|
|
590
|
+
|
|
381
591
|
describe('theme-local adaptation values', () => {
|
|
382
592
|
const localName = '--astryx-theme-local-root-control-height';
|
|
383
593
|
|