@weasel-js/ui 1.5.1 → 1.5.2
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/chunks/{ActionBar-GZdcfdQL.js → ActionBar-CLwiY3Jg.js} +5 -5
- package/dist/chunks/ActionBar-CLwiY3Jg.js.map +1 -0
- package/dist/chunks/{ActionsBar-Fhx_40iP.js → ActionsBar-D84a4eGy.js} +2 -2
- package/dist/chunks/{ActionsBar-Fhx_40iP.js.map → ActionsBar-D84a4eGy.js.map} +1 -1
- package/dist/chunks/{Badge-Bf8Rd1R6.js → Badge-CW9pBPFl.js} +5 -5
- package/dist/chunks/Badge-CW9pBPFl.js.map +1 -0
- package/dist/chunks/{BandEditor-D8I5Uun-.js → BandEditor-jY-PFKY6.js} +12 -12
- package/dist/chunks/BandEditor-jY-PFKY6.js.map +1 -0
- package/dist/chunks/{Button-CExdkQcU.js → Button-DRSApvnK.js} +15 -15
- package/dist/chunks/Button-DRSApvnK.js.map +1 -0
- package/dist/chunks/{Callout-cx5_CWcW.js → Callout-DrNu-9Qr.js} +12 -12
- package/dist/chunks/Callout-DrNu-9Qr.js.map +1 -0
- package/dist/chunks/{Checkbox-BZZsPaVF.js → Checkbox-BOsDAY2F.js} +5 -5
- package/dist/chunks/Checkbox-BOsDAY2F.js.map +1 -0
- package/dist/chunks/{ColorField-YVf8irfr.js → ColorField-BYzgZM9o.js} +6 -6
- package/dist/chunks/ColorField-BYzgZM9o.js.map +1 -0
- package/dist/chunks/{ComboBox-D57tNYDD.js → ComboBox-Cz3f0Y_8.js} +13 -13
- package/dist/chunks/ComboBox-Cz3f0Y_8.js.map +1 -0
- package/dist/chunks/{CurveEditor-BXiMoN9d.js → CurveEditor-DXwSP-iA.js} +2 -2
- package/dist/chunks/{CurveEditor-BXiMoN9d.js.map → CurveEditor-DXwSP-iA.js.map} +1 -1
- package/dist/chunks/{DataGrid-BVdDMZkQ.js → DataGrid-C8KrYtw7.js} +11 -11
- package/dist/chunks/DataGrid-C8KrYtw7.js.map +1 -0
- package/dist/chunks/{DetentSlider-BWNSv07Z.js → DetentSlider-CAubVX0J.js} +2 -2
- package/dist/chunks/{DetentSlider-BWNSv07Z.js.map → DetentSlider-CAubVX0J.js.map} +1 -1
- package/dist/chunks/{Dialog-DuOzsR2g.js → Dialog-fGqqQ6o_.js} +9 -9
- package/dist/chunks/Dialog-fGqqQ6o_.js.map +1 -0
- package/dist/chunks/{Disclosure-9UgDzc7Z.js → Disclosure-CILDfWsU.js} +6 -6
- package/dist/chunks/Disclosure-CILDfWsU.js.map +1 -0
- package/dist/chunks/{Field-BNqvUJfg.js → Field-DWnV8WZY.js} +6 -6
- package/dist/chunks/Field-DWnV8WZY.js.map +1 -0
- package/dist/chunks/{FontFamilySelect-CO19kyOO.js → FontFamilySelect-DxfgTC3G.js} +2 -2
- package/dist/chunks/{FontFamilySelect-CO19kyOO.js.map → FontFamilySelect-DxfgTC3G.js.map} +1 -1
- package/dist/chunks/{GradientEditor-B_ymIr4Q.js → GradientEditor-rRBmf3G0.js} +7 -7
- package/dist/chunks/GradientEditor-rRBmf3G0.js.map +1 -0
- package/dist/chunks/{Icon-QhLhaGFe.js → Icon-DT0x6HaQ.js} +23 -2
- package/dist/chunks/Icon-DT0x6HaQ.js.map +1 -0
- package/dist/chunks/{Input-B9Vh7ASP.js → Input-DbMKpkXy.js} +5 -5
- package/dist/chunks/Input-DbMKpkXy.js.map +1 -0
- package/dist/chunks/{ItemList-BZJQReXD.js → ItemList-B9zYb0GE.js} +7 -7
- package/dist/chunks/ItemList-B9zYb0GE.js.map +1 -0
- package/dist/chunks/{Jog-BYrxbAQU.js → Jog-DkkTlL3_.js} +8 -8
- package/dist/chunks/Jog-DkkTlL3_.js.map +1 -0
- package/dist/chunks/{Keycaps-CGNQV2Pz.js → Keycaps-DunVpejA.js} +5 -5
- package/dist/chunks/{Keycaps-CGNQV2Pz.js.map → Keycaps-DunVpejA.js.map} +1 -1
- package/dist/chunks/{LayerStack-DOylrQcm.js → LayerStack-CfQ6GsRz.js} +18 -18
- package/dist/chunks/LayerStack-CfQ6GsRz.js.map +1 -0
- package/dist/chunks/{MenuButton-DGE-0DP0.js → MenuButton-C_4nox39.js} +7 -7
- package/dist/chunks/MenuButton-C_4nox39.js.map +1 -0
- package/dist/chunks/{MeshEditor-CHoGQ9K8.js → MeshEditor-Bipz-Ocl.js} +8 -8
- package/dist/chunks/MeshEditor-Bipz-Ocl.js.map +1 -0
- package/dist/chunks/{NumberField-CQzS6TjF.js → NumberField-CCjEDZCg.js} +9 -9
- package/dist/chunks/NumberField-CCjEDZCg.js.map +1 -0
- package/dist/chunks/{OptionsBar-BWaYG_OH.js → OptionsBar-DeQ-vUeZ.js} +2 -2
- package/dist/chunks/{OptionsBar-BWaYG_OH.js.map → OptionsBar-DeQ-vUeZ.js.map} +1 -1
- package/dist/chunks/{PaintField-BVYMu3OI.js → PaintField-jBOJ32rL.js} +8 -8
- package/dist/chunks/PaintField-jBOJ32rL.js.map +1 -0
- package/dist/chunks/{PaintInput-BzAHCKro.js → PaintInput-Qs7Rul5R.js} +10 -10
- package/dist/chunks/PaintInput-Qs7Rul5R.js.map +1 -0
- package/dist/chunks/{PatternPicker-C4OryrYi.js → PatternPicker-BMpXWboq.js} +6 -6
- package/dist/chunks/PatternPicker-BMpXWboq.js.map +1 -0
- package/dist/chunks/{Plot2D-Czvyt_vG.js → Plot2D-CXf_f7QD.js} +1 -1
- package/dist/chunks/{Plot2D-Czvyt_vG.js.map → Plot2D-CXf_f7QD.js.map} +1 -1
- package/dist/chunks/{PointPlotter-Xvb98GwB.js → PointPlotter-S_gz7VYt.js} +2 -2
- package/dist/chunks/{PointPlotter-Xvb98GwB.js.map → PointPlotter-S_gz7VYt.js.map} +1 -1
- package/dist/chunks/{Powerline-B_EH-7Z-.js → Powerline-Ak5AWUlK.js} +5 -5
- package/dist/chunks/Powerline-Ak5AWUlK.js.map +1 -0
- package/dist/chunks/Prefs-CNC8tzyN.js +308 -0
- package/dist/chunks/Prefs-CNC8tzyN.js.map +1 -0
- package/dist/chunks/{Properties-B3KU69NI.js → Properties-Rnb6TAbN.js} +230 -213
- package/dist/chunks/Properties-Rnb6TAbN.js.map +1 -0
- package/dist/chunks/{RadioGroup-C6xpdQNg.js → RadioGroup-CsVp3SEu.js} +6 -6
- package/dist/chunks/RadioGroup-CsVp3SEu.js.map +1 -0
- package/dist/chunks/{RangeSlider-CzgeGLVS.js → RangeSlider-DNr-pJpZ.js} +8 -8
- package/dist/chunks/RangeSlider-DNr-pJpZ.js.map +1 -0
- package/dist/chunks/{ResizeHandle-1Ey8AOij.js → ResizeHandle-RXFf5fXr.js} +1 -1
- package/dist/chunks/{ResizeHandle-1Ey8AOij.js.map → ResizeHandle-RXFf5fXr.js.map} +1 -1
- package/dist/chunks/Select-BEope086.js +190 -0
- package/dist/chunks/Select-BEope086.js.map +1 -0
- package/dist/chunks/SelectionPanel-CEbLS-0D.js +102 -0
- package/dist/chunks/SelectionPanel-CEbLS-0D.js.map +1 -0
- package/dist/chunks/{Sidebar-BlUjn8lD.js → Sidebar-qn_oSCNX.js} +4 -4
- package/dist/chunks/Sidebar-qn_oSCNX.js.map +1 -0
- package/dist/chunks/{SidebarPanel-BqHfz6VK.js → SidebarPanel-Bs6V21hg.js} +12 -12
- package/dist/chunks/SidebarPanel-Bs6V21hg.js.map +1 -0
- package/dist/chunks/{Slider-B2ywUZH6.js → Slider-CIIrqiFS.js} +18 -18
- package/dist/chunks/Slider-CIIrqiFS.js.map +1 -0
- package/dist/chunks/{StatusBar-BFt7Yw5O.js → StatusBar-B4L15DSm.js} +6 -6
- package/dist/chunks/StatusBar-B4L15DSm.js.map +1 -0
- package/dist/chunks/{Switch-Om3t3ASc.js → Switch-DH5POG0T.js} +5 -5
- package/dist/chunks/Switch-DH5POG0T.js.map +1 -0
- package/dist/chunks/{Tabs-EAvYywil.js → Tabs-BFHikpml.js} +5 -5
- package/dist/chunks/Tabs-BFHikpml.js.map +1 -0
- package/dist/chunks/{Timeline-BEyKaBXl.js → Timeline-DNKY_yiK.js} +40 -40
- package/dist/chunks/Timeline-DNKY_yiK.js.map +1 -0
- package/dist/chunks/{Toast-iqLDD_XZ.js → Toast-CI1UDuK6.js} +15 -15
- package/dist/chunks/Toast-CI1UDuK6.js.map +1 -0
- package/dist/chunks/{ToggleBar--9As2PWG.js → ToggleBar-CClus5Cd.js} +8 -8
- package/dist/chunks/ToggleBar-CClus5Cd.js.map +1 -0
- package/dist/chunks/TokenPanel-BPHq24dc.js +634 -0
- package/dist/chunks/TokenPanel-BPHq24dc.js.map +1 -0
- package/dist/chunks/{ToolButton-Dd-1T5aX.js → ToolButton-9QzJCmuM.js} +7 -7
- package/dist/chunks/ToolButton-9QzJCmuM.js.map +1 -0
- package/dist/chunks/{ToolGroup-BBI-W-Gm.js → ToolGroup-BJiDrH_i.js} +3 -3
- package/dist/chunks/ToolGroup-BJiDrH_i.js.map +1 -0
- package/dist/chunks/ToolOptionsBar-CAM6RcUH.js +85 -0
- package/dist/chunks/ToolOptionsBar-CAM6RcUH.js.map +1 -0
- package/dist/chunks/{ToolPalette-BmTDDpmz.js → ToolPalette-DGkKwE7D.js} +8 -8
- package/dist/chunks/ToolPalette-DGkKwE7D.js.map +1 -0
- package/dist/chunks/{Tooltip-BHre_vbI.js → Tooltip-C4YBczLq.js} +3 -3
- package/dist/chunks/Tooltip-C4YBczLq.js.map +1 -0
- package/dist/chunks/{createKeyframeLayer-7j7ukrSx.js → createKeyframeLayer-DKtO0Sw_.js} +3 -3
- package/dist/chunks/{createKeyframeLayer-7j7ukrSx.js.map → createKeyframeLayer-DKtO0Sw_.js.map} +1 -1
- package/dist/chunks/{icons-Btrs-JD7.js → icons-DFLytcui.js} +2 -2
- package/dist/chunks/{icons-Btrs-JD7.js.map → icons-DFLytcui.js.map} +1 -1
- package/dist/chunks/model-13kZ_-mE.js +483 -0
- package/dist/chunks/model-13kZ_-mE.js.map +1 -0
- package/dist/chunks/number-BHz66zQO.js +89 -0
- package/dist/chunks/number-BHz66zQO.js.map +1 -0
- package/dist/chunks/{schema-MCVT1MLv.js → schema-Dft4Cu2p.js} +1 -1
- package/dist/chunks/schema-Dft4Cu2p.js.map +1 -0
- package/dist/chunks/segmentedControl.module-DS72X1ns.js +11 -0
- package/dist/chunks/segmentedControl.module-DS72X1ns.js.map +1 -0
- package/dist/chunks/{snap-B0WQwetQ.js → snap-CEjuWOhN.js} +1 -1
- package/dist/chunks/{snap-B0WQwetQ.js.map → snap-CEjuWOhN.js.map} +1 -1
- package/dist/chunks/useRovingTabIndex-Dkpf_KhN.js.map +1 -1
- package/dist/color/oklch.d.ts +2 -1
- package/dist/color/oklch.d.ts.map +1 -1
- package/dist/components/ActionBar/index.js +1 -1
- package/dist/components/ActionsBar/index.js +1 -1
- package/dist/components/Badge/index.js +1 -1
- package/dist/components/BandEditor/index.js +1 -1
- package/dist/components/Button/index.js +1 -1
- package/dist/components/Callout/index.js +1 -1
- package/dist/components/Checkbox/index.js +1 -1
- package/dist/components/ColorField/index.js +1 -1
- package/dist/components/ComboBox/index.js +1 -1
- package/dist/components/CurveEditor/index.js +3 -3
- package/dist/components/DataGrid/index.js +1 -1
- package/dist/components/DetentSlider/index.js +1 -1
- package/dist/components/Dialog/index.js +1 -1
- package/dist/components/Disclosure/index.js +1 -1
- package/dist/components/Field/index.js +1 -1
- package/dist/components/FontFamilySelect/index.js +1 -1
- package/dist/components/GradientEditor/index.js +1 -1
- package/dist/components/Input/index.js +1 -1
- package/dist/components/ItemList/index.js +1 -1
- package/dist/components/Jog/index.js +1 -1
- package/dist/components/Keycaps/index.js +1 -1
- package/dist/components/LayerStack/index.js +1 -1
- package/dist/components/MenuButton/index.js +1 -1
- package/dist/components/MeshEditor/index.js +1 -1
- package/dist/components/NumberField/UnitField.d.ts +2 -1
- package/dist/components/NumberField/UnitField.d.ts.map +1 -1
- package/dist/components/NumberField/index.js +1 -1
- package/dist/components/OptionsBar/index.js +1 -1
- package/dist/components/PaintField/index.js +1 -1
- package/dist/components/PaintInput/index.js +1 -1
- package/dist/components/PatternPicker/index.js +1 -1
- package/dist/components/Plot2D/index.js +1 -1
- package/dist/components/PointPlotter/index.js +1 -1
- package/dist/components/Powerline/index.js +2 -2
- package/dist/components/Prefs/index.js +2 -2
- package/dist/components/Prefs/schema.d.ts +2 -1
- package/dist/components/Prefs/schema.d.ts.map +1 -1
- package/dist/components/Properties/PropertyGroup.d.ts +7 -1
- package/dist/components/Properties/PropertyGroup.d.ts.map +1 -1
- package/dist/components/Properties/PropertyPanel.d.ts +36 -38
- package/dist/components/Properties/PropertyPanel.d.ts.map +1 -1
- package/dist/components/Properties/index.d.ts +2 -4
- package/dist/components/Properties/index.d.ts.map +1 -1
- package/dist/components/Properties/index.js +2 -2
- package/dist/components/RadioGroup/index.js +1 -1
- package/dist/components/RangeSlider/index.js +1 -1
- package/dist/components/ResizeHandle/index.js +1 -1
- package/dist/components/Select/Select.d.ts +18 -0
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/index.d.ts +1 -1
- package/dist/components/Select/index.d.ts.map +1 -1
- package/dist/components/Select/index.js +1 -1
- package/dist/components/SelectionPanel/SelectionPanel.d.ts +3 -50
- package/dist/components/SelectionPanel/SelectionPanel.d.ts.map +1 -1
- package/dist/components/SelectionPanel/index.js +3 -2
- package/dist/components/SelectionPanel/model.d.ts +4 -1
- package/dist/components/SelectionPanel/model.d.ts.map +1 -1
- package/dist/components/SelectionPanel/renderLeaf.d.ts +106 -0
- package/dist/components/SelectionPanel/renderLeaf.d.ts.map +1 -0
- package/dist/components/Sidebar/index.js +1 -1
- package/dist/components/SidebarPanel/index.js +1 -1
- package/dist/components/Slider/index.js +1 -1
- package/dist/components/StatusBar/index.js +1 -1
- package/dist/components/Switch/index.js +1 -1
- package/dist/components/Tabs/index.js +1 -1
- package/dist/components/Timeline/index.js +1 -1
- package/dist/components/Toast/index.js +1 -1
- package/dist/components/ToggleBar/index.js +1 -1
- package/dist/components/TokenPanel/TokenPanel.d.ts +10 -4
- package/dist/components/TokenPanel/TokenPanel.d.ts.map +1 -1
- package/dist/components/TokenPanel/index.d.ts +2 -2
- package/dist/components/TokenPanel/index.d.ts.map +1 -1
- package/dist/components/TokenPanel/index.js +2 -2
- package/dist/components/TokenPanel/tokenTypes.d.ts +24 -0
- package/dist/components/TokenPanel/tokenTypes.d.ts.map +1 -1
- package/dist/components/ToolButton/index.js +1 -1
- package/dist/components/ToolGroup/index.js +1 -1
- package/dist/components/ToolOptionsBar/ToolOptionsBar.d.ts +29 -18
- package/dist/components/ToolOptionsBar/ToolOptionsBar.d.ts.map +1 -1
- package/dist/components/ToolOptionsBar/index.js +1 -1
- package/dist/components/ToolPalette/ToolPalette.d.ts +5 -4
- package/dist/components/ToolPalette/ToolPalette.d.ts.map +1 -1
- package/dist/components/ToolPalette/index.js +1 -1
- package/dist/components/Tooltip/index.js +1 -1
- package/dist/format/number.d.ts +10 -1
- package/dist/format/number.d.ts.map +1 -1
- package/dist/icons/paths.d.ts +9 -1
- package/dist/icons/paths.d.ts.map +1 -1
- package/dist/index.js +69 -75
- package/dist/index.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/useRovingTabIndex.d.ts +7 -5
- package/dist/useRovingTabIndex.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/chunks/ActionBar-GZdcfdQL.js.map +0 -1
- package/dist/chunks/Badge-Bf8Rd1R6.js.map +0 -1
- package/dist/chunks/BandEditor-D8I5Uun-.js.map +0 -1
- package/dist/chunks/Button-CExdkQcU.js.map +0 -1
- package/dist/chunks/Callout-cx5_CWcW.js.map +0 -1
- package/dist/chunks/Checkbox-BZZsPaVF.js.map +0 -1
- package/dist/chunks/ColorField-YVf8irfr.js.map +0 -1
- package/dist/chunks/ComboBox-D57tNYDD.js.map +0 -1
- package/dist/chunks/DataGrid-BVdDMZkQ.js.map +0 -1
- package/dist/chunks/Dialog-DuOzsR2g.js.map +0 -1
- package/dist/chunks/Disclosure-9UgDzc7Z.js.map +0 -1
- package/dist/chunks/Field-BNqvUJfg.js.map +0 -1
- package/dist/chunks/GradientEditor-B_ymIr4Q.js.map +0 -1
- package/dist/chunks/Icon-QhLhaGFe.js.map +0 -1
- package/dist/chunks/Input-B9Vh7ASP.js.map +0 -1
- package/dist/chunks/ItemList-BZJQReXD.js.map +0 -1
- package/dist/chunks/Jog-BYrxbAQU.js.map +0 -1
- package/dist/chunks/LayerStack-DOylrQcm.js.map +0 -1
- package/dist/chunks/MenuButton-DGE-0DP0.js.map +0 -1
- package/dist/chunks/MeshEditor-CHoGQ9K8.js.map +0 -1
- package/dist/chunks/NumberField-CQzS6TjF.js.map +0 -1
- package/dist/chunks/PaintField-BVYMu3OI.js.map +0 -1
- package/dist/chunks/PaintInput-BzAHCKro.js.map +0 -1
- package/dist/chunks/PatternPicker-C4OryrYi.js.map +0 -1
- package/dist/chunks/Powerline-B_EH-7Z-.js.map +0 -1
- package/dist/chunks/Prefs-FuaJBs3t.js +0 -308
- package/dist/chunks/Prefs-FuaJBs3t.js.map +0 -1
- package/dist/chunks/Properties-B3KU69NI.js.map +0 -1
- package/dist/chunks/RadioGroup-C6xpdQNg.js.map +0 -1
- package/dist/chunks/RangeSlider-CzgeGLVS.js.map +0 -1
- package/dist/chunks/Select-BMYVh10x.js +0 -127
- package/dist/chunks/Select-BMYVh10x.js.map +0 -1
- package/dist/chunks/SelectionPanel-DTpcQidl.js +0 -572
- package/dist/chunks/SelectionPanel-DTpcQidl.js.map +0 -1
- package/dist/chunks/Sidebar-BlUjn8lD.js.map +0 -1
- package/dist/chunks/SidebarPanel-BqHfz6VK.js.map +0 -1
- package/dist/chunks/Slider-B2ywUZH6.js.map +0 -1
- package/dist/chunks/StatusBar-BFt7Yw5O.js.map +0 -1
- package/dist/chunks/Switch-Om3t3ASc.js.map +0 -1
- package/dist/chunks/Tabs-EAvYywil.js.map +0 -1
- package/dist/chunks/Timeline-BEyKaBXl.js.map +0 -1
- package/dist/chunks/Toast-iqLDD_XZ.js.map +0 -1
- package/dist/chunks/ToggleBar--9As2PWG.js.map +0 -1
- package/dist/chunks/TokenPanel-BL9hlq7x.js +0 -374
- package/dist/chunks/TokenPanel-BL9hlq7x.js.map +0 -1
- package/dist/chunks/ToolButton-Dd-1T5aX.js.map +0 -1
- package/dist/chunks/ToolGroup-BBI-W-Gm.js.map +0 -1
- package/dist/chunks/ToolOptionsBar-B2xPWzJf.js +0 -27
- package/dist/chunks/ToolOptionsBar-B2xPWzJf.js.map +0 -1
- package/dist/chunks/ToolPalette-BmTDDpmz.js.map +0 -1
- package/dist/chunks/Tooltip-BHre_vbI.js.map +0 -1
- package/dist/chunks/number-f6PydOZK.js +0 -52
- package/dist/chunks/number-f6PydOZK.js.map +0 -1
- package/dist/chunks/schema-MCVT1MLv.js.map +0 -1
- package/dist/chunks/segmentedControl.module-DmeUMYe3.js +0 -11
- package/dist/chunks/segmentedControl.module-DmeUMYe3.js.map +0 -1
- package/dist/components/Properties/PinDot.d.ts +0 -18
- package/dist/components/Properties/PinDot.d.ts.map +0 -1
|
@@ -1,374 +0,0 @@
|
|
|
1
|
-
import { t as e } from "./Button-CExdkQcU.js";
|
|
2
|
-
import { n as t } from "./Disclosure-9UgDzc7Z.js";
|
|
3
|
-
import { t as n } from "./Select-BMYVh10x.js";
|
|
4
|
-
import { t as r } from "./Input-B9Vh7ASP.js";
|
|
5
|
-
import { n as i } from "./NumberField-CQzS6TjF.js";
|
|
6
|
-
import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
7
|
-
import { memo as c, useCallback as l, useMemo as u, useState as d } from "react";
|
|
8
|
-
//#region src/components/TokenPanel/color.ts
|
|
9
|
-
var f = /^#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i, p = /^rgba?\(\s*(\d{1,3})[\s,]+(\d{1,3})[\s,]+(\d{1,3})\b/i, m = /^(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color|color-mix)\(.+\)$/i, h = new Set([
|
|
10
|
-
"transparent",
|
|
11
|
-
"currentcolor",
|
|
12
|
-
"black",
|
|
13
|
-
"white",
|
|
14
|
-
"gray",
|
|
15
|
-
"silver",
|
|
16
|
-
"red",
|
|
17
|
-
"orange",
|
|
18
|
-
"yellow",
|
|
19
|
-
"gold",
|
|
20
|
-
"lime",
|
|
21
|
-
"green",
|
|
22
|
-
"teal",
|
|
23
|
-
"cyan",
|
|
24
|
-
"blue",
|
|
25
|
-
"navy",
|
|
26
|
-
"purple",
|
|
27
|
-
"magenta",
|
|
28
|
-
"pink",
|
|
29
|
-
"brown"
|
|
30
|
-
]);
|
|
31
|
-
function g() {
|
|
32
|
-
return typeof CSS < "u" && typeof CSS.supports == "function" ? (e) => CSS.supports("color", e) : null;
|
|
33
|
-
}
|
|
34
|
-
function _(e, t = g()) {
|
|
35
|
-
let n = e.trim();
|
|
36
|
-
return !n || n.includes("var(") ? !1 : t ? t(n) : f.test(n) || m.test(n) || h.has(n.toLowerCase());
|
|
37
|
-
}
|
|
38
|
-
function v(e) {
|
|
39
|
-
if (f.test(e)) {
|
|
40
|
-
let t = e.slice(1).toLowerCase();
|
|
41
|
-
return `#${t.length <= 4 ? [...t.slice(0, 3)].map((e) => e + e).join("") : t.slice(0, 6)}`;
|
|
42
|
-
}
|
|
43
|
-
let t = p.exec(e);
|
|
44
|
-
return t ? `#${t.slice(1, 4).map((e) => Math.min(255, Number(e)).toString(16).padStart(2, "0")).join("")}` : null;
|
|
45
|
-
}
|
|
46
|
-
var y;
|
|
47
|
-
function b(e) {
|
|
48
|
-
if (y === void 0) try {
|
|
49
|
-
y = document.createElement("canvas").getContext("2d");
|
|
50
|
-
} catch {
|
|
51
|
-
y = null;
|
|
52
|
-
}
|
|
53
|
-
if (!y) return null;
|
|
54
|
-
y.fillStyle = "#000000", y.fillStyle = e;
|
|
55
|
-
let t = String(y.fillStyle);
|
|
56
|
-
return y.fillStyle = "#ffffff", y.fillStyle = e, t === String(y.fillStyle) ? t : null;
|
|
57
|
-
}
|
|
58
|
-
function x(e) {
|
|
59
|
-
let t = e.trim(), n = v(t);
|
|
60
|
-
if (n) return n;
|
|
61
|
-
let r = typeof document > "u" ? null : b(t);
|
|
62
|
-
return r && r !== t ? v(r) : null;
|
|
63
|
-
}
|
|
64
|
-
var S = {
|
|
65
|
-
panel: "_panel_1vnnk_1",
|
|
66
|
-
section: "_section_1vnnk_7",
|
|
67
|
-
sectionHead: "_sectionHead_1vnnk_17",
|
|
68
|
-
sectionBody: "_sectionBody_1vnnk_26",
|
|
69
|
-
row: "_row_1vnnk_33",
|
|
70
|
-
family: "_family_1vnnk_34",
|
|
71
|
-
name: "_name_1vnnk_41",
|
|
72
|
-
edit: "_edit_1vnnk_50",
|
|
73
|
-
field: "_field_1vnnk_57",
|
|
74
|
-
number: "_number_1vnnk_63",
|
|
75
|
-
unit: "_unit_1vnnk_69",
|
|
76
|
-
swatchInput: "_swatchInput_1vnnk_76",
|
|
77
|
-
chip: "_chip_1vnnk_88",
|
|
78
|
-
curve: "_curve_1vnnk_97",
|
|
79
|
-
strip: "_strip_1vnnk_104",
|
|
80
|
-
swatch: "_swatch_1vnnk_76",
|
|
81
|
-
tight: "_tight_1vnnk_138"
|
|
82
|
-
}, C = [
|
|
83
|
-
{
|
|
84
|
-
id: "color",
|
|
85
|
-
title: "Color"
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
id: "type",
|
|
89
|
-
title: "Type"
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
id: "size",
|
|
93
|
-
title: "Size"
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
id: "motion",
|
|
97
|
-
title: "Motion"
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
id: "depth",
|
|
101
|
-
title: "Depth"
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
id: "other",
|
|
105
|
-
title: "Other"
|
|
106
|
-
}
|
|
107
|
-
], w = /^(?:font|tracking|leading|letter|line-height)/;
|
|
108
|
-
function T(e) {
|
|
109
|
-
switch (e.type) {
|
|
110
|
-
case "color": return "color";
|
|
111
|
-
case "fontFamily":
|
|
112
|
-
case "fontWeight": return "type";
|
|
113
|
-
case "duration":
|
|
114
|
-
case "cubicBezier": return "motion";
|
|
115
|
-
case "shadow":
|
|
116
|
-
case "gradient": return "depth";
|
|
117
|
-
case "dimension":
|
|
118
|
-
case "number": return w.test(e.group) ? "type" : e.type === "number" && (e.group === "z" || e.group === "z-index") ? "depth" : "size";
|
|
119
|
-
default: return "other";
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
var E = String.raw`-?(?:\d+\.?\d*|\.\d+)`, D = RegExp(`^${E}(?:px|rem|em|%|ch|ex|lh|rlh|vh|vw|vmin|vmax|svh|lvh|dvh|cqw|cqh|pt|pc|cm|mm|in|q)$`, "i"), O = RegExp(`^${E}m?s$`), k = RegExp(`^${E}$`), A = RegExp(`^${E}(?:px|rem|em)?$`), j = RegExp(`^cubic-bezier\\(\\s*(${E})\\s*,\\s*(${E})\\s*,\\s*(${E})\\s*,\\s*(${E})\\s*\\)$`, "i"), M = /^(?:repeating-)?(?:linear|radial|conic)-gradient\(/i, N = /,(?![^(]*\))/, P = /[a-z-]+\([^)]*\)|\S+/gi;
|
|
123
|
-
function F(e) {
|
|
124
|
-
return e.split(N).every((e) => {
|
|
125
|
-
let t = e.trim().replace(/^inset\s+/i, "").match(P) ?? [], n = t.filter((e) => A.test(e)), r = t.filter((e) => !A.test(e));
|
|
126
|
-
return n.length >= 2 && n.length <= 4 && r.length <= 1 && r.every((e) => _(e));
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
function I(e) {
|
|
130
|
-
let t = e.trim();
|
|
131
|
-
return t ? O.test(t) ? "duration" : D.test(t) ? "dimension" : k.test(t) ? "number" : j.test(t) ? "cubicBezier" : M.test(t) ? "gradient" : _(t) ? "color" : F(t) ? "shadow" : "string" : "string";
|
|
132
|
-
}
|
|
133
|
-
function L(e) {
|
|
134
|
-
let t = RegExp(`^(${E})([a-z%]*)$`, "i").exec(e.trim());
|
|
135
|
-
return t ? {
|
|
136
|
-
amount: Number(t[1]),
|
|
137
|
-
unit: t[2] ?? ""
|
|
138
|
-
} : null;
|
|
139
|
-
}
|
|
140
|
-
function R(e) {
|
|
141
|
-
let t = j.exec(e.trim());
|
|
142
|
-
if (!t) return null;
|
|
143
|
-
let [n, r, i, a] = t.slice(1, 5).map(Number);
|
|
144
|
-
return [
|
|
145
|
-
n,
|
|
146
|
-
r,
|
|
147
|
-
i,
|
|
148
|
-
a
|
|
149
|
-
];
|
|
150
|
-
}
|
|
151
|
-
//#endregion
|
|
152
|
-
//#region src/components/TokenPanel/TokenPanel.tsx
|
|
153
|
-
var z = [
|
|
154
|
-
"100",
|
|
155
|
-
"200",
|
|
156
|
-
"300",
|
|
157
|
-
"400",
|
|
158
|
-
"500",
|
|
159
|
-
"600",
|
|
160
|
-
"700",
|
|
161
|
-
"800",
|
|
162
|
-
"900"
|
|
163
|
-
], B = {
|
|
164
|
-
maximumFractionDigits: 4,
|
|
165
|
-
useGrouping: !1
|
|
166
|
-
};
|
|
167
|
-
function V(e, t) {
|
|
168
|
-
let n = /* @__PURE__ */ new Map();
|
|
169
|
-
for (let t of e) t.type === "color" && n.set(t.group, (n.get(t.group) ?? 0) + 1);
|
|
170
|
-
let r = /* @__PURE__ */ new Map(), i = [];
|
|
171
|
-
for (let a of e) {
|
|
172
|
-
if (a.type !== "color" || (n.get(a.group) ?? 0) < t) {
|
|
173
|
-
i.push({
|
|
174
|
-
kind: "row",
|
|
175
|
-
token: a
|
|
176
|
-
});
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
let e = r.get(a.group);
|
|
180
|
-
e || (e = {
|
|
181
|
-
kind: "family",
|
|
182
|
-
group: a.group,
|
|
183
|
-
tokens: []
|
|
184
|
-
}, r.set(a.group, e), i.push(e)), e.tokens.push(a);
|
|
185
|
-
}
|
|
186
|
-
return i;
|
|
187
|
-
}
|
|
188
|
-
function H({ points: e, label: t }) {
|
|
189
|
-
let [n, r, i, a] = e, s = Math.min(0, 1 - r, 1 - a), c = Math.max(1, 1 - r, 1 - a);
|
|
190
|
-
return /* @__PURE__ */ o("svg", {
|
|
191
|
-
className: S.curve,
|
|
192
|
-
viewBox: `-0.1 ${s - .1} 1.2 ${c - s + .2}`,
|
|
193
|
-
role: "img",
|
|
194
|
-
"aria-label": t,
|
|
195
|
-
children: /* @__PURE__ */ o("path", {
|
|
196
|
-
d: `M0 1 C${n} ${1 - r} ${i} ${1 - a} 1 0`,
|
|
197
|
-
fill: "none",
|
|
198
|
-
stroke: "currentColor",
|
|
199
|
-
strokeWidth: .08
|
|
200
|
-
})
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
function U({ token: e, set: t }) {
|
|
204
|
-
let { name: c, type: l, value: d } = e, f = `${c} value`, p = u(() => l === "color" ? x(d) : null, [l, d]);
|
|
205
|
-
if (l === "dimension" || l === "duration" || l === "number") {
|
|
206
|
-
let e = L(d);
|
|
207
|
-
if (e) return /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o(i, {
|
|
208
|
-
className: S.number,
|
|
209
|
-
"aria-label": f,
|
|
210
|
-
value: e.amount,
|
|
211
|
-
hideSteppers: !0,
|
|
212
|
-
formatOptions: B,
|
|
213
|
-
onChange: (n) => {
|
|
214
|
-
Number.isFinite(n) && t(`${n}${e.unit}`);
|
|
215
|
-
}
|
|
216
|
-
}), e.unit ? /* @__PURE__ */ o("span", {
|
|
217
|
-
className: S.unit,
|
|
218
|
-
children: e.unit
|
|
219
|
-
}) : null] });
|
|
220
|
-
}
|
|
221
|
-
if (l === "fontWeight") return /* @__PURE__ */ o(n, {
|
|
222
|
-
"aria-label": c,
|
|
223
|
-
width: "fit",
|
|
224
|
-
selectedKey: d,
|
|
225
|
-
options: (z.includes(d) ? z : [...z, d]).map((e) => ({
|
|
226
|
-
value: e,
|
|
227
|
-
label: e
|
|
228
|
-
})),
|
|
229
|
-
onSelectionChange: t
|
|
230
|
-
});
|
|
231
|
-
let m = l === "cubicBezier" ? R(d) : null;
|
|
232
|
-
return /* @__PURE__ */ s(a, { children: [m ? /* @__PURE__ */ o(H, {
|
|
233
|
-
points: m,
|
|
234
|
-
label: `${c} curve`
|
|
235
|
-
}) : null, /* @__PURE__ */ o(r, {
|
|
236
|
-
className: S.field,
|
|
237
|
-
"aria-label": f,
|
|
238
|
-
value: d,
|
|
239
|
-
onChange: t,
|
|
240
|
-
leadingAdornment: l === "color" ? p ? /* @__PURE__ */ o("input", {
|
|
241
|
-
type: "color",
|
|
242
|
-
className: S.swatchInput,
|
|
243
|
-
"aria-label": `${c} color`,
|
|
244
|
-
value: p,
|
|
245
|
-
onChange: (e) => t(e.target.value)
|
|
246
|
-
}) : /* @__PURE__ */ o("span", {
|
|
247
|
-
className: S.chip,
|
|
248
|
-
style: { "--token-color": d },
|
|
249
|
-
"aria-hidden": "true"
|
|
250
|
-
}) : void 0
|
|
251
|
-
})] });
|
|
252
|
-
}
|
|
253
|
-
var W = c(function({ token: t, onChange: n }) {
|
|
254
|
-
let r = l((e) => n(t.name, e), [n, t.name]);
|
|
255
|
-
return /* @__PURE__ */ s("div", {
|
|
256
|
-
className: S.row,
|
|
257
|
-
role: "group",
|
|
258
|
-
"aria-label": t.name,
|
|
259
|
-
children: [/* @__PURE__ */ o("span", {
|
|
260
|
-
className: S.name,
|
|
261
|
-
title: t.description || t.name,
|
|
262
|
-
children: t.name
|
|
263
|
-
}), /* @__PURE__ */ s("div", {
|
|
264
|
-
className: S.edit,
|
|
265
|
-
children: [/* @__PURE__ */ o(U, {
|
|
266
|
-
token: t,
|
|
267
|
-
set: r
|
|
268
|
-
}), t.overridden ? /* @__PURE__ */ o(e, {
|
|
269
|
-
variant: "ghost",
|
|
270
|
-
size: "sm",
|
|
271
|
-
ariaLabel: `Reset ${t.name}`,
|
|
272
|
-
onClick: () => n(t.name, null),
|
|
273
|
-
children: "Reset"
|
|
274
|
-
}) : null]
|
|
275
|
-
})]
|
|
276
|
-
});
|
|
277
|
-
}, (e, t) => e.onChange === t.onChange && e.token.name === t.token.name && e.token.type === t.token.type && e.token.value === t.token.value && e.token.overridden === t.token.overridden && e.token.description === t.token.description);
|
|
278
|
-
function G({ group: e, tokens: t, onChange: n }) {
|
|
279
|
-
let [r, i] = d(null), a = t.find((e) => e.name === r) ?? null;
|
|
280
|
-
return /* @__PURE__ */ s("div", {
|
|
281
|
-
className: S.family,
|
|
282
|
-
role: "group",
|
|
283
|
-
"aria-label": e,
|
|
284
|
-
children: [
|
|
285
|
-
/* @__PURE__ */ o("span", {
|
|
286
|
-
className: S.name,
|
|
287
|
-
children: e
|
|
288
|
-
}),
|
|
289
|
-
/* @__PURE__ */ o("div", {
|
|
290
|
-
className: S.strip,
|
|
291
|
-
children: t.map((e) => /* @__PURE__ */ o("button", {
|
|
292
|
-
type: "button",
|
|
293
|
-
className: S.swatch,
|
|
294
|
-
style: { "--token-color": e.value },
|
|
295
|
-
"aria-label": e.name,
|
|
296
|
-
"aria-pressed": e.name === r,
|
|
297
|
-
title: `${e.name}: ${e.value}`,
|
|
298
|
-
"data-overridden": e.overridden ? "" : void 0,
|
|
299
|
-
onClick: () => i((t) => t === e.name ? null : e.name)
|
|
300
|
-
}, e.name))
|
|
301
|
-
}),
|
|
302
|
-
a ? /* @__PURE__ */ o(W, {
|
|
303
|
-
token: a,
|
|
304
|
-
onChange: n
|
|
305
|
-
}) : null
|
|
306
|
-
]
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
function K({ title: e, open: n, onToggle: r, tokens: i, familySize: a, onChange: c }) {
|
|
310
|
-
let l = u(() => V(i, a), [i, a]);
|
|
311
|
-
return /* @__PURE__ */ s("section", {
|
|
312
|
-
className: S.section,
|
|
313
|
-
"aria-label": e,
|
|
314
|
-
children: [/* @__PURE__ */ o(t, {
|
|
315
|
-
className: S.sectionHead,
|
|
316
|
-
open: n,
|
|
317
|
-
onToggle: r,
|
|
318
|
-
label: e,
|
|
319
|
-
children: /* @__PURE__ */ o("span", {
|
|
320
|
-
"aria-hidden": "true",
|
|
321
|
-
children: e
|
|
322
|
-
})
|
|
323
|
-
}), n ? /* @__PURE__ */ o("div", {
|
|
324
|
-
className: S.sectionBody,
|
|
325
|
-
children: l.map((e) => e.kind === "row" ? /* @__PURE__ */ o(W, {
|
|
326
|
-
token: e.token,
|
|
327
|
-
onChange: c
|
|
328
|
-
}, e.token.name) : /* @__PURE__ */ o(G, {
|
|
329
|
-
group: e.group,
|
|
330
|
-
tokens: e.tokens,
|
|
331
|
-
onChange: c
|
|
332
|
-
}, `family:${e.group}`))
|
|
333
|
-
}) : null]
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
function q({ tokens: e, onChange: t, collapsed: n, onCollapsedChange: r, categorize: i = T, familySize: a = 3, density: s = "normal", className: c }) {
|
|
337
|
-
let [l, f] = d({}), p = n ?? l, m = u(() => {
|
|
338
|
-
let t = /* @__PURE__ */ new Map();
|
|
339
|
-
for (let n of e) {
|
|
340
|
-
let e = i(n);
|
|
341
|
-
t.set(e, [...t.get(e) ?? [], n]);
|
|
342
|
-
}
|
|
343
|
-
return t;
|
|
344
|
-
}, [e, i]);
|
|
345
|
-
return /* @__PURE__ */ o("div", {
|
|
346
|
-
className: [
|
|
347
|
-
S.panel,
|
|
348
|
-
s === "tight" && S.tight,
|
|
349
|
-
c
|
|
350
|
-
].filter(Boolean).join(" "),
|
|
351
|
-
children: C.map(({ id: e, title: i }) => {
|
|
352
|
-
let s = m.get(e);
|
|
353
|
-
if (!s) return null;
|
|
354
|
-
let c = !p[e];
|
|
355
|
-
return /* @__PURE__ */ o(K, {
|
|
356
|
-
title: i,
|
|
357
|
-
open: c,
|
|
358
|
-
onToggle: () => {
|
|
359
|
-
n === void 0 && f((t) => ({
|
|
360
|
-
...t,
|
|
361
|
-
[e]: c
|
|
362
|
-
})), r?.(e, c);
|
|
363
|
-
},
|
|
364
|
-
tokens: s,
|
|
365
|
-
familySize: a,
|
|
366
|
-
onChange: t
|
|
367
|
-
}, e);
|
|
368
|
-
})
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
//#endregion
|
|
372
|
-
export { T as i, C as n, I as r, q as t };
|
|
373
|
-
|
|
374
|
-
//# sourceMappingURL=TokenPanel-BL9hlq7x.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TokenPanel-BL9hlq7x.js","names":[],"sources":["../../src/components/TokenPanel/color.ts","../../src/components/TokenPanel/TokenPanel.module.css","../../src/components/TokenPanel/tokenTypes.ts","../../src/components/TokenPanel/TokenPanel.tsx"],"sourcesContent":["const HEX = /^#(?:[\\da-f]{3,4}|[\\da-f]{6}|[\\da-f]{8})$/i;\nconst RGB = /^rgba?\\(\\s*(\\d{1,3})[\\s,]+(\\d{1,3})[\\s,]+(\\d{1,3})\\b/i;\nconst COLOR_FUNCTION = /^(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color|color-mix)\\(.+\\)$/i;\nconst KEYWORDS = new Set([\n 'transparent',\n 'currentcolor',\n 'black',\n 'white',\n 'gray',\n 'silver',\n 'red',\n 'orange',\n 'yellow',\n 'gold',\n 'lime',\n 'green',\n 'teal',\n 'cyan',\n 'blue',\n 'navy',\n 'purple',\n 'magenta',\n 'pink',\n 'brown',\n]);\n\ntype Supports = ((value: string) => boolean) | null;\n\nfunction browserSupports(): Supports {\n return typeof CSS !== 'undefined' && typeof CSS.supports === 'function'\n ? (value) => CSS.supports('color', value)\n : null;\n}\n\n/** Whether `value` is a CSS color — the browser's answer where it has `CSS.supports`, a small parser's otherwise. */\nexport function parsesAsColor(value: string, supports: Supports = browserSupports()): boolean {\n const v = value.trim();\n // `CSS.supports` accepts any `var()` for any property.\n if (!v || v.includes('var(')) return false;\n if (supports) return supports(v);\n return HEX.test(v) || COLOR_FUNCTION.test(v) || KEYWORDS.has(v.toLowerCase());\n}\n\nfunction hexOf(v: string): string | null {\n if (HEX.test(v)) {\n const digits = v.slice(1).toLowerCase();\n return `#${digits.length <= 4 ? [...digits.slice(0, 3)].map((d) => d + d).join('') : digits.slice(0, 6)}`;\n }\n const rgb = RGB.exec(v);\n return rgb\n ? `#${rgb\n .slice(1, 4)\n .map((n) => Math.min(255, Number(n)).toString(16).padStart(2, '0'))\n .join('')}`\n : null;\n}\n\nlet paint: CanvasRenderingContext2D | null | undefined;\n\n/** The browser's serialization of a color, through a canvas fill style; null where it has none or rejects `value`. */\nfunction serialized(value: string): string | null {\n if (paint === undefined) {\n try {\n paint = document.createElement('canvas').getContext('2d');\n } catch {\n paint = null;\n }\n }\n if (!paint) return null;\n // A rejected value leaves the previous fill style, so two different ones tell a rejection apart.\n paint.fillStyle = '#000000';\n paint.fillStyle = value;\n const onBlack = String(paint.fillStyle);\n paint.fillStyle = '#ffffff';\n paint.fillStyle = value;\n return onBlack === String(paint.fillStyle) ? onBlack : null;\n}\n\n/** `value` as the `#rrggbb` a color input takes, alpha dropped; null when it cannot be converted. */\nexport function toHex(value: string): string | null {\n const v = value.trim();\n const direct = hexOf(v);\n if (direct) return direct;\n const browser = typeof document === 'undefined' ? null : serialized(v);\n return browser && browser !== v ? hexOf(browser) : null;\n}\n",".panel {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.section {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.section + .section {\n border-top: var(--wzl-border-w) solid var(--wzl-line-subtle);\n}\n\n.sectionHead {\n padding-block: var(--wzl-space-xs);\n color: var(--wzl-fg-muted);\n font-family: var(--wzl-font-display);\n font-size: var(--wzl-font-size-sm);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.sectionBody {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-sm);\n padding-block-end: var(--wzl-space-sm);\n}\n\n.row,\n.family {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.name {\n overflow: hidden;\n color: var(--wzl-fg-muted);\n font-family: var(--wzl-font-mono);\n font-size: var(--wzl-font-size-sm);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.edit {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-xs);\n min-width: 0;\n}\n\n.field {\n --wzl-font-ui: var(--wzl-font-mono);\n flex: 1;\n min-width: 0;\n}\n\n.number {\n --wzl-font-ui: var(--wzl-font-mono);\n flex: 1;\n min-width: 0;\n}\n\n.unit {\n color: var(--wzl-fg-muted);\n font-family: var(--wzl-font-mono);\n font-size: var(--wzl-font-size-sm);\n}\n\n/* Padding inflates a native color input past its box in Chrome. */\n.swatchInput {\n box-sizing: border-box;\n flex-shrink: 0;\n width: 18px;\n height: 14px;\n padding: 0;\n background: transparent;\n border: 0;\n border-radius: var(--wzl-radius-sm);\n cursor: pointer;\n}\n\n.chip {\n flex-shrink: 0;\n width: 18px;\n height: 14px;\n background: var(--token-color);\n border-radius: var(--wzl-radius-sm);\n box-shadow: inset 0 0 0 1px var(--wzl-line);\n}\n\n.curve {\n flex-shrink: 0;\n width: 24px;\n height: 24px;\n color: var(--wzl-fg);\n}\n\n.strip {\n display: flex;\n height: var(--wzl-control-h);\n overflow: hidden;\n border: var(--wzl-border-w) solid var(--wzl-line);\n border-radius: var(--wzl-radius-sm);\n}\n\n.swatch {\n flex: 1 1 0;\n min-width: 0;\n height: 100%;\n padding: 0;\n background: var(--token-color);\n border: 0;\n border-radius: 0;\n cursor: pointer;\n}\n\n.swatch[data-overridden] {\n box-shadow: inset 0 -3px 0 var(--wzl-accent);\n}\n\n.swatch[aria-pressed='true'],\n.swatch:focus-visible {\n position: relative;\n z-index: 1;\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: -2px;\n}\n\n/* Tight: a token to a line, with the names on a fixed rail so the values read\n down the panel as a column. A stacked row spends its height on the name and\n lets the field take the whole width, which a set of ninety cannot afford. */\n.tight .sectionBody {\n gap: 2px;\n padding-block-end: var(--wzl-space-xs);\n}\n\n.tight .row {\n flex-direction: row;\n align-items: center;\n gap: var(--wzl-space-xs);\n}\n\n.tight .row > .name {\n flex: 0 0 11rem;\n}\n\n.tight .edit {\n flex: 1 1 auto;\n}\n\n.tight .field,\n.tight .number {\n flex: 0 1 16rem;\n font-variant-numeric: tabular-nums;\n}\n\n.tight .unit {\n font-variant-numeric: tabular-nums;\n}\n\n/* Grid rather than a row, so a picked swatch's editor still spans the full width. */\n.tight .family {\n display: grid;\n grid-template-columns: 11rem minmax(0, 1fr);\n align-items: center;\n column-gap: var(--wzl-space-xs);\n row-gap: 2px;\n}\n\n.tight .family > .row {\n grid-column: 1 / -1;\n}\n\n.tight .strip {\n height: 16px;\n}\n\n.tight .curve {\n width: 16px;\n height: 16px;\n}\n","import { parsesAsColor } from './color';\n\n/** A design token as `TokenPanel` edits it. */\nexport interface TokenEntry {\n /** The custom property, e.g. `--wzl-gray-50`. */\n name: string;\n /** A DTCG type name. A type the panel has no control for edits as text. */\n type: string;\n /** Tokens sharing a group sit together; a color group large enough draws as one row of swatches. */\n group: string;\n value: string;\n /** Whether `value` overrides the token's own, which offers Reset. */\n overridden?: boolean;\n description?: string;\n}\n\nexport type TokenCategory = 'color' | 'type' | 'size' | 'motion' | 'depth' | 'other';\n\n/** The panel's sections, in the order it draws them. */\nexport const TOKEN_CATEGORIES: readonly { id: TokenCategory; title: string }[] = [\n { id: 'color', title: 'Color' },\n { id: 'type', title: 'Type' },\n { id: 'size', title: 'Size' },\n { id: 'motion', title: 'Motion' },\n { id: 'depth', title: 'Depth' },\n { id: 'other', title: 'Other' },\n];\n\nconst TYPE_SCALE = /^(?:font|tracking|leading|letter|line-height)/;\n\n/** The section a token is filed under: by its type, and for a bare dimension or number by its group. */\nexport function tokenCategory(token: TokenEntry): TokenCategory {\n switch (token.type) {\n case 'color':\n return 'color';\n case 'fontFamily':\n case 'fontWeight':\n return 'type';\n case 'duration':\n case 'cubicBezier':\n return 'motion';\n case 'shadow':\n case 'gradient':\n return 'depth';\n case 'dimension':\n case 'number':\n if (TYPE_SCALE.test(token.group)) return 'type';\n if (token.type === 'number' && (token.group === 'z' || token.group === 'z-index')) return 'depth';\n return 'size';\n default:\n return 'other';\n }\n}\n\nconst AMOUNT = String.raw`-?(?:\\d+\\.?\\d*|\\.\\d+)`;\nconst DIMENSION = new RegExp(\n `^${AMOUNT}(?:px|rem|em|%|ch|ex|lh|rlh|vh|vw|vmin|vmax|svh|lvh|dvh|cqw|cqh|pt|pc|cm|mm|in|q)$`,\n 'i',\n);\nconst DURATION = new RegExp(`^${AMOUNT}m?s$`);\nconst NUMBER = new RegExp(`^${AMOUNT}$`);\nconst LENGTH = new RegExp(`^${AMOUNT}(?:px|rem|em)?$`);\nconst BEZIER = new RegExp(`^cubic-bezier\\\\(\\\\s*(${AMOUNT})\\\\s*,\\\\s*(${AMOUNT})\\\\s*,\\\\s*(${AMOUNT})\\\\s*,\\\\s*(${AMOUNT})\\\\s*\\\\)$`, 'i');\nconst GRADIENT = /^(?:repeating-)?(?:linear|radial|conic)-gradient\\(/i;\n/** Commas outside parentheses: a shadow's layers, not a color function's arguments. */\nconst LAYERS = /,(?![^(]*\\))/;\nconst PARTS = /[a-z-]+\\([^)]*\\)|\\S+/gi;\n\nfunction isShadow(value: string): boolean {\n return value.split(LAYERS).every((layer) => {\n const parts = layer.trim().replace(/^inset\\s+/i, '').match(PARTS) ?? [];\n const lengths = parts.filter((part) => LENGTH.test(part));\n const rest = parts.filter((part) => !LENGTH.test(part));\n return lengths.length >= 2 && lengths.length <= 4 && rest.length <= 1 && rest.every((part) => parsesAsColor(part));\n });\n}\n\n/** A DTCG type read off the shape of a value, for a token that arrives without one. `'string'` when nothing fits. */\nexport function inferTokenType(value: string): string {\n const v = value.trim();\n if (!v) return 'string';\n if (DURATION.test(v)) return 'duration';\n if (DIMENSION.test(v)) return 'dimension';\n if (NUMBER.test(v)) return 'number';\n if (BEZIER.test(v)) return 'cubicBezier';\n if (GRADIENT.test(v)) return 'gradient';\n if (parsesAsColor(v)) return 'color';\n if (isShadow(v)) return 'shadow';\n return 'string';\n}\n\n/** A number and its unit, or null for a value that is not one. */\nexport function splitUnit(value: string): { amount: number; unit: string } | null {\n const match = new RegExp(`^(${AMOUNT})([a-z%]*)$`, 'i').exec(value.trim());\n return match ? { amount: Number(match[1]), unit: match[2] ?? '' } : null;\n}\n\n/** The four control points of a `cubic-bezier()`, or null for any other easing. */\nexport function bezierPoints(value: string): readonly [number, number, number, number] | null {\n const match = BEZIER.exec(value.trim());\n if (!match) return null;\n const [x1, y1, x2, y2] = match.slice(1, 5).map(Number) as [number, number, number, number];\n return [x1, y1, x2, y2];\n}\n","import { type CSSProperties, memo, useCallback, useMemo, useState } from 'react';\nimport { Button } from '../Button';\nimport { DisclosureRow } from '../Disclosure';\nimport { Input } from '../Input';\nimport { NumberField } from '../NumberField';\nimport { Select } from '../Select';\nimport { toHex } from './color';\nimport s from './TokenPanel.module.css';\nimport {\n bezierPoints,\n splitUnit,\n TOKEN_CATEGORIES,\n type TokenCategory,\n type TokenEntry,\n tokenCategory,\n} from './tokenTypes';\n\ntype OnChange = (name: string, value: string | null) => void;\n\n/** Props for `<TokenPanel>`. */\nexport interface TokenPanelProps {\n tokens: readonly TokenEntry[];\n /** A token's new value, or null to drop its override. Keep it stable: rows re-render only when it or their token changes. */\n onChange: OnChange;\n /** Sections held closed, by category. Omit to let the panel keep that state itself. */\n collapsed?: Readonly<Partial<Record<TokenCategory, boolean>>>;\n onCollapsedChange?: (category: TokenCategory, collapsed: boolean) => void;\n /** Files a token under a section. Defaults to `tokenCategory`. */\n categorize?: (token: TokenEntry) => TokenCategory;\n /** The fewest colors sharing a group that draw as one row of swatches. Default 3. */\n familySize?: number;\n /**\n * Row layout. `tight` puts a token on one line — name, control, Reset — with the\n * names on a fixed rail so the values read down the panel as a column, and caps\n * the field rather than letting it span the panel. Default `normal` stacks the\n * control under its name.\n */\n density?: 'tight' | 'normal';\n className?: string;\n}\n\nconst WEIGHTS = ['100', '200', '300', '400', '500', '600', '700', '800', '900'];\nconst NUMBER_FORMAT = { maximumFractionDigits: 4, useGrouping: false } as const;\n\ntype Item = { kind: 'row'; token: TokenEntry } | { kind: 'family'; group: string; tokens: TokenEntry[] };\n\nfunction itemsOf(tokens: readonly TokenEntry[], familySize: number): Item[] {\n const colors = new Map<string, number>();\n for (const token of tokens) if (token.type === 'color') colors.set(token.group, (colors.get(token.group) ?? 0) + 1);\n const families = new Map<string, Extract<Item, { kind: 'family' }>>();\n const items: Item[] = [];\n for (const token of tokens) {\n if (token.type !== 'color' || (colors.get(token.group) ?? 0) < familySize) {\n items.push({ kind: 'row', token });\n continue;\n }\n let family = families.get(token.group);\n if (!family) {\n family = { kind: 'family', group: token.group, tokens: [] };\n families.set(token.group, family);\n items.push(family);\n }\n family.tokens.push(token);\n }\n return items;\n}\n\nfunction Curve({ points, label }: { points: readonly [number, number, number, number]; label: string }) {\n const [x1, y1, x2, y2] = points;\n // y is flipped so the curve rises, and the box grows to hold an overshoot.\n const top = Math.min(0, 1 - y1, 1 - y2);\n const bottom = Math.max(1, 1 - y1, 1 - y2);\n return (\n <svg className={s.curve} viewBox={`-0.1 ${top - 0.1} 1.2 ${bottom - top + 0.2}`} role=\"img\" aria-label={label}>\n <path d={`M0 1 C${x1} ${1 - y1} ${x2} ${1 - y2} 1 0`} fill=\"none\" stroke=\"currentColor\" strokeWidth={0.08} />\n </svg>\n );\n}\n\nfunction TokenControl({ token, set }: { token: TokenEntry; set: (value: string) => void }) {\n const { name, type, value } = token;\n const label = `${name} value`;\n const hex = useMemo(() => (type === 'color' ? toHex(value) : null), [type, value]);\n\n if (type === 'dimension' || type === 'duration' || type === 'number') {\n const split = splitUnit(value);\n if (split) {\n return (\n <>\n <NumberField\n className={s.number}\n aria-label={label}\n value={split.amount}\n hideSteppers\n formatOptions={NUMBER_FORMAT}\n onChange={(amount) => {\n if (Number.isFinite(amount)) set(`${amount}${split.unit}`);\n }}\n />\n {split.unit ? <span className={s.unit}>{split.unit}</span> : null}\n </>\n );\n }\n }\n\n if (type === 'fontWeight') {\n const options = (WEIGHTS.includes(value) ? WEIGHTS : [...WEIGHTS, value]).map((weight) => ({\n value: weight,\n label: weight,\n }));\n return <Select aria-label={name} width=\"fit\" selectedKey={value} options={options} onSelectionChange={set} />;\n }\n\n const points = type === 'cubicBezier' ? bezierPoints(value) : null;\n return (\n <>\n {points ? <Curve points={points} label={`${name} curve`} /> : null}\n <Input\n className={s.field}\n aria-label={label}\n value={value}\n onChange={set}\n leadingAdornment={\n type !== 'color' ? undefined : hex ? (\n <input\n type=\"color\"\n className={s.swatchInput}\n aria-label={`${name} color`}\n value={hex}\n onChange={(event) => set(event.target.value)}\n />\n ) : (\n <span className={s.chip} style={{ '--token-color': value } as CSSProperties} aria-hidden=\"true\" />\n )\n }\n />\n </>\n );\n}\n\nconst TokenRow = memo(\n function TokenRow({ token, onChange }: { token: TokenEntry; onChange: OnChange }) {\n const set = useCallback((value: string) => onChange(token.name, value), [onChange, token.name]);\n return (\n <div className={s.row} role=\"group\" aria-label={token.name}>\n <span className={s.name} title={token.description || token.name}>\n {token.name}\n </span>\n <div className={s.edit}>\n <TokenControl token={token} set={set} />\n {token.overridden ? (\n <Button variant=\"ghost\" size=\"sm\" ariaLabel={`Reset ${token.name}`} onClick={() => onChange(token.name, null)}>\n Reset\n </Button>\n ) : null}\n </div>\n </div>\n );\n },\n // Consumers rebuild their entries each render; a row only has to redraw when what it shows changed.\n (a, b) =>\n a.onChange === b.onChange &&\n a.token.name === b.token.name &&\n a.token.type === b.token.type &&\n a.token.value === b.token.value &&\n a.token.overridden === b.token.overridden &&\n a.token.description === b.token.description,\n);\n\nfunction Family({ group, tokens, onChange }: { group: string; tokens: readonly TokenEntry[]; onChange: OnChange }) {\n const [picked, setPicked] = useState<string | null>(null);\n const token = tokens.find((t) => t.name === picked) ?? null;\n return (\n <div className={s.family} role=\"group\" aria-label={group}>\n <span className={s.name}>{group}</span>\n <div className={s.strip}>\n {tokens.map((t) => (\n <button\n key={t.name}\n type=\"button\"\n className={s.swatch}\n style={{ '--token-color': t.value } as CSSProperties}\n aria-label={t.name}\n aria-pressed={t.name === picked}\n title={`${t.name}: ${t.value}`}\n data-overridden={t.overridden ? '' : undefined}\n onClick={() => setPicked((current) => (current === t.name ? null : t.name))}\n />\n ))}\n </div>\n {token ? <TokenRow token={token} onChange={onChange} /> : null}\n </div>\n );\n}\n\nfunction Section({\n title,\n open,\n onToggle,\n tokens,\n familySize,\n onChange,\n}: {\n title: string;\n open: boolean;\n onToggle: () => void;\n tokens: readonly TokenEntry[];\n familySize: number;\n onChange: OnChange;\n}) {\n const items = useMemo(() => itemsOf(tokens, familySize), [tokens, familySize]);\n return (\n <section className={s.section} aria-label={title}>\n <DisclosureRow className={s.sectionHead} open={open} onToggle={onToggle} label={title}>\n <span aria-hidden=\"true\">{title}</span>\n </DisclosureRow>\n {open ? (\n <div className={s.sectionBody}>\n {items.map((item) =>\n item.kind === 'row' ? (\n <TokenRow key={item.token.name} token={item.token} onChange={onChange} />\n ) : (\n <Family key={`family:${item.group}`} group={item.group} tokens={item.tokens} onChange={onChange} />\n ),\n )}\n </div>\n ) : null}\n </section>\n );\n}\n\n/**\n * Edits a set of design tokens by type: collapsible sections by category, a\n * color group drawn as one row of swatches sized to fit, and a control for each\n * type — a number with its unit for dimensions and durations, the nine weights\n * for a font weight, a curve beside a `cubic-bezier()`, a swatch beside a color,\n * and text for everything else.\n */\nexport function TokenPanel({\n tokens,\n onChange,\n collapsed,\n onCollapsedChange,\n categorize = tokenCategory,\n familySize = 3,\n density = 'normal',\n className,\n}: TokenPanelProps) {\n const [ownCollapsed, setOwnCollapsed] = useState<Partial<Record<TokenCategory, boolean>>>({});\n const closed = collapsed ?? ownCollapsed;\n const byCategory = useMemo(() => {\n const sections = new Map<TokenCategory, TokenEntry[]>();\n for (const token of tokens) {\n const category = categorize(token);\n sections.set(category, [...(sections.get(category) ?? []), token]);\n }\n return sections;\n }, [tokens, categorize]);\n\n return (\n <div className={[s.panel, density === 'tight' && s.tight, className].filter(Boolean).join(' ')}>\n {TOKEN_CATEGORIES.map(({ id, title }) => {\n const inSection = byCategory.get(id);\n if (!inSection) return null;\n const open = !closed[id];\n return (\n <Section\n key={id}\n title={title}\n open={open}\n onToggle={() => {\n if (collapsed === undefined) setOwnCollapsed((prev) => ({ ...prev, [id]: open }));\n onCollapsedChange?.(id, open);\n }}\n tokens={inSection}\n familySize={familySize}\n onChange={onChange}\n />\n );\n })}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ToolButton-Dd-1T5aX.js","names":[],"sources":["../../src/components/ToolButton/ToolButton.module.css","../../src/components/ToolButton/ToolButton.tsx"],"sourcesContent":[".button {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n min-width: 44px;\n padding: 6px 4px;\n background: transparent;\n border: 1px solid transparent;\n border-radius: var(--wzl-radius-sm);\n color: var(--wzl-fg);\n cursor: default;\n font-family: inherit;\n font-size: var(--wzl-font-size-xs);\n line-height: 1.1;\n}\n.button:hover:not([disabled]) {\n background: var(--wzl-surface-hover);\n color: var(--wzl-fg);\n}\n.button:focus-visible {\n outline: 2px solid var(--wzl-accent);\n outline-offset: -2px;\n}\n.button.active {\n background: var(--wzl-surface-pressed);\n border-color: var(--wzl-accent);\n color: var(--wzl-fg);\n}\n.button[disabled] {\n opacity: 0.4;\n}\n\n.icon { display: block; }\n.icon > svg { display: block; }\n.label { font-size: var(--wzl-font-size-xs); }\n.shortcut {\n color: var(--wzl-fg-muted);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: var(--wzl-font-size-2xs);\n}\n","import type { KeyboardEvent, ReactNode } from 'react';\nimport { Focusable } from 'react-aria-components';\nimport { Tooltip, TooltipTrigger } from '../Tooltip';\nimport s from './ToolButton.module.css';\n\n/** Props for {@link ToolButton}. */\nexport interface ToolButtonProps {\n /** Icon node (typically an SVG component). */\n icon: ReactNode;\n /** Human-readable label shown under the icon. */\n label: string;\n /** Optional shortcut hint (e.g. \"V\" or \"⌘Z\"). */\n shortcut?: string;\n /** Selected/active state — toggles the active visual treatment. */\n active?: boolean;\n /** Disabled state — passes through to the underlying button. */\n disabled?: boolean;\n /**\n * When true, sets `aria-disabled=\"true\"` on the button without using the\n * native `disabled` attribute. This keeps the button focusable and reachable\n * by keyboard (roving-tabindex still applies) while marking it as ineligible\n * to screen readers. The caller is responsible for making `onClick` a no-op.\n */\n ariaDisabled?: boolean;\n /**\n * Whether this button is the currently tabbable member of its toolbar.\n * Toolbars use roving tabindex: exactly one button has `tabIndex=0` at\n * a time; the rest are `-1`. Caller manages which.\n */\n tabbable?: boolean;\n /** Click handler. */\n onClick(): void;\n /** Key handler for the underlying button — a toolbar's roving-tabindex\n * navigation attaches here. */\n onKeyDown?(e: KeyboardEvent<HTMLElement>): void;\n /**\n * Tooltip content. Defaults to `label` (plus `shortcut` if provided).\n */\n title?: string;\n /** Additional class for the root button. */\n className?: string;\n}\n\n/**\n * Generic icon-+-label toolbar button — building block for `ToolPalette`\n * and similar surfaces. Headless about layout direction (parent group\n * supplies flex direction via `ToolGroup`). Theme via `--wzl-*` tokens.\n */\nexport function ToolButton(props: ToolButtonProps) {\n const {\n icon, label, shortcut, active, disabled, ariaDisabled, tabbable,\n onClick, onKeyDown, title, className,\n } = props;\n const resolvedTitle = title ?? (shortcut ? `${label} (${shortcut})` : label);\n const cls = [s.button, active && s.active, className].filter(Boolean).join(' ');\n return (\n <TooltipTrigger isDisabled={disabled}>\n <Focusable isDisabled={disabled}>\n <button\n type=\"button\"\n tabIndex={tabbable ? 0 : -1}\n className={cls}\n aria-current={active ? 'true' : undefined}\n aria-disabled={ariaDisabled ? 'true' : undefined}\n disabled={disabled}\n onClick={onClick}\n onKeyDown={onKeyDown}\n >\n <span className={s.icon} aria-hidden=\"true\">{icon}</span>\n <span className={s.label}>{label}</span>\n {shortcut && <span className={s.shortcut}>{shortcut}</span>}\n </button>\n </Focusable>\n <Tooltip>{resolvedTitle}</Tooltip>\n </TooltipTrigger>\n );\n}\n"],"mappings":";;;;;;;;;;;;ACgDA,SAAgB,EAAW,GAAwB;CACjD,IAAM,EACJ,SAAM,UAAO,aAAU,WAAQ,aAAU,iBAAc,aACvD,YAAS,cAAW,UAAO,iBACzB,GACE,IAAgB,MAAU,IAAW,GAAG,EAAM,IAAI,EAAS,KAAK,IAChE,IAAM;EAAC,EAAE;EAAQ,KAAU,EAAE;EAAQ;EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;AAC/E,QACE,kBAAC,GAAD;EAAgB,YAAY;YAA5B,CACE,kBAAC,GAAD;GAAW,YAAY;aACrB,kBAAC,UAAD;IACE,MAAK;IACL,UAAU,IAAW,IAAI;IACzB,WAAW;IACX,gBAAc,IAAS,SAAS,KAAA;IAChC,iBAAe,IAAe,SAAS,KAAA;IAC7B;IACD;IACE;cARb;KAUE,kBAAC,QAAD;MAAM,WAAW,EAAE;MAAM,eAAY;gBAAQ;MAAY,CAAA;KACzD,kBAAC,QAAD;MAAM,WAAW,EAAE;gBAAQ;MAAa,CAAA;KACvC,KAAY,kBAAC,QAAD;MAAM,WAAW,EAAE;gBAAW;MAAgB,CAAA;KACpD;;GACC,CAAA,EACZ,kBAAC,GAAD,EAAA,UAAU,GAAwB,CAAA,CACnB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ToolGroup-BBI-W-Gm.js","names":[],"sources":["../../src/components/ToolGroup/ToolGroup.module.css","../../src/components/ToolGroup/ToolGroup.tsx"],"sourcesContent":[".group {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.group.horizontal {\n flex-direction: row;\n}\n","import type { ReactNode } from 'react';\nimport s from './ToolGroup.module.css';\n\n/** Props for {@link ToolGroup}. */\nexport interface ToolGroupProps {\n children: ReactNode;\n /**\n * Lays children along an axis. `'vertical'` (default) stacks them in\n * a column; `'horizontal'` lays them in a row. Independent of the\n * parent toolbar's own orientation.\n */\n orientation?: 'vertical' | 'horizontal';\n /**\n * Optional `data-group` attribute — useful for parents that want to\n * select the group from CSS or tests by name.\n */\n groupKey?: string;\n /** Accessible name for the group (rendered as `aria-label`). */\n ariaLabel?: string;\n className?: string;\n}\n\n/**\n * Generic toolbar group — a `role=\"group\"` flex container that arranges\n * `<ToolButton>`s (or any children) along a chosen axis. No visual chrome\n * beyond layout; theming lives on the buttons.\n */\nexport function ToolGroup(props: ToolGroupProps) {\n const { children, orientation = 'vertical', groupKey, ariaLabel, className } = props;\n const cls = [s.group, orientation === 'horizontal' && s.horizontal, className]\n .filter(Boolean).join(' ');\n return (\n <div className={cls} role=\"group\" data-group={groupKey} aria-label={ariaLabel}>\n {children}\n </div>\n );\n}\n"],"mappings":";;;;;;;AC2BA,SAAgB,EAAU,GAAuB;CAC/C,IAAM,EAAE,aAAU,iBAAc,YAAY,aAAU,cAAW,iBAAc;AAG/E,QACE,kBAAC,OAAD;EAAK,WAHK;GAAC,EAAE;GAAO,MAAgB,gBAAgB,EAAE;GAAY;GAAU,CAC3E,OAAO,QAAQ,CAAC,KAAK,IAEN;EAAK,MAAK;EAAQ,cAAY;EAAU,cAAY;EACjE;EACG,CAAA"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { jsx as e, jsxs as t } from "react/jsx-runtime";
|
|
2
|
-
var n = {
|
|
3
|
-
root: "_root_cfvzx_13",
|
|
4
|
-
label: "_label_cfvzx_25",
|
|
5
|
-
controls: "_controls_cfvzx_6"
|
|
6
|
-
};
|
|
7
|
-
//#endregion
|
|
8
|
-
//#region src/components/ToolOptionsBar/ToolOptionsBar.tsx
|
|
9
|
-
function r(r) {
|
|
10
|
-
let { label: i, children: a, className: o } = r;
|
|
11
|
-
return /* @__PURE__ */ t("div", {
|
|
12
|
-
className: [n.root, o].filter(Boolean).join(" "),
|
|
13
|
-
role: "toolbar",
|
|
14
|
-
"aria-label": i,
|
|
15
|
-
children: [i !== void 0 && /* @__PURE__ */ e("span", {
|
|
16
|
-
className: n.label,
|
|
17
|
-
children: i
|
|
18
|
-
}), /* @__PURE__ */ e("div", {
|
|
19
|
-
className: n.controls,
|
|
20
|
-
children: a
|
|
21
|
-
})]
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
//#endregion
|
|
25
|
-
export { r as t };
|
|
26
|
-
|
|
27
|
-
//# sourceMappingURL=ToolOptionsBar-B2xPWzJf.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ToolOptionsBar-B2xPWzJf.js","names":[],"sources":["../../src/components/ToolOptionsBar/ToolOptionsBar.module.css","../../src/components/ToolOptionsBar/ToolOptionsBar.tsx"],"sourcesContent":["/* Horizontal strip reserved above the workspace for contextual tool\n options. Fixed height so mounting/unmounting content never resizes\n the workspace beneath it — that's the whole reason this row exists\n as permanent chrome rather than an on-demand overlay.\n\n Overflow: when controls exceed the available width, `.controls`\n scrolls horizontally rather than wrapping (which would grow the row\n and defeat the fixed-height guarantee above) or clipping (which\n would hide controls with no way to reach them). A flyout/long-press\n affordance was considered and rejected — grouped, directly visible\n layouts are preferred in this repo. */\n\n.root {\n display: flex;\n align-items: center;\n gap: 8px;\n height: var(--wzl-tb-height, 28px);\n padding: 0 8px;\n background: var(--wzl-surface);\n border-bottom: 1px solid var(--wzl-border);\n color: var(--wzl-fg);\n overflow: hidden;\n}\n\n.label {\n flex: 0 0 auto;\n font-size: var(--wzl-font-size-sm);\n font-weight: var(--wzl-font-weight-bold);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--wzl-fg-muted);\n white-space: nowrap;\n}\n\n.controls {\n display: flex;\n align-items: center;\n gap: 6px;\n flex: 1 1 auto;\n min-width: 0;\n height: 100%;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: thin;\n}\n\n/* Firefox gets a thin scrollbar for free via `scrollbar-width` above.\n * Chromium/WebKit need it spelled out — on a classic (non-overlay)\n * scrollbar theme (default on Windows Chrome/Edge), an unstyled\n * horizontal scrollbar is ~15-17px tall and renders *inside* this box,\n * clipping/off-centering the row's controls. That would reintroduce the\n * exact height instability the scroll-over-wrap overflow choice above\n * exists to avoid — just at the row's inner edge instead of its outer\n * one. Pin it thin and out of the way instead. */\n.controls::-webkit-scrollbar {\n height: 4px;\n}\n.controls::-webkit-scrollbar-track {\n background: transparent;\n}\n.controls::-webkit-scrollbar-thumb {\n background: var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n}\n","import type { ReactNode } from 'react';\nimport s from './ToolOptionsBar.module.css';\n\n/** Props for {@link ToolOptionsBar}. */\nexport interface ToolOptionsBarProps {\n /**\n * Context label for the row — e.g. the active tool's name. Rendered\n * before the children and doubles as the toolbar's `aria-label`. Omit\n * it and the row still renders (it's a permanently reserved slot), just\n * without an accessible name.\n *\n * Using `label` for both the visible text and `aria-label` means a\n * screen reader announces it twice when landing on the toolbar (\"Text,\n * toolbar\", then \"Text\" again when browsing into the visible span).\n * `aria-labelledby` would avoid the echo at the cost of id plumbing and\n * an awkward no-`id`-to-point-at case when `label` is omitted. The\n * double-announcement is common enough for labelled landmark regions\n * that it's left as-is — considered, not missed.\n */\n label?: string;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * Horizontal strip reserved above the workspace for contextual tool\n * options — its first tenant is the character controls a text tool\n * exposes while a caret range is active. Pure chrome: it renders an\n * optional label and a children slot, nothing else. It knows nothing\n * about text, or about any specific tool — any tool can fill it.\n *\n * The row always renders, even with no `label` and no `children`,\n * because the app reserves its height permanently rather than mounting\n * it on demand — mounting mid-edit would resize the workspace under a\n * canvas that's sized to the page.\n *\n * `role=\"toolbar\"` without roving tabindex: the ARIA authoring practices\n * expect arrow-key roving focus across a toolbar's items, but this\n * component doesn't own or know the shape of its children — they're\n * arbitrary, possibly compound controls (`NumberField`, `Select`,\n * `ColorField`) that already use arrow keys for their own value editing.\n * Imposing roving focus here would fight those controls' own key\n * handling. Tab order falls back to normal DOM order for now; revisit\n * once the first tenant's control set is concrete and a roving-focus\n * contract can be designed in coordination with those controls.\n */\nexport function ToolOptionsBar(props: ToolOptionsBarProps) {\n const { label, children, className } = props;\n const cls = [s.root, className].filter(Boolean).join(' ');\n return (\n <div className={cls} role=\"toolbar\" aria-label={label}>\n {label !== undefined && <span className={s.label}>{label}</span>}\n <div className={s.controls}>{children}</div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;AC8CA,SAAgB,EAAe,GAA4B;CACzD,IAAM,EAAE,UAAO,aAAU,iBAAc;AAEvC,QACE,kBAAC,OAAD;EAAK,WAFK,CAAC,EAAE,MAAM,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAEnC;EAAK,MAAK;EAAU,cAAY;YAAhD,CACG,MAAU,KAAA,KAAa,kBAAC,QAAD;GAAM,WAAW,EAAE;aAAQ;GAAa,CAAA,EAChE,kBAAC,OAAD;GAAK,WAAW,EAAE;GAAW;GAAe,CAAA,CACxC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ToolPalette-BmTDDpmz.js","names":[],"sources":["../../src/components/ToolPalette/ToolPalette.module.css","../../src/components/ToolPalette/formatShortcut.ts","../../src/components/ToolPalette/ToolPalette.tsx"],"sourcesContent":[".palette {\n display: flex;\n flex-direction: column;\n gap: 4px;\n background: var(--wzl-surface);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n padding: 4px;\n user-select: none;\n}\n.palette.horizontal {\n flex-direction: row;\n}\n\n/* Marker only — `useRovingTabIndex` finds the palette's buttons by this class.\n Carries no styles; deleting it breaks keyboard navigation. */\n.paletteBtn {}\n\n/* Applied to ineligible tool buttons in the active mode. */\n.ineligibleBtn {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.separator {\n background: var(--wzl-border);\n}\n.palette:not(.horizontal) .separator {\n height: 1px;\n margin: 2px 0;\n}\n.palette.horizontal .separator {\n width: 1px;\n margin: 0 2px;\n}\n","import { keyGlyph } from '../Keycaps/keyGlyph';\n\nexport interface ShortcutInput {\n key: string | readonly string[];\n mod?: boolean;\n alt?: boolean;\n shift?: boolean | 'optional';\n}\n\n/** Format a shortcut as an array of display chips, one per key — modifier\n * icons (⌘, ↑, ⌥) followed by the key glyph. UIs that want a boxed\n * per-key look render each chip in its own element. `shift: 'optional'` is\n * treated as falsy. */\nexport function formatShortcutParts(b: ShortcutInput | undefined): readonly string[] | undefined {\n if (!b) return undefined;\n const rawKey = Array.isArray(b.key) ? b.key[0] : (b.key as string);\n const parts: string[] = [];\n if (b.mod) parts.push('⌘');\n if (b.shift === true) parts.push('⇧');\n if (b.alt) parts.push('⌥');\n parts.push(keyGlyph(rawKey));\n return parts;\n}\n\n/** Format a shortcut as a single display string. Order: mod, shift, alt,\n * key. Returns `undefined` for `undefined` input so callers can `??` a\n * fallback. When `key` is an array, the first element is used. `shift: 'optional'`\n * is treated as falsy. */\nexport function formatShortcut(b: ShortcutInput | undefined): string | undefined {\n const parts = formatShortcutParts(b);\n return parts ? parts.join('') : undefined;\n}\n","import { Fragment, type ReactNode } from 'react';\nimport { UnknownIcon } from '@weasel-js/core';\nimport type { AnyTool, ToolsApi } from '@weasel-js/core';\nimport { eligibleContribution, type ModeRegistry } from '@weasel-js/modes';\nimport { ToolButton } from '../ToolButton';\nimport { ToolGroup } from '../ToolGroup';\nimport { useRovingTabIndex } from '../../useRovingTabIndex';\nimport s from './ToolPalette.module.css';\nimport { formatShortcut, type ShortcutInput } from './formatShortcut';\n\nconst DEFAULT_GROUP_ORDER = ['select', 'shape', 'draw', 'type', 'view'] as const;\nconst MISC = 'misc';\n\nfunction partitionByGroup(list: AnyTool[]): Map<string, AnyTool[]> {\n const groups = new Map<string, AnyTool[]>();\n for (const tool of list) {\n const g = tool.presentation?.group ?? MISC;\n const bucket = groups.get(g) ?? [];\n bucket.push(tool);\n groups.set(g, bucket);\n }\n return groups;\n}\n\nfunction orderedGroupKeys(\n groups: Map<string, AnyTool[]>,\n groupOrder: readonly string[],\n): string[] {\n const seen = new Set(groups.keys());\n const ordered: string[] = [];\n for (const known of groupOrder) {\n if (seen.has(known)) {\n ordered.push(known);\n seen.delete(known);\n }\n }\n // Unknown groups in insertion order (Map preserves it), misc last.\n for (const key of groups.keys()) {\n if (seen.has(key) && key !== MISC) {\n ordered.push(key);\n seen.delete(key);\n }\n }\n if (seen.has(MISC)) ordered.push(MISC);\n return ordered;\n}\n\nfunction resolveIcon(tool: AnyTool): ReactNode {\n const rawIcon = tool.presentation?.icon;\n if (rawIcon == null) return <UnknownIcon />;\n if (typeof rawIcon === 'function') return rawIcon(undefined);\n return rawIcon;\n}\n\n/** Props for {@link ToolPalette}. */\nexport interface ToolPaletteProps {\n tools: ToolsApi;\n orientation?: 'vertical' | 'horizontal';\n className?: string;\n /** Derive the keyboard shortcut for a tool button from the action registry.\n * Called with the tool's id; return `undefined` to suppress a chip. When\n * omitted, falls back to `tool.keybinding` (legacy path). */\n lookupShortcut?: (toolId: string) => ShortcutInput | undefined;\n /**\n * Optional mode registry. When provided, tools whose `capabilities` do not\n * match the current mode are rendered greyed-out, aria-disabled, and their\n * onClick is suppressed. When omitted, all tools are treated as eligible\n * (preserves existing behaviour in consumers that haven't wired a registry).\n */\n modeRegistry?: ModeRegistry;\n /**\n * Presentation-group display order. Groups not listed keep their registry\n * insertion order after the listed ones; `misc` always renders last.\n * Defaults to `['select', 'shape', 'draw', 'type', 'view']`.\n */\n groupOrder?: readonly string[];\n}\n\n/**\n * Toolbar of the registered tools, split into separator-divided groups by\n * each tool's presentation group and navigable by arrow keys. Clicking a\n * button makes that tool active.\n *\n * Given a `modeRegistry`, tools whose capabilities the current mode does not\n * allow render greyed out and inert rather than disappearing.\n */\nexport function ToolPalette(props: ToolPaletteProps) {\n const {\n tools, orientation = 'vertical', className, lookupShortcut, modeRegistry,\n groupOrder = DEFAULT_GROUP_ORDER,\n } = props;\n const list = Object.values(tools.registry);\n const groups = partitionByGroup(list);\n const groupKeys = orderedGroupKeys(groups, groupOrder);\n const cls = [s.palette, orientation === 'horizontal' && s.horizontal, className]\n .filter(Boolean).join(' ');\n\n // Flat, in DOM order — the roving-tabindex hook indexes by this order.\n const ordered = groupKeys.flatMap((k) => groups.get(k)!);\n const eligibility = ordered.map(\n (tool) => (modeRegistry ? eligibleContribution(modeRegistry, tool) : true),\n );\n const activeIndex = ordered.findIndex((t) => t.id === tools.active);\n const roving = useRovingTabIndex({\n items: eligibility.map((enabled) => ({ disabled: !enabled })),\n itemClassName: s.paletteBtn,\n // An ineligible active tool can't hold the tab stop; fall back to the\n // hook's first-enabled default.\n ...(activeIndex >= 0 && eligibility[activeIndex] ? { tabStopIndex: activeIndex } : {}),\n });\n let index = -1;\n\n return (\n <div\n ref={roving.rootRef}\n className={cls}\n role=\"toolbar\"\n aria-label=\"Tools\"\n >\n {groupKeys.map((key, i) => (\n <Fragment key={key}>\n {i > 0 && (\n <div\n className={s.separator}\n role=\"separator\"\n aria-orientation={orientation === 'horizontal' ? 'vertical' : 'horizontal'}\n />\n )}\n <ToolGroup orientation={orientation} groupKey={key}>\n {groups.get(key)!.map((tool) => {\n const i = ++index;\n const label = tool.presentation?.label ?? tool.id;\n const shortcut = tool.presentation?.shortcut\n ?? formatShortcut(lookupShortcut ? lookupShortcut(tool.id) : tool.keybinding);\n const enabled = eligibility[i];\n const modeName = modeRegistry ? modeRegistry.current().id : undefined;\n const resolvedTitle = !enabled && modeName\n ? `${label}${shortcut ? ` (${shortcut})` : ''} — disabled in ${modeName} mode`\n : undefined;\n return (\n <ToolButton\n key={tool.id}\n icon={resolveIcon(tool)}\n label={label}\n shortcut={shortcut}\n active={tools.active === tool.id}\n tabbable={roving.tabIndexFor(i) === 0}\n ariaDisabled={!enabled}\n className={[s.paletteBtn, !enabled && s.ineligibleBtn].filter(Boolean).join(' ')}\n title={resolvedTitle}\n onClick={enabled ? () => tools.setActive(tool.id) : () => {}}\n onKeyDown={roving.onKeyDown(i)}\n />\n );\n })}\n </ToolGroup>\n </Fragment>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip-BHre_vbI.js","names":[],"sources":["../../src/components/Tooltip/Tooltip.module.css","../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":[".tooltip {\n /* Above Dialog overlay (1000) and ToastRegion (1100) — RAC sets no z-index. */\n z-index: 1200;\n background: var(--wzl-surface);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);\n color: var(--wzl-fg);\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size-sm);\n line-height: 1.3;\n padding: 4px 8px;\n max-width: 260px;\n transition: opacity var(--wzl-motion-fast);\n}\n\n.tooltip[data-entering],\n.tooltip[data-exiting] {\n opacity: 0;\n}\n\n.arrow svg {\n display: block;\n fill: var(--wzl-surface);\n stroke: var(--wzl-border);\n stroke-width: 1;\n}\n\n.arrow[data-placement='bottom'] svg {\n transform: rotate(180deg);\n}\n\n.arrow[data-placement='left'] svg {\n transform: rotate(-90deg);\n}\n\n.arrow[data-placement='right'] svg {\n transform: rotate(90deg);\n}\n","import type { ReactNode } from 'react';\nimport {\n TooltipTrigger as RACTooltipTrigger,\n Tooltip as RACTooltip,\n OverlayArrow,\n type TooltipProps as RACTooltipProps,\n type TooltipTriggerComponentProps,\n} from 'react-aria-components';\nimport { useOverlayPortal, type OverlayPortalProps, type WithoutPortalTarget } from '../../overlays/portalHost';\nimport s from './Tooltip.module.css';\n\n/**\n * Props for {@link TooltipTrigger} — React Aria's `TooltipTrigger` props\n * unchanged.\n */\nexport type TooltipTriggerProps = TooltipTriggerComponentProps;\n\n/**\n * TooltipTrigger with kit defaults: ~600 ms open delay, instant close.\n * Wrap a focusable trigger plus a `<Tooltip>`. Non-RAC triggers (plain\n * `<button>` etc.) must be wrapped in `<Focusable>` from\n * react-aria-components so hover/focus props reach the DOM node.\n *\n * Caveat: while a tooltip is open, react-aria captures the first Escape\n * keydown (document-level, capture phase) to dismiss it — app-level\n * Escape handlers (deselect, cancel gesture) see only the second press.\n */\nexport function TooltipTrigger(props: TooltipTriggerProps) {\n const { delay = 600, closeDelay = 0, ...rest } = props;\n return <RACTooltipTrigger delay={delay} closeDelay={closeDelay} {...rest} />;\n}\n\n/** Props for {@link Tooltip}, on top of React Aria's `Tooltip` props. */\nexport type TooltipProps = Omit<WithoutPortalTarget<RACTooltipProps>, 'children' | 'className'> &\n OverlayPortalProps & {\n children?: ReactNode;\n className?: string;\n };\n\n/**\n * Tooltip bubble with an arrow pointing at the trigger. Non-interactive\n * content only (ARIA tooltip semantics). Use inside `<TooltipTrigger>`.\n */\nexport function Tooltip(props: TooltipProps) {\n const { children, className, placement = 'top', offset = 8, portalContainer, ...rest } = props;\n const { anchor, portalProps } = useOverlayPortal(portalContainer);\n return (\n <>\n {anchor}\n <RACTooltip\n {...rest}\n placement={placement}\n offset={offset}\n className={[s.tooltip, className].filter(Boolean).join(' ')}\n data-weasel-overlay=\"\"\n {...portalProps}\n >\n <OverlayArrow className={s.arrow}>\n <svg width={8} height={8} viewBox=\"0 0 8 8\" aria-hidden=\"true\">\n <path d=\"M0 0 L4 4 L8 0\" />\n </svg>\n </OverlayArrow>\n {children}\n </RACTooltip>\n </>\n );\n}\n"],"mappings":";;;;;;;;;AC2BA,SAAgB,EAAe,GAA4B;CACzD,IAAM,EAAE,WAAQ,KAAK,gBAAa,GAAG,GAAG,MAAS;AACjD,QAAO,kBAAC,GAAD;EAA0B;EAAmB;EAAY,GAAI;EAAQ,CAAA;;AAc9E,SAAgB,EAAQ,GAAqB;CAC3C,IAAM,EAAE,aAAU,cAAW,eAAY,OAAO,YAAS,GAAG,oBAAiB,GAAG,MAAS,GACnF,EAAE,WAAQ,mBAAgB,EAAiB,EAAgB;AACjE,QACE,kBAAA,GAAA,EAAA,UAAA,CACG,GACD,kBAAC,GAAD;EACE,GAAI;EACO;EACH;EACR,WAAW,CAAC,EAAE,SAAS,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;EAC3D,uBAAoB;EACpB,GAAI;YANN,CAQE,kBAAC,GAAD;GAAc,WAAW,EAAE;aACzB,kBAAC,OAAD;IAAK,OAAO;IAAG,QAAQ;IAAG,SAAQ;IAAU,eAAY;cACtD,kBAAC,QAAD,EAAM,GAAE,kBAAmB,CAAA;IACvB,CAAA;GACO,CAAA,EACd,EACU;IACZ,EAAA,CAAA"}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
//#region src/format/number.ts
|
|
2
|
-
var e = "−";
|
|
3
|
-
function t(e, t) {
|
|
4
|
-
return (Number.isFinite(e) ? e.toLocaleString(void 0, t) : String(e)).replace(/^-/, "−");
|
|
5
|
-
}
|
|
6
|
-
function n(e) {
|
|
7
|
-
return Number(e.replace("−", "-"));
|
|
8
|
-
}
|
|
9
|
-
var r = {
|
|
10
|
-
k: 3,
|
|
11
|
-
m: 6,
|
|
12
|
-
b: 9,
|
|
13
|
-
t: 12
|
|
14
|
-
};
|
|
15
|
-
function i(e, n = 0) {
|
|
16
|
-
if (!Number.isFinite(e)) return t(e);
|
|
17
|
-
let r = Math.abs(e) < 1e3 ? {
|
|
18
|
-
useGrouping: !1,
|
|
19
|
-
minimumFractionDigits: n,
|
|
20
|
-
maximumFractionDigits: n
|
|
21
|
-
} : {
|
|
22
|
-
notation: "compact",
|
|
23
|
-
minimumFractionDigits: 1,
|
|
24
|
-
maximumFractionDigits: 1
|
|
25
|
-
};
|
|
26
|
-
return e.toLocaleString("en-US", r).replace(/^-/, "−");
|
|
27
|
-
}
|
|
28
|
-
function a(e, t) {
|
|
29
|
-
if (t) {
|
|
30
|
-
let n = e.trim(), r = o(n, t);
|
|
31
|
-
if (r !== void 0) {
|
|
32
|
-
let e = a(n.slice(0, -r.length)), i = t[r];
|
|
33
|
-
return i < 1 ? e / (1 / i) : e * i;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
let n = e.trim().replace("−", "-"), i = r[n.slice(-1).toLowerCase()];
|
|
37
|
-
return i !== void 0 && (n = n.slice(0, -1).trimEnd()), /^[-+]?\d{1,3}(,\d{3})+(\.\d*)?$/.test(n) && (n = n.replace(/,/g, "")), /\d/.test(n) ? Number(i === void 0 ? n : `${n}e${i}`) : NaN;
|
|
38
|
-
}
|
|
39
|
-
function o(e, t) {
|
|
40
|
-
let n = Object.keys(t).filter((e) => e !== "").sort((e, t) => t.length - e.length), r = e.toLowerCase();
|
|
41
|
-
return n.find((t) => e.endsWith(t)) ?? n.find((e) => r.endsWith(e.toLowerCase()));
|
|
42
|
-
}
|
|
43
|
-
function s(e) {
|
|
44
|
-
return String(e).replace(/^-/, "−");
|
|
45
|
-
}
|
|
46
|
-
function c(e) {
|
|
47
|
-
return Number.isFinite(e) ? e <= 2 ? `${s(Math.round(e * 100))}%` : e >= 100 ? `${Math.round(e).toLocaleString("en-US")}x` : `${s(Math.round(e * 10) / 10)}x` : String(e);
|
|
48
|
-
}
|
|
49
|
-
//#endregion
|
|
50
|
-
export { a, c as i, i as n, n as o, t as r, e as t };
|
|
51
|
-
|
|
52
|
-
//# sourceMappingURL=number-f6PydOZK.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"number-f6PydOZK.js","names":[],"sources":["../../src/format/number.ts"],"sourcesContent":["/**\n * Display-formatter for numbers. Use this anywhere a number is shown to\n * a user. The whole point: negative values get prefixed with the real\n * MINUS SIGN (U+2212) instead of the ASCII HYPHEN-MINUS (U+002D) that\n * `toLocaleString` and template literals produce by default.\n *\n * U+2212 is the same visual width as `+` and reads as a sign rather\n * than a hyphen — columns of signed numbers align cleanly and the\n * glyph doesn't get confused with a bullet or list dash.\n */\nexport const MINUS_SIGN = '−';\n\n/**\n * Formats a number for display, substituting {@link MINUS_SIGN} for the ASCII\n * hyphen `toLocaleString` emits. Non-finite values stringify as-is.\n */\nexport function formatNumber(value: number, options?: Intl.NumberFormatOptions): string {\n const formatted = Number.isFinite(value)\n ? value.toLocaleString(undefined, options)\n : String(value);\n return formatted.replace(/^-/, MINUS_SIGN);\n}\n\n/**\n * Parses a string that may carry {@link MINUS_SIGN} in place of the ASCII\n * hyphen. The inverse of {@link formatNumber} for any editing surface that\n * renders its value through it and reads the edited text back.\n */\nexport function parseSignedNumber(text: string): number {\n return Number(text.replace(MINUS_SIGN, '-'));\n}\n\n/** Powers of ten a typed magnitude suffix stands for. */\nconst EXPONENTS: Record<string, number> = { k: 3, m: 6, b: 9, t: 12 };\n\n/**\n * Formats a number the way a `compact` readout shows it: below 1,000 at\n * `decimals` places, from 1,000 up at one decimal with a magnitude suffix\n * (`40.0K`, `2.0M`). Always `en-US`, so {@link parseNumber} reads it back.\n */\nexport function formatCompact(value: number, decimals = 0): string {\n if (!Number.isFinite(value)) return formatNumber(value);\n const options: Intl.NumberFormatOptions =\n Math.abs(value) < 1000\n ? { useGrouping: false, minimumFractionDigits: decimals, maximumFractionDigits: decimals }\n : { notation: 'compact', minimumFractionDigits: 1, maximumFractionDigits: 1 };\n return value.toLocaleString('en-US', options).replace(/^-/, MINUS_SIGN);\n}\n\n/**\n * Reads a typed number: anything {@link parseSignedNumber} reads, plus\n * thousands commas in the `40,000` shape and a `k`/`m`/`b`/`t` suffix in either\n * case (`2.5m` is 2,500,000). Empty text is NaN rather than zero.\n *\n * Given `units` — a suffix mapped to the factor it scales by — a trailing unit\n * name is read first: the longest match wins, exact case before any case, and\n * a unit beats a magnitude suffix, so with `m` accepted `2m` is `2 * units.m`.\n */\nexport function parseNumber(text: string, units?: Readonly<Record<string, number>>): number {\n if (units) {\n const trimmed = text.trim();\n const name = unitSuffixOf(trimmed, units);\n if (name !== undefined) {\n const n = parseNumber(trimmed.slice(0, -name.length));\n const factor = units[name]!;\n // Divided by the reciprocal below 1: 12 * 0.1 is 1.2000000000000002, 12 / 10 is 1.2.\n return factor < 1 ? n / (1 / factor) : n * factor;\n }\n }\n let t = text.trim().replace(MINUS_SIGN, '-');\n const exponent = EXPONENTS[t.slice(-1).toLowerCase()];\n if (exponent !== undefined) t = t.slice(0, -1).trimEnd();\n if (/^[-+]?\\d{1,3}(,\\d{3})+(\\.\\d*)?$/.test(t)) t = t.replace(/,/g, '');\n if (!/\\d/.test(t)) return Number.NaN;\n // Scaled through the exponent rather than by multiplying: 1.1 * 1000 is 1100.0000000000002.\n return Number(exponent === undefined ? t : `${t}e${exponent}`);\n}\n\n/** The longest unit name `text` ends with — exact case first, then any case. */\nfunction unitSuffixOf(text: string, units: Readonly<Record<string, number>>): string | undefined {\n const names = Object.keys(units).filter((n) => n !== '').sort((a, b) => b.length - a.length);\n const lower = text.toLowerCase();\n return names.find((n) => text.endsWith(n)) ?? names.find((n) => lower.endsWith(n.toLowerCase()));\n}\n\n/** {@link String} with the leading ASCII hyphen swapped for {@link MINUS_SIGN}.\n * Locale-independent, unlike `toLocaleString`. */\nfunction signedString(value: number): string {\n return String(value).replace(/^-/, MINUS_SIGN);\n}\n\n/**\n * Formats a zoom factor for display. Below 2x a percentage reads naturally;\n * past it the numbers get long and a multiplier is what people say out loud,\n * so 250% shows as `2.5x`. Past 100x a tenth is noise, so the decimal is\n * dropped and thousands are grouped: `1009.74` reads as `1,010x`.\n */\nexport function formatZoom(zoom: number): string {\n if (!Number.isFinite(zoom)) return String(zoom);\n if (zoom <= 2) return `${signedString(Math.round(zoom * 100))}%`;\n if (zoom >= 100) return `${Math.round(zoom).toLocaleString('en-US')}x`;\n return `${signedString(Math.round(zoom * 10) / 10)}x`;\n}\n"],"mappings":";AAUA,IAAa,IAAa;AAM1B,SAAgB,EAAa,GAAe,GAA4C;AAItF,SAHkB,OAAO,SAAS,EAAM,GACpC,EAAM,eAAe,KAAA,GAAW,EAAQ,GACxC,OAAO,EAAM,EACA,QAAQ,MAAA,IAAiB;;AAQ5C,SAAgB,EAAkB,GAAsB;AACtD,QAAO,OAAO,EAAK,QAAA,KAAoB,IAAI,CAAC;;AAI9C,IAAM,IAAoC;CAAE,GAAG;CAAG,GAAG;CAAG,GAAG;CAAG,GAAG;CAAI;AAOrE,SAAgB,EAAc,GAAe,IAAW,GAAW;AACjE,KAAI,CAAC,OAAO,SAAS,EAAM,CAAE,QAAO,EAAa,EAAM;CACvD,IAAM,IACJ,KAAK,IAAI,EAAM,GAAG,MACd;EAAE,aAAa;EAAO,uBAAuB;EAAU,uBAAuB;EAAU,GACxF;EAAE,UAAU;EAAW,uBAAuB;EAAG,uBAAuB;EAAG;AACjF,QAAO,EAAM,eAAe,SAAS,EAAQ,CAAC,QAAQ,MAAA,IAAiB;;AAYzE,SAAgB,EAAY,GAAc,GAAkD;AAC1F,KAAI,GAAO;EACT,IAAM,IAAU,EAAK,MAAM,EACrB,IAAO,EAAa,GAAS,EAAM;AACzC,MAAI,MAAS,KAAA,GAAW;GACtB,IAAM,IAAI,EAAY,EAAQ,MAAM,GAAG,CAAC,EAAK,OAAO,CAAC,EAC/C,IAAS,EAAM;AAErB,UAAO,IAAS,IAAI,KAAK,IAAI,KAAU,IAAI;;;CAG/C,IAAI,IAAI,EAAK,MAAM,CAAC,QAAA,KAAoB,IAAI,EACtC,IAAW,EAAU,EAAE,MAAM,GAAG,CAAC,aAAa;AAKpD,QAJI,MAAa,KAAA,MAAW,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,SAAS,GACpD,kCAAkC,KAAK,EAAE,KAAE,IAAI,EAAE,QAAQ,MAAM,GAAG,GACjE,KAAK,KAAK,EAAE,GAEV,OAAO,MAAa,KAAA,IAAY,IAAI,GAAG,EAAE,GAAG,IAAW,GAFpC;;AAM5B,SAAS,EAAa,GAAc,GAA6D;CAC/F,IAAM,IAAQ,OAAO,KAAK,EAAM,CAAC,QAAQ,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,OAAO,EACtF,IAAQ,EAAK,aAAa;AAChC,QAAO,EAAM,MAAM,MAAM,EAAK,SAAS,EAAE,CAAC,IAAI,EAAM,MAAM,MAAM,EAAM,SAAS,EAAE,aAAa,CAAC,CAAC;;AAKlG,SAAS,EAAa,GAAuB;AAC3C,QAAO,OAAO,EAAM,CAAC,QAAQ,MAAA,IAAiB;;AAShD,SAAgB,EAAW,GAAsB;AAI/C,QAHK,OAAO,SAAS,EAAK,GACtB,KAAQ,IAAU,GAAG,EAAa,KAAK,MAAM,IAAO,IAAI,CAAC,CAAC,KAC1D,KAAQ,MAAY,GAAG,KAAK,MAAM,EAAK,CAAC,eAAe,QAAQ,CAAC,KAC7D,GAAG,EAAa,KAAK,MAAM,IAAO,GAAG,GAAG,GAAG,CAAC,KAHhB,OAAO,EAAK"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema-MCVT1MLv.js","names":[],"sources":["../../src/components/Prefs/schema.ts"],"sourcesContent":["// Preference-schema vocabulary for PrefsForm / PrefsDialog / SelectionPanel:\n// core's `ToolPref*` family under this package's names. Never re-declare them\n// here — this was a hand-kept structural copy until it drifted, and the\n// independence from `@weasel-js/core` it bought is long gone anyway.\n\nexport type {\n ToolPref as BuiltinPref,\n ToolPrefBoolean as PrefBoolean,\n ToolPrefBooleanControl as PrefBooleanControl,\n ToolPrefColor as PrefColor,\n ToolPrefCustom as PrefCustom,\n ToolPrefEnum as PrefEnum,\n ToolPrefEnumControl as PrefEnumControl,\n ToolPrefEnumEncoding as PrefEnumEncoding,\n ToolPrefGroup as PrefGroup,\n ToolPrefKind as PrefKind,\n ToolPrefLeaf as PrefLeaf,\n ToolPrefNumber as PrefNumber,\n ToolPrefNumberControl as PrefNumberControl,\n ToolPrefNumberFormat as PrefNumberFormat,\n ToolPrefNumberUnit as PrefNumberUnit,\n ToolPrefObject as PrefObject,\n ToolPrefPaint as PrefPaint,\n ToolPrefString as PrefString,\n ToolPrefStringControl as PrefStringControl,\n} from '@weasel-js/core';\n\nimport type { ToolPrefGroup, ToolPrefLeaf, ToolPrefNumber, ToolPrefNumberUnit as PrefNumberUnitType } from '@weasel-js/core';\n\n/**\n * A number leaf's bounds in the unit it is displayed in.\n *\n * Only what the leaf declares converts: an omitted bound has no stored\n * counterpart to put through the conversion, and its fallback — 0..100 for a\n * slider's track, a step of 1 — is a display-space number already. `min` and\n * `max` are points, so they convert the way the value does; `step` is a\n * distance, and a unit with an offset maps zero somewhere else, so converting\n * it as a point would scale it wrong. A decreasing conversion swaps which end\n * is the lower one.\n */\nexport function prefDisplayBounds(\n p: ToolPrefNumber,\n): { min?: number; max?: number; step: number } {\n if (!p.unit) return { min: p.min, max: p.max, step: p.step ?? 1 };\n const { toDisplay } = p.unit;\n const lo = p.min === undefined ? undefined : toDisplay(p.min);\n const hi = p.max === undefined ? undefined : toDisplay(p.max);\n const flipped = lo !== undefined && hi !== undefined && lo > hi;\n const step = p.step === undefined\n ? 1\n : Math.abs(toDisplay(p.step) - toDisplay(0)) || p.step;\n return { min: flipped ? hi : lo, max: flipped ? lo : hi, step };\n}\n\n/** What a unit leaf's field reads as typed text: its `accepts` table, and its\n * `suffix` as the display unit itself. */\nexport function prefUnitAccepts(unit: PrefNumberUnitType): Readonly<Record<string, number>> {\n return unit.suffix === undefined ? { ...unit.accepts } : { [unit.suffix]: 1, ...unit.accepts };\n}\n\n/** Distinguishes a leaf from a group while walking a schema tree. */\nexport function isPrefLeaf(node: ToolPrefLeaf | ToolPrefGroup): node is ToolPrefLeaf {\n return 'kind' in node;\n}\n\n/** Get the value at a dotted path inside a nested value tree. Returns\n * `undefined` when a segment is missing or hits a non-object. */\nexport function prefValueAtPath(values: unknown, path: string): unknown {\n let cur: unknown = values;\n for (const seg of path.split('.')) {\n if (cur == null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[seg];\n }\n return cur;\n}\n\n/**\n * Recursively drop `hidden` leaves (unless `showHidden`), pruning groups\n * that end up empty. Returns null when the entire subtree is hidden.\n */\nexport function visiblePrefSubtree<T extends ToolPrefLeaf | ToolPrefGroup>(\n node: T,\n showHidden: boolean,\n): T | null {\n if (isPrefLeaf(node)) return node.hidden && !showHidden ? null : node;\n const group = node as ToolPrefGroup;\n const children: Record<string, ToolPrefLeaf | ToolPrefGroup> = {};\n for (const [key, child] of Object.entries(group.children)) {\n const kept = visiblePrefSubtree(child, showHidden);\n if (kept) children[key] = kept;\n }\n if (Object.keys(children).length === 0) return null;\n return { ...node, children };\n}\n"],"mappings":";AAwCA,SAAgB,EACd,GAC8C;AAC9C,KAAI,CAAC,EAAE,KAAM,QAAO;EAAE,KAAK,EAAE;EAAK,KAAK,EAAE;EAAK,MAAM,EAAE,QAAQ;EAAG;CACjE,IAAM,EAAE,iBAAc,EAAE,MAClB,IAAK,EAAE,QAAQ,KAAA,IAAY,KAAA,IAAY,EAAU,EAAE,IAAI,EACvD,IAAK,EAAE,QAAQ,KAAA,IAAY,KAAA,IAAY,EAAU,EAAE,IAAI,EACvD,IAAU,MAAO,KAAA,KAAa,MAAO,KAAA,KAAa,IAAK,GACvD,IAAO,EAAE,SAAS,KAAA,IACpB,IACA,KAAK,IAAI,EAAU,EAAE,KAAK,GAAG,EAAU,EAAE,CAAC,IAAI,EAAE;AACpD,QAAO;EAAE,KAAK,IAAU,IAAK;EAAI,KAAK,IAAU,IAAK;EAAI;EAAM;;AAKjE,SAAgB,EAAgB,GAA4D;AAC1F,QAAO,EAAK,WAAW,KAAA,IAAY,EAAE,GAAG,EAAK,SAAS,GAAG;GAAG,EAAK,SAAS;EAAG,GAAG,EAAK;EAAS;;AAIhG,SAAgB,EAAW,GAA0D;AACnF,QAAO,UAAU;;AAKnB,SAAgB,EAAgB,GAAiB,GAAuB;CACtE,IAAI,IAAe;AACnB,MAAK,IAAM,KAAO,EAAK,MAAM,IAAI,EAAE;AACjC,MAAmB,OAAO,KAAQ,aAA9B,EAAwC;AAC5C,MAAO,EAAgC;;AAEzC,QAAO;;AAOT,SAAgB,EACd,GACA,GACU;AACV,KAAI,EAAW,EAAK,CAAE,QAAO,EAAK,UAAU,CAAC,IAAa,OAAO;CACjE,IAAM,IAAQ,GACR,IAAyD,EAAE;AACjE,MAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAM,SAAS,EAAE;EACzD,IAAM,IAAO,EAAmB,GAAO,EAAW;AAClD,EAAI,MAAM,EAAS,KAAO;;AAG5B,QADI,OAAO,KAAK,EAAS,CAAC,WAAW,IAAU,OACxC;EAAE,GAAG;EAAM;EAAU"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
var e = {
|
|
2
|
-
root: "_root_nj5x1_10",
|
|
3
|
-
segment: "_segment_nj5x1_32",
|
|
4
|
-
segmentSelected: "_segmentSelected_nj5x1_81",
|
|
5
|
-
size_sm: "_size_sm_nj5x1_139",
|
|
6
|
-
variant_minimal: "_variant_minimal_nj5x1_152"
|
|
7
|
-
};
|
|
8
|
-
//#endregion
|
|
9
|
-
export { e as t };
|
|
10
|
-
|
|
11
|
-
//# sourceMappingURL=segmentedControl.module-DmeUMYe3.js.map
|