@astryx-vue/core 0.3.0 → 0.4.0
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/dist/AlertDialog/index.js +1 -1
- package/dist/{AlertDialog-RAVA_cT1.js → AlertDialog-C2inDZWG.js} +5 -5
- package/dist/AppShell/index.js +1 -1
- package/dist/{AppShell-0wTvOo3H.js → AppShell-CumzH-8z.js} +3 -3
- package/dist/Avatar/index.js +1 -1
- package/dist/{Avatar-pPZ4dI_s.js → Avatar-BW0TE8t9.js} +47 -34
- package/dist/AvatarGroup/index.d.ts +1 -1
- package/dist/AvatarGroup/index.js +1 -1
- package/dist/{AvatarGroup-B--NQSB3.js → AvatarGroup-DLC_FFR5.js} +57 -13
- package/dist/Banner/index.d.ts +1 -1
- package/dist/Banner/index.js +1 -1
- package/dist/{Banner-GbGxrqQO.js → Banner-C5VAwo4D.js} +68 -34
- package/dist/Blockquote/index.js +1 -1
- package/dist/Blockquote-DRoKdcxZ.js +27 -0
- package/dist/BottomSheet/index.d.ts +1 -1
- package/dist/BottomSheet/index.js +2 -2
- package/dist/{BottomSheet-pt7m4CvC.js → BottomSheet-B4sc3F1S.js} +286 -140
- package/dist/{BottomSheet-JYMB_Ofl.js → BottomSheet-m54uCMJN.js} +20 -4
- package/dist/Breadcrumbs/index.d.ts +2 -2
- package/dist/Breadcrumbs/index.js +2 -2
- package/dist/Breadcrumbs-CTaz7Kh4.js +223 -0
- package/dist/Button/index.d.ts +1 -1
- package/dist/Button/index.js +1 -1
- package/dist/{Button-B6Hj_O_s.js → Button-ONOoHdkg.js} +25 -15
- package/dist/ButtonGroup/index.d.ts +1 -1
- package/dist/ButtonGroup/index.js +1 -1
- package/dist/ButtonGroup-DnkSZ9a5.js +87 -0
- package/dist/{ButtonTooltip-nWWrth8j.js → ButtonTooltip-CNKOQHYR.js} +7 -4
- package/dist/Calendar/index.d.ts +1 -1
- package/dist/Calendar/index.js +1 -1
- package/dist/{Calendar-B7vIowKq.js → Calendar-BAqzzQm2.js} +5 -5
- package/dist/Card/index.d.ts +2 -2
- package/dist/Carousel/index.js +1 -1
- package/dist/{Carousel-CA8zpD9v.js → Carousel-DXC22UWq.js} +4 -4
- package/dist/Chat/index.d.ts +1 -1
- package/dist/Chat/index.js +1 -1
- package/dist/{Chat-Bmna9EOA.js → Chat-BdJW6IX5.js} +147 -83
- package/dist/CheckboxIndicator/index.js +1 -1
- package/dist/{CheckboxIndicator-D37cm2Rh.js → CheckboxIndicator-fH4d-JE1.js} +9 -3
- package/dist/CheckboxInput/index.d.ts +1 -1
- package/dist/CheckboxInput/index.js +1 -1
- package/dist/{CheckboxInput-BS9J6edf.js → CheckboxInput-DJHCbwgC.js} +19 -11
- package/dist/CheckboxList/index.d.ts +1 -1
- package/dist/CheckboxList/index.js +1 -1
- package/dist/{CheckboxList-CX1i_jVP.js → CheckboxList-BdZIP4_J.js} +155 -38
- package/dist/Citation/index.js +1 -1
- package/dist/{Citation-Djgwa0ko.js → Citation-DbZn2vms.js} +8 -3
- package/dist/ClickableCard/index.d.ts +1 -1
- package/dist/ClickableCard/index.js +1 -1
- package/dist/{ClickableCard-DUsC-j03.js → ClickableCard-ChAfiw9T.js} +9 -6
- package/dist/Code/index.js +3 -3
- package/dist/{Code-XnPuGxey.js → Code-Bg7GBdxy.js} +2 -1
- package/dist/{CodeBlock-D0BFubut.js → CodeBlock-Caaflp7C.js} +3 -3
- package/dist/Collapsible/index.d.ts +1 -1
- package/dist/Collapsible/index.js +1 -1
- package/dist/{Collapsible-Cov3Pyq5.js → Collapsible-Bdj0WYpb.js} +13 -11
- package/dist/CommandPalette/index.d.ts +1 -1
- package/dist/CommandPalette/index.js +1 -1
- package/dist/{CommandPalette-YHsUNg3V.js → CommandPalette-C_MClfAg.js} +143 -63
- package/dist/ComplexSelector/index.d.ts +1 -1
- package/dist/ComplexSelector/index.js +1 -1
- package/dist/{ComplexSelector-DWLdKPGI.js → ComplexSelector-BeVQaqRf.js} +85 -20
- package/dist/ContextMenu/index.d.ts +2 -2
- package/dist/ContextMenu/index.js +2 -2
- package/dist/{ContextMenu-Bq9b3Ti5.js → ContextMenu-C6hPYvYz.js} +297 -179
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.js +1 -1
- package/dist/{DateInput-DT518j5E.js → DateInput-BjLdmYor.js} +567 -76
- package/dist/DateRangeInput/index.d.ts +1 -1
- package/dist/DateRangeInput/index.js +1 -1
- package/dist/{DateRangeInput-Bqi5tlIA.js → DateRangeInput-Br3wVEfD.js} +85 -20
- package/dist/DateTimeInput/index.d.ts +1 -1
- package/dist/DateTimeInput/index.js +1 -1
- package/dist/DateTimeInput-CAZBwoRe.js +562 -0
- package/dist/Dialog/index.d.ts +1 -1
- package/dist/Dialog/index.js +2 -2
- package/dist/{Dialog-BiOSKQso.js → Dialog-Dce4Y97V.js} +28 -11
- package/dist/{Dialog-FGHfDu5M.js → Dialog-fhyxB00e.js} +32 -5
- package/dist/Divider/index.d.ts +1 -1
- package/dist/Divider/index.js +1 -1
- package/dist/{Divider-BtwnL18I.js → Divider-mOZ6vIQw.js} +5 -1
- package/dist/DropdownMenu/index.d.ts +2 -2
- package/dist/DropdownMenu/index.js +3 -3
- package/dist/{DropdownMenu-CoOQVlRp.js → DropdownMenu-BdGmQVb1.js} +85 -57
- package/dist/{DropdownMenu-DEb2dSSP.js → DropdownMenu-BzQrNV9C.js} +479 -264
- package/dist/{DropdownMenuRadioItem.vue-CXEURBcq.d.ts → DropdownMenuRadioItem.vue-Qd-8Rg4Q.d.ts} +236 -230
- package/dist/EmptyState/index.js +1 -1
- package/dist/{EmptyState-C_GH7IV5.js → EmptyState-CmOQf2SH.js} +2 -2
- package/dist/Field/index.d.ts +4 -3
- package/dist/Field/index.js +4 -3
- package/dist/{Field-D5gUEGw4.js → Field--OEsLBfE.js} +4 -3
- package/dist/{FieldInfoTip-Ds-sW_jY.js → FieldInfoTip-gxsnfkZw.js} +3 -3
- package/dist/{FieldLabel-BNeXRuGH.js → FieldLabel-jxIiWgLw.js} +12 -7
- package/dist/FieldStatus/index.d.ts +1 -1
- package/dist/FileInput/index.d.ts +1 -1
- package/dist/FileInput/index.js +1 -1
- package/dist/{FileInput-BpdiO1V8.js → FileInput-B_pUxB0Y.js} +106 -29
- package/dist/FormLayout/index.d.ts +1 -1
- package/dist/FormLayout/index.js +1 -1
- package/dist/{FormLayout-D47FjiOq.js → FormLayout-B9dUB6Ps.js} +1 -1
- package/dist/Heading/index.d.ts +1 -1
- package/dist/Heading/index.js +1 -1
- package/dist/{Heading-BnwWEWkp.js → Heading-BzBunfN7.js} +1 -1
- package/dist/HoverCard/index.js +1 -1
- package/dist/{HoverCard-ycY50pRN.js → HoverCard-BpJhT0sn.js} +35 -22
- package/dist/Icon/index.d.ts +4 -4
- package/dist/Icon/index.js +1 -1
- package/dist/{Icon-bteSId7T.js → Icon-KDnUyY7f.js} +12 -20
- package/dist/IconButton/index.js +1 -1
- package/dist/{IconButton-DDNgNl7B.js → IconButton-DI-XBbtV.js} +1 -1
- package/dist/Indicator/index.d.ts +2 -2
- package/dist/Indicator/index.js +2 -1
- package/dist/InputClearButton-CwXPan8c.js +40 -0
- package/dist/InputGroup/index.d.ts +1 -1
- package/dist/InputGroup/index.js +2 -2
- package/dist/{InputGroup-CA03Smrs.js → InputGroup-DiiocoIW.js} +2 -2
- package/dist/InternationalizationProvider/index.d.ts +1 -1
- package/dist/InternationalizationProvider/index.js +1 -1
- package/dist/{InternationalizationProvider-DJay_w3B.js → InternationalizationProvider-kBapgKAQ.js} +5 -9
- package/dist/{Item-KhFKX9St.js → Item-DWMIjN8n.js} +34 -9
- package/dist/Kbd/index.js +1 -1
- package/dist/{Kbd-BB-Dw6zE.js → Kbd-CV3LO2Ge.js} +18 -2
- package/dist/LayerContentBoundary-CvsKxwwm.js +27 -0
- package/dist/LayerProvider/index.js +1 -1
- package/dist/{LayerProvider-D9NsQFzL.js → LayerProvider-B6zpMBWC.js} +15 -3
- package/dist/Layout/index.d.ts +1 -1
- package/dist/Layout/index.js +2 -2
- package/dist/{Layout-C6RHllr-.js → Layout-JJRCG7Mf.js} +1 -1
- package/dist/{LayoutPanel-DXOsaeQb.js → LayoutPanel-zM5vjrKS.js} +12 -8
- package/dist/Lightbox/index.js +1 -1
- package/dist/{Lightbox-DTF9EdTG.js → Lightbox-D8wyPgMK.js} +8 -6
- package/dist/Link/index.js +1 -1
- package/dist/{Link-BqHCtiyt.js → Link-DweIpOtN.js} +29 -12
- package/dist/List/index.d.ts +1 -1
- package/dist/List/index.js +2 -2
- package/dist/{ListItem-8RWT8XAG.js → ListItem-BQXMu1Tb.js} +1 -1
- package/dist/Markdown/index.d.ts +5 -2
- package/dist/Markdown/index.js +5 -2
- package/dist/Markdown/parser/index.d.ts +4 -0
- package/dist/Markdown/parser/index.js +3 -0
- package/dist/Markdown/plugin-protocol/index.d.ts +35 -0
- package/dist/Markdown/plugin-protocol/index.js +107 -0
- package/dist/Markdown/plugin-renderer/index.d.ts +31 -0
- package/dist/Markdown/plugin-renderer/index.js +42 -0
- package/dist/{Markdown-CvtN7HnF.js → Markdown-DhVfOvXk.js} +195 -484
- package/dist/MediaTheme-DlLqYhDy.js +433 -0
- package/dist/MetadataList/index.js +1 -1
- package/dist/{MetadataList-B-OelQlt.js → MetadataList-CEYceIlN.js} +15 -7
- package/dist/MobileNav/index.js +1 -1
- package/dist/{MobileNavToggle-DxGz0xKA.js → MobileNavToggle-pdoJFZHx.js} +52 -17
- package/dist/MoreMenu/index.d.ts +1 -1
- package/dist/MoreMenu/index.js +1 -1
- package/dist/{MoreMenu-Dlb7MLlW.js → MoreMenu-CFNqSRev.js} +72 -59
- package/dist/MultiSelector/index.d.ts +1 -1
- package/dist/MultiSelector/index.js +1 -1
- package/dist/MultiSelector-DuVatmq5.js +1456 -0
- package/dist/{NavDisclosure-C_fugrQ3.js → NavDisclosure-Bq9DTZLO.js} +29 -7
- package/dist/{NavHeadingSurface-B3yJspSN.js → NavHeadingSurface-C4v_MtkX.js} +29 -26
- package/dist/NavItem/index.d.ts +1 -1
- package/dist/NavItem/index.js +2 -2
- package/dist/{NavItem-BBIGSvDj.js → NavItem-BPb3yfgz.js} +17 -4
- package/dist/NavMenu/index.d.ts +1 -1
- package/dist/NavMenu/index.js +3 -3
- package/dist/{NavMenu-ThXguZAz.js → NavMenu-BYIDzjix.js} +42 -15
- package/dist/{NavMenuItem-BvJNsDFC.js → NavMenuItem-D3FO90GR.js} +14 -12
- package/dist/NumberInput/index.d.ts +1 -1
- package/dist/NumberInput/index.js +1 -1
- package/dist/NumberInput-B0vzOg3N.js +727 -0
- package/dist/Outline/index.d.ts +2 -2
- package/dist/Outline/index.js +2 -2
- package/dist/{Outline-755h-lMP.js → Outline-CfGv2F1o.js} +91 -6
- package/dist/OverflowList/index.d.ts +2 -2
- package/dist/OverflowList/index.js +1 -1
- package/dist/{OverflowList-NmrSMbxb.js → OverflowList-BgRLZ3dh.js} +23 -6
- package/dist/Pagination/index.d.ts +1 -1
- package/dist/Pagination/index.js +1 -1
- package/dist/{Pagination-DqwNQFRp.js → Pagination-Bfe12018.js} +2 -2
- package/dist/PickerWheel-CSwUYfes.js +69 -0
- package/dist/Popover/index.d.ts +1 -1
- package/dist/Popover/index.js +1 -1
- package/dist/{Popover-DJf8POzL.js → Popover-78dFjTb9.js} +20 -15
- package/dist/PowerSearch/index.d.ts +1 -1
- package/dist/PowerSearch/index.js +1 -1
- package/dist/{PowerSearch-DvjiPqMZ.js → PowerSearch-BoAMdFaT.js} +774 -586
- package/dist/ProgressBar/index.d.ts +1 -1
- package/dist/ProgressBar/index.js +1 -1
- package/dist/{ProgressBar-CVLzdoBK.js → ProgressBar-VP4JS7vm.js} +10 -7
- package/dist/Radio/index.d.ts +1 -1
- package/dist/Radio/index.js +1 -1
- package/dist/{RadioGroup-Bfu6JSNV.js → RadioGroup-BIipql-L.js} +94 -26
- package/dist/RadioList/index.d.ts +1 -1
- package/dist/RadioList/index.js +1 -1
- package/dist/{RadioList-xY1cwLdZ.js → RadioList-GyhgBg4j.js} +57 -8
- package/dist/Resizable/index.d.ts +1 -1
- package/dist/Resizable/index.js +1 -1
- package/dist/{ResizeHandle-q4nD_586.js → ResizeHandle-TPlUCAHD.js} +103 -50
- package/dist/ScrollableArea/index.d.ts +1 -1
- package/dist/ScrollableArea/index.js +1 -1
- package/dist/{ScrollableArea-D4dCJv9I.js → ScrollableArea-0u6RWtGG.js} +1 -1
- package/dist/SegmentedControl/index.d.ts +1 -1
- package/dist/SegmentedControl/index.js +1 -1
- package/dist/{SegmentedControl-ChHmFrrC.js → SegmentedControl-D1wWGBZo.js} +11 -5
- package/dist/SelectableCard/index.d.ts +1 -1
- package/dist/SelectableCard/index.js +1 -1
- package/dist/{SelectableCard-Cku4dRzc.js → SelectableCard-BEqnhPaX.js} +16 -11
- package/dist/Selector/index.d.ts +1 -1
- package/dist/Selector/index.js +1 -1
- package/dist/Selector-CPISLzp7.js +1049 -0
- package/dist/SideNav/index.d.ts +1 -1
- package/dist/SideNav/index.js +1 -1
- package/dist/{SideNav-BF8mYDxl.js → SideNav-CN2QeAtY.js} +51 -37
- package/dist/Slider/index.d.ts +1 -1
- package/dist/Slider/index.js +1 -1
- package/dist/{Slider-DWobsPgm.js → Slider-pdC0jpHu.js} +172 -46
- package/dist/Spinner/index.js +1 -1
- package/dist/Spinner-DdVUadii.js +200 -0
- package/dist/Stack/index.d.ts +1 -1
- package/dist/Stack/index.js +2 -2
- package/dist/{Stack-CTsTFfar.js → Stack-Bb_h60t3.js} +1 -1
- package/dist/{Stack-kQlYbbL4.js → Stack-Bp-XN9J4.js} +12 -7
- package/dist/StatusDot/index.d.ts +1 -1
- package/dist/StatusDot/index.js +1 -1
- package/dist/{StatusDot-BPUhMOff.js → StatusDot-BS_ohXhd.js} +8 -4
- package/dist/Stepper/index.js +1 -1
- package/dist/{Stepper-CE8dHysu.js → Stepper-CyaSRSdu.js} +101 -79
- package/dist/Switch/index.d.ts +1 -1
- package/dist/Switch/index.js +1 -1
- package/dist/{Switch-DaVPRxvN.js → Switch-Z2Vfiiic.js} +38 -22
- package/dist/TabList/index.d.ts +2 -2
- package/dist/TabList/index.js +1 -1
- package/dist/{TabList-DIkK9sgK.js → TabList-DRqP0Hrv.js} +205 -63
- package/dist/Table/index.d.ts +3 -3
- package/dist/Table/index.js +1 -1
- package/dist/{Table-fecqnm7P.js → Table-BcrrylMX.js} +726 -452
- package/dist/Text/index.d.ts +1 -1
- package/dist/Text/index.js +1 -1
- package/dist/{Text-CV3LmscH.js → Text-CmTOgYXf.js} +1 -1
- package/dist/TextArea/index.d.ts +1 -1
- package/dist/TextArea/index.js +1 -1
- package/dist/{TextArea-Ab5Sw60T.js → TextArea-DA9CCG_J.js} +104 -50
- package/dist/TextInput/index.d.ts +1 -1
- package/dist/TextInput/index.js +1 -1
- package/dist/{TextInput-zFT1_qgI.js → TextInput-CI96einV.js} +71 -38
- package/dist/Theme/index.d.ts +3 -3
- package/dist/Theme/index.js +3 -2
- package/dist/Theme-BbDT8B_C.js +2125 -0
- package/dist/Thumbnail/index.js +1 -1
- package/dist/{Thumbnail-C3NnJUFG.js → Thumbnail-B2ZAY59J.js} +13 -10
- package/dist/{TimeField-CoHDGmsP.js → TimeField-CpAgja9D.js} +297 -40
- package/dist/TimeInput/index.d.ts +1 -1
- package/dist/TimeInput/index.js +1 -1
- package/dist/{TimeInput-D2k3Ux3p.js → TimeInput-Bw_lHS4M.js} +78 -9
- package/dist/Timer/index.d.ts +1 -1
- package/dist/Timer/index.js +1 -1
- package/dist/{Timer-avMQk5DN.js → Timer-CH7GsEVu.js} +1 -1
- package/dist/Timestamp/index.d.ts +1 -1
- package/dist/Timestamp/index.js +1 -1
- package/dist/{Timestamp-xpQKCk0d.js → Timestamp-BFNuoTZ0.js} +5 -5
- package/dist/Toast/index.d.ts +1 -1
- package/dist/Toast/index.js +1 -1
- package/dist/Toast-DwnPjx6j.js +685 -0
- package/dist/ToggleButton/index.d.ts +1 -1
- package/dist/ToggleButton/index.js +1 -1
- package/dist/{ToggleButton-B-C-Q7XP.js → ToggleButton-cLjh9W-x.js} +5 -4
- package/dist/Token/index.d.ts +1 -1
- package/dist/Token/index.js +1 -1
- package/dist/{Token-DsntTYhQ.js → Token-BfS4vi__.js} +32 -17
- package/dist/Tokenizer/index.d.ts +1 -1
- package/dist/Tokenizer/index.js +1 -1
- package/dist/{Tokenizer-B5C_qY7t.js → Tokenizer-Ci3E5bvP.js} +107 -23
- package/dist/Toolbar/index.d.ts +2 -2
- package/dist/Toolbar/index.js +1 -1
- package/dist/{Toolbar-BrgvvTCk.js → Toolbar-C0pMWL4S.js} +1 -1
- package/dist/Tooltip/index.d.ts +1 -1
- package/dist/Tooltip/index.js +1 -1
- package/dist/{Tooltip-C4Vaqd3G.js → Tooltip-sAM8i1eO.js} +23 -19
- package/dist/TopNav/index.d.ts +1 -1
- package/dist/TopNav/index.js +1 -1
- package/dist/{TopNav-Ciq0l1w7.js → TopNav-gW59zp1o.js} +16 -15
- package/dist/TreeList/index.d.ts +1 -1
- package/dist/TreeList/index.js +1 -1
- package/dist/{TreeList-BUz-KZJd.js → TreeList-DaoI7zaH.js} +124 -41
- package/dist/Typeahead/index.d.ts +1 -1
- package/dist/Typeahead/index.js +2 -2
- package/dist/{Typeahead-JP9RT87x.js → Typeahead-D4JjvjK4.js} +123 -26
- package/dist/{TypeaheadMenu-DBW6rHeO.js → TypeaheadMenu-BQlMrfqX.js} +141 -51
- package/dist/{announce-Cnio10Wk.js → announce-B210eJVf.js} +17 -2
- package/dist/characterReferences-BJ-jLhsR.js +65 -0
- package/dist/characters-rcDbGt71.d.ts +29 -0
- package/dist/characters-wTnzjkkR.js +58 -0
- package/dist/{colorMode-CBgdgDSn.js → colorMode-BxqfDP4P.js} +1 -4
- package/dist/composables/index.d.ts +5 -4
- package/dist/composables/index.js +23 -18
- package/dist/{composables-CbKx9C1Y.js → composables-Bc02zKAO.js} +167 -197
- package/dist/context-B6UElI5X.js +5 -0
- package/dist/{context-Cfjh8te1.js → context-Cfml4jaK.js} +5 -3
- package/dist/{context-iABt_ueM.js → context-DWfi56sq.js} +451 -122
- package/dist/context-IvbU9c3T.js +8 -0
- package/dist/context-pjBxaMSh.js +28 -0
- package/dist/fieldParts--SyRZVQG.js +44 -0
- package/dist/fieldParts-LXpQMKE8.d.ts +27 -0
- package/dist/{focus-CpficIgf.js → focus-l8jVTcqd.js} +1 -1
- package/dist/hoverIntent-DMHGb85c.js +115 -0
- package/dist/{index-Cde5JvtX.d.ts → index-B-nESNam.d.ts} +8 -7
- package/dist/{index-CsNi1I8j.d.ts → index-B08-Uxhv.d.ts} +4 -2
- package/dist/{index-Cn-sSds-.d.ts → index-B56j4eI2.d.ts} +24 -1
- package/dist/{index-BkjSF265.d.ts → index-BEZ4ezJk.d.ts} +3 -3
- package/dist/{index-DeQwYJbg.d.ts → index-BNaRK-s5.d.ts} +10 -1
- package/dist/{index-0QGtSf3r.d.ts → index-BO9TY87G.d.ts} +3 -2
- package/dist/{index-IBAInumL.d.ts → index-BQEJj72c.d.ts} +23 -10
- package/dist/{index-D97pQbua.d.ts → index-BV2D2x_u.d.ts} +1 -1
- package/dist/{index-Crp3NFLW.d.ts → index-BZKgbyN9.d.ts} +1 -1
- package/dist/index-BkUkm6Al.d.ts +11 -0
- package/dist/{index-ClNU2Th8.d.ts → index-Bn-v89Vt.d.ts} +10 -6
- package/dist/{index-Bu8NA2SD.d.ts → index-BnEhvmdR.d.ts} +16 -7
- package/dist/index-Bo-ofFyg.d.ts +166 -0
- package/dist/{index-i0tNFWfz.d.ts → index-BqhgeAT4.d.ts} +2 -0
- package/dist/{index-DWh2WC8W.d.ts → index-C4Cjz6OK.d.ts} +2 -2
- package/dist/{index-B7yhzGUT.d.ts → index-C7sam-SB.d.ts} +2 -2
- package/dist/{index-BrJzFA5X.d.ts → index-C90l2rH1.d.ts} +1 -1
- package/dist/{index-vP0EtrJJ.d.ts → index-C9gAlDt_.d.ts} +6 -3
- package/dist/{index-xrzJC4wm.d.ts → index-CJ6ajsUC.d.ts} +1 -1
- package/dist/{index-B9e52paP.d.ts → index-CK-Dbh0f.d.ts} +1 -1
- package/dist/index-CKUfpmFL.d.ts +375 -0
- package/dist/{index-DXpSFlPG.d.ts → index-CKgBTAzC.d.ts} +4 -4
- package/dist/{index-gW0HW02U.d.ts → index-COxy6LEW.d.ts} +1 -1
- package/dist/{index-B4OOtNP8.d.ts → index-CPtDjmcX.d.ts} +3 -3
- package/dist/{index-12QYAbiz.d.ts → index-CRrSHbok.d.ts} +3 -2
- package/dist/{index-DG52Bg0W.d.ts → index-CTf3SK0b.d.ts} +6 -0
- package/dist/{index-BVKivP59.d.ts → index-CTjkJP4x.d.ts} +32 -3
- package/dist/{index-COgrQZIL.d.ts → index-CdvmnNMH.d.ts} +1 -1
- package/dist/{index-GI9xIV9l.d.ts → index-CikMzeab.d.ts} +2 -2
- package/dist/{index-DUaLJO7l.d.ts → index-CpNlPLBF.d.ts} +172 -126
- package/dist/{index-yT1yiiww.d.ts → index-Cs1xsHKi.d.ts} +24 -12
- package/dist/{index-Cyb9Du5Z.d.ts → index-CtTGt6Dv.d.ts} +1 -1
- package/dist/{index-Byar3h1e.d.ts → index-D05JGsT3.d.ts} +6 -3
- package/dist/{index-B3Fomy15.d.ts → index-D0_HsuC3.d.ts} +3 -3
- package/dist/{index-BgT6mH3U.d.ts → index-D7ShT2c-.d.ts} +1 -1
- package/dist/{index-CkKPMIeX.d.ts → index-D7XRtUTY.d.ts} +9 -0
- package/dist/{index-TntQsADQ.d.ts → index-DEm3kRBO.d.ts} +4 -3
- package/dist/{index-C2nbK2AA.d.ts → index-DLAG3m9W.d.ts} +13 -3
- package/dist/{index-DVmgNb78.d.ts → index-DRJZ-v1E.d.ts} +4 -4
- package/dist/{index-CL1T2j4y.d.ts → index-DY8Wph-A.d.ts} +3 -3
- package/dist/{index-B1WJxt-n.d.ts → index-DfC05uKG.d.ts} +17 -7
- package/dist/{index-C5e-7Obr.d.ts → index-Dj1_1t3j.d.ts} +19 -6
- package/dist/{index-D41_xqjs.d.ts → index-Dr4b_oji.d.ts} +20 -13
- package/dist/{index-CqE4Bf3Q.d.ts → index-Ds201-d2.d.ts} +16 -2
- package/dist/{index-DIXAzTKL.d.ts → index-DxxudRgB.d.ts} +1 -1
- package/dist/{index-B42oE_F-.d.ts → index-IfsSCj8J.d.ts} +18 -5
- package/dist/{index-XuAAcYiP.d.ts → index-f3d9cVtj.d.ts} +1 -1
- package/dist/{index-T2FOcOuI.d.ts → index-jOwU3YoR.d.ts} +400 -90
- package/dist/{index-CICeEoZV.d.ts → index-pNtfr-RW.d.ts} +1 -1
- package/dist/{index-BhpAUzUr.d.ts → index-unAZVFGz.d.ts} +2 -2
- package/dist/index.d.ts +80 -74
- package/dist/index.js +149 -134
- package/dist/inlineSize-BNe8wggI.js +66 -0
- package/dist/inputPresentation-BOyHkCDr.js +62 -0
- package/dist/interactionModality-ACpTMhak.js +44 -0
- package/dist/isApplePlatform-B1ju6F5B.js +27 -0
- package/dist/isRenderable-BnKHIqfd.js +21 -0
- package/dist/layerDepth-CNDh-IHb.js +181 -0
- package/dist/link-DuuA2eCL.js +30 -0
- package/dist/{loadCatalog-BGHKG_9N.d.ts → loadCatalog-DlLFZreI.d.ts} +281 -7
- package/dist/loadCatalog-eopw74qb.js +424 -0
- package/dist/locale/index.d.ts +2 -2
- package/dist/locale/index.js +4 -3
- package/dist/locale-CabGJlGp.js +343 -0
- package/dist/modalOutlet-CUOcrhIu.js +56 -0
- package/dist/optionAction-Cg7xQLUA.d.ts +6 -0
- package/dist/{power-search-DrDfcoL1.d.ts → power-search-gHLIYXs5.d.ts} +2 -0
- package/dist/protocol-DHxY0NI8.js +113 -0
- package/dist/protocol-RSeMzAN1.d.ts +238 -0
- package/dist/publicParser-B0MRoikr.d.ts +141 -0
- package/dist/publicParser-uHC_T0Fo.js +895 -0
- package/dist/resizableChannel-3vivrEcT.js +20 -0
- package/dist/safeUrl-CsvfcZ9m.js +54 -0
- package/dist/scopedProvide-C-Df7c15.js +30 -0
- package/dist/scrollKeyboardDelegation-D7cumnOl.js +238 -0
- package/dist/scrollLock-C3aT4-0z.js +102 -0
- package/dist/{searchResultMessage-hXXNOFJP.js → searchResultMessage-mCpJBvra.js} +5 -14
- package/dist/{semantic-CKH9XVqa.d.ts → semantic-BF_AjLvk.d.ts} +6 -3
- package/dist/slug-C65CUsf9.js +32 -0
- package/dist/syntaxContext-DmIfNNtb.js +4 -0
- package/dist/triggerVariant-BsL8jMHs.js +16 -0
- package/dist/{types-0Q_SJv_F.d.ts → types-Bb7OGivY.d.ts} +6 -1
- package/dist/{types-CwyibrRB.d.ts → types-C5GQ2KCK.d.ts} +23 -3
- package/dist/{types-gKsEkk2g.d.ts → types-CsqwQkf1.d.ts} +143 -10
- package/dist/upstreamMap-xr3gvREu.js +731 -0
- package/dist/{useAnchoredListbox-DwztMNjP.js → useAnchoredListbox-DGxxKHZb.js} +2 -2
- package/dist/{useAsyncSource-xpQovjV_.d.ts → useAsyncSource-aGzrvRkI.d.ts} +3 -0
- package/dist/{useClickableContainer-DyNpnSEa.js → useClickableContainer-CdGp_Cev.js} +1 -1
- package/dist/{useClipboard-BDfbEsWd.js → useClipboard-Dk8cS810.js} +1 -1
- package/dist/useHoverLayerDismiss-kYJ_NqL4.js +27 -0
- package/dist/{useIndicator-i1NORM7W.js → useIndicator-MZmfBWid.js} +5 -23
- package/dist/{useInputContainer-CpgDe2-4.js → useInputContainer-CLcYrby4.js} +1 -1
- package/dist/{useInputStatusIcon-DBOwxV4x.js → useInputStatusIcon-DAE7PExr.js} +1 -1
- package/dist/useLayerMountTarget-BmZyeKWE.js +156 -0
- package/dist/{useListFocus-D0iOJl39.js → useListFocus-ChxLg0b4.js} +3 -2
- package/dist/{useMenuDrillIn-DzKGkTho.js → useMenuDrillIn-DhUnPvKs.js} +6 -5
- package/dist/useMenuHover-Djreu23i.js +170 -0
- package/dist/useMenuPress-8foxY8z4.js +764 -0
- package/dist/{useMergedRefs-CfHHlCsn.js → useMergedRefs-Cb6_w93m.js} +24 -4
- package/dist/{useNumberField-4-dIGVed.js → useNumberField-Dk1BE3-K.js} +3 -3
- package/dist/useOptionActionGrid-CkJcuvaU.js +97 -0
- package/dist/{usePositionedLayer-Cru9_00b.js → usePositionedLayer-B7cvG-_v.js} +43 -49
- package/dist/usePressFeedback-BJCpjEpv.js +319 -0
- package/dist/{useResizable-DDwPpPe6.d.ts → useResizable-1MHPNaRD.d.ts} +19 -1
- package/dist/{useResizable-B3ahKLoZ.js → useResizable-I3BCiLSL.js} +72 -40
- package/dist/useResolvedLabelHidden-B2rlWiaI.js +30 -0
- package/dist/{useRestoreFocus-Djw9RUIf.js → useRestoreFocus-XEKs5-gp.js} +49 -7
- package/dist/useScrollOverflow-DuMoGXmm.js +67 -0
- package/dist/useScrollableArea-BE8b3qm7.js +222 -0
- package/dist/{useTimeValue-6ufHM15W.js → useTimeValue-BJd0xBhG.js} +4 -22
- package/dist/useTranslator-BmWt2BBt.js +35 -0
- package/dist/{useTypeahead-PAK8lMYz.js → useTypeahead-BvtflkRk.js} +4 -5
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +5 -0
- package/dist/{utils-D33VQDnk.js → utils-ClVseK2w.js} +29 -2
- package/dist/utils-z3Q6BGIJ.js +819 -0
- package/locales/SOURCE.json +1 -1
- package/package.json +18 -2
- package/reset.css +364 -1
- package/styles/avatar-group.css +9 -1
- package/styles/badge.css +8 -5
- package/styles/banner.css +124 -26
- package/styles/blockquote.css +1 -0
- package/styles/bordered-control.css +1 -1
- package/styles/bottom-sheet.css +74 -6
- package/styles/breadcrumbs.css +16 -2
- package/styles/button-group.css +3 -1
- package/styles/button.css +53 -11
- package/styles/card.css +1 -1
- package/styles/chat.css +16 -6
- package/styles/checkbox-input.css +10 -0
- package/styles/clickable-card.css +10 -3
- package/styles/collapsible.css +12 -5
- package/styles/command-palette.css +29 -14
- package/styles/complex-selector.css +22 -5
- package/styles/context-menu.css +3 -3
- package/styles/date-input.css +111 -1
- package/styles/dialog-header.css +4 -1
- package/styles/dialog.css +7 -0
- package/styles/dropdown-menu.css +12 -3
- package/styles/field.css +5 -0
- package/styles/form-layout.css +1 -0
- package/styles/heading.css +18 -8
- package/styles/icon.css +4 -0
- package/styles/kbd.css +1 -1
- package/styles/layer.css +72 -0
- package/styles/list.css +9 -2
- package/styles/metadata-list.css +1 -0
- package/styles/mobile-nav.css +4 -1
- package/styles/multi-selector.css +48 -1
- package/styles/nav-item.css +9 -2
- package/styles/nav-menu.css +12 -2
- package/styles/number-input.css +9 -1
- package/styles/overflow-list.css +1 -1
- package/styles/popover.css +2 -1
- package/styles/power-search.css +5 -3
- package/styles/pressable.css +63 -22
- package/styles/progress-bar.css +15 -3
- package/styles/radio.css +16 -0
- package/styles/resize-handle.css +42 -0
- package/styles/segmented-control.css +12 -4
- package/styles/selector.css +53 -1
- package/styles/side-nav.css +19 -0
- package/styles/slider.css +4 -3
- package/styles/spinner.css +48 -42
- package/styles/stepper.css +58 -4
- package/styles/switch.css +26 -0
- package/styles/tab-list.css +132 -3
- package/styles/table.css +88 -10
- package/styles/text-area.css +1 -1
- package/styles/text-input.css +1 -1
- package/styles/text.css +6 -6
- package/styles/thumbnail.css +11 -3
- package/styles/time-input.css +8 -0
- package/styles/toast.css +37 -3
- package/styles/token.css +2 -2
- package/styles/tokenizer.css +1 -1
- package/styles/toolbar.css +4 -1
- package/styles/tree-list.css +1 -1
- package/styles/typeahead.css +34 -1
- package/styles.css +1 -0
- package/dist/Blockquote-DFqBv_oJ.js +0 -18
- package/dist/Breadcrumbs-DIm4figq.js +0 -141
- package/dist/ButtonGroup-ySQWanDP.js +0 -125
- package/dist/DateTimeInput-A7m2O3bg.js +0 -268
- package/dist/MultiSelector-BtAUfQ3t.js +0 -990
- package/dist/NumberInput-AZ9x3oja.js +0 -473
- package/dist/Selector-DJ2BhUTV.js +0 -677
- package/dist/Spinner-9cYUCnDy.js +0 -84
- package/dist/Theme-CtaUWo4g.js +0 -1246
- package/dist/Toast-BuqIZV5z.js +0 -322
- package/dist/context-4PuqD1Ic.js +0 -4
- package/dist/context-D5-MwxnN.js +0 -4
- package/dist/index-BH9PzQ1F.d.ts +0 -87
- package/dist/link-C4_WogdF.js +0 -18
- package/dist/loadCatalog-CXKqEB9s.js +0 -877
- package/dist/locale-DgkZEMTn.js +0 -105
- package/dist/platform-B_9W_aHW.js +0 -33
- package/dist/scrollLock-BzIvIimL.js +0 -42
- package/dist/useMenuPress-D-FRNrBW.js +0 -573
- package/dist/useScrollableArea-DDk_CluT.js +0 -172
- /package/dist/{index-lgvUFSCO.d.ts → index-CryFtTT6.d.ts} +0 -0
package/dist/Theme-CtaUWo4g.js
DELETED
|
@@ -1,1246 +0,0 @@
|
|
|
1
|
-
import { t as useMediaQuery } from "./useMediaQuery-GMmgp28-.js";
|
|
2
|
-
import { n as themeContextKey, r as themeNestingKey, t as mediaThemeKey } from "./context-Cws_tXTr.js";
|
|
3
|
-
import { a as syntaxThemeStyle } from "./syntaxTheme-R7xnu5x5.js";
|
|
4
|
-
import { n as resolveLightDark, r as syntaxThemeKey, t as readColorMode } from "./colorMode-CBgdgDSn.js";
|
|
5
|
-
import { computed, createBlock, createCommentVNode, createElementBlock, defineComponent, h, inject, markRaw, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, provide, ref, renderSlot, unref, useAttrs, useTemplateRef, watch } from "vue";
|
|
6
|
-
import "../styles/media-theme.css";
|
|
7
|
-
import "../styles/theme.css";
|
|
8
|
-
//#region src/Theme/tokenName.ts
|
|
9
|
-
const THEME_TOKEN_PREFIX = /^--(?:color|font|text|radius|duration|ease|spacing|size|shadow|border|focus|heading)-/;
|
|
10
|
-
/** Accept `--color-accent`, `--astryx-color-accent`, or `color-accent`. */
|
|
11
|
-
function normalizeTokenName(name) {
|
|
12
|
-
const trimmed = name.trim();
|
|
13
|
-
if (trimmed.startsWith("--astryx-")) return trimmed;
|
|
14
|
-
if (trimmed.startsWith("--")) return `--astryx-${trimmed.slice(2)}`;
|
|
15
|
-
return `--astryx-${trimmed}`;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Rewrite `var(--color-accent)` to `var(--astryx-color-accent)`.
|
|
19
|
-
*
|
|
20
|
-
* Custom properties outside the theme vocabulary are left alone.
|
|
21
|
-
*/
|
|
22
|
-
function prefixTokenReferences(value) {
|
|
23
|
-
return value.replace(/var\(\s*(--(?!astryx-)[\w-]+)/g, (match, name) => {
|
|
24
|
-
if (!THEME_TOKEN_PREFIX.test(name)) return match;
|
|
25
|
-
return `var(${normalizeTokenName(name)}`;
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
//#endregion
|
|
29
|
-
//#region src/Theme/componentStyles.ts
|
|
30
|
-
const COMPONENT_NAME = /^[a-z][a-z0-9-]*$/i;
|
|
31
|
-
const STYLE_PART = /^([a-z][a-z0-9-]*):([a-z0-9][a-z0-9-]*)$/;
|
|
32
|
-
const UNSAFE_VALUE = /[;{}<>\n\r\\]|\/\*|\*\//;
|
|
33
|
-
const PSEUDO = /* @__PURE__ */ new Set([
|
|
34
|
-
":hover",
|
|
35
|
-
":focus",
|
|
36
|
-
":focus-visible",
|
|
37
|
-
":focus-within",
|
|
38
|
-
":active",
|
|
39
|
-
":checked",
|
|
40
|
-
":disabled",
|
|
41
|
-
":invalid",
|
|
42
|
-
":valid",
|
|
43
|
-
":placeholder-shown",
|
|
44
|
-
":read-only",
|
|
45
|
-
":required"
|
|
46
|
-
]);
|
|
47
|
-
function componentClass(name) {
|
|
48
|
-
const kebab = name.trim().replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
|
|
49
|
-
if (!COMPONENT_NAME.test(kebab)) throw new Error(`Theme component name "${name}" is not a component name.`);
|
|
50
|
-
return `astryx-${kebab}`;
|
|
51
|
-
}
|
|
52
|
-
function styleTargets(className, key) {
|
|
53
|
-
if (key === "base") return `.${className}`;
|
|
54
|
-
const parts = key.split("+");
|
|
55
|
-
if (parts.length === 0 || parts.some((part) => !STYLE_PART.test(part))) throw new Error(`Theme component style "${key}" must be base or prop:value.`);
|
|
56
|
-
return `.${className}${parts.map((part) => {
|
|
57
|
-
const match = STYLE_PART.exec(part);
|
|
58
|
-
return `[data-${match?.[1]}="${match?.[2]}"]`;
|
|
59
|
-
}).join("")}, .${className}${parts.map((part) => {
|
|
60
|
-
const match = STYLE_PART.exec(part);
|
|
61
|
-
return `.${className}--${match?.[1]}-${match?.[2]}`;
|
|
62
|
-
}).join("")}`;
|
|
63
|
-
}
|
|
64
|
-
function scope(themeName, targets) {
|
|
65
|
-
return targets.split(", ").map((target) => `[data-astryx-theme="${themeName}"] ${target}`).join(", ");
|
|
66
|
-
}
|
|
67
|
-
function cssProperty(name) {
|
|
68
|
-
if (name.startsWith("--")) {
|
|
69
|
-
const normalized = normalizeTokenName(name);
|
|
70
|
-
if (!/^--astryx-[a-z0-9-]+$/.test(normalized)) throw new Error(`Theme style property "${name}" is not a custom property.`);
|
|
71
|
-
return normalized;
|
|
72
|
-
}
|
|
73
|
-
const kebab = name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
74
|
-
if (!/^-?[a-z][a-z0-9-]*$/.test(kebab)) throw new Error(`Theme style property "${name}" is not a CSS property.`);
|
|
75
|
-
return kebab;
|
|
76
|
-
}
|
|
77
|
-
function declarationValue(value, property) {
|
|
78
|
-
if (UNSAFE_VALUE.test(value)) throw new Error(`Theme style ${property} has an unsupported value.`);
|
|
79
|
-
return prefixTokenReferences(value);
|
|
80
|
-
}
|
|
81
|
-
function declarations(body) {
|
|
82
|
-
return Object.entries(body).map(([property, value]) => {
|
|
83
|
-
const name = cssProperty(property);
|
|
84
|
-
return ` ${name}: ${declarationValue(value, name)};`;
|
|
85
|
-
}).join("\n");
|
|
86
|
-
}
|
|
87
|
-
function splitOverrides(overrides) {
|
|
88
|
-
const base = {};
|
|
89
|
-
const pseudos = {};
|
|
90
|
-
for (const [key, value] of Object.entries(overrides)) {
|
|
91
|
-
if (key.startsWith(":")) {
|
|
92
|
-
if (!PSEUDO.has(key) || typeof value === "string") throw new Error(`Theme style pseudo "${key}" is not supported.`);
|
|
93
|
-
pseudos[key] = value;
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
if (typeof value !== "string") throw new Error(`Theme style property "${key}" must be a CSS value.`);
|
|
97
|
-
base[key] = value;
|
|
98
|
-
}
|
|
99
|
-
return {
|
|
100
|
-
base,
|
|
101
|
-
pseudos
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
function withPseudo(selectorList, pseudo) {
|
|
105
|
-
return selectorList.split(", ").map((selector) => `${selector}${pseudo}`).join(", ");
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Compile component style overrides into one scoped sheet.
|
|
109
|
-
*
|
|
110
|
-
* `base` matches `.astryx-<component>`. `variant:secondary` matches both
|
|
111
|
-
* `[data-variant="secondary"]` and `.astryx-<component>--variant-secondary`.
|
|
112
|
-
* Join props with `+`. A `:hover` block skips disabled controls.
|
|
113
|
-
* The sheet lives in the `astryx.overrides` layer.
|
|
114
|
-
*/
|
|
115
|
-
function compileComponentStyles(themeName, components) {
|
|
116
|
-
if (!components || Object.keys(components).length === 0) return void 0;
|
|
117
|
-
const rules = [];
|
|
118
|
-
for (const [component, styles] of Object.entries(components)) {
|
|
119
|
-
const className = componentClass(component);
|
|
120
|
-
for (const [key, overrides] of Object.entries(styles)) {
|
|
121
|
-
const selector = scope(themeName, styleTargets(className, key));
|
|
122
|
-
const { base, pseudos } = splitOverrides(overrides);
|
|
123
|
-
if (Object.keys(base).length > 0) rules.push(`${selector} {\n${declarations(base)}\n}`);
|
|
124
|
-
for (const [pseudo, body] of Object.entries(pseudos)) {
|
|
125
|
-
const suffix = pseudo === ":hover" ? ":hover:not(:disabled):not([aria-disabled=\"true\"])" : pseudo;
|
|
126
|
-
if (Object.keys(body).length === 0) continue;
|
|
127
|
-
rules.push(`${withPseudo(selector, suffix)} {\n${declarations(body)}\n}`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (rules.length === 0) return void 0;
|
|
132
|
-
return `@layer astryx.overrides {\n${rules.join("\n")}\n}\n`;
|
|
133
|
-
}
|
|
134
|
-
function mergeComponentMaps(base, next) {
|
|
135
|
-
if (base == null && next == null) return void 0;
|
|
136
|
-
const names = /* @__PURE__ */ new Set([...Object.keys(base ?? {}), ...Object.keys(next ?? {})]);
|
|
137
|
-
const merged = {};
|
|
138
|
-
for (const name of names) merged[name] = {
|
|
139
|
-
...base?.[name],
|
|
140
|
-
...next?.[name]
|
|
141
|
-
};
|
|
142
|
-
return merged;
|
|
143
|
-
}
|
|
144
|
-
//#endregion
|
|
145
|
-
//#region src/Theme/contrast.ts
|
|
146
|
-
const HEX$1 = /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
147
|
-
const RGB = /^rgba?\(\s*([\d.]+)[,\s]+([\d.]+)[,\s]+([\d.]+)(?:[,\s/]+([\d.]+)(%)?)?\s*\)$/i;
|
|
148
|
-
function parseColor(input) {
|
|
149
|
-
const value = input.trim().toLowerCase();
|
|
150
|
-
if (value === "transparent") return {
|
|
151
|
-
r: 0,
|
|
152
|
-
g: 0,
|
|
153
|
-
b: 0,
|
|
154
|
-
a: 0
|
|
155
|
-
};
|
|
156
|
-
const hex = HEX$1.exec(value);
|
|
157
|
-
if (hex?.[1]) {
|
|
158
|
-
const raw = hex[1];
|
|
159
|
-
const expanded = raw.length === 3 ? raw.split("").map((part) => part + part).join("") : raw;
|
|
160
|
-
const channels = expanded.length === 6 ? `${expanded}ff` : expanded;
|
|
161
|
-
return {
|
|
162
|
-
r: Number.parseInt(channels.slice(0, 2), 16),
|
|
163
|
-
g: Number.parseInt(channels.slice(2, 4), 16),
|
|
164
|
-
b: Number.parseInt(channels.slice(4, 6), 16),
|
|
165
|
-
a: Number.parseInt(channels.slice(6, 8), 16) / 255
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
const rgb = RGB.exec(value);
|
|
169
|
-
if (!rgb) return null;
|
|
170
|
-
const alpha = rgb[4] == null ? 1 : rgb[5] === "%" ? Number.parseFloat(rgb[4]) / 100 : Number.parseFloat(rgb[4]);
|
|
171
|
-
return {
|
|
172
|
-
r: Number.parseFloat(rgb[1] ?? "0"),
|
|
173
|
-
g: Number.parseFloat(rgb[2] ?? "0"),
|
|
174
|
-
b: Number.parseFloat(rgb[3] ?? "0"),
|
|
175
|
-
a: alpha
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
function channel(value) {
|
|
179
|
-
const scaled = value / 255;
|
|
180
|
-
return scaled <= .04045 ? scaled / 12.92 : ((scaled + .055) / 1.055) ** 2.4;
|
|
181
|
-
}
|
|
182
|
-
function relativeLuminance(color) {
|
|
183
|
-
return .2126 * channel(color.r) + .7152 * channel(color.g) + .0722 * channel(color.b);
|
|
184
|
-
}
|
|
185
|
-
/** WCAG contrast ratio. 1 is no contrast. */
|
|
186
|
-
function contrastRatio(foreground, background) {
|
|
187
|
-
const first = relativeLuminance(foreground);
|
|
188
|
-
const second = relativeLuminance(background);
|
|
189
|
-
const lighter = Math.max(first, second);
|
|
190
|
-
const darker = Math.min(first, second);
|
|
191
|
-
return (lighter + .05) / (darker + .05);
|
|
192
|
-
}
|
|
193
|
-
const ON_DARK = {
|
|
194
|
-
r: 255,
|
|
195
|
-
g: 255,
|
|
196
|
-
b: 255,
|
|
197
|
-
a: 1
|
|
198
|
-
};
|
|
199
|
-
const ON_LIGHT = {
|
|
200
|
-
r: 23,
|
|
201
|
-
g: 23,
|
|
202
|
-
b: 23,
|
|
203
|
-
a: 1
|
|
204
|
-
};
|
|
205
|
-
/**
|
|
206
|
-
* Choose a media surface from the painted background.
|
|
207
|
-
*
|
|
208
|
-
* `off` means the ambient text already reads on that background at 3:1, so no
|
|
209
|
-
* inverted context is needed. `null` means the background is too transparent
|
|
210
|
-
* to judge.
|
|
211
|
-
*/
|
|
212
|
-
function pickMediaMode(background, ambientText) {
|
|
213
|
-
if (background.a < .2) return null;
|
|
214
|
-
if (contrastRatio(ambientText, background) >= 3) return "off";
|
|
215
|
-
return contrastRatio(ON_DARK, background) >= contrastRatio(ON_LIGHT, background) ? "dark" : "light";
|
|
216
|
-
}
|
|
217
|
-
//#endregion
|
|
218
|
-
//#region src/Theme/hct.ts
|
|
219
|
-
const D65_WHITE = [
|
|
220
|
-
.95047,
|
|
221
|
-
1,
|
|
222
|
-
1.08883
|
|
223
|
-
];
|
|
224
|
-
const PALETTE_TONES = [
|
|
225
|
-
0,
|
|
226
|
-
5,
|
|
227
|
-
10,
|
|
228
|
-
20,
|
|
229
|
-
30,
|
|
230
|
-
40,
|
|
231
|
-
50,
|
|
232
|
-
60,
|
|
233
|
-
70,
|
|
234
|
-
80,
|
|
235
|
-
90,
|
|
236
|
-
95,
|
|
237
|
-
99,
|
|
238
|
-
100
|
|
239
|
-
];
|
|
240
|
-
const HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
|
|
241
|
-
function isHexColor(value) {
|
|
242
|
-
return HEX.test(value.trim());
|
|
243
|
-
}
|
|
244
|
-
function srgbToLinear(channel) {
|
|
245
|
-
const scaled = channel / 255;
|
|
246
|
-
return scaled <= .04045 ? scaled / 12.92 : ((scaled + .055) / 1.055) ** 2.4;
|
|
247
|
-
}
|
|
248
|
-
function linearToSrgb(channel) {
|
|
249
|
-
const scaled = channel <= .0031308 ? channel * 12.92 : 1.055 * channel ** (1 / 2.4) - .055;
|
|
250
|
-
return Math.round(Math.min(255, Math.max(0, scaled * 255)));
|
|
251
|
-
}
|
|
252
|
-
function linearRgbToXyz(r, g, b) {
|
|
253
|
-
return [
|
|
254
|
-
.4124564 * r + .3575761 * g + .1804375 * b,
|
|
255
|
-
.2126729 * r + .7151522 * g + .072175 * b,
|
|
256
|
-
.0193339 * r + .119192 * g + .9503041 * b
|
|
257
|
-
];
|
|
258
|
-
}
|
|
259
|
-
function xyzToLinearRgb(x, y, z) {
|
|
260
|
-
return [
|
|
261
|
-
3.2404542 * x - 1.5371385 * y - .4985314 * z,
|
|
262
|
-
-.969266 * x + 1.8760108 * y + .041556 * z,
|
|
263
|
-
.0556434 * x - .2040259 * y + 1.0572252 * z
|
|
264
|
-
];
|
|
265
|
-
}
|
|
266
|
-
function labF(t) {
|
|
267
|
-
const delta = 6 / 29;
|
|
268
|
-
return t > delta ** 3 ? Math.cbrt(t) : t / (3 * delta * delta) + 4 / 29;
|
|
269
|
-
}
|
|
270
|
-
function labFInv(t) {
|
|
271
|
-
const delta = 6 / 29;
|
|
272
|
-
return t > delta ? t ** 3 : 3 * delta * delta * (t - 4 / 29);
|
|
273
|
-
}
|
|
274
|
-
function xyzToLab(x, y, z) {
|
|
275
|
-
const fx = labF(x / D65_WHITE[0]);
|
|
276
|
-
const fy = labF(y / D65_WHITE[1]);
|
|
277
|
-
const fz = labF(z / D65_WHITE[2]);
|
|
278
|
-
return [
|
|
279
|
-
116 * fy - 16,
|
|
280
|
-
500 * (fx - fy),
|
|
281
|
-
200 * (fy - fz)
|
|
282
|
-
];
|
|
283
|
-
}
|
|
284
|
-
function labToXyz(l, a, b) {
|
|
285
|
-
const fy = (l + 16) / 116;
|
|
286
|
-
const fx = a / 500 + fy;
|
|
287
|
-
const fz = fy - b / 200;
|
|
288
|
-
return [
|
|
289
|
-
labFInv(fx) * D65_WHITE[0],
|
|
290
|
-
labFInv(fy) * D65_WHITE[1],
|
|
291
|
-
labFInv(fz) * D65_WHITE[2]
|
|
292
|
-
];
|
|
293
|
-
}
|
|
294
|
-
function toneToY(tone) {
|
|
295
|
-
return labFInv((tone + 16) / 116);
|
|
296
|
-
}
|
|
297
|
-
function formatHex(r, g, b) {
|
|
298
|
-
return `#${[
|
|
299
|
-
r,
|
|
300
|
-
g,
|
|
301
|
-
b
|
|
302
|
-
].map((channel) => channel.toString(16).padStart(2, "0")).join("")}`.toUpperCase();
|
|
303
|
-
}
|
|
304
|
-
function parseHexChannels(hex) {
|
|
305
|
-
const raw = HEX.exec(hex.trim())?.[1];
|
|
306
|
-
if (!raw) return null;
|
|
307
|
-
const expanded = raw.length === 3 ? raw.split("").map((part) => part + part).join("") : raw;
|
|
308
|
-
return [
|
|
309
|
-
Number.parseInt(expanded.slice(0, 2), 16),
|
|
310
|
-
Number.parseInt(expanded.slice(2, 4), 16),
|
|
311
|
-
Number.parseInt(expanded.slice(4, 6), 16)
|
|
312
|
-
];
|
|
313
|
-
}
|
|
314
|
-
/** Hue 0–360, chroma from 0, tone 0–100. An unreadable hex is black. */
|
|
315
|
-
function hexToHct(hex) {
|
|
316
|
-
const [r, g, b] = parseHexChannels(hex) ?? [
|
|
317
|
-
0,
|
|
318
|
-
0,
|
|
319
|
-
0
|
|
320
|
-
];
|
|
321
|
-
const [x, y, z] = linearRgbToXyz(srgbToLinear(r), srgbToLinear(g), srgbToLinear(b));
|
|
322
|
-
const [l, a, bLab] = xyzToLab(x, y, z);
|
|
323
|
-
let hue = Math.atan2(bLab, a) * 180 / Math.PI;
|
|
324
|
-
if (hue < 0) hue += 360;
|
|
325
|
-
return {
|
|
326
|
-
hue,
|
|
327
|
-
chroma: Math.sqrt(a * a + bLab * bLab),
|
|
328
|
-
tone: Math.max(0, Math.min(100, l))
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
function toneToGray(tone) {
|
|
332
|
-
return linearToSrgb(toneToY(tone));
|
|
333
|
-
}
|
|
334
|
-
function hctComponentToHex(hue, chroma, tone) {
|
|
335
|
-
const hueRad = hue * Math.PI / 180;
|
|
336
|
-
const [x, y, z] = labToXyz(tone, Math.cos(hueRad) * chroma, Math.sin(hueRad) * chroma);
|
|
337
|
-
const [linearR, linearG, linearB] = xyzToLinearRgb(x, y, z);
|
|
338
|
-
const r = linearToSrgb(linearR);
|
|
339
|
-
const g = linearToSrgb(linearG);
|
|
340
|
-
const bOut = linearToSrgb(linearB);
|
|
341
|
-
const tolerance = .02;
|
|
342
|
-
if (Math.abs(srgbToLinear(r) - linearR) > tolerance || Math.abs(srgbToLinear(g) - linearG) > tolerance || Math.abs(srgbToLinear(bOut) - linearB) > tolerance || r < 0 || r > 255 || g < 0 || g > 255 || bOut < 0 || bOut > 255) return null;
|
|
343
|
-
return formatHex(r, g, bOut);
|
|
344
|
-
}
|
|
345
|
-
/** Fit chroma down until the color is inside sRGB. */
|
|
346
|
-
function hctToHex(hct) {
|
|
347
|
-
const { hue, chroma, tone } = hct;
|
|
348
|
-
if (tone <= 0) return "#000000";
|
|
349
|
-
if (tone >= 100) return "#FFFFFF";
|
|
350
|
-
if (chroma < .5) {
|
|
351
|
-
const gray = toneToGray(tone);
|
|
352
|
-
return formatHex(gray, gray, gray);
|
|
353
|
-
}
|
|
354
|
-
let low = 0;
|
|
355
|
-
let high = chroma;
|
|
356
|
-
let best = "#000000";
|
|
357
|
-
for (let step = 0; step < 16; step += 1) {
|
|
358
|
-
const mid = (low + high) / 2;
|
|
359
|
-
const candidate = hctComponentToHex(hue, mid, tone);
|
|
360
|
-
if (candidate != null) {
|
|
361
|
-
best = candidate;
|
|
362
|
-
low = mid;
|
|
363
|
-
} else high = mid;
|
|
364
|
-
}
|
|
365
|
-
return best;
|
|
366
|
-
}
|
|
367
|
-
/** Hex stops at the standard tones for one hue and chroma. */
|
|
368
|
-
function tonalPalette(hue, chroma) {
|
|
369
|
-
const palette = {};
|
|
370
|
-
for (const tone of PALETTE_TONES) palette[tone] = hctToHex({
|
|
371
|
-
hue,
|
|
372
|
-
chroma,
|
|
373
|
-
tone
|
|
374
|
-
});
|
|
375
|
-
return palette;
|
|
376
|
-
}
|
|
377
|
-
/** `#RRGGBB` plus an alpha byte, for example `0.1` becomes `1A`. */
|
|
378
|
-
function hexWithAlpha(hex, alpha) {
|
|
379
|
-
return `${hex}${Math.round(alpha * 255).toString(16).padStart(2, "0").toUpperCase()}`;
|
|
380
|
-
}
|
|
381
|
-
//#endregion
|
|
382
|
-
//#region src/Theme/expandColorScale.ts
|
|
383
|
-
const NEUTRAL_CHROMA = {
|
|
384
|
-
warm: 7,
|
|
385
|
-
cool: 5,
|
|
386
|
-
neutral: 3
|
|
387
|
-
};
|
|
388
|
-
const NEUTRAL_VARIANT_CHROMA = {
|
|
389
|
-
warm: 10,
|
|
390
|
-
cool: 8,
|
|
391
|
-
neutral: 6
|
|
392
|
-
};
|
|
393
|
-
/** Hue source when `accent` is omitted. Accent tokens themselves stay unset. */
|
|
394
|
-
const DEFAULT_ACCENT_SEED = "#0064E0";
|
|
395
|
-
const NON_TEXT_MIN_CONTRAST = 3;
|
|
396
|
-
function lightDark(light, dark) {
|
|
397
|
-
return `light-dark(${light}, ${dark})`;
|
|
398
|
-
}
|
|
399
|
-
function accentWithAlpha(alpha) {
|
|
400
|
-
return `color-mix(in srgb, var(--color-accent) ${alpha * 100}%, transparent)`;
|
|
401
|
-
}
|
|
402
|
-
function ratio(foreground, background) {
|
|
403
|
-
const fg = parseColor(foreground);
|
|
404
|
-
const bg = parseColor(background);
|
|
405
|
-
if (!fg || !bg) return 1;
|
|
406
|
-
return contrastRatio(fg, bg);
|
|
407
|
-
}
|
|
408
|
-
/**
|
|
409
|
-
* Walk tone until the color reaches `minRatio` against `background`.
|
|
410
|
-
* Tone is Lab lightness, so each step moves luminance in one direction.
|
|
411
|
-
*/
|
|
412
|
-
function ensureContrastTone(hue, chroma, startTone, step, background, minRatio) {
|
|
413
|
-
let tone = startTone;
|
|
414
|
-
let hex = hctToHex({
|
|
415
|
-
hue,
|
|
416
|
-
chroma,
|
|
417
|
-
tone
|
|
418
|
-
});
|
|
419
|
-
while (ratio(hex, background) < minRatio && tone + step >= 0 && tone + step <= 100) {
|
|
420
|
-
tone += step;
|
|
421
|
-
hex = hctToHex({
|
|
422
|
-
hue,
|
|
423
|
-
chroma,
|
|
424
|
-
tone
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
return hex;
|
|
428
|
-
}
|
|
429
|
-
function assertAccent(value, which) {
|
|
430
|
-
if (!isHexColor(value)) throw new Error(`Theme color ${which} must be a hex color such as #0064E0.`);
|
|
431
|
-
}
|
|
432
|
-
function seedPair(accent) {
|
|
433
|
-
if (accent == null) return [DEFAULT_ACCENT_SEED, DEFAULT_ACCENT_SEED];
|
|
434
|
-
if (typeof accent === "string") {
|
|
435
|
-
assertAccent(accent, "accent");
|
|
436
|
-
return [accent, accent];
|
|
437
|
-
}
|
|
438
|
-
const [light, dark] = accent;
|
|
439
|
-
assertAccent(light, "accent light stop");
|
|
440
|
-
assertAccent(dark, "accent dark stop");
|
|
441
|
-
return [light, dark];
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* Semantic color tokens derived from an accent.
|
|
445
|
-
*
|
|
446
|
-
* Status colors, chart colors, and on-dark / on-light stay out of this map.
|
|
447
|
-
* `--color-accent-muted`, `--color-text-accent`, and `--color-icon-accent`
|
|
448
|
-
* point at `var(--color-accent)`. `--color-on-accent` is baked from the seed,
|
|
449
|
-
* because the contrast pick cannot be expressed as a CSS reference.
|
|
450
|
-
*
|
|
451
|
-
* Names are the upstream names. `defineTheme()` adds the `--astryx-` prefix.
|
|
452
|
-
*/
|
|
453
|
-
function expandColorScale(config = {}) {
|
|
454
|
-
const { accent, neutralStyle = "cool", contrast = "standard" } = config;
|
|
455
|
-
const [lightAccent, darkAccent] = seedPair(accent);
|
|
456
|
-
const lightSeed = hexToHct(lightAccent);
|
|
457
|
-
const sameSeed = darkAccent.toLowerCase() === lightAccent.toLowerCase();
|
|
458
|
-
const darkSeed = sameSeed ? lightSeed : hexToHct(darkAccent);
|
|
459
|
-
const neutralChroma = NEUTRAL_CHROMA[neutralStyle] ?? 5;
|
|
460
|
-
const neutralVariantChroma = NEUTRAL_VARIANT_CHROMA[neutralStyle] ?? 8;
|
|
461
|
-
const accentLight = tonalPalette(lightSeed.hue, Math.max(lightSeed.chroma, 48));
|
|
462
|
-
const neutralLight = tonalPalette(lightSeed.hue, neutralChroma);
|
|
463
|
-
const neutralVariantLight = tonalPalette(lightSeed.hue, neutralVariantChroma);
|
|
464
|
-
const accentDark = sameSeed ? accentLight : tonalPalette(darkSeed.hue, Math.max(darkSeed.chroma, 48));
|
|
465
|
-
const neutralDark = sameSeed ? neutralLight : tonalPalette(darkSeed.hue, neutralChroma);
|
|
466
|
-
const neutralVariantDark = sameSeed ? neutralVariantLight : tonalPalette(darkSeed.hue, neutralVariantChroma);
|
|
467
|
-
const high = contrast === "high";
|
|
468
|
-
const textPrimaryLight = high ? 0 : 10;
|
|
469
|
-
const textPrimaryDark = high ? 99 : 90;
|
|
470
|
-
const textSecondaryLight = high ? 20 : 30;
|
|
471
|
-
const textSecondaryDark = high ? 80 : 70;
|
|
472
|
-
const borderAlpha = high ? .2 : .1;
|
|
473
|
-
const borderEmphasized = lightDark(ensureContrastTone(lightSeed.hue, neutralVariantChroma, high ? 50 : 70, -1, neutralLight[99] ?? "#FFFFFF", NON_TEXT_MIN_CONTRAST), ensureContrastTone(darkSeed.hue, neutralVariantChroma, high ? 50 : 30, 1, neutralDark[10] ?? "#000000", NON_TEXT_MIN_CONTRAST));
|
|
474
|
-
return {
|
|
475
|
-
...accent != null ? {
|
|
476
|
-
"--color-accent": lightDark(accentLight[40] ?? "#000000", accentDark[80] ?? "#FFFFFF"),
|
|
477
|
-
"--color-accent-muted": lightDark(accentWithAlpha(.2), accentWithAlpha(.25)),
|
|
478
|
-
"--color-on-accent": lightDark(accentLight[100] ?? "#FFFFFF", accentDark[20] ?? "#000000")
|
|
479
|
-
} : {},
|
|
480
|
-
"--color-neutral": lightDark(hexWithAlpha(neutralLight[10] ?? "#000000", .1), hexWithAlpha(neutralDark[90] ?? "#FFFFFF", .2)),
|
|
481
|
-
"--color-background-surface": lightDark(neutralLight[99] ?? "#FFFFFF", neutralDark[10] ?? "#000000"),
|
|
482
|
-
"--color-background-body": lightDark(neutralLight[95] ?? "#FFFFFF", neutralDark[5] ?? "#000000"),
|
|
483
|
-
"--color-overlay": lightDark(hexWithAlpha(neutralLight[10] ?? "#000000", .4), hexWithAlpha(neutralDark[10] ?? "#000000", .6)),
|
|
484
|
-
"--color-overlay-hover": lightDark(hexWithAlpha(neutralLight[10] ?? "#000000", .05), hexWithAlpha(neutralDark[100] ?? "#FFFFFF", .05)),
|
|
485
|
-
"--color-overlay-pressed": lightDark(hexWithAlpha(neutralLight[10] ?? "#000000", .1), hexWithAlpha(neutralDark[100] ?? "#FFFFFF", .1)),
|
|
486
|
-
"--color-background-muted": lightDark(hexWithAlpha(neutralLight[10] ?? "#000000", .05), hexWithAlpha(neutralDark[10] ?? "#000000", .5)),
|
|
487
|
-
"--color-text-primary": lightDark(neutralLight[textPrimaryLight] ?? "#000000", neutralDark[textPrimaryDark] ?? "#FFFFFF"),
|
|
488
|
-
"--color-text-secondary": lightDark(neutralVariantLight[textSecondaryLight] ?? "#000000", neutralVariantDark[textSecondaryDark] ?? "#FFFFFF"),
|
|
489
|
-
"--color-text-disabled": lightDark(neutralVariantLight[60] ?? "#000000", neutralVariantDark[40] ?? "#FFFFFF"),
|
|
490
|
-
"--color-text-accent": "var(--color-accent)",
|
|
491
|
-
"--color-icon-accent": "var(--color-accent)",
|
|
492
|
-
"--color-icon-primary": lightDark(neutralLight[textPrimaryLight] ?? "#000000", neutralDark[textPrimaryDark] ?? "#FFFFFF"),
|
|
493
|
-
"--color-icon-secondary": lightDark(neutralVariantLight[textSecondaryLight] ?? "#000000", neutralVariantDark[textSecondaryDark] ?? "#FFFFFF"),
|
|
494
|
-
"--color-icon-disabled": lightDark(neutralVariantLight[60] ?? "#000000", neutralVariantDark[40] ?? "#FFFFFF"),
|
|
495
|
-
"--color-background-card": lightDark(neutralLight[99] ?? "#FFFFFF", neutralDark[10] ?? "#000000"),
|
|
496
|
-
"--color-background-popover": lightDark(neutralLight[99] ?? "#FFFFFF", neutralDark[20] ?? "#000000"),
|
|
497
|
-
"--color-background-inverted": lightDark(neutralLight[10] ?? "#000000", neutralDark[99] ?? "#FFFFFF"),
|
|
498
|
-
"--color-border": lightDark(hexWithAlpha(neutralLight[10] ?? "#000000", borderAlpha), hexWithAlpha(neutralDark[95] ?? "#FFFFFF", borderAlpha)),
|
|
499
|
-
"--color-border-emphasized": borderEmphasized,
|
|
500
|
-
"--color-skeleton": lightDark(neutralVariantLight[70] ?? "#000000", neutralVariantDark[30] ?? "#FFFFFF"),
|
|
501
|
-
"--color-track": lightDark(neutralVariantLight[70] ?? "#000000", neutralVariantDark[30] ?? "#FFFFFF"),
|
|
502
|
-
"--color-shadow": lightDark(hexWithAlpha(neutralLight[0] ?? "#000000", .1), hexWithAlpha(neutralDark[0] ?? "#000000", .3)),
|
|
503
|
-
"--color-tint-hover": lightDark("black", "white")
|
|
504
|
-
};
|
|
505
|
-
}
|
|
506
|
-
//#endregion
|
|
507
|
-
//#region src/Theme/expandMotionScale.ts
|
|
508
|
-
function assertMotion(config) {
|
|
509
|
-
for (const [label, value] of [
|
|
510
|
-
["fast", config.fast],
|
|
511
|
-
["medium", config.medium],
|
|
512
|
-
["slow", config.slow]
|
|
513
|
-
]) {
|
|
514
|
-
if (value == null) continue;
|
|
515
|
-
if (!Number.isFinite(value) || value < 0) throw new Error(`Theme motion ${label} must be a non-negative number of milliseconds.`);
|
|
516
|
-
}
|
|
517
|
-
if (!Number.isFinite(config.ratio) || config.ratio <= 0 || config.ratio > 1) throw new Error("Theme motion ratio must be greater than 0 and at most 1.");
|
|
518
|
-
if (config.easing != null && /[;{}<>\n\r]/.test(config.easing)) throw new Error("Theme motion easing has an unsupported value.");
|
|
519
|
-
}
|
|
520
|
-
function roundMs(ms) {
|
|
521
|
-
return Math.round(ms / 5) * 5;
|
|
522
|
-
}
|
|
523
|
-
/** `--duration-*` and an optional `--ease-standard`. */
|
|
524
|
-
function expandMotionScale(config) {
|
|
525
|
-
assertMotion(config);
|
|
526
|
-
const { fast, medium, slow, ratio, easing } = config;
|
|
527
|
-
const tokens = {
|
|
528
|
-
"--duration-fast-min": `${roundMs(fast * ratio)}ms`,
|
|
529
|
-
"--duration-fast": `${roundMs(fast)}ms`,
|
|
530
|
-
"--duration-fast-max": `${roundMs(fast / ratio)}ms`,
|
|
531
|
-
"--duration-medium-min": `${roundMs(medium * ratio)}ms`,
|
|
532
|
-
"--duration-medium": `${roundMs(medium)}ms`,
|
|
533
|
-
"--duration-medium-max": `${roundMs(medium / ratio)}ms`
|
|
534
|
-
};
|
|
535
|
-
if (slow != null) {
|
|
536
|
-
tokens["--duration-slow-min"] = `${roundMs(slow * ratio)}ms`;
|
|
537
|
-
tokens["--duration-slow"] = `${roundMs(slow)}ms`;
|
|
538
|
-
tokens["--duration-slow-max"] = `${roundMs(slow / ratio)}ms`;
|
|
539
|
-
}
|
|
540
|
-
if (easing) tokens["--ease-standard"] = easing;
|
|
541
|
-
return tokens;
|
|
542
|
-
}
|
|
543
|
-
//#endregion
|
|
544
|
-
//#region src/Theme/expandRadiusScale.ts
|
|
545
|
-
function assertRadius(config) {
|
|
546
|
-
if (!Number.isFinite(config.base) || config.base < 0) throw new Error("Theme radius base must be a non-negative number of pixels.");
|
|
547
|
-
if (!Number.isFinite(config.multiplier) || config.multiplier < 0) throw new Error("Theme radius multiplier must be a non-negative number.");
|
|
548
|
-
}
|
|
549
|
-
/** `--radius-*` tokens. Names are unprefixed; `defineTheme()` adds `--astryx-`. */
|
|
550
|
-
function expandRadiusScale(config) {
|
|
551
|
-
assertRadius(config);
|
|
552
|
-
const { base, multiplier } = config;
|
|
553
|
-
const step = (factor) => `${Math.round(base * factor * multiplier)}px`;
|
|
554
|
-
return {
|
|
555
|
-
"--radius-none": "0px",
|
|
556
|
-
"--radius-inner": step(1),
|
|
557
|
-
"--radius-element": step(2),
|
|
558
|
-
"--radius-container": step(3),
|
|
559
|
-
"--radius-page": step(7),
|
|
560
|
-
"--radius-chat": step(7),
|
|
561
|
-
"--radius-full": "9999px"
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
//#endregion
|
|
565
|
-
//#region src/Theme/expandTypeScale.ts
|
|
566
|
-
const STEP_TO_SIZE_TOKEN = {
|
|
567
|
-
[-5]: "--font-size-4xs",
|
|
568
|
-
[-4]: "--font-size-3xs",
|
|
569
|
-
[-3]: "--font-size-2xs",
|
|
570
|
-
[-2]: "--font-size-xs",
|
|
571
|
-
[-1]: "--font-size-sm",
|
|
572
|
-
0: "--font-size-base",
|
|
573
|
-
1: "--font-size-lg",
|
|
574
|
-
2: "--font-size-xl",
|
|
575
|
-
3: "--font-size-2xl",
|
|
576
|
-
4: "--font-size-3xl",
|
|
577
|
-
5: "--font-size-4xl",
|
|
578
|
-
6: "--font-size-5xl"
|
|
579
|
-
};
|
|
580
|
-
const HEADING_STEPS = {
|
|
581
|
-
1: 3,
|
|
582
|
-
2: 2,
|
|
583
|
-
3: 1,
|
|
584
|
-
4: 0,
|
|
585
|
-
5: -1,
|
|
586
|
-
6: -2
|
|
587
|
-
};
|
|
588
|
-
const TEXT_STEPS = {
|
|
589
|
-
"body": 0,
|
|
590
|
-
"large": 1,
|
|
591
|
-
"label": 0,
|
|
592
|
-
"code": 0,
|
|
593
|
-
"supporting": -1,
|
|
594
|
-
"display-1": 6,
|
|
595
|
-
"display-2": 5,
|
|
596
|
-
"display-3": 4
|
|
597
|
-
};
|
|
598
|
-
const DEFAULT_HEADING_WEIGHTS = {
|
|
599
|
-
1: "var(--font-weight-semibold)",
|
|
600
|
-
2: "var(--font-weight-semibold)",
|
|
601
|
-
3: "var(--font-weight-semibold)",
|
|
602
|
-
4: "var(--font-weight-semibold)",
|
|
603
|
-
5: "var(--font-weight-semibold)",
|
|
604
|
-
6: "var(--font-weight-semibold)"
|
|
605
|
-
};
|
|
606
|
-
const DEFAULT_TEXT_WEIGHTS = {
|
|
607
|
-
"body": "var(--font-weight-normal)",
|
|
608
|
-
"large": "var(--font-weight-semibold)",
|
|
609
|
-
"label": "var(--font-weight-medium)",
|
|
610
|
-
"code": "var(--font-weight-normal)",
|
|
611
|
-
"supporting": "var(--font-weight-normal)",
|
|
612
|
-
"display-1": "var(--font-weight-normal)",
|
|
613
|
-
"display-2": "var(--font-weight-normal)",
|
|
614
|
-
"display-3": "var(--font-weight-normal)"
|
|
615
|
-
};
|
|
616
|
-
const TEXT_FONT_FAMILIES = {
|
|
617
|
-
"body": "var(--font-family-body)",
|
|
618
|
-
"large": "var(--font-family-body)",
|
|
619
|
-
"label": "var(--font-family-body)",
|
|
620
|
-
"code": "var(--font-family-code)",
|
|
621
|
-
"supporting": "var(--font-family-body)",
|
|
622
|
-
"display-1": "var(--font-family-heading)",
|
|
623
|
-
"display-2": "var(--font-family-heading)",
|
|
624
|
-
"display-3": "var(--font-family-heading)"
|
|
625
|
-
};
|
|
626
|
-
function assertScale(config) {
|
|
627
|
-
if (!Number.isFinite(config.base) || config.base <= 0) throw new Error("Theme type scale base must be a positive number of pixels.");
|
|
628
|
-
if (!Number.isFinite(config.ratio) || config.ratio <= 0) throw new Error("Theme type scale ratio must be a positive number.");
|
|
629
|
-
}
|
|
630
|
-
function computeSize(base, ratio, step) {
|
|
631
|
-
return Math.round(base * ratio ** step);
|
|
632
|
-
}
|
|
633
|
-
function pxToRem(px) {
|
|
634
|
-
return `${Math.round(px / 16 * 1e4) / 1e4}rem`;
|
|
635
|
-
}
|
|
636
|
-
/** Under 20px uses 1.5, under 32px uses 1.4, and the rest uses 1.25. */
|
|
637
|
-
function targetLeadingRatio(fontSize) {
|
|
638
|
-
if (fontSize < 20) return 1.5;
|
|
639
|
-
if (fontSize < 32) return 1.4;
|
|
640
|
-
return 1.25;
|
|
641
|
-
}
|
|
642
|
-
function computeLeading(fontSize) {
|
|
643
|
-
const raw = fontSize * targetLeadingRatio(fontSize);
|
|
644
|
-
const snapped = Math.max(Math.round(raw / 4) * 4, Math.ceil((fontSize + 4) / 4) * 4);
|
|
645
|
-
return Math.round(snapped / fontSize * 1e4) / 1e4;
|
|
646
|
-
}
|
|
647
|
-
/**
|
|
648
|
-
* Raw `--font-size-*` steps, then heading and text roles.
|
|
649
|
-
*
|
|
650
|
-
* Sizes on the roles point at the raw steps with `var()`. Line heights are
|
|
651
|
-
* unitless ratios snapped onto a 4px grid. Weights point at `--font-weight-*`.
|
|
652
|
-
*/
|
|
653
|
-
function expandTypeScale(config) {
|
|
654
|
-
assertScale(config);
|
|
655
|
-
const { base, ratio, weights } = config;
|
|
656
|
-
const tokens = {};
|
|
657
|
-
const headingWeights = {
|
|
658
|
-
...DEFAULT_HEADING_WEIGHTS,
|
|
659
|
-
...weights?.heading
|
|
660
|
-
};
|
|
661
|
-
const textWeights = {
|
|
662
|
-
...DEFAULT_TEXT_WEIGHTS,
|
|
663
|
-
...weights?.text
|
|
664
|
-
};
|
|
665
|
-
for (let step = -5; step <= 6; step += 1) {
|
|
666
|
-
const name = STEP_TO_SIZE_TOKEN[step];
|
|
667
|
-
if (name) tokens[name] = pxToRem(computeSize(base, ratio, step));
|
|
668
|
-
}
|
|
669
|
-
for (const level of [
|
|
670
|
-
1,
|
|
671
|
-
2,
|
|
672
|
-
3,
|
|
673
|
-
4,
|
|
674
|
-
5,
|
|
675
|
-
6
|
|
676
|
-
]) {
|
|
677
|
-
const step = HEADING_STEPS[level] ?? 0;
|
|
678
|
-
const size = computeSize(base, ratio, step);
|
|
679
|
-
const sizeToken = STEP_TO_SIZE_TOKEN[step];
|
|
680
|
-
tokens[`--text-heading-${level}-size`] = `var(${sizeToken})`;
|
|
681
|
-
tokens[`--text-heading-${level}-weight`] = headingWeights[level] ?? "var(--font-weight-semibold)";
|
|
682
|
-
tokens[`--text-heading-${level}-leading`] = `${computeLeading(size)}`;
|
|
683
|
-
}
|
|
684
|
-
for (const [type, step] of Object.entries(TEXT_STEPS)) {
|
|
685
|
-
const size = computeSize(base, ratio, step);
|
|
686
|
-
tokens[`--text-${type}-size`] = `var(${STEP_TO_SIZE_TOKEN[step]})`;
|
|
687
|
-
tokens[`--text-${type}-weight`] = textWeights[type] ?? DEFAULT_TEXT_WEIGHTS[type] ?? "var(--font-weight-normal)";
|
|
688
|
-
tokens[`--text-${type}-leading`] = `${computeLeading(size)}`;
|
|
689
|
-
}
|
|
690
|
-
return tokens;
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* Heading and text rules that read the generated tokens.
|
|
694
|
-
*
|
|
695
|
-
* `type:display-*` is emitted after `level:*` so display sizing wins when a
|
|
696
|
-
* heading carries both classes.
|
|
697
|
-
*/
|
|
698
|
-
function generateTypeScaleComponents() {
|
|
699
|
-
const heading = {};
|
|
700
|
-
for (const level of [
|
|
701
|
-
1,
|
|
702
|
-
2,
|
|
703
|
-
3,
|
|
704
|
-
4,
|
|
705
|
-
5,
|
|
706
|
-
6
|
|
707
|
-
]) heading[`level:${level}`] = {
|
|
708
|
-
fontFamily: "var(--font-family-heading)",
|
|
709
|
-
fontSize: `var(--text-heading-${level}-size)`,
|
|
710
|
-
fontWeight: `var(--text-heading-${level}-weight)`,
|
|
711
|
-
lineHeight: `var(--text-heading-${level}-leading)`
|
|
712
|
-
};
|
|
713
|
-
for (const type of [
|
|
714
|
-
"display-1",
|
|
715
|
-
"display-2",
|
|
716
|
-
"display-3"
|
|
717
|
-
]) heading[`type:${type}`] = {
|
|
718
|
-
fontFamily: "var(--font-family-heading)",
|
|
719
|
-
fontSize: `var(--text-${type}-size)`,
|
|
720
|
-
lineHeight: `var(--text-${type}-leading)`
|
|
721
|
-
};
|
|
722
|
-
const text = {};
|
|
723
|
-
for (const type of [
|
|
724
|
-
"body",
|
|
725
|
-
"large",
|
|
726
|
-
"label",
|
|
727
|
-
"code",
|
|
728
|
-
"supporting",
|
|
729
|
-
"display-1",
|
|
730
|
-
"display-2",
|
|
731
|
-
"display-3"
|
|
732
|
-
]) text[`type:${type}`] = {
|
|
733
|
-
fontFamily: TEXT_FONT_FAMILIES[type] ?? "var(--font-family-body)",
|
|
734
|
-
fontSize: `var(--text-${type}-size)`,
|
|
735
|
-
lineHeight: `var(--text-${type}-leading)`
|
|
736
|
-
};
|
|
737
|
-
return {
|
|
738
|
-
heading,
|
|
739
|
-
text
|
|
740
|
-
};
|
|
741
|
-
}
|
|
742
|
-
//#endregion
|
|
743
|
-
//#region src/Theme/typography.ts
|
|
744
|
-
const NAMED_WEIGHTS = {
|
|
745
|
-
normal: "var(--font-weight-normal)",
|
|
746
|
-
regular: "var(--font-weight-normal)",
|
|
747
|
-
medium: "var(--font-weight-medium)",
|
|
748
|
-
semibold: "var(--font-weight-semibold)",
|
|
749
|
-
bold: "var(--font-weight-bold)"
|
|
750
|
-
};
|
|
751
|
-
function weightToken(value) {
|
|
752
|
-
return NAMED_WEIGHTS[value.trim()] ?? value;
|
|
753
|
-
}
|
|
754
|
-
function quoteFamily(family) {
|
|
755
|
-
const trimmed = family.trim();
|
|
756
|
-
if (trimmed.startsWith("\"") || trimmed.startsWith("'")) return trimmed;
|
|
757
|
-
if (/[^a-z0-9-]/i.test(trimmed)) return `"${trimmed.replace(/"/g, "")}"`;
|
|
758
|
-
return trimmed;
|
|
759
|
-
}
|
|
760
|
-
function fontStack(role) {
|
|
761
|
-
if (!role?.family && !role?.fallbacks) return void 0;
|
|
762
|
-
const family = role.family ? quoteFamily(role.family) : void 0;
|
|
763
|
-
if (family && role.fallbacks) return `${family}, ${role.fallbacks}`;
|
|
764
|
-
return family ?? role.fallbacks;
|
|
765
|
-
}
|
|
766
|
-
function headingSizeAliases(tokens) {
|
|
767
|
-
const aliases = {};
|
|
768
|
-
for (let level = 1; level <= 6; level += 1) {
|
|
769
|
-
const size = `--text-heading-${level}-size`;
|
|
770
|
-
if (tokens[size]) aliases[`--heading-level-${level}-size`] = `var(${size})`;
|
|
771
|
-
}
|
|
772
|
-
for (const step of [
|
|
773
|
-
1,
|
|
774
|
-
2,
|
|
775
|
-
3
|
|
776
|
-
]) {
|
|
777
|
-
const size = `--text-display-${step}-size`;
|
|
778
|
-
if (tokens[size]) aliases[`--heading-display-${step}-size`] = `var(${size})`;
|
|
779
|
-
}
|
|
780
|
-
return aliases;
|
|
781
|
-
}
|
|
782
|
-
function assignHeadingWeight(heading, level, weight) {
|
|
783
|
-
if (level >= 1 && level <= 6) heading[level] = weightToken(weight);
|
|
784
|
-
}
|
|
785
|
-
function scaleConfig(config) {
|
|
786
|
-
const scale = config.scale;
|
|
787
|
-
if (!scale) throw new Error("Theme typography scale is missing.");
|
|
788
|
-
const heading = {};
|
|
789
|
-
if (config.heading?.weight) {
|
|
790
|
-
const weight = weightToken(config.heading.weight);
|
|
791
|
-
for (const level of [
|
|
792
|
-
1,
|
|
793
|
-
2,
|
|
794
|
-
3,
|
|
795
|
-
4,
|
|
796
|
-
5,
|
|
797
|
-
6
|
|
798
|
-
]) heading[level] = weight;
|
|
799
|
-
}
|
|
800
|
-
for (const [level, weight] of Object.entries(config.heading?.weights ?? {})) if (weight) assignHeadingWeight(heading, Number(level), weight);
|
|
801
|
-
for (const [level, weight] of Object.entries(scale.weights?.heading ?? {})) if (weight) assignHeadingWeight(heading, Number(level), weight);
|
|
802
|
-
const text = {};
|
|
803
|
-
if (config.body?.weight) text.body = weightToken(config.body.weight);
|
|
804
|
-
if (config.code?.weight) text.code = weightToken(config.code.weight);
|
|
805
|
-
for (const [name, weight] of Object.entries(scale.weights?.text ?? {})) if (weight) text[name] = weightToken(weight);
|
|
806
|
-
return {
|
|
807
|
-
base: scale.base,
|
|
808
|
-
ratio: scale.ratio,
|
|
809
|
-
weights: {
|
|
810
|
-
heading,
|
|
811
|
-
text
|
|
812
|
-
}
|
|
813
|
-
};
|
|
814
|
-
}
|
|
815
|
-
/**
|
|
816
|
-
* Font stacks, the type scale, and the heading size aliases Heading reads.
|
|
817
|
-
* Heading inherits the body stack when it does not name its own.
|
|
818
|
-
*/
|
|
819
|
-
function resolveTypography(config) {
|
|
820
|
-
if (!config) return { tokens: {} };
|
|
821
|
-
const tokens = {};
|
|
822
|
-
const bodyStack = fontStack(config.body);
|
|
823
|
-
const headingStack = fontStack(config.heading) ?? bodyStack;
|
|
824
|
-
const codeStack = fontStack(config.code);
|
|
825
|
-
if (bodyStack) tokens["--font-family-body"] = bodyStack;
|
|
826
|
-
if (headingStack) tokens["--font-family-heading"] = headingStack;
|
|
827
|
-
if (codeStack) tokens["--font-family-code"] = codeStack;
|
|
828
|
-
const components = {};
|
|
829
|
-
if (config.scale) {
|
|
830
|
-
Object.assign(tokens, expandTypeScale(scaleConfig(config)));
|
|
831
|
-
Object.assign(tokens, headingSizeAliases(tokens));
|
|
832
|
-
Object.assign(components, generateTypeScaleComponents());
|
|
833
|
-
}
|
|
834
|
-
if (fontStack(config.heading)) components.heading = {
|
|
835
|
-
...components.heading,
|
|
836
|
-
base: {
|
|
837
|
-
fontFamily: "var(--font-family-heading)",
|
|
838
|
-
...components.heading?.base
|
|
839
|
-
}
|
|
840
|
-
};
|
|
841
|
-
if (codeStack) components.text = {
|
|
842
|
-
...components.text,
|
|
843
|
-
"type:code": {
|
|
844
|
-
fontFamily: "var(--font-family-code)",
|
|
845
|
-
...components.text?.["type:code"]
|
|
846
|
-
}
|
|
847
|
-
};
|
|
848
|
-
return {
|
|
849
|
-
tokens,
|
|
850
|
-
...Object.keys(components).length > 0 ? { components } : {}
|
|
851
|
-
};
|
|
852
|
-
}
|
|
853
|
-
//#endregion
|
|
854
|
-
//#region src/Theme/defineTheme.ts
|
|
855
|
-
const THEME_NAME = /^[a-z0-9][a-z0-9-]*$/i;
|
|
856
|
-
const UNSAFE_TOKEN = /[;{}<>\n\r]/;
|
|
857
|
-
function isDefinedTheme(value) {
|
|
858
|
-
return !!value && typeof value === "object" && value.__astryxTheme === true;
|
|
859
|
-
}
|
|
860
|
-
function assertTokenValue(value, name) {
|
|
861
|
-
if (UNSAFE_TOKEN.test(value)) throw new Error(`Theme token ${name} has an unsupported value.`);
|
|
862
|
-
}
|
|
863
|
-
function isTokenPair(value) {
|
|
864
|
-
return Array.isArray(value);
|
|
865
|
-
}
|
|
866
|
-
function resolveTokenMap(tokens) {
|
|
867
|
-
const resolved = {};
|
|
868
|
-
if (!tokens) return resolved;
|
|
869
|
-
for (const [name, value] of Object.entries(tokens)) {
|
|
870
|
-
if (value == null) continue;
|
|
871
|
-
const key = normalizeTokenName(name);
|
|
872
|
-
if (isTokenPair(value)) {
|
|
873
|
-
const [light, dark] = value;
|
|
874
|
-
assertTokenValue(light, key);
|
|
875
|
-
assertTokenValue(dark, key);
|
|
876
|
-
resolved[key] = prefixTokenReferences(`light-dark(${light}, ${dark})`);
|
|
877
|
-
continue;
|
|
878
|
-
}
|
|
879
|
-
assertTokenValue(value, key);
|
|
880
|
-
resolved[key] = prefixTokenReferences(value);
|
|
881
|
-
}
|
|
882
|
-
return resolved;
|
|
883
|
-
}
|
|
884
|
-
function mergeMaps(base, next) {
|
|
885
|
-
if (base == null && next == null) return void 0;
|
|
886
|
-
return {
|
|
887
|
-
...base,
|
|
888
|
-
...next
|
|
889
|
-
};
|
|
890
|
-
}
|
|
891
|
-
function sealIndicators(indicators) {
|
|
892
|
-
if (indicators == null) return void 0;
|
|
893
|
-
const sealed = {};
|
|
894
|
-
for (const [name, component] of Object.entries(indicators)) if (component) sealed[name] = markRaw(component);
|
|
895
|
-
return sealed;
|
|
896
|
-
}
|
|
897
|
-
/**
|
|
898
|
-
* Create a theme object that `Theme` can apply to a subtree.
|
|
899
|
-
*
|
|
900
|
-
* Token names are the upstream names (`--color-accent`) or this package's
|
|
901
|
-
* prefixed names (`--astryx-color-accent`). A `[light, dark]` tuple becomes
|
|
902
|
-
* `light-dark()`. `color`, `typography`, `radius`, and `motion` generate
|
|
903
|
-
* tokens; an explicit `tokens` entry wins for that name.
|
|
904
|
-
*
|
|
905
|
-
* `var(--color-accent)` inside a value is rewritten to the prefixed name.
|
|
906
|
-
*/
|
|
907
|
-
function defineTheme(input) {
|
|
908
|
-
if (!THEME_NAME.test(input.name)) throw new Error(`Theme name "${input.name}" must use letters, numbers, and hyphens.`);
|
|
909
|
-
if (input.extends != null && !isDefinedTheme(input.extends)) throw new Error("defineTheme extends must be a theme returned by defineTheme().");
|
|
910
|
-
const base = input.extends;
|
|
911
|
-
const typography = resolveTypography(input.typography);
|
|
912
|
-
const generated = {
|
|
913
|
-
...input.color ? expandColorScale(input.color) : {},
|
|
914
|
-
...typography.tokens,
|
|
915
|
-
...input.radius ? expandRadiusScale(input.radius) : {},
|
|
916
|
-
...input.motion ? expandMotionScale(input.motion) : {}
|
|
917
|
-
};
|
|
918
|
-
const icons = mergeMaps(base?.icons, input.icons);
|
|
919
|
-
const indicators = sealIndicators(mergeMaps(base?.indicators, input.indicators));
|
|
920
|
-
const components = mergeComponentMaps(mergeComponentMaps(base?.components, typography.components), input.components);
|
|
921
|
-
const css = compileComponentStyles(input.name, components);
|
|
922
|
-
return {
|
|
923
|
-
__astryxTheme: true,
|
|
924
|
-
name: input.name,
|
|
925
|
-
tokens: {
|
|
926
|
-
...base?.tokens,
|
|
927
|
-
...resolveTokenMap({
|
|
928
|
-
...generated,
|
|
929
|
-
...input.tokens
|
|
930
|
-
})
|
|
931
|
-
},
|
|
932
|
-
onDark: {
|
|
933
|
-
...base?.onDark,
|
|
934
|
-
...resolveTokenMap(input.onDark?.tokens)
|
|
935
|
-
},
|
|
936
|
-
onLight: {
|
|
937
|
-
...base?.onLight,
|
|
938
|
-
...resolveTokenMap(input.onLight?.tokens)
|
|
939
|
-
},
|
|
940
|
-
syntax: input.syntax ?? base?.syntax,
|
|
941
|
-
...icons ? { icons } : {},
|
|
942
|
-
...indicators ? { indicators } : {},
|
|
943
|
-
...components ? { components } : {},
|
|
944
|
-
...css ? { css } : {}
|
|
945
|
-
};
|
|
946
|
-
}
|
|
947
|
-
/** Neutral, with no token overrides. Colors come from `@astryx-vue/themes/neutral.css`. */
|
|
948
|
-
const neutralTheme = defineTheme({ name: "neutral" });
|
|
949
|
-
//#endregion
|
|
950
|
-
//#region src/Theme/themeStyle.ts
|
|
951
|
-
/**
|
|
952
|
-
* Aliases declared on `:root` are substituted there. A later override of the
|
|
953
|
-
* semantic token does not flow through that already-substituted value, so the
|
|
954
|
-
* alias has to be written again on the element that sets the semantic token.
|
|
955
|
-
*
|
|
956
|
-
* Card background and border are not aliases: Neutral paints them with its own
|
|
957
|
-
* stops, and they follow the semantic token only when a theme sets one.
|
|
958
|
-
*/
|
|
959
|
-
const COMPONENT_BRIDGES = {
|
|
960
|
-
"--astryx-color-text-primary": [
|
|
961
|
-
"--astryx-text-foreground",
|
|
962
|
-
"--astryx-heading-foreground",
|
|
963
|
-
"--astryx-button-secondary-foreground",
|
|
964
|
-
"--astryx-button-ghost-foreground"
|
|
965
|
-
],
|
|
966
|
-
"--astryx-color-text-secondary": ["--astryx-text-supporting-foreground"],
|
|
967
|
-
"--astryx-color-accent": ["--astryx-button-primary-background", "--astryx-button-focus"],
|
|
968
|
-
"--astryx-color-on-accent": ["--astryx-button-primary-foreground"],
|
|
969
|
-
"--astryx-color-neutral": ["--astryx-button-secondary-background"],
|
|
970
|
-
"--astryx-color-icon-primary": ["--astryx-icon-primary-foreground"],
|
|
971
|
-
"--astryx-color-background-card": ["--astryx-card-background"],
|
|
972
|
-
"--astryx-color-background-muted": ["--astryx-card-muted-background"],
|
|
973
|
-
"--astryx-color-border": ["--astryx-card-border"]
|
|
974
|
-
};
|
|
975
|
-
/** Surfaces keep their own button treatment. Text aliases still follow onDark and onLight. */
|
|
976
|
-
const SURFACE_BRIDGES = {
|
|
977
|
-
"--astryx-color-text-primary": ["--astryx-text-foreground", "--astryx-heading-foreground"],
|
|
978
|
-
"--astryx-color-text-secondary": ["--astryx-text-supporting-foreground"],
|
|
979
|
-
"--astryx-color-background-card": ["--astryx-card-background"],
|
|
980
|
-
"--astryx-color-background-muted": ["--astryx-card-muted-background"],
|
|
981
|
-
"--astryx-color-border": ["--astryx-card-border"]
|
|
982
|
-
};
|
|
983
|
-
function bridgeComponentTokens(tokens, bridges = COMPONENT_BRIDGES) {
|
|
984
|
-
const style = { ...tokens };
|
|
985
|
-
for (const [source, targets] of Object.entries(bridges)) {
|
|
986
|
-
const value = tokens[source];
|
|
987
|
-
if (!value) continue;
|
|
988
|
-
for (const target of targets) style[target] = value;
|
|
989
|
-
}
|
|
990
|
-
return style;
|
|
991
|
-
}
|
|
992
|
-
/** Token bridges for an inverted surface. Button colors stay with MediaTheme. */
|
|
993
|
-
function bridgeSurfaceTokens(tokens) {
|
|
994
|
-
return bridgeComponentTokens(tokens, SURFACE_BRIDGES);
|
|
995
|
-
}
|
|
996
|
-
/** Inline custom properties for a theme subtree, including syntax colors. */
|
|
997
|
-
function themeStyle(theme) {
|
|
998
|
-
const style = bridgeComponentTokens(theme.tokens);
|
|
999
|
-
if (theme.syntax) Object.assign(style, syntaxThemeStyle(theme.syntax));
|
|
1000
|
-
return style;
|
|
1001
|
-
}
|
|
1002
|
-
//#endregion
|
|
1003
|
-
//#region src/Theme/useAutoMediaMode.ts
|
|
1004
|
-
function readPaintedBackground(start) {
|
|
1005
|
-
let current = start;
|
|
1006
|
-
for (let depth = 0; current && depth < 6; depth += 1) {
|
|
1007
|
-
const style = getComputedStyle(current);
|
|
1008
|
-
const background = parseColor(style.backgroundColor);
|
|
1009
|
-
if (background && background.a >= .2) return {
|
|
1010
|
-
background,
|
|
1011
|
-
ambient: parseColor(style.color) ?? {
|
|
1012
|
-
r: 23,
|
|
1013
|
-
g: 23,
|
|
1014
|
-
b: 23,
|
|
1015
|
-
a: 1
|
|
1016
|
-
}
|
|
1017
|
-
};
|
|
1018
|
-
current = current.parentElement;
|
|
1019
|
-
}
|
|
1020
|
-
return null;
|
|
1021
|
-
}
|
|
1022
|
-
/**
|
|
1023
|
-
* Measure the element that actually paints behind a `display: contents` media
|
|
1024
|
-
* theme. Returns `null` when the surface cannot be read.
|
|
1025
|
-
*/
|
|
1026
|
-
function useAutoMediaMode(element, enabled) {
|
|
1027
|
-
const detected = ref(null);
|
|
1028
|
-
function measure() {
|
|
1029
|
-
if (!enabled.value || typeof getComputedStyle !== "function") {
|
|
1030
|
-
detected.value = null;
|
|
1031
|
-
return;
|
|
1032
|
-
}
|
|
1033
|
-
const parent = element.value?.parentElement;
|
|
1034
|
-
if (!parent) {
|
|
1035
|
-
detected.value = null;
|
|
1036
|
-
return;
|
|
1037
|
-
}
|
|
1038
|
-
const painted = readPaintedBackground(parent);
|
|
1039
|
-
detected.value = painted ? pickMediaMode(painted.background, painted.ambient) : null;
|
|
1040
|
-
}
|
|
1041
|
-
onMounted(measure);
|
|
1042
|
-
watch(enabled, measure);
|
|
1043
|
-
return detected;
|
|
1044
|
-
}
|
|
1045
|
-
//#endregion
|
|
1046
|
-
//#region src/Theme/MediaTheme.vue
|
|
1047
|
-
const _hoisted_1$1 = ["data-astryx-media"];
|
|
1048
|
-
const _sfc_main$1 = /*@__PURE__*/ defineComponent({
|
|
1049
|
-
name: "AstryxMediaTheme",
|
|
1050
|
-
inheritAttrs: false,
|
|
1051
|
-
__name: "MediaTheme",
|
|
1052
|
-
props: {
|
|
1053
|
-
mode: {},
|
|
1054
|
-
fallback: { default: "dark" }
|
|
1055
|
-
},
|
|
1056
|
-
setup(__props, { expose: __expose }) {
|
|
1057
|
-
const props = __props;
|
|
1058
|
-
const attrs = useAttrs();
|
|
1059
|
-
const root = useTemplateRef("root");
|
|
1060
|
-
const theme = inject(themeContextKey, null);
|
|
1061
|
-
const detected = useAutoMediaMode(root, computed(() => props.mode === "auto"));
|
|
1062
|
-
const resolved = computed(() => {
|
|
1063
|
-
if (props.mode === "off") return "off";
|
|
1064
|
-
if (props.mode === "auto") return detected.value ?? props.fallback;
|
|
1065
|
-
return props.mode;
|
|
1066
|
-
});
|
|
1067
|
-
provide(mediaThemeKey, resolved);
|
|
1068
|
-
const rootStyle = computed(() => {
|
|
1069
|
-
const surface = resolved.value === "dark" ? theme?.value.theme.onDark : resolved.value === "light" ? theme?.value.theme.onLight : void 0;
|
|
1070
|
-
if (!surface) return {};
|
|
1071
|
-
return bridgeSurfaceTokens(surface);
|
|
1072
|
-
});
|
|
1073
|
-
__expose({ element: root });
|
|
1074
|
-
return (_ctx, _cache) => {
|
|
1075
|
-
return openBlock(), createElementBlock("div", {
|
|
1076
|
-
ref_key: "root",
|
|
1077
|
-
ref: root,
|
|
1078
|
-
class: normalizeClass(["astryx-media-theme", unref(attrs).class]),
|
|
1079
|
-
"data-astryx-media": resolved.value === "off" ? void 0 : resolved.value,
|
|
1080
|
-
style: normalizeStyle([rootStyle.value, unref(attrs).style])
|
|
1081
|
-
}, [renderSlot(_ctx.$slots, "default")], 14, _hoisted_1$1);
|
|
1082
|
-
};
|
|
1083
|
-
}
|
|
1084
|
-
});
|
|
1085
|
-
//#endregion
|
|
1086
|
-
//#region src/Theme/themeStyleTag.ts
|
|
1087
|
-
/** Injects compiled component rules. A template `<style>` is ignored by Vue. */
|
|
1088
|
-
const ThemeStyle = defineComponent({
|
|
1089
|
-
name: "AstryxThemeStyle",
|
|
1090
|
-
props: { css: {
|
|
1091
|
-
type: String,
|
|
1092
|
-
required: true
|
|
1093
|
-
} },
|
|
1094
|
-
setup(props) {
|
|
1095
|
-
return () => h("style", { "data-astryx-theme-style": "" }, props.css);
|
|
1096
|
-
}
|
|
1097
|
-
});
|
|
1098
|
-
//#endregion
|
|
1099
|
-
//#region src/Theme/useThemeRootSync.ts
|
|
1100
|
-
const entries = [];
|
|
1101
|
-
let baseSnapshot = null;
|
|
1102
|
-
function capture() {
|
|
1103
|
-
const root = document.documentElement;
|
|
1104
|
-
return {
|
|
1105
|
-
theme: root.getAttribute("data-astryx-theme"),
|
|
1106
|
-
mode: root.getAttribute("data-astryx-color-mode")
|
|
1107
|
-
};
|
|
1108
|
-
}
|
|
1109
|
-
function writeAttribute(name, value) {
|
|
1110
|
-
const root = document.documentElement;
|
|
1111
|
-
if (value == null) root.removeAttribute(name);
|
|
1112
|
-
else root.setAttribute(name, value);
|
|
1113
|
-
}
|
|
1114
|
-
function apply(entry) {
|
|
1115
|
-
const root = document.documentElement;
|
|
1116
|
-
root.setAttribute("data-astryx-theme", entry.name());
|
|
1117
|
-
const mode = entry.mode();
|
|
1118
|
-
if (mode === "light" || mode === "dark") root.setAttribute("data-astryx-color-mode", mode);
|
|
1119
|
-
else root.removeAttribute("data-astryx-color-mode");
|
|
1120
|
-
}
|
|
1121
|
-
function restoreBase() {
|
|
1122
|
-
if (!baseSnapshot) return;
|
|
1123
|
-
writeAttribute("data-astryx-theme", baseSnapshot.theme);
|
|
1124
|
-
writeAttribute("data-astryx-color-mode", baseSnapshot.mode);
|
|
1125
|
-
baseSnapshot = null;
|
|
1126
|
-
}
|
|
1127
|
-
/**
|
|
1128
|
-
* The outermost Theme mirrors its name and mode onto `documentElement`, so
|
|
1129
|
-
* portaled UI and browser chrome see the same theme. Nested themes do not.
|
|
1130
|
-
*/
|
|
1131
|
-
function useThemeRootSync(isNested, themeName, mode) {
|
|
1132
|
-
if (isNested || typeof document === "undefined") return;
|
|
1133
|
-
const entry = {
|
|
1134
|
-
name: themeName,
|
|
1135
|
-
mode
|
|
1136
|
-
};
|
|
1137
|
-
onMounted(() => {
|
|
1138
|
-
if (entries.length === 0) baseSnapshot = capture();
|
|
1139
|
-
entries.push(entry);
|
|
1140
|
-
apply(entry);
|
|
1141
|
-
});
|
|
1142
|
-
watch(() => [themeName(), mode()], () => {
|
|
1143
|
-
if (entries[entries.length - 1] === entry) apply(entry);
|
|
1144
|
-
});
|
|
1145
|
-
onBeforeUnmount(() => {
|
|
1146
|
-
const index = entries.lastIndexOf(entry);
|
|
1147
|
-
if (index >= 0) entries.splice(index, 1);
|
|
1148
|
-
const top = entries[entries.length - 1];
|
|
1149
|
-
if (top) apply(top);
|
|
1150
|
-
else restoreBase();
|
|
1151
|
-
});
|
|
1152
|
-
}
|
|
1153
|
-
//#endregion
|
|
1154
|
-
//#region src/Theme/Theme.vue
|
|
1155
|
-
const _hoisted_1 = ["data-astryx-theme", "data-astryx-color-mode"];
|
|
1156
|
-
const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
1157
|
-
name: "AstryxTheme",
|
|
1158
|
-
inheritAttrs: false,
|
|
1159
|
-
__name: "Theme",
|
|
1160
|
-
props: {
|
|
1161
|
-
theme: {},
|
|
1162
|
-
mode: { default: "system" }
|
|
1163
|
-
},
|
|
1164
|
-
setup(__props, { expose: __expose }) {
|
|
1165
|
-
const props = __props;
|
|
1166
|
-
const attrs = useAttrs();
|
|
1167
|
-
const root = useTemplateRef("root");
|
|
1168
|
-
const isNested = inject(themeNestingKey, false);
|
|
1169
|
-
const parentSyntax = inject(syntaxThemeKey, null);
|
|
1170
|
-
provide(themeNestingKey, true);
|
|
1171
|
-
provide(themeContextKey, computed(() => ({
|
|
1172
|
-
theme: props.theme,
|
|
1173
|
-
mode: props.mode
|
|
1174
|
-
})));
|
|
1175
|
-
if (parentSyntax || props.theme.syntax) provide(syntaxThemeKey, computed(() => props.theme.syntax ?? parentSyntax?.value ?? null));
|
|
1176
|
-
useThemeRootSync(isNested, () => props.theme.name, () => props.mode);
|
|
1177
|
-
const colorScheme = computed(() => {
|
|
1178
|
-
if (props.mode === "dark") return "dark";
|
|
1179
|
-
if (props.mode === "light") return "light";
|
|
1180
|
-
return "light dark";
|
|
1181
|
-
});
|
|
1182
|
-
const rootStyle = computed(() => ({
|
|
1183
|
-
colorScheme: colorScheme.value,
|
|
1184
|
-
...themeStyle(props.theme)
|
|
1185
|
-
}));
|
|
1186
|
-
__expose({ element: root });
|
|
1187
|
-
return (_ctx, _cache) => {
|
|
1188
|
-
return openBlock(), createElementBlock("div", {
|
|
1189
|
-
ref_key: "root",
|
|
1190
|
-
ref: root,
|
|
1191
|
-
class: normalizeClass(["astryx-theme", unref(attrs).class]),
|
|
1192
|
-
"data-astryx-theme": __props.theme.name,
|
|
1193
|
-
"data-astryx-color-mode": __props.mode === "system" ? void 0 : __props.mode,
|
|
1194
|
-
style: normalizeStyle([rootStyle.value, unref(attrs).style])
|
|
1195
|
-
}, [__props.theme.css ? (openBlock(), createBlock(unref(ThemeStyle), {
|
|
1196
|
-
key: 0,
|
|
1197
|
-
css: __props.theme.css
|
|
1198
|
-
}, null, 8, ["css"])) : createCommentVNode("v-if", true), renderSlot(_ctx.$slots, "default")], 14, _hoisted_1);
|
|
1199
|
-
};
|
|
1200
|
-
}
|
|
1201
|
-
});
|
|
1202
|
-
//#endregion
|
|
1203
|
-
//#region src/Theme/useMediaTheme.ts
|
|
1204
|
-
/** Read the nearest MediaTheme. Outside one, the mode is `off`. */
|
|
1205
|
-
function useMediaTheme() {
|
|
1206
|
-
return { mode: inject(mediaThemeKey, null) ?? computed(() => "off") };
|
|
1207
|
-
}
|
|
1208
|
-
//#endregion
|
|
1209
|
-
//#region src/Theme/useTheme.ts
|
|
1210
|
-
function readDocumentToken(name, mode) {
|
|
1211
|
-
if (typeof document === "undefined") return "";
|
|
1212
|
-
const raw = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
1213
|
-
return raw ? resolveLightDark(raw, mode) : "";
|
|
1214
|
-
}
|
|
1215
|
-
/**
|
|
1216
|
-
* Read the nearest theme. Outside a `Theme`, the name is `neutral` and tokens
|
|
1217
|
-
* are read from the document's custom properties.
|
|
1218
|
-
*/
|
|
1219
|
-
function useTheme() {
|
|
1220
|
-
const context = inject(themeContextKey, null);
|
|
1221
|
-
const prefersDark = useMediaQuery("(prefers-color-scheme: dark)");
|
|
1222
|
-
const mode = computed(() => {
|
|
1223
|
-
const requested = context?.value.mode;
|
|
1224
|
-
if (requested === "light" || requested === "dark") return requested;
|
|
1225
|
-
return readColorMode(prefersDark.value);
|
|
1226
|
-
});
|
|
1227
|
-
const name = computed(() => context?.value.theme.name ?? "neutral");
|
|
1228
|
-
const tokens = computed(() => {
|
|
1229
|
-
const source = context?.value.theme.tokens ?? {};
|
|
1230
|
-
const resolved = {};
|
|
1231
|
-
for (const [key, value] of Object.entries(source)) resolved[key] = resolveLightDark(value, mode.value);
|
|
1232
|
-
return resolved;
|
|
1233
|
-
});
|
|
1234
|
-
function token(tokenName) {
|
|
1235
|
-
const key = normalizeTokenName(tokenName);
|
|
1236
|
-
return tokens.value[key] ?? readDocumentToken(key, mode.value);
|
|
1237
|
-
}
|
|
1238
|
-
return {
|
|
1239
|
-
name,
|
|
1240
|
-
mode,
|
|
1241
|
-
token,
|
|
1242
|
-
tokens
|
|
1243
|
-
};
|
|
1244
|
-
}
|
|
1245
|
-
//#endregion
|
|
1246
|
-
export { defineTheme as a, expandTypeScale as c, expandColorScale as d, normalizeTokenName as f, _sfc_main$1 as i, expandRadiusScale as l, useMediaTheme as n, isDefinedTheme as o, _sfc_main as r, neutralTheme as s, useTheme as t, expandMotionScale as u };
|