@weasel-js/ui 1.8.0 → 1.8.1
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-xA73vzzF.js → ActionBar-CfXS7-9f.js} +2 -2
- package/dist/chunks/{ActionBar-xA73vzzF.js.map → ActionBar-CfXS7-9f.js.map} +1 -1
- package/dist/chunks/{Badge-jYQjrTKc.js → Badge-4ShpqA0h.js} +2 -2
- package/dist/chunks/{Badge-jYQjrTKc.js.map → Badge-4ShpqA0h.js.map} +1 -1
- package/dist/chunks/{Badge-CTc9Lkwn.js → Badge-qkV9EqKs.js} +6 -2
- package/dist/chunks/Badge-qkV9EqKs.js.map +1 -0
- package/dist/chunks/{Button-XB-T75YL.js → Button-CQA-K1g9.js} +17 -17
- package/dist/chunks/Button-CQA-K1g9.js.map +1 -0
- package/dist/chunks/Button-KF-qSGtA.js +11 -0
- package/dist/chunks/Button-KF-qSGtA.js.map +1 -0
- package/dist/chunks/{ButtonBar-CIMKPPRS.js → ButtonBar-B-cYuoem.js} +10 -4
- package/dist/chunks/ButtonBar-B-cYuoem.js.map +1 -0
- package/dist/chunks/{Callout-DpTO3fkb.js → Callout-VyYDIP7w.js} +18 -18
- package/dist/chunks/Callout-VyYDIP7w.js.map +1 -0
- package/dist/chunks/{CloseButton-wb7Or5Eg.js → CloseButton-CKarkTT9.js} +3 -3
- package/dist/chunks/{CloseButton-wb7Or5Eg.js.map → CloseButton-CKarkTT9.js.map} +1 -1
- package/dist/chunks/{Code-AsKpgnv6.js → Code-ChwKP1V0.js} +8 -2
- package/dist/chunks/Code-ChwKP1V0.js.map +1 -0
- package/dist/chunks/{ColorModeControl-DET6Itwq.js → ColorModeControl-CH9PmDlT.js} +6 -6
- package/dist/chunks/{ColorModeControl-DET6Itwq.js.map → ColorModeControl-CH9PmDlT.js.map} +1 -1
- package/dist/chunks/{ComboBox-DKln_mOd.js → ComboBox-BMj_IKBj.js} +4 -4
- package/dist/chunks/ComboBox-BMj_IKBj.js.map +1 -0
- package/dist/chunks/{DataGrid-B6IS9vUk.js → DataGrid-CjiVKoaA.js} +2 -2
- package/dist/chunks/{DataGrid-B6IS9vUk.js.map → DataGrid-CjiVKoaA.js.map} +1 -1
- package/dist/chunks/{Dialog-h-5MeYpu.js → Dialog-Du4POZ52.js} +5 -5
- package/dist/chunks/Dialog-Du4POZ52.js.map +1 -0
- package/dist/chunks/{DragGhost-BeYDJyLZ.js → DragGhost-_IpuN_xM.js} +2 -2
- package/dist/chunks/{DragGhost-BeYDJyLZ.js.map → DragGhost-_IpuN_xM.js.map} +1 -1
- package/dist/chunks/{FallthroughDiagram-CS1IhQaU.js → FallthroughDiagram-Cn6QLWKA.js} +9 -9
- package/dist/chunks/{FallthroughDiagram-CS1IhQaU.js.map → FallthroughDiagram-Cn6QLWKA.js.map} +1 -1
- package/dist/chunks/{FillStrokeSwatch-C4h3rUFM.js → FillStrokeSwatch-BkUhlpQL.js} +2 -2
- package/dist/chunks/{FillStrokeSwatch-C4h3rUFM.js.map → FillStrokeSwatch-BkUhlpQL.js.map} +1 -1
- package/dist/chunks/{FontFamilySelect-DEvMXyZd.js → FontFamilySelect-CXN7O2-p.js} +2 -2
- package/dist/chunks/{FontFamilySelect-DEvMXyZd.js.map → FontFamilySelect-CXN7O2-p.js.map} +1 -1
- package/dist/chunks/{FontWeightSelect-BLQ_LMJF.js → FontWeightSelect-BBuJGe_2.js} +2 -2
- package/dist/chunks/{FontWeightSelect-BLQ_LMJF.js.map → FontWeightSelect-BBuJGe_2.js.map} +1 -1
- package/dist/chunks/{GestureRoute-BXESrHI0.js → GestureRoute-BqHUrGeQ.js} +13 -13
- package/dist/chunks/{GestureRoute-BXESrHI0.js.map → GestureRoute-BqHUrGeQ.js.map} +1 -1
- package/dist/chunks/{GradientEditor-vz771M-N.js → GradientEditor-DX4sb1Hf.js} +3 -3
- package/dist/chunks/{GradientEditor-vz771M-N.js.map → GradientEditor-DX4sb1Hf.js.map} +1 -1
- package/dist/chunks/{Icon-DPRUIo3G.js → Icon-BfqYtAX5.js} +30 -1
- package/dist/chunks/Icon-BfqYtAX5.js.map +1 -0
- package/dist/chunks/{ItemList-CRu9y7hL.js → ItemList-nbakLf3N.js} +32 -32
- package/dist/chunks/ItemList-nbakLf3N.js.map +1 -0
- package/dist/chunks/{Jog-TE6QI9i1.js → Jog-BU0xuM3G.js} +6 -6
- package/dist/chunks/{Jog-TE6QI9i1.js.map → Jog-BU0xuM3G.js.map} +1 -1
- package/dist/chunks/{Keycaps-C-FJyG8k.js → Keycaps-CM-gOj0e.js} +8 -2
- package/dist/chunks/Keycaps-CM-gOj0e.js.map +1 -0
- package/dist/chunks/LayerList-vfAoImxX.js +432 -0
- package/dist/chunks/LayerList-vfAoImxX.js.map +1 -0
- package/dist/chunks/{ListEditor-DGtwj99m.js → ListEditor-BAKs47bN.js} +3 -3
- package/dist/chunks/{ListEditor-DGtwj99m.js.map → ListEditor-BAKs47bN.js.map} +1 -1
- package/dist/chunks/{MenuButton-TAFg88Lp.js → MenuButton-CJGdhwGr.js} +5 -5
- package/dist/chunks/MenuButton-CJGdhwGr.js.map +1 -0
- package/dist/chunks/{MeshEditor-8CRsu-Td.js → MeshEditor-rhf7cXfG.js} +2 -2
- package/dist/chunks/{MeshEditor-8CRsu-Td.js.map → MeshEditor-rhf7cXfG.js.map} +1 -1
- package/dist/chunks/{OptionsBar-DeTAjVb7.js → OptionsBar-DyTXbev-.js} +9 -3
- package/dist/chunks/OptionsBar-DyTXbev-.js.map +1 -0
- package/dist/chunks/{PaintField-DX4uYlF9.js → PaintField--GbF8sL7.js} +7 -7
- package/dist/chunks/PaintField--GbF8sL7.js.map +1 -0
- package/dist/chunks/{PaintInput-CWyOJXUM.js → PaintInput-DSS5IjXn.js} +5 -5
- package/dist/chunks/{PaintInput-CWyOJXUM.js.map → PaintInput-DSS5IjXn.js.map} +1 -1
- package/dist/chunks/{PatternPicker-0j51aDJ3.js → PatternPicker-82DCUvUk.js} +2 -2
- package/dist/chunks/{PatternPicker-0j51aDJ3.js.map → PatternPicker-82DCUvUk.js.map} +1 -1
- package/dist/chunks/{Powerline-6wIFmDik.js → Powerline-CogJv9VU.js} +2 -2
- package/dist/chunks/{Powerline-6wIFmDik.js.map → Powerline-CogJv9VU.js.map} +1 -1
- package/dist/chunks/{Prefs-gbjYqvSD.js → Prefs-BSSKOvPa.js} +41 -41
- package/dist/chunks/Prefs-BSSKOvPa.js.map +1 -0
- package/dist/chunks/{Properties-BbNuMiic.js → Properties-DteSVEWs.js} +4 -4
- package/dist/chunks/{Properties-BbNuMiic.js.map → Properties-DteSVEWs.js.map} +1 -1
- package/dist/chunks/{PropertyField-CWUtNK1w.js → PropertyField-CLbUOynA.js} +67 -67
- package/dist/chunks/PropertyField-CLbUOynA.js.map +1 -0
- package/dist/chunks/{Select-ouV8O6cp.js → Select-BhHwjNsb.js} +13 -13
- package/dist/chunks/Select-BhHwjNsb.js.map +1 -0
- package/dist/chunks/{SelectionPanel-BpUqP75b.js → SelectionPanel-B6HinSdB.js} +2 -2
- package/dist/chunks/{SelectionPanel-BpUqP75b.js.map → SelectionPanel-B6HinSdB.js.map} +1 -1
- package/dist/chunks/{SidebarPanel--dJ-k9-V.js → SidebarPanel-P3a8tIIj.js} +2 -2
- package/dist/chunks/{SidebarPanel--dJ-k9-V.js.map → SidebarPanel-P3a8tIIj.js.map} +1 -1
- package/dist/chunks/{StatusBar-BEOfOX0D.js → StatusBar-DEh7J2Gj.js} +14 -9
- package/dist/chunks/StatusBar-DEh7J2Gj.js.map +1 -0
- package/dist/chunks/{SwatchStrip-BY6A511W.js → SwatchStrip-D7YNn_p0.js} +2 -2
- package/dist/chunks/{SwatchStrip-BY6A511W.js.map → SwatchStrip-D7YNn_p0.js.map} +1 -1
- package/dist/chunks/{ThemeSwitcher-tnATkIo1.js → ThemeSwitcher-BJWP1l87.js} +6 -6
- package/dist/chunks/{ThemeSwitcher-tnATkIo1.js.map → ThemeSwitcher-BJWP1l87.js.map} +1 -1
- package/dist/chunks/{Timeline-FlLUm8nd.js → Timeline-CisRg82u.js} +2 -2
- package/dist/chunks/{Timeline-FlLUm8nd.js.map → Timeline-CisRg82u.js.map} +1 -1
- package/dist/chunks/{Toast-CuHkT0x0.js → Toast-DhkU9Z0b.js} +3 -3
- package/dist/chunks/{Toast-CuHkT0x0.js.map → Toast-DhkU9Z0b.js.map} +1 -1
- package/dist/chunks/ToggleBar-CRc2k89_.js +10 -0
- package/dist/chunks/ToggleBar-CRc2k89_.js.map +1 -0
- package/dist/chunks/{ToggleBar-BZ4Gk1IU.js → ToggleBar-CfYbMK3x.js} +9 -9
- package/dist/chunks/ToggleBar-CfYbMK3x.js.map +1 -0
- package/dist/chunks/{TokenPanel-DongdiZM.js → TokenPanel-cL37E39j.js} +5 -5
- package/dist/chunks/{TokenPanel-DongdiZM.js.map → TokenPanel-cL37E39j.js.map} +1 -1
- package/dist/chunks/{ToolButton-BURp4YIO.js → ToolButton-Bo7WH1wt.js} +2 -2
- package/dist/chunks/{ToolButton-BURp4YIO.js.map → ToolButton-Bo7WH1wt.js.map} +1 -1
- package/dist/chunks/{ToolOptionsBar-wTPJFfOn.js → ToolOptionsBar-DmhzrOmd.js} +2 -2
- package/dist/chunks/{ToolOptionsBar-wTPJFfOn.js.map → ToolOptionsBar-DmhzrOmd.js.map} +1 -1
- package/dist/chunks/{ToolPalette-DKDFWOX-.js → ToolPalette-BTD84k9C.js} +2 -2
- package/dist/chunks/{ToolPalette-DKDFWOX-.js.map → ToolPalette-BTD84k9C.js.map} +1 -1
- package/dist/chunks/{Tooltip-C6eFCYxw.js → Tooltip-DljsPEQG.js} +4 -4
- package/dist/chunks/Tooltip-DljsPEQG.js.map +1 -0
- package/dist/chunks/Tree-B_PW6K-W.js +215 -0
- package/dist/chunks/Tree-B_PW6K-W.js.map +1 -0
- package/dist/chunks/{icons-CofIOTiI.js → icons-B_fPKEis.js} +52 -43
- package/dist/chunks/icons-B_fPKEis.js.map +1 -0
- package/dist/chunks/{model-qQj8Ny9w.js → model-Ca0f95r0.js} +5 -5
- package/dist/chunks/{model-qQj8Ny9w.js.map → model-Ca0f95r0.js.map} +1 -1
- package/dist/chunks/{portalHost-CE70wLzo.js → portalHost-RUQPxIoW.js} +3 -2
- package/dist/chunks/{portalHost-CE70wLzo.js.map → portalHost-RUQPxIoW.js.map} +1 -1
- package/dist/chunks/{prefField-CCm_nzlM.js → prefField-DPPbAmRR.js} +3 -3
- package/dist/chunks/{prefField-CCm_nzlM.js.map → prefField-DPPbAmRR.js.map} +1 -1
- package/dist/chunks/{segmentTooltip-CGxCOWNz.js → segmentTooltip-8VBPNgEc.js} +2 -2
- package/dist/chunks/{segmentTooltip-CGxCOWNz.js.map → segmentTooltip-8VBPNgEc.js.map} +1 -1
- package/dist/chunks/segmentedControl.module-62qjNWJk.js +11 -0
- package/dist/chunks/{segmentedControl.module-BzGXUL5G.js.map → segmentedControl.module-62qjNWJk.js.map} +1 -1
- package/dist/chunks/{useReorderDragList-CStYKjHl.js → useReorderDragList-DnqqvRGK.js} +38 -30
- package/dist/chunks/useReorderDragList-DnqqvRGK.js.map +1 -0
- package/dist/components/ActionBar/index.js +1 -1
- package/dist/components/Badge/index.d.ts +1 -0
- package/dist/components/Badge/index.d.ts.map +1 -1
- package/dist/components/Badge/index.js +3 -3
- package/dist/components/Badge/variantIcons.d.ts +5 -0
- package/dist/components/Badge/variantIcons.d.ts.map +1 -0
- package/dist/components/Button/index.d.ts +1 -0
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +3 -2
- package/dist/components/Button/variantIcons.d.ts +5 -0
- package/dist/components/Button/variantIcons.d.ts.map +1 -0
- package/dist/components/ButtonBar/index.d.ts +1 -0
- package/dist/components/ButtonBar/index.d.ts.map +1 -1
- package/dist/components/ButtonBar/index.js +2 -2
- package/dist/components/ButtonBar/variantIcons.d.ts +5 -0
- package/dist/components/ButtonBar/variantIcons.d.ts.map +1 -0
- package/dist/components/Callout/Callout.d.ts.map +1 -1
- package/dist/components/Callout/index.js +1 -1
- package/dist/components/CloseButton/index.js +1 -1
- package/dist/components/Code/index.d.ts +1 -0
- package/dist/components/Code/index.d.ts.map +1 -1
- package/dist/components/Code/index.js +2 -2
- package/dist/components/Code/variantIcons.d.ts +5 -0
- package/dist/components/Code/variantIcons.d.ts.map +1 -0
- package/dist/components/ColorModeControl/index.js +1 -1
- package/dist/components/ComboBox/ComboBox.d.ts.map +1 -1
- package/dist/components/ComboBox/index.js +1 -1
- package/dist/components/DataGrid/index.js +1 -1
- package/dist/components/Dialog/Dialog.d.ts.map +1 -1
- package/dist/components/Dialog/index.js +1 -1
- package/dist/components/DragGhost/index.js +1 -1
- package/dist/components/FallthroughDiagram/index.js +1 -1
- package/dist/components/FillStrokeSwatch/index.js +1 -1
- package/dist/components/FontFamilySelect/index.js +1 -1
- package/dist/components/FontWeightSelect/index.js +1 -1
- package/dist/components/GestureRoute/index.js +1 -1
- package/dist/components/GradientEditor/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.d.ts +1 -0
- package/dist/components/Keycaps/index.d.ts.map +1 -1
- package/dist/components/Keycaps/index.js +2 -2
- package/dist/components/Keycaps/variantIcons.d.ts +5 -0
- package/dist/components/Keycaps/variantIcons.d.ts.map +1 -0
- package/dist/components/LayerList/LayerList.d.ts.map +1 -1
- package/dist/components/LayerList/index.js +1 -1
- package/dist/components/ListEditor/index.js +1 -1
- package/dist/components/MenuButton/MenuButton.d.ts.map +1 -1
- package/dist/components/MenuButton/index.js +1 -1
- package/dist/components/MeshEditor/index.js +1 -1
- package/dist/components/OptionsBar/index.d.ts +1 -0
- package/dist/components/OptionsBar/index.d.ts.map +1 -1
- package/dist/components/OptionsBar/index.js +2 -2
- package/dist/components/OptionsBar/variantIcons.d.ts +5 -0
- package/dist/components/OptionsBar/variantIcons.d.ts.map +1 -0
- package/dist/components/PaintField/PaintField.d.ts.map +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/Powerline/index.js +2 -2
- package/dist/components/Prefs/index.js +2 -2
- package/dist/components/Properties/index.js +2 -2
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/index.js +1 -1
- package/dist/components/SelectionPanel/index.js +2 -2
- package/dist/components/SidebarPanel/index.js +1 -1
- package/dist/components/StatusBar/StatusBar.d.ts +2 -0
- package/dist/components/StatusBar/StatusBar.d.ts.map +1 -1
- package/dist/components/StatusBar/index.js +1 -1
- package/dist/components/SwatchStrip/index.js +1 -1
- package/dist/components/ThemeSwitcher/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.d.ts +1 -0
- package/dist/components/ToggleBar/index.d.ts.map +1 -1
- package/dist/components/ToggleBar/index.js +3 -2
- package/dist/components/ToggleBar/variantIcons.d.ts +5 -0
- package/dist/components/ToggleBar/variantIcons.d.ts.map +1 -0
- package/dist/components/TokenPanel/index.js +1 -1
- package/dist/components/ToolButton/index.js +1 -1
- package/dist/components/ToolOptionsBar/index.js +1 -1
- package/dist/components/ToolPalette/index.js +1 -1
- package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/index.js +1 -1
- package/dist/components/Tree/Tree.d.ts +1 -1
- package/dist/components/Tree/Tree.d.ts.map +1 -1
- package/dist/components/Tree/index.js +1 -1
- package/dist/icons/index.d.ts +6 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/paths.d.ts +12 -0
- package/dist/icons/paths.d.ts.map +1 -1
- package/dist/index.js +100 -98
- package/dist/index.js.map +1 -1
- package/dist/overlays/portalHost.d.ts +10 -4
- package/dist/overlays/portalHost.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/dist/useReorderDragList.d.ts +3 -0
- package/dist/useReorderDragList.d.ts.map +1 -1
- package/package.json +10 -9
- package/dist/chunks/Badge-CTc9Lkwn.js.map +0 -1
- package/dist/chunks/Button-XB-T75YL.js.map +0 -1
- package/dist/chunks/ButtonBar-CIMKPPRS.js.map +0 -1
- package/dist/chunks/Callout-DpTO3fkb.js.map +0 -1
- package/dist/chunks/Code-AsKpgnv6.js.map +0 -1
- package/dist/chunks/ComboBox-DKln_mOd.js.map +0 -1
- package/dist/chunks/Dialog-h-5MeYpu.js.map +0 -1
- package/dist/chunks/Icon-DPRUIo3G.js.map +0 -1
- package/dist/chunks/ItemList-CRu9y7hL.js.map +0 -1
- package/dist/chunks/Keycaps-C-FJyG8k.js.map +0 -1
- package/dist/chunks/LayerList-BXTAjK-4.js +0 -421
- package/dist/chunks/LayerList-BXTAjK-4.js.map +0 -1
- package/dist/chunks/MenuButton-TAFg88Lp.js.map +0 -1
- package/dist/chunks/OptionsBar-DeTAjVb7.js.map +0 -1
- package/dist/chunks/PaintField-DX4uYlF9.js.map +0 -1
- package/dist/chunks/Prefs-gbjYqvSD.js.map +0 -1
- package/dist/chunks/PropertyField-CWUtNK1w.js.map +0 -1
- package/dist/chunks/Select-ouV8O6cp.js.map +0 -1
- package/dist/chunks/StatusBar-BEOfOX0D.js.map +0 -1
- package/dist/chunks/ToggleBar-BZ4Gk1IU.js.map +0 -1
- package/dist/chunks/Tooltip-C6eFCYxw.js.map +0 -1
- package/dist/chunks/Tree-hzIbj2q1.js +0 -203
- package/dist/chunks/Tree-hzIbj2q1.js.map +0 -1
- package/dist/chunks/icons-CofIOTiI.js.map +0 -1
- package/dist/chunks/interactiveTarget-BNZmTow2.js +0 -24
- package/dist/chunks/interactiveTarget-BNZmTow2.js.map +0 -1
- package/dist/chunks/segmentedControl.module-BzGXUL5G.js +0 -11
- package/dist/chunks/useReorderDragList-CStYKjHl.js.map +0 -1
- package/dist/interactiveTarget.d.ts +0 -9
- package/dist/interactiveTarget.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MeshEditor-8CRsu-Td.js","names":["s","s","handleHalf","paintPreviewCss","ToggleBar","MeshEditor_module_default","SPACES","MeshEditor","props","space","value","withCorner","asPaint","patchIndex","patch","b","c","d","next","corner","color","className","previewOf","ColorField","onInput","onChange","spaceSwitch","isMeshPaint","isMeshGradientFill","fill","handleOverlay_module_default","HandleOverlay","Guide","Edge","a","points","DragPoint","start","useRef","at","drag","useHandleDrag","p","moved","onDrag","point","variant","radius","label","amount","e","KEY_STEP","dx","dy","CORNER_RADIUS","CONTROL_RADIUS","MeshHandles","meshGuides","handles","meshHandles","emit","moveMeshHandle","handle","toLocal","phase","ordered","h","edges","toScreen","edge","i","arms","from","to","labelOf","prefix","index"],"sources":["../../src/components/MeshEditor/MeshEditor.module.css","../../src/components/MeshEditor/MeshEditor.tsx","../../src/components/GradientEditor/handleOverlay.module.css","../../src/components/GradientEditor/handleOverlay.tsx","../../src/components/MeshEditor/MeshHandles.tsx"],"sourcesContent":[".root {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-4);\n}\n\n.patch {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-4);\n}\n\n.preview {\n inline-size: 34px;\n block-size: 34px;\n flex: 0 0 auto;\n border-radius: var(--wzl-radius-sm);\n box-shadow: inset 0 0 0 1px var(--wzl-border);\n}\n\n.corners {\n display: grid;\n grid-template-columns: repeat(2, auto);\n gap: var(--wzl-space-2) var(--wzl-space-3);\n min-inline-size: 0;\n}\n\n.corner {\n min-inline-size: 0;\n}\n","import { type ReactElement } from 'react';\nimport { asPaint, type ColorSpace, type FillStyle } from '@weasel-js/core';\nimport { isMeshGradientFill, type MeshGradientFill } from '@weasel-js/core/mesh';\nimport { ColorField } from '../ColorField';\nimport { ToggleBar, type ToggleBarItem } from '../ToggleBar';\nimport { paintPreviewCss } from '../../paintPreview';\nimport s from './MeshEditor.module.css';\n\nconst SPACES: readonly ToggleBarItem<ColorSpace>[] = [\n { value: 'rgb', label: 'sRGB' },\n { value: 'oklab', label: 'OKLab' },\n { value: 'oklch', label: 'OKLCh' },\n];\n\n/** Props for {@link MeshEditor}. `onInput` fires throughout a gesture and\n * `onChange` once at its end. */\nexport interface MeshEditorProps {\n value: MeshGradientFill;\n /** Emitted as a `FillStyle`, which is what every paint control passes\n * around — `FillStyle`'s discriminant stays closed over the built-in\n * members, so a registered kind's own shape only travels through it. */\n onInput?: (next: FillStyle) => void;\n onChange: (next: FillStyle) => void;\n /** Show the sRGB / OKLab / OKLCh switch. Default true. */\n spaceSwitch?: boolean;\n className?: string;\n}\n\n/**\n * Editor for a mesh gradient's colors.\n *\n * Geometry is absent for the same reason it is absent from `GradientEditor`:\n * a patch's twelve control points are a thing to drag on the artwork\n * (`MeshHandles`), not a column of numbers in a panel. What is left is what a panel is good at — the\n * color at each corner, and the space the four of them blend through.\n *\n * Corners are numbered in the patch's own walk order, which is the order the\n * paint stores them in, so a corner's number is stable while it is dragged.\n */\nexport function MeshEditor(props: MeshEditorProps): ReactElement {\n const { value, onInput, onChange, spaceSwitch = true, className } = props;\n const space = value.interpolate ?? 'rgb';\n\n const withCorner = (patchIndex: number, corner: number, color: string): FillStyle => asPaint({\n ...value,\n patches: value.patches.map((patch, i) => {\n if (i !== patchIndex) return patch;\n const [a, b, c, d] = patch.colors;\n const next: [string, string, string, string] = [a, b, c, d];\n next[corner] = color;\n return { ...patch, colors: next };\n }),\n });\n\n return (\n <div className={[s.root, className].filter(Boolean).join(' ')}>\n {value.patches.map((patch, patchIndex) => (\n // A patch has no id; its position in the list is its identity, the way\n // a gradient stop's is.\n <div key={patchIndex} className={s.patch}>\n <span\n className={s.preview}\n aria-hidden=\"true\"\n style={{ background: previewOf(value, patchIndex) }}\n />\n <div className={s.corners}>\n {patch.colors.map((color, corner) => (\n <ColorField\n key={corner}\n value={color}\n alpha\n aria-label={`Patch ${patchIndex + 1} corner ${corner + 1}`}\n className={s.corner}\n onInput={(next) => onInput?.(withCorner(patchIndex, corner, next))}\n onChange={(next) => onChange(withCorner(patchIndex, corner, next))}\n />\n ))}\n </div>\n </div>\n ))}\n\n {spaceSwitch && (\n <ToggleBar<ColorSpace>\n items={SPACES}\n value={space}\n size=\"sm\"\n ariaLabel=\"Blend space\"\n onChange={(next) => next && onChange(asPaint({ ...value, interpolate: next }))}\n />\n )}\n </div>\n );\n}\n\n/** One patch as a swatch: the paint with the other patches taken out, so a\n * multi-patch mesh shows which row belongs to which part of it. */\nfunction previewOf(value: MeshGradientFill, patchIndex: number): string | undefined {\n return paintPreviewCss(\n { ...value, patches: [value.patches[patchIndex]] } as unknown as FillStyle,\n );\n}\n\n/** Narrowing for a consumer rendering this behind a kind switch. */\nexport function isMeshPaint(fill: FillStyle | null | undefined): fill is FillStyle & MeshGradientFill {\n return isMeshGradientFill(fill);\n}\n","/* The overlay covers the canvas but must not intercept tool input; only the\n * handles opt back into hit-testing. */\n.overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n/* These sit over artwork of unknown color, not over the app's own surface,\n * so they are deliberately not themed: a themed handle disappears against\n * whatever the user painted underneath. White-on-dark reads on anything,\n * which is why every editor draws handles this way. */\n.guide {\n fill: none;\n stroke: #ffffff;\n stroke-opacity: 0.7;\n stroke-dasharray: 4 4;\n paint-order: stroke;\n}\n\n.handle {\n fill: #ffffff;\n stroke: #222222;\n stroke-width: 2;\n cursor: grab;\n pointer-events: auto;\n}\n\n.handle:active {\n cursor: grabbing;\n}\n\n.handle:focus-visible {\n outline: 2px solid var(--wzl-accent);\n outline-offset: 2px;\n}\n\n/* A point that shapes an edge rather than ending one — drawn dark-on-light,\n * the inverse of the handle it hangs off, so the two read apart at a glance. */\n.control {\n fill: #222222;\n stroke: #ffffff;\n stroke-width: 1.5;\n}\n\n/* A patch edge: the outline the handles reshape, solid so it reads as the\n * artwork's structure rather than as a construction line. */\n.edge {\n fill: none;\n stroke: #ffffff;\n stroke-opacity: 0.85;\n stroke-width: 1;\n}\n","import { useRef, type KeyboardEvent as ReactKeyboardEvent, type ReactElement, type ReactNode } from 'react';\nimport { useHandleDrag } from '@weasel-js/core';\nimport s from './handleOverlay.module.css';\n\n/** The pieces every paint-geometry overlay draws with — `GradientHandles`\n * and `MeshHandles` — kept here so the two drag, step and look alike. */\n\nexport interface OverlayPoint {\n x: number;\n y: number;\n}\n\n/** Which half of a gesture an edit belongs to: a live preview, or the one\n * write that ends it. */\nexport type EditPhase = 'input' | 'commit';\n\n/** The SVG overlay itself: covers its container, passes pointer input\n * through everywhere but the handles. */\nexport function HandleOverlay(props: {\n width: number;\n height: number;\n className?: string;\n children: ReactNode;\n}): ReactElement {\n return (\n <svg\n className={[s.overlay, props.className].filter(Boolean).join(' ')}\n width={props.width}\n height={props.height}\n >\n {props.children}\n </svg>\n );\n}\n\nexport function Guide(props: { x1: number; y1: number; x2: number; y2: number }): ReactElement {\n return <line className={s.guide} {...props} />;\n}\n\n/** A cubic Bézier edge through four overlay-space points. */\nexport function Edge({ points }: { points: readonly [OverlayPoint, OverlayPoint, OverlayPoint, OverlayPoint] }): ReactElement {\n const [a, b, c, d] = points;\n return <path className={s.edge} d={`M${a.x} ${a.y}C${b.x} ${b.y} ${c.x} ${c.y} ${d.x} ${d.y}`} />;\n}\n\n/**\n * One draggable point. `onDrag` receives overlay pixels; a press that never\n * moved writes nothing, and a canceled gesture puts the preview back.\n */\nexport function DragPoint({\n at,\n label,\n radius,\n variant = 'handle',\n onDrag,\n}: {\n at: OverlayPoint;\n label: string;\n radius: number;\n /** `control` draws the inverted style a secondary point wears. */\n variant?: 'handle' | 'control';\n onDrag: (p: OverlayPoint, phase: EditPhase) => void;\n}): ReactElement {\n const start = useRef<OverlayPoint>(at);\n const drag = useHandleDrag<SVGCircleElement>({\n onStart: () => { start.current = at; },\n onMove: (p) => { onDrag(p, 'input'); },\n onEnd: ({ point, moved }) => {\n if (moved) onDrag(point, 'commit');\n },\n onCancel: () => { onDrag(start.current, 'input'); },\n });\n const onKeyDown = (e: ReactKeyboardEvent<SVGCircleElement>): void => {\n const amount = e.shiftKey ? KEY_STEP * 10 : KEY_STEP;\n let dx = 0;\n let dy = 0;\n if (e.key === 'ArrowLeft') dx = -amount;\n else if (e.key === 'ArrowRight') dx = amount;\n else if (e.key === 'ArrowUp') dy = -amount;\n else if (e.key === 'ArrowDown') dy = amount;\n else return;\n e.preventDefault();\n const next = { x: at.x + dx, y: at.y + dy };\n onDrag(next, 'input');\n onDrag(next, 'commit');\n };\n return (\n <circle\n className={variant === 'control' ? `${s.handle} ${s.control}` : s.handle}\n cx={at.x}\n cy={at.y}\n r={radius}\n // Not `slider`: the handle carries a 2-D position, not one value, so\n // it has no `aria-valuenow` to honor the role's contract with.\n role=\"button\"\n aria-label={label}\n tabIndex={0}\n onKeyDown={onKeyDown}\n {...drag}\n />\n );\n}\n\n/** One arrow-key step, in overlay pixels. */\nconst KEY_STEP = 1;\n","import { type ReactElement } from 'react';\nimport { asPaint, type FillStyle } from '@weasel-js/core';\nimport {\n meshGuides,\n meshHandles,\n moveMeshHandle,\n type MeshGradientFill,\n type MeshHandle,\n} from '@weasel-js/core/mesh';\nimport { handleHalf } from '../../handles';\nimport {\n DragPoint,\n Edge,\n Guide,\n HandleOverlay,\n type EditPhase,\n type OverlayPoint as Point,\n} from '../GradientEditor/handleOverlay';\n\n/** Props for {@link MeshHandles}. `onInput` fires throughout a drag and\n * `onChange` once at its end. */\nexport interface MeshHandlesProps {\n /** The mesh whose points these handles move, in the space `toScreen`\n * maps from. A `units: 'bounds'` mesh is resolved first with\n * `fillInPoseFrame(fill, box)`, and edits converted back with\n * `fillToBoundsFrame(next, box)`. */\n value: MeshGradientFill;\n /** Mesh space → overlay pixels. */\n toScreen: (p: Point) => Point;\n /** Overlay pixels → mesh space. Must invert `toScreen`. */\n toLocal: (p: Point) => Point;\n /** Live during a drag — wire for preview, do not write to history. Emitted\n * as a `FillStyle`, which is what every paint control passes around. */\n onInput?: (next: FillStyle) => void;\n /** Committed at drag end: one call per gesture. */\n onChange: (next: FillStyle) => void;\n /** Overlay size in CSS pixels. */\n width: number;\n height: number;\n className?: string;\n}\n\nconst CORNER_RADIUS = handleHalf('--wzl-handle-size-lg');\nconst CONTROL_RADIUS = handleHalf('--wzl-handle-size');\n\n/**\n * Direct-manipulation handles for a mesh gradient's geometry, drawn as an\n * SVG overlay: every patch corner, the two controls of each edge, and a\n * tensor patch's interior points, over the patch outlines they shape.\n *\n * Dragging a corner carries its controls with it. Points two patches share\n * are one handle, so a drag moves the seam instead of tearing it.\n *\n * The overlay ignores pointer events except on the handles themselves.\n */\nexport function MeshHandles(props: MeshHandlesProps): ReactElement {\n const { value, toScreen, toLocal, onInput, onChange, width, height, className } = props;\n const { edges, arms } = meshGuides(value);\n const handles = meshHandles(value);\n\n const emit = (handle: MeshHandle, p: Point, phase: EditPhase): void => {\n const next = asPaint(moveMeshHandle(value, handle, toLocal(p)));\n if (phase === 'input') onInput?.(next);\n else onChange(next);\n };\n\n // Corners last, so where a control collapses onto its corner the corner\n // is the one on top.\n const ordered = [\n ...handles.filter((h) => h.kind !== 'corner'),\n ...handles.filter((h) => h.kind === 'corner'),\n ];\n\n return (\n <HandleOverlay width={width} height={height} className={className}>\n {edges.map((edge, i) => (\n // Guides have no identity beyond their place in the walk.\n <Edge key={`e${i}`} points={[toScreen(edge[0]), toScreen(edge[1]), toScreen(edge[2]), toScreen(edge[3])]} />\n ))}\n {arms.map(([from, to], i) => {\n const a = toScreen(from);\n const b = toScreen(to);\n return <Guide key={`a${i}`} x1={a.x} y1={a.y} x2={b.x} y2={b.y} />;\n })}\n {ordered.map((handle) => (\n <DragPoint\n key={handle.id}\n at={toScreen(handle.at)}\n label={labelOf(handle)}\n radius={handle.kind === 'corner' ? CORNER_RADIUS : CONTROL_RADIUS}\n variant={handle.kind === 'corner' ? 'handle' : 'control'}\n onDrag={(p, phase) => emit(handle, p, phase)}\n />\n ))}\n </HandleOverlay>\n );\n}\n\n/** Numbered in the patch's own walk, matching `MeshEditor`'s corner fields. */\nfunction labelOf(handle: MeshHandle): string {\n const { patch, index } = handle.refs[0];\n const prefix = `Patch ${patch + 1}`;\n if (handle.kind === 'corner') return `${prefix} corner ${index / 3 + 1}`;\n if (handle.kind === 'interior') return `${prefix} interior ${index - 11}`;\n return `${prefix} edge ${Math.floor(index / 3) + 1} control ${index % 3}`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MeshEditor-rhf7cXfG.js","names":["s","s","handleHalf","paintPreviewCss","ToggleBar","MeshEditor_module_default","SPACES","MeshEditor","props","space","value","withCorner","asPaint","patchIndex","patch","b","c","d","next","corner","color","className","previewOf","ColorField","onInput","onChange","spaceSwitch","isMeshPaint","isMeshGradientFill","fill","handleOverlay_module_default","HandleOverlay","Guide","Edge","a","points","DragPoint","start","useRef","at","drag","useHandleDrag","p","moved","onDrag","point","variant","radius","label","amount","e","KEY_STEP","dx","dy","CORNER_RADIUS","CONTROL_RADIUS","MeshHandles","meshGuides","handles","meshHandles","emit","moveMeshHandle","handle","toLocal","phase","ordered","h","edges","toScreen","edge","i","arms","from","to","labelOf","prefix","index"],"sources":["../../src/components/MeshEditor/MeshEditor.module.css","../../src/components/MeshEditor/MeshEditor.tsx","../../src/components/GradientEditor/handleOverlay.module.css","../../src/components/GradientEditor/handleOverlay.tsx","../../src/components/MeshEditor/MeshHandles.tsx"],"sourcesContent":[".root {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-4);\n}\n\n.patch {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-4);\n}\n\n.preview {\n inline-size: 34px;\n block-size: 34px;\n flex: 0 0 auto;\n border-radius: var(--wzl-radius-sm);\n box-shadow: inset 0 0 0 1px var(--wzl-border);\n}\n\n.corners {\n display: grid;\n grid-template-columns: repeat(2, auto);\n gap: var(--wzl-space-2) var(--wzl-space-3);\n min-inline-size: 0;\n}\n\n.corner {\n min-inline-size: 0;\n}\n","import { type ReactElement } from 'react';\nimport { asPaint, type ColorSpace, type FillStyle } from '@weasel-js/core';\nimport { isMeshGradientFill, type MeshGradientFill } from '@weasel-js/core/mesh';\nimport { ColorField } from '../ColorField';\nimport { ToggleBar, type ToggleBarItem } from '../ToggleBar';\nimport { paintPreviewCss } from '../../paintPreview';\nimport s from './MeshEditor.module.css';\n\nconst SPACES: readonly ToggleBarItem<ColorSpace>[] = [\n { value: 'rgb', label: 'sRGB' },\n { value: 'oklab', label: 'OKLab' },\n { value: 'oklch', label: 'OKLCh' },\n];\n\n/** Props for {@link MeshEditor}. `onInput` fires throughout a gesture and\n * `onChange` once at its end. */\nexport interface MeshEditorProps {\n value: MeshGradientFill;\n /** Emitted as a `FillStyle`, which is what every paint control passes\n * around — `FillStyle`'s discriminant stays closed over the built-in\n * members, so a registered kind's own shape only travels through it. */\n onInput?: (next: FillStyle) => void;\n onChange: (next: FillStyle) => void;\n /** Show the sRGB / OKLab / OKLCh switch. Default true. */\n spaceSwitch?: boolean;\n className?: string;\n}\n\n/**\n * Editor for a mesh gradient's colors.\n *\n * Geometry is absent for the same reason it is absent from `GradientEditor`:\n * a patch's twelve control points are a thing to drag on the artwork\n * (`MeshHandles`), not a column of numbers in a panel. What is left is what a panel is good at — the\n * color at each corner, and the space the four of them blend through.\n *\n * Corners are numbered in the patch's own walk order, which is the order the\n * paint stores them in, so a corner's number is stable while it is dragged.\n */\nexport function MeshEditor(props: MeshEditorProps): ReactElement {\n const { value, onInput, onChange, spaceSwitch = true, className } = props;\n const space = value.interpolate ?? 'rgb';\n\n const withCorner = (patchIndex: number, corner: number, color: string): FillStyle => asPaint({\n ...value,\n patches: value.patches.map((patch, i) => {\n if (i !== patchIndex) return patch;\n const [a, b, c, d] = patch.colors;\n const next: [string, string, string, string] = [a, b, c, d];\n next[corner] = color;\n return { ...patch, colors: next };\n }),\n });\n\n return (\n <div className={[s.root, className].filter(Boolean).join(' ')}>\n {value.patches.map((patch, patchIndex) => (\n // A patch has no id; its position in the list is its identity, the way\n // a gradient stop's is.\n <div key={patchIndex} className={s.patch}>\n <span\n className={s.preview}\n aria-hidden=\"true\"\n style={{ background: previewOf(value, patchIndex) }}\n />\n <div className={s.corners}>\n {patch.colors.map((color, corner) => (\n <ColorField\n key={corner}\n value={color}\n alpha\n aria-label={`Patch ${patchIndex + 1} corner ${corner + 1}`}\n className={s.corner}\n onInput={(next) => onInput?.(withCorner(patchIndex, corner, next))}\n onChange={(next) => onChange(withCorner(patchIndex, corner, next))}\n />\n ))}\n </div>\n </div>\n ))}\n\n {spaceSwitch && (\n <ToggleBar<ColorSpace>\n items={SPACES}\n value={space}\n size=\"sm\"\n ariaLabel=\"Blend space\"\n onChange={(next) => next && onChange(asPaint({ ...value, interpolate: next }))}\n />\n )}\n </div>\n );\n}\n\n/** One patch as a swatch: the paint with the other patches taken out, so a\n * multi-patch mesh shows which row belongs to which part of it. */\nfunction previewOf(value: MeshGradientFill, patchIndex: number): string | undefined {\n return paintPreviewCss(\n { ...value, patches: [value.patches[patchIndex]] } as unknown as FillStyle,\n );\n}\n\n/** Narrowing for a consumer rendering this behind a kind switch. */\nexport function isMeshPaint(fill: FillStyle | null | undefined): fill is FillStyle & MeshGradientFill {\n return isMeshGradientFill(fill);\n}\n","/* The overlay covers the canvas but must not intercept tool input; only the\n * handles opt back into hit-testing. */\n.overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n/* These sit over artwork of unknown color, not over the app's own surface,\n * so they are deliberately not themed: a themed handle disappears against\n * whatever the user painted underneath. White-on-dark reads on anything,\n * which is why every editor draws handles this way. */\n.guide {\n fill: none;\n stroke: #ffffff;\n stroke-opacity: 0.7;\n stroke-dasharray: 4 4;\n paint-order: stroke;\n}\n\n.handle {\n fill: #ffffff;\n stroke: #222222;\n stroke-width: 2;\n cursor: grab;\n pointer-events: auto;\n}\n\n.handle:active {\n cursor: grabbing;\n}\n\n.handle:focus-visible {\n outline: 2px solid var(--wzl-accent);\n outline-offset: 2px;\n}\n\n/* A point that shapes an edge rather than ending one — drawn dark-on-light,\n * the inverse of the handle it hangs off, so the two read apart at a glance. */\n.control {\n fill: #222222;\n stroke: #ffffff;\n stroke-width: 1.5;\n}\n\n/* A patch edge: the outline the handles reshape, solid so it reads as the\n * artwork's structure rather than as a construction line. */\n.edge {\n fill: none;\n stroke: #ffffff;\n stroke-opacity: 0.85;\n stroke-width: 1;\n}\n","import { useRef, type KeyboardEvent as ReactKeyboardEvent, type ReactElement, type ReactNode } from 'react';\nimport { useHandleDrag } from '@weasel-js/core';\nimport s from './handleOverlay.module.css';\n\n/** The pieces every paint-geometry overlay draws with — `GradientHandles`\n * and `MeshHandles` — kept here so the two drag, step and look alike. */\n\nexport interface OverlayPoint {\n x: number;\n y: number;\n}\n\n/** Which half of a gesture an edit belongs to: a live preview, or the one\n * write that ends it. */\nexport type EditPhase = 'input' | 'commit';\n\n/** The SVG overlay itself: covers its container, passes pointer input\n * through everywhere but the handles. */\nexport function HandleOverlay(props: {\n width: number;\n height: number;\n className?: string;\n children: ReactNode;\n}): ReactElement {\n return (\n <svg\n className={[s.overlay, props.className].filter(Boolean).join(' ')}\n width={props.width}\n height={props.height}\n >\n {props.children}\n </svg>\n );\n}\n\nexport function Guide(props: { x1: number; y1: number; x2: number; y2: number }): ReactElement {\n return <line className={s.guide} {...props} />;\n}\n\n/** A cubic Bézier edge through four overlay-space points. */\nexport function Edge({ points }: { points: readonly [OverlayPoint, OverlayPoint, OverlayPoint, OverlayPoint] }): ReactElement {\n const [a, b, c, d] = points;\n return <path className={s.edge} d={`M${a.x} ${a.y}C${b.x} ${b.y} ${c.x} ${c.y} ${d.x} ${d.y}`} />;\n}\n\n/**\n * One draggable point. `onDrag` receives overlay pixels; a press that never\n * moved writes nothing, and a canceled gesture puts the preview back.\n */\nexport function DragPoint({\n at,\n label,\n radius,\n variant = 'handle',\n onDrag,\n}: {\n at: OverlayPoint;\n label: string;\n radius: number;\n /** `control` draws the inverted style a secondary point wears. */\n variant?: 'handle' | 'control';\n onDrag: (p: OverlayPoint, phase: EditPhase) => void;\n}): ReactElement {\n const start = useRef<OverlayPoint>(at);\n const drag = useHandleDrag<SVGCircleElement>({\n onStart: () => { start.current = at; },\n onMove: (p) => { onDrag(p, 'input'); },\n onEnd: ({ point, moved }) => {\n if (moved) onDrag(point, 'commit');\n },\n onCancel: () => { onDrag(start.current, 'input'); },\n });\n const onKeyDown = (e: ReactKeyboardEvent<SVGCircleElement>): void => {\n const amount = e.shiftKey ? KEY_STEP * 10 : KEY_STEP;\n let dx = 0;\n let dy = 0;\n if (e.key === 'ArrowLeft') dx = -amount;\n else if (e.key === 'ArrowRight') dx = amount;\n else if (e.key === 'ArrowUp') dy = -amount;\n else if (e.key === 'ArrowDown') dy = amount;\n else return;\n e.preventDefault();\n const next = { x: at.x + dx, y: at.y + dy };\n onDrag(next, 'input');\n onDrag(next, 'commit');\n };\n return (\n <circle\n className={variant === 'control' ? `${s.handle} ${s.control}` : s.handle}\n cx={at.x}\n cy={at.y}\n r={radius}\n // Not `slider`: the handle carries a 2-D position, not one value, so\n // it has no `aria-valuenow` to honor the role's contract with.\n role=\"button\"\n aria-label={label}\n tabIndex={0}\n onKeyDown={onKeyDown}\n {...drag}\n />\n );\n}\n\n/** One arrow-key step, in overlay pixels. */\nconst KEY_STEP = 1;\n","import { type ReactElement } from 'react';\nimport { asPaint, type FillStyle } from '@weasel-js/core';\nimport {\n meshGuides,\n meshHandles,\n moveMeshHandle,\n type MeshGradientFill,\n type MeshHandle,\n} from '@weasel-js/core/mesh';\nimport { handleHalf } from '../../handles';\nimport {\n DragPoint,\n Edge,\n Guide,\n HandleOverlay,\n type EditPhase,\n type OverlayPoint as Point,\n} from '../GradientEditor/handleOverlay';\n\n/** Props for {@link MeshHandles}. `onInput` fires throughout a drag and\n * `onChange` once at its end. */\nexport interface MeshHandlesProps {\n /** The mesh whose points these handles move, in the space `toScreen`\n * maps from. A `units: 'bounds'` mesh is resolved first with\n * `fillInPoseFrame(fill, box)`, and edits converted back with\n * `fillToBoundsFrame(next, box)`. */\n value: MeshGradientFill;\n /** Mesh space → overlay pixels. */\n toScreen: (p: Point) => Point;\n /** Overlay pixels → mesh space. Must invert `toScreen`. */\n toLocal: (p: Point) => Point;\n /** Live during a drag — wire for preview, do not write to history. Emitted\n * as a `FillStyle`, which is what every paint control passes around. */\n onInput?: (next: FillStyle) => void;\n /** Committed at drag end: one call per gesture. */\n onChange: (next: FillStyle) => void;\n /** Overlay size in CSS pixels. */\n width: number;\n height: number;\n className?: string;\n}\n\nconst CORNER_RADIUS = handleHalf('--wzl-handle-size-lg');\nconst CONTROL_RADIUS = handleHalf('--wzl-handle-size');\n\n/**\n * Direct-manipulation handles for a mesh gradient's geometry, drawn as an\n * SVG overlay: every patch corner, the two controls of each edge, and a\n * tensor patch's interior points, over the patch outlines they shape.\n *\n * Dragging a corner carries its controls with it. Points two patches share\n * are one handle, so a drag moves the seam instead of tearing it.\n *\n * The overlay ignores pointer events except on the handles themselves.\n */\nexport function MeshHandles(props: MeshHandlesProps): ReactElement {\n const { value, toScreen, toLocal, onInput, onChange, width, height, className } = props;\n const { edges, arms } = meshGuides(value);\n const handles = meshHandles(value);\n\n const emit = (handle: MeshHandle, p: Point, phase: EditPhase): void => {\n const next = asPaint(moveMeshHandle(value, handle, toLocal(p)));\n if (phase === 'input') onInput?.(next);\n else onChange(next);\n };\n\n // Corners last, so where a control collapses onto its corner the corner\n // is the one on top.\n const ordered = [\n ...handles.filter((h) => h.kind !== 'corner'),\n ...handles.filter((h) => h.kind === 'corner'),\n ];\n\n return (\n <HandleOverlay width={width} height={height} className={className}>\n {edges.map((edge, i) => (\n // Guides have no identity beyond their place in the walk.\n <Edge key={`e${i}`} points={[toScreen(edge[0]), toScreen(edge[1]), toScreen(edge[2]), toScreen(edge[3])]} />\n ))}\n {arms.map(([from, to], i) => {\n const a = toScreen(from);\n const b = toScreen(to);\n return <Guide key={`a${i}`} x1={a.x} y1={a.y} x2={b.x} y2={b.y} />;\n })}\n {ordered.map((handle) => (\n <DragPoint\n key={handle.id}\n at={toScreen(handle.at)}\n label={labelOf(handle)}\n radius={handle.kind === 'corner' ? CORNER_RADIUS : CONTROL_RADIUS}\n variant={handle.kind === 'corner' ? 'handle' : 'control'}\n onDrag={(p, phase) => emit(handle, p, phase)}\n />\n ))}\n </HandleOverlay>\n );\n}\n\n/** Numbered in the patch's own walk, matching `MeshEditor`'s corner fields. */\nfunction labelOf(handle: MeshHandle): string {\n const { patch, index } = handle.refs[0];\n const prefix = `Patch ${patch + 1}`;\n if (handle.kind === 'corner') return `${prefix} corner ${index / 3 + 1}`;\n if (handle.kind === 'interior') return `${prefix} interior ${index - 11}`;\n return `${prefix} edge ${Math.floor(index / 3) + 1} control ${index % 3}`;\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./useRovingTabIndex-D7u22Ia_.js";
|
|
2
|
-
import { t } from "./segmentedControl.module-
|
|
2
|
+
import { t } from "./segmentedControl.module-62qjNWJk.js";
|
|
3
3
|
import { jsx as n } from "react/jsx-runtime";
|
|
4
4
|
import "react";
|
|
5
5
|
//#region src/components/OptionsBar/OptionsBar.tsx
|
|
@@ -38,6 +38,12 @@ function r(r) {
|
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
//#endregion
|
|
41
|
-
|
|
41
|
+
//#region src/components/OptionsBar/variantIcons.ts
|
|
42
|
+
var i = {
|
|
43
|
+
default: "variantSegmented",
|
|
44
|
+
minimal: "variantSegmentedMinimal"
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
export { r as n, i as t };
|
|
42
48
|
|
|
43
|
-
//# sourceMappingURL=OptionsBar-
|
|
49
|
+
//# sourceMappingURL=OptionsBar-DyTXbev-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OptionsBar-DyTXbev-.js","names":["s","useRovingTabIndex","OptionsBar","props","toggle","item","items","index","roving","segmentedControl_module_default","style","height","rootCls","size","variant","className","ariaLabel","cls","i","OPTIONS_BAR_VARIANT_ICONS"],"sources":["../../src/components/OptionsBar/OptionsBar.tsx","../../src/components/OptionsBar/variantIcons.ts"],"sourcesContent":["import { type CSSProperties, type ReactElement, type ReactNode } from 'react';\nimport s from '../segmentedControl.module.css';\nimport { useRovingTabIndex } from '../../useRovingTabIndex';\n\n/**\n * One segment of an {@link OptionsBar}. Unlike `ToggleBar`, each item carries\n * its own selected state and its own `onChange`.\n */\nexport type OptionsBarItem<V extends string | number = string> = {\n value: V;\n label?: ReactNode;\n ariaLabel?: string;\n disabled?: boolean;\n selected: boolean;\n onChange: (next: boolean) => void;\n};\n\n/** Segment height and type scale for an {@link OptionsBar}. */\nexport type OptionsBarSize = 'sm' | 'md';\n/** Visual treatment of an {@link OptionsBar}. */\nexport type OptionsBarVariant = 'default' | 'minimal';\n\n/** Props for {@link OptionsBar}. */\nexport type OptionsBarProps<V extends string | number = string> = {\n items: readonly OptionsBarItem<V>[];\n ariaLabel?: string;\n className?: string;\n height?: number;\n /** Size variant. `sm` is ~60% of the default height with reduced padding\n * and font size — sized for dense surfaces like lab control panels. */\n size?: OptionsBarSize;\n /** Visual variant. `minimal` strips the pill track and glass treatment;\n * selection becomes a flat accent. For dense diagnostic surfaces. */\n variant?: OptionsBarVariant;\n};\n\n/**\n * Segmented strip of independent on/off options, each owning its own state.\n * Use it when the segments are unrelated booleans; use `ToggleBar` when they\n * are values of one setting.\n */\nexport function OptionsBar<V extends string | number = string>(props: OptionsBarProps<V>): ReactElement {\n const { items, ariaLabel, className, height, size, variant } = props;\n\n const toggle = (index: number) => {\n const item = items[index];\n if (item.disabled) return;\n item.onChange(!item.selected);\n };\n\n const roving = useRovingTabIndex({ itemSelector: `.${s.segment}`, onActivate: toggle });\n\n const style: CSSProperties | undefined = height !== undefined\n ? ({ ['--tb-h' as string]: `${height}px` } as CSSProperties)\n : undefined;\n\n const rootCls = [\n s.root,\n size && s[`size_${size}`],\n variant && s[`variant_${variant}`],\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <div\n ref={roving.rootRef}\n onKeyDown={roving.onKeyDown}\n className={rootCls}\n role=\"group\"\n aria-label={ariaLabel}\n style={style}\n >\n {items.map((item, i) => {\n const cls = `${s.segment}${item.selected ? ` ${s.segmentSelected}` : ''}`;\n return (\n <button\n key={item.value}\n type=\"button\"\n aria-pressed={item.selected}\n aria-label={item.ariaLabel}\n disabled={item.disabled}\n className={cls}\n onClick={() => toggle(i)}\n >\n {item.label}\n </button>\n );\n })}\n </div>\n );\n}\n","import type { IconName } from '../../icons/paths';\nimport type { OptionsBarVariant } from './OptionsBar';\n\n/** The glyph for each variant, for a picker that shows them. */\nexport const OPTIONS_BAR_VARIANT_ICONS: Readonly<Record<OptionsBarVariant, IconName>> = {\n default: 'variantSegmented',\n minimal: 'variantSegmentedMinimal',\n};\n"],"mappings":";;;;;AAyCA,SAAgBE,EAA+C,GAAyC;CACtG,IAAM,EAAE,UAAO,cAAW,cAAW,WAAQ,SAAM,eAAYC,GAEzDC,KAAU,MAAkB;EAChC,IAAMC,IAAOC,EAAMC;EACnB,AAAIF,EAAK,YACTA,EAAK,SAAS,CAACA,EAAK,QAAQ;CAC9B,GAEMG,IAASP,EAAkB;EAAE,cAAc,IAAID,EAAE;EAAW,YAAYI;CAAO,CAAC,GAEhFM,IAAmCC,MAAW,KAAA,IAEhD,KAAA,IADC,EAAG,UAAqB,GAAGA,EAAO,IAAI,GAGrCC,IAAU;EACdZ,EAAE;EACFa,KAAQb,EAAE,QAAQa;EAClBC,KAAWd,EAAE,WAAWc;EACxBC;CACF,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAE1B,OACE,kBAAC,OAAD;EACE,KAAKP,EAAO;EACZ,WAAWA,EAAO;EAClB,WAAWI;EACX,MAAK;EACL,cAAYI;EACL;EAEN,UAAAV,EAAM,KAAK,GAAM,MAAM;GACtB,IAAMW,IAAM,GAAGjB,EAAE,UAAUK,EAAK,WAAW,IAAIL,EAAE,oBAAoB;GACrE,OACE,kBAAC,UAAD;IAEE,MAAK;IACL,gBAAcK,EAAK;IACnB,cAAYA,EAAK;IACjB,UAAUA,EAAK;IACf,WAAWY;IACX,eAAeb,EAAOc,CAAC;IAEtB,UAAAb,EAAK;GACA,GATDA,EAAK,KASJ;EAEZ,CAAC;CACE,CAAA;AAET;;;ACtFA,IAAac,IAA2E;CACtF,SAAS;CACT,SAAS;AACX"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { i as e } from "./portalHost-
|
|
1
|
+
import { i as e } from "./portalHost-RUQPxIoW.js";
|
|
2
2
|
import { t } from "./listbox.module-BcdVJMbm.js";
|
|
3
3
|
import { t as n } from "./paintPreview-CuSZiHpR.js";
|
|
4
|
-
import { t as r } from "./PaintInput-
|
|
4
|
+
import { t as r } from "./PaintInput-DSS5IjXn.js";
|
|
5
5
|
import { usePaintKind as i } from "@weasel-js/core";
|
|
6
6
|
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
7
7
|
import "react";
|
|
@@ -19,7 +19,7 @@ function f(e, t, n) {
|
|
|
19
19
|
return t ? "Mixed" : e === null ? "None" : e === void 0 ? "—" : n ?? e.fill ?? "solid";
|
|
20
20
|
}
|
|
21
21
|
function p(p) {
|
|
22
|
-
let { value: m, mixed: h = !1, unset: g = !1, kinds: _, allowNone: v = !0, onInput: y, onChange: b, className: x, portalContainer: S } = p, C = p["aria-label"], { anchor: w, portalProps: T } = e(S),
|
|
22
|
+
let { value: m, mixed: h = !1, unset: g = !1, kinds: _, allowNone: v = !0, onInput: y, onChange: b, className: x, portalContainer: S } = p, C = p["aria-label"], { anchor: w, portalProps: T, ready: E } = e(S), D = h ? void 0 : n(m), O = i(m?.fill)?.label;
|
|
23
23
|
return /* @__PURE__ */ o(l, { children: [
|
|
24
24
|
w,
|
|
25
25
|
/* @__PURE__ */ o(s, {
|
|
@@ -30,13 +30,13 @@ function p(p) {
|
|
|
30
30
|
children: [/* @__PURE__ */ a("span", {
|
|
31
31
|
className: d.swatch,
|
|
32
32
|
"aria-hidden": "true",
|
|
33
|
-
...
|
|
33
|
+
...D ? { style: { background: D } } : { "data-empty": "" }
|
|
34
34
|
}), /* @__PURE__ */ a("span", {
|
|
35
35
|
className: d.label,
|
|
36
|
-
children: f(m, h,
|
|
36
|
+
children: f(m, h, O)
|
|
37
37
|
})]
|
|
38
38
|
}),
|
|
39
|
-
/* @__PURE__ */ a(u, {
|
|
39
|
+
E && /* @__PURE__ */ a(u, {
|
|
40
40
|
className: d.popover,
|
|
41
41
|
"data-weasel-overlay": "",
|
|
42
42
|
...T,
|
|
@@ -60,4 +60,4 @@ function p(p) {
|
|
|
60
60
|
//#endregion
|
|
61
61
|
export { p as t };
|
|
62
62
|
|
|
63
|
-
//# sourceMappingURL=PaintField
|
|
63
|
+
//# sourceMappingURL=PaintField--GbF8sL7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PaintField--GbF8sL7.js","names":["RACButton","s","RACPopover","RACDialog","listbox","useOverlayPortal","paintPreviewCss","PaintInput","PaintField_module_default","kindLabel","mixed","paint","label","PaintField","props","ariaLabel","portalContainer","preview","value","usePaintKind","DialogTrigger","anchor","Button","className","unset","ready","Popover","portalProps","Dialog","listbox_module_default"],"sources":["../../src/components/PaintField/PaintField.module.css","../../src/components/PaintField/PaintField.tsx"],"sourcesContent":[".trigger {\n display: inline-flex;\n align-items: center;\n gap: var(--wzl-space-3);\n inline-size: 100%;\n min-inline-size: 0;\n padding: 1px var(--wzl-space-3) 1px 1px;\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n background: var(--wzl-surface);\n color: var(--wzl-fg);\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size-sm);\n cursor: pointer;\n}\n\n.trigger[data-unset] {\n opacity: 0.6;\n}\n\n.trigger[data-focus-visible] {\n outline: none;\n border-color: var(--wzl-focus-ring);\n box-shadow: 0 0 0 1px var(--wzl-focus-ring);\n}\n\n.swatch {\n /* A paint preview at a fixed 26:18 aspect, not a control box. */\n inline-size: 26px;\n block-size: 18px; /* not-a-control */\n flex: 0 0 auto;\n border-radius: calc(var(--wzl-radius-sm) - var(--wzl-border-w));\n /* Checker under the paint, so a translucent one reads as translucent. */\n background-color: var(--wzl-surface-raised);\n box-shadow: inset 0 0 0 1px var(--wzl-border);\n}\n\n/* No paint to show: the checker stands in rather than an invented color. */\n.swatch[data-empty],\n.trigger[data-mixed] .swatch {\n background: repeating-conic-gradient(\n var(--wzl-checker-a) 0% 25%,\n var(--wzl-checker-b) 0% 50%\n )\n 50% / var(--wzl-checker-size) var(--wzl-checker-size);\n}\n\n.label {\n flex: 1 1 auto;\n min-inline-size: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: start;\n}\n\n.popover {\n outline: none;\n}\n\n.body {\n inline-size: 240px;\n padding: var(--wzl-space-4);\n}\n","import { type ReactElement } from 'react';\nimport {\n Button as RACButton,\n Dialog as RACDialog,\n DialogTrigger,\n Popover as RACPopover,\n} from 'react-aria-components';\nimport { usePaintKind, type FillStyle, type PaintKind } from '@weasel-js/core';\nimport { useOverlayPortal, type OverlayPortalProps } from '../../overlays/portalHost';\nimport { paintPreviewCss } from '../../paintPreview';\nimport { PaintInput } from '../PaintInput';\nimport listbox from '../listbox.module.css';\nimport s from './PaintField.module.css';\n\n/** Props for {@link PaintField}. `onInput` fires throughout a gesture inside\n * the popover and `onChange` once at its end. */\nexport interface PaintFieldProps extends OverlayPortalProps {\n /** The paint being edited. `null` is an explicit \"no paint\"; `undefined` is\n * no value to show. */\n value: FillStyle | null | undefined;\n /** Indeterminate presentation: the trigger says \"Mixed\" and the editor\n * lights no kind. */\n mixed?: boolean;\n /** Dim the trigger — a value is in effect but was never chosen. */\n unset?: boolean;\n /** Restrict the editor's kind bar. Default: every registered kind. */\n kinds?: readonly PaintKind[];\n /** Offer \"None\" in the editor. Default `true`. */\n allowNone?: boolean;\n onInput?: (next: FillStyle | null) => void;\n onChange: (next: FillStyle | null) => void;\n /** Names the paint this field edits — `Fill`, `Color`. */\n 'aria-label'?: string;\n className?: string;\n}\n\n/** What the trigger says it is holding. */\nfunction kindLabel(paint: FillStyle | null | undefined, mixed: boolean, label: string | undefined): string {\n if (mixed) return 'Mixed';\n if (paint === null) return 'None';\n if (paint === undefined) return '—';\n return label ?? (paint.fill ?? 'solid');\n}\n\n/**\n * A whole `FillStyle` in one control slot: a swatch that says which kind it\n * holds, and a popover holding {@link PaintInput}.\n *\n * `PaintInput` itself is a kind bar over a body — six segments and a stop\n * editor — which a property row's control column cannot hold. This is the\n * shape for a narrow slot, and the difference that matters is fidelity: a\n * `ColorField` in that slot reads a gradient's first stop and writes a solid\n * back, so touching the control loses the paint.\n */\nexport function PaintField(props: PaintFieldProps): ReactElement {\n const {\n value, mixed = false, unset = false, kinds, allowNone = true,\n onInput, onChange, className, portalContainer,\n } = props;\n const ariaLabel = props['aria-label'];\n const { anchor, portalProps, ready } = useOverlayPortal(portalContainer);\n const preview = mixed ? undefined : paintPreviewCss(value);\n const label = usePaintKind(value?.fill)?.label;\n\n return (\n <DialogTrigger>\n {anchor}\n <RACButton\n className={[s.trigger, className].filter(Boolean).join(' ')}\n aria-label={ariaLabel}\n {...(unset ? { 'data-unset': '' } : {})}\n {...(mixed ? { 'data-mixed': '' } : {})}\n >\n <span\n className={s.swatch}\n aria-hidden=\"true\"\n {...(preview ? { style: { background: preview } } : { 'data-empty': '' })}\n />\n <span className={s.label}>{kindLabel(value, mixed, label)}</span>\n </RACButton>\n {/* `data-weasel-overlay`: see Select — the popover renders in a portal,\n outside the subtree the trigger sits in. */}\n {ready && (\n <RACPopover className={s.popover} data-weasel-overlay=\"\" {...portalProps}>\n <RACDialog className={`${listbox.surface} ${s.body}`} aria-label={ariaLabel ? `${ariaLabel} editor` : 'Paint editor'}>\n <PaintInput\n value={value}\n mixed={mixed}\n unset={unset}\n kinds={kinds}\n allowNone={allowNone}\n onInput={onInput}\n onChange={onChange}\n aria-label={ariaLabel}\n />\n </RACDialog>\n </RACPopover>\n )}\n </DialogTrigger>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;ACqCA,SAASS,EAAU,GAAqC,GAAgB,GAAmC;CAIzG,OAHIC,IAAc,UACdC,MAAU,OAAa,SACvBA,MAAU,KAAA,IAAkB,MACzBC,KAAUD,EAAM,QAAQ;AACjC;AAYA,SAAgBE,EAAW,GAAsC;CAC/D,IAAM,EACJ,UAAO,WAAQ,IAAO,WAAQ,IAAO,UAAO,eAAY,IACxD,YAAS,aAAU,cAAW,uBAC5BC,GACEC,IAAYD,EAAM,eAClB,EAAE,WAAQ,gBAAa,aAAUT,EAAiBW,CAAe,GACjEC,IAAUP,IAAQ,KAAA,IAAYJ,EAAgBY,CAAK,GACnDN,IAAQO,EAAaD,GAAO,IAAI,CAAC,EAAE;CAEzC,OACE,kBAACE,GAAD,EAAA,UAAA;EACGC;EACD,kBAACrB,GAAD;GACE,WAAW,CAACC,EAAE,SAASsB,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;GAC1D,cAAYR;GACZ,GAAKS,IAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;GACrC,GAAKd,IAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;GAJvC,UAAA,CAME,kBAAC,QAAD;IACE,WAAWT,EAAE;IACb,eAAY;IACZ,GAAKgB,IAAU,EAAE,OAAO,EAAE,YAAYA,EAAQ,EAAE,IAAI,EAAE,cAAc,GAAG;GACxE,CAAA,GACD,kBAAC,QAAD;IAAM,WAAWhB,EAAE;IAAQ,UAAAQ,EAAUS,GAAOR,GAAOE,CAAK;GAAQ,CAAA,CACvD;;EAGVa,KACC,kBAACvB,GAAD;GAAY,WAAWD,EAAE;GAAS,uBAAoB;GAAG,GAAI0B;GAC3D,UAAA,kBAACxB,GAAD;IAAW,WAAW,GAAGC,EAAQ,QAAQ,GAAGH,EAAE;IAAQ,cAAYc,IAAY,GAAGA,EAAU,WAAW;IACpG,UAAA,kBAACR,GAAD;KACS;KACA;KACA;KACA;KACI;KACF;KACC;KACV,cAAYQ;IACb,CAAA;GACQ,CAAA;EACD,CAAA;CAED,EAAA,CAAA;AAEnB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as e, t } from "./Icon-
|
|
1
|
+
import { a as e, t } from "./Icon-BfqYtAX5.js";
|
|
2
2
|
import { n, t as r } from "./ColorField-BwlelY26.js";
|
|
3
|
-
import { t as i } from "./ToggleBar-
|
|
4
|
-
import { r as a } from "./GradientEditor-
|
|
5
|
-
import { t as o } from "./PatternPicker-
|
|
3
|
+
import { t as i } from "./ToggleBar-CfYbMK3x.js";
|
|
4
|
+
import { r as a } from "./GradientEditor-DX4sb1Hf.js";
|
|
5
|
+
import { t as o } from "./PatternPicker-82DCUvUk.js";
|
|
6
6
|
import { getAlpha01 as s, getPaintKind as c, paintAlpha as l, paintWithAlpha as u, solid as d, switchGradientKind as f, toHex8 as p, usePaintKind as m, usePaintKinds as h, withAlpha01 as g } from "@weasel-js/core";
|
|
7
7
|
import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
8
8
|
import { useCallback as b, useRef as x } from "react";
|
|
@@ -129,4 +129,4 @@ function k(s) {
|
|
|
129
129
|
//#endregion
|
|
130
130
|
export { k as t };
|
|
131
131
|
|
|
132
|
-
//# sourceMappingURL=PaintInput-
|
|
132
|
+
//# sourceMappingURL=PaintInput-DSS5IjXn.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PaintInput-CWyOJXUM.js","names":["s","_Fragment","ICON_PATHS","ColorField","ToggleBar","GradientEditor","PatternPicker","PaintInput_module_default","FALLBACK_COLOR","NONE","solidHex8","hex8","toHex8","paint","withAlpha01","getAlpha01","paintAlpha","solidFromField","solid","color","isPattern","kindOf","PaintInput","props","ariaLabel","remembered","useRef","active","mixed","value","valueKind","usePaintKind","entries","usePaintKinds","kinds","entry","segment","icon","id","Icon","label","items","allowNone","currentColor","useCallback","switchKind","kind","seen","converted","switchGradientKind","getPaintKind","onChange","unset","className","renderBody","withOpacity","Fragment","body","OpacityRange","onInput","paintWithAlpha","a01","Editor"],"sources":["../../src/components/PaintInput/PaintInput.module.css","../../src/components/PaintInput/PaintInput.tsx"],"sourcesContent":["/* Kind switch stacked over whichever paint body it selects. */\n.root {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-3);\n min-inline-size: 0;\n}\n\n/* A value is in effect but nobody chose it. Never louder than mixed. */\n.unset {\n opacity: 0.55;\n}\n\n/* A kind with no editor: named, not editable. */\n.noEditor {\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n}\n\n/* The opacity slider under a paint with no single color, laid out as the\n * solid's sits beside its swatch. */\n.opacity {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-3);\n}\n","import { useCallback, useRef, type ReactElement } from 'react';\nimport {\n getAlpha01,\n getPaintKind,\n paintAlpha,\n paintWithAlpha,\n solid,\n switchGradientKind,\n toHex8,\n usePaintKind,\n usePaintKinds,\n withAlpha01,\n type FillStyle,\n type PaintKind,\n} from '@weasel-js/core';\nimport { Icon } from '../../icons/Icon';\nimport { ICON_PATHS, type IconName } from '../../icons/paths';\nimport { ColorField } from '../ColorField';\nimport { OpacityRange } from '../ColorField/OpacityRange';\nimport { GradientEditor } from '../GradientEditor';\nimport { PatternPicker, type PatternFill } from '../PatternPicker';\nimport { ToggleBar, type ToggleBarItem } from '../ToggleBar';\nimport s from './PaintInput.module.css';\n\n/** What a kind with no color of its own seeds from. */\nconst FALLBACK_COLOR = '#000000ff';\n\n/** The bar's answer for \"no paint at all\". Not a registered kind — absence\n * has no seed, no color and nothing to render — so it is this control's own\n * segment rather than a registry entry. */\nconst NONE = 'none';\n\n/** A solid paint as the one `#rrggbbaa` a color field edits. Its alpha lives\n * in `opacity`; a hex alpha left in `color` multiplies with it when painted,\n * so both fold in. */\nfunction solidHex8(paint: FillStyle): string {\n const hex8 = toHex8((paint as { color: string }).color);\n return withAlpha01(hex8.slice(0, 7), getAlpha01(hex8) * paintAlpha(paint));\n}\n\n/** `solid(color)` at the slider's own 1% resolution: the alpha arrives\n * through a hex channel, which would turn 70% into 0.70196. */\nfunction solidFromField(color: string): FillStyle {\n const paint = solid(color);\n return paint.opacity === undefined\n ? paint\n : { ...paint, opacity: Math.round(paint.opacity * 100) / 100 };\n}\n\nfunction isPattern(paint: FillStyle | undefined): paint is PatternFill {\n return paint?.fill === 'pattern';\n}\n\n/** A paint's own discriminant. The solid member leaves `fill` off, and an\n * explicit `null` is the absence of paint rather than an unknown one. */\nfunction kindOf(paint: FillStyle | null | undefined): PaintKind | null {\n if (paint === null) return NONE;\n if (paint === undefined) return null;\n return paint.fill ?? 'solid';\n}\n\n/** Props for {@link PaintInput}. `onInput` fires throughout a gesture and\n * `onChange` once at its end. */\nexport interface PaintInputProps {\n /** The paint being edited. `null` is an explicit \"no paint\"; `undefined`\n * is no value to show. */\n value: FillStyle | null | undefined;\n /** Indeterminate presentation: no kind lit, and the body withheld because\n * there is no single paint to show. */\n mixed?: boolean;\n /** Dim the control — a value is in effect but was never chosen. */\n unset?: boolean;\n /** Restrict the kind bar. Default: every registered kind. */\n kinds?: readonly PaintKind[];\n /** Offer \"None\". Default `true` — the bar answers \"what kind of paint is\n * this?\" and no-paint is one of the answers. Turn it off where the slot\n * cannot express absence. */\n allowNone?: boolean;\n onInput?: (next: FillStyle | null) => void;\n onChange: (next: FillStyle | null) => void;\n /** Names the paint this control edits — `Fill`, `Color`. Carried by the\n * solid body's swatch, which is the part with a value to announce. */\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * Editor for a whole `FillStyle` — a kind bar over whichever body that kind\n * wants.\n *\n * The bar is driven by the paint-kind registry rather than a fixed list, so a\n * consumer's registered kind appears in it and renders that entry's `Editor`.\n * The five built-in kinds keep their branch here: their editors live in this\n * package and `@weasel-js/core`, which owns the registry, cannot import it.\n *\n * Geometry is deliberately absent — on a canvas it belongs on the artwork,\n * via `<SceneGradientHandles>`.\n */\nexport function PaintInput(props: PaintInputProps): ReactElement {\n const {\n value, mixed = false, unset = false, kinds, allowNone = true,\n onInput, onChange, className,\n } = props;\n const ariaLabel = props['aria-label'];\n\n // Per-kind memory, so linear → solid → linear comes back with its stops.\n // A ref, not state: it must not survive the control being pointed at a\n // different selection, and nothing renders off it directly.\n const remembered = useRef(new Map<PaintKind, FillStyle>());\n\n const active = mixed ? null : kindOf(value);\n if (value != null && active !== null) remembered.current.set(active, value);\n\n const valueKind = usePaintKind(value?.fill);\n const entries = usePaintKinds().filter(\n (entry) => kinds === undefined || kinds.includes(entry.id),\n );\n const segment = (id: string, label: string, icon: string | undefined): ToggleBarItem<PaintKind> =>\n icon && icon in ICON_PATHS\n // Icon-only: six labelled segments do not fit a property row, and the\n // full label stays the accessible name.\n // 14 to match the panel's other glyph segments. A `sm` bar is 17px tall\n // over 1px of padding, so 15 fills the segment box edge to edge.\n ? { value: id, label: <Icon name={icon as IconName} size={14} />, ariaLabel: label }\n : { value: id, label };\n\n const items: readonly ToggleBarItem<PaintKind>[] = [\n ...(allowNone ? [segment(NONE, 'None', 'paintNone')] : []),\n ...entries.map((entry) => segment(entry.id, entry.label, entry.icon)),\n ];\n\n /** The color a switch seeds from: whatever the current paint shows. */\n const currentColor = useCallback((): string => {\n if (value == null) return FALLBACK_COLOR;\n return valueKind?.colorOf(value) ?? FALLBACK_COLOR;\n }, [value, valueKind]);\n\n const switchKind = (kind: PaintKind): void => {\n if (kind === active) return;\n if (kind === NONE) {\n onChange(null);\n return;\n }\n const seen = remembered.current.get(kind);\n if (seen !== undefined) {\n onChange(seen);\n return;\n }\n const converted = value != null ? switchGradientKind(value, kind) : undefined;\n if (converted !== undefined) {\n onChange(converted);\n return;\n }\n const entry = getPaintKind(kind);\n if (entry) onChange(entry.seed(currentColor()));\n };\n\n return (\n <div\n className={[s.root, unset && s.unset, className].filter(Boolean).join(' ')}\n title={unset ? 'Not set' : undefined}\n >\n <ToggleBar<PaintKind>\n items={items}\n value={active}\n size=\"sm\"\n ariaLabel=\"Paint kind\"\n onChange={(kind) => kind && switchKind(kind)}\n />\n {renderBody()}\n </div>\n );\n\n /** A solid's alpha rides its swatch; every other kind has no one color to\n * carry it, so its `opacity` gets the same slider under the body. */\n function withOpacity(paint: FillStyle, body: ReactElement): ReactElement {\n return (\n <>\n {body}\n <div className={s.opacity}>\n <OpacityRange\n value={paintAlpha(paint)}\n aria-label={ariaLabel}\n onInput={(a01) => onInput?.(paintWithAlpha(paint, a01))}\n onChange={(a01) => onChange(paintWithAlpha(paint, a01))}\n />\n </div>\n </>\n );\n }\n\n function renderBody(): ReactElement | null {\n if (mixed || value === undefined) {\n return (\n <ColorField\n mixed\n aria-label={ariaLabel}\n onChange={(color) => onChange(solidFromField(color))}\n />\n );\n }\n // Absence has nothing to edit. The lit segment is the whole statement.\n if (value === null) return null;\n // A registered `Editor` wins even for a built-in id: re-registering one is\n // how a consumer replaces a kit control, and the built-in branches below\n // are the fallback for the ids that ship without an entry editor.\n if (valueKind?.Editor) {\n const Editor = valueKind.Editor;\n return withOpacity(value, <Editor value={value} onInput={onInput} onChange={onChange} />);\n }\n if (valueKind?.stopsOf) {\n return withOpacity(value, (\n <GradientEditor\n value={value}\n kindSwitch={false}\n onInput={onInput}\n onChange={onChange}\n />\n ));\n }\n if (isPattern(value)) {\n return withOpacity(\n value,\n <PatternPicker value={value} color={currentColor()} onChange={onChange} />,\n );\n }\n const kind = kindOf(value);\n if (kind !== 'solid') {\n // Editing a paint this control cannot represent would overwrite it, so\n // a kind with no editor is shown and left alone.\n return <div className={s.noEditor}>{valueKind?.label ?? kind}: no editor</div>;\n }\n return (\n <ColorField\n value={solidHex8(value)}\n alpha\n aria-label={ariaLabel}\n onInput={(color) => onInput?.(solidFromField(color))}\n onChange={(color) => onChange(solidFromField(color))}\n />\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PaintInput-DSS5IjXn.js","names":["s","_Fragment","ICON_PATHS","ColorField","ToggleBar","GradientEditor","PatternPicker","PaintInput_module_default","FALLBACK_COLOR","NONE","solidHex8","hex8","toHex8","paint","withAlpha01","getAlpha01","paintAlpha","solidFromField","solid","color","isPattern","kindOf","PaintInput","props","ariaLabel","remembered","useRef","active","mixed","value","valueKind","usePaintKind","entries","usePaintKinds","kinds","entry","segment","icon","id","Icon","label","items","allowNone","currentColor","useCallback","switchKind","kind","seen","converted","switchGradientKind","getPaintKind","onChange","unset","className","renderBody","withOpacity","Fragment","body","OpacityRange","onInput","paintWithAlpha","a01","Editor"],"sources":["../../src/components/PaintInput/PaintInput.module.css","../../src/components/PaintInput/PaintInput.tsx"],"sourcesContent":["/* Kind switch stacked over whichever paint body it selects. */\n.root {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-3);\n min-inline-size: 0;\n}\n\n/* A value is in effect but nobody chose it. Never louder than mixed. */\n.unset {\n opacity: 0.55;\n}\n\n/* A kind with no editor: named, not editable. */\n.noEditor {\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n}\n\n/* The opacity slider under a paint with no single color, laid out as the\n * solid's sits beside its swatch. */\n.opacity {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-3);\n}\n","import { useCallback, useRef, type ReactElement } from 'react';\nimport {\n getAlpha01,\n getPaintKind,\n paintAlpha,\n paintWithAlpha,\n solid,\n switchGradientKind,\n toHex8,\n usePaintKind,\n usePaintKinds,\n withAlpha01,\n type FillStyle,\n type PaintKind,\n} from '@weasel-js/core';\nimport { Icon } from '../../icons/Icon';\nimport { ICON_PATHS, type IconName } from '../../icons/paths';\nimport { ColorField } from '../ColorField';\nimport { OpacityRange } from '../ColorField/OpacityRange';\nimport { GradientEditor } from '../GradientEditor';\nimport { PatternPicker, type PatternFill } from '../PatternPicker';\nimport { ToggleBar, type ToggleBarItem } from '../ToggleBar';\nimport s from './PaintInput.module.css';\n\n/** What a kind with no color of its own seeds from. */\nconst FALLBACK_COLOR = '#000000ff';\n\n/** The bar's answer for \"no paint at all\". Not a registered kind — absence\n * has no seed, no color and nothing to render — so it is this control's own\n * segment rather than a registry entry. */\nconst NONE = 'none';\n\n/** A solid paint as the one `#rrggbbaa` a color field edits. Its alpha lives\n * in `opacity`; a hex alpha left in `color` multiplies with it when painted,\n * so both fold in. */\nfunction solidHex8(paint: FillStyle): string {\n const hex8 = toHex8((paint as { color: string }).color);\n return withAlpha01(hex8.slice(0, 7), getAlpha01(hex8) * paintAlpha(paint));\n}\n\n/** `solid(color)` at the slider's own 1% resolution: the alpha arrives\n * through a hex channel, which would turn 70% into 0.70196. */\nfunction solidFromField(color: string): FillStyle {\n const paint = solid(color);\n return paint.opacity === undefined\n ? paint\n : { ...paint, opacity: Math.round(paint.opacity * 100) / 100 };\n}\n\nfunction isPattern(paint: FillStyle | undefined): paint is PatternFill {\n return paint?.fill === 'pattern';\n}\n\n/** A paint's own discriminant. The solid member leaves `fill` off, and an\n * explicit `null` is the absence of paint rather than an unknown one. */\nfunction kindOf(paint: FillStyle | null | undefined): PaintKind | null {\n if (paint === null) return NONE;\n if (paint === undefined) return null;\n return paint.fill ?? 'solid';\n}\n\n/** Props for {@link PaintInput}. `onInput` fires throughout a gesture and\n * `onChange` once at its end. */\nexport interface PaintInputProps {\n /** The paint being edited. `null` is an explicit \"no paint\"; `undefined`\n * is no value to show. */\n value: FillStyle | null | undefined;\n /** Indeterminate presentation: no kind lit, and the body withheld because\n * there is no single paint to show. */\n mixed?: boolean;\n /** Dim the control — a value is in effect but was never chosen. */\n unset?: boolean;\n /** Restrict the kind bar. Default: every registered kind. */\n kinds?: readonly PaintKind[];\n /** Offer \"None\". Default `true` — the bar answers \"what kind of paint is\n * this?\" and no-paint is one of the answers. Turn it off where the slot\n * cannot express absence. */\n allowNone?: boolean;\n onInput?: (next: FillStyle | null) => void;\n onChange: (next: FillStyle | null) => void;\n /** Names the paint this control edits — `Fill`, `Color`. Carried by the\n * solid body's swatch, which is the part with a value to announce. */\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * Editor for a whole `FillStyle` — a kind bar over whichever body that kind\n * wants.\n *\n * The bar is driven by the paint-kind registry rather than a fixed list, so a\n * consumer's registered kind appears in it and renders that entry's `Editor`.\n * The five built-in kinds keep their branch here: their editors live in this\n * package and `@weasel-js/core`, which owns the registry, cannot import it.\n *\n * Geometry is deliberately absent — on a canvas it belongs on the artwork,\n * via `<SceneGradientHandles>`.\n */\nexport function PaintInput(props: PaintInputProps): ReactElement {\n const {\n value, mixed = false, unset = false, kinds, allowNone = true,\n onInput, onChange, className,\n } = props;\n const ariaLabel = props['aria-label'];\n\n // Per-kind memory, so linear → solid → linear comes back with its stops.\n // A ref, not state: it must not survive the control being pointed at a\n // different selection, and nothing renders off it directly.\n const remembered = useRef(new Map<PaintKind, FillStyle>());\n\n const active = mixed ? null : kindOf(value);\n if (value != null && active !== null) remembered.current.set(active, value);\n\n const valueKind = usePaintKind(value?.fill);\n const entries = usePaintKinds().filter(\n (entry) => kinds === undefined || kinds.includes(entry.id),\n );\n const segment = (id: string, label: string, icon: string | undefined): ToggleBarItem<PaintKind> =>\n icon && icon in ICON_PATHS\n // Icon-only: six labelled segments do not fit a property row, and the\n // full label stays the accessible name.\n // 14 to match the panel's other glyph segments. A `sm` bar is 17px tall\n // over 1px of padding, so 15 fills the segment box edge to edge.\n ? { value: id, label: <Icon name={icon as IconName} size={14} />, ariaLabel: label }\n : { value: id, label };\n\n const items: readonly ToggleBarItem<PaintKind>[] = [\n ...(allowNone ? [segment(NONE, 'None', 'paintNone')] : []),\n ...entries.map((entry) => segment(entry.id, entry.label, entry.icon)),\n ];\n\n /** The color a switch seeds from: whatever the current paint shows. */\n const currentColor = useCallback((): string => {\n if (value == null) return FALLBACK_COLOR;\n return valueKind?.colorOf(value) ?? FALLBACK_COLOR;\n }, [value, valueKind]);\n\n const switchKind = (kind: PaintKind): void => {\n if (kind === active) return;\n if (kind === NONE) {\n onChange(null);\n return;\n }\n const seen = remembered.current.get(kind);\n if (seen !== undefined) {\n onChange(seen);\n return;\n }\n const converted = value != null ? switchGradientKind(value, kind) : undefined;\n if (converted !== undefined) {\n onChange(converted);\n return;\n }\n const entry = getPaintKind(kind);\n if (entry) onChange(entry.seed(currentColor()));\n };\n\n return (\n <div\n className={[s.root, unset && s.unset, className].filter(Boolean).join(' ')}\n title={unset ? 'Not set' : undefined}\n >\n <ToggleBar<PaintKind>\n items={items}\n value={active}\n size=\"sm\"\n ariaLabel=\"Paint kind\"\n onChange={(kind) => kind && switchKind(kind)}\n />\n {renderBody()}\n </div>\n );\n\n /** A solid's alpha rides its swatch; every other kind has no one color to\n * carry it, so its `opacity` gets the same slider under the body. */\n function withOpacity(paint: FillStyle, body: ReactElement): ReactElement {\n return (\n <>\n {body}\n <div className={s.opacity}>\n <OpacityRange\n value={paintAlpha(paint)}\n aria-label={ariaLabel}\n onInput={(a01) => onInput?.(paintWithAlpha(paint, a01))}\n onChange={(a01) => onChange(paintWithAlpha(paint, a01))}\n />\n </div>\n </>\n );\n }\n\n function renderBody(): ReactElement | null {\n if (mixed || value === undefined) {\n return (\n <ColorField\n mixed\n aria-label={ariaLabel}\n onChange={(color) => onChange(solidFromField(color))}\n />\n );\n }\n // Absence has nothing to edit. The lit segment is the whole statement.\n if (value === null) return null;\n // A registered `Editor` wins even for a built-in id: re-registering one is\n // how a consumer replaces a kit control, and the built-in branches below\n // are the fallback for the ids that ship without an entry editor.\n if (valueKind?.Editor) {\n const Editor = valueKind.Editor;\n return withOpacity(value, <Editor value={value} onInput={onInput} onChange={onChange} />);\n }\n if (valueKind?.stopsOf) {\n return withOpacity(value, (\n <GradientEditor\n value={value}\n kindSwitch={false}\n onInput={onInput}\n onChange={onChange}\n />\n ));\n }\n if (isPattern(value)) {\n return withOpacity(\n value,\n <PatternPicker value={value} color={currentColor()} onChange={onChange} />,\n );\n }\n const kind = kindOf(value);\n if (kind !== 'solid') {\n // Editing a paint this control cannot represent would overwrite it, so\n // a kind with no editor is shown and left alone.\n return <div className={s.noEditor}>{valueKind?.label ?? kind}: no editor</div>;\n }\n return (\n <ColorField\n value={solidHex8(value)}\n alpha\n aria-label={ariaLabel}\n onInput={(color) => onInput?.(solidFromField(color))}\n onChange={(color) => onChange(solidFromField(color))}\n />\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./ToggleBar-
|
|
1
|
+
import { t as e } from "./ToggleBar-CfYbMK3x.js";
|
|
2
2
|
import { r as t } from "./NumberField-BXFrOi5M.js";
|
|
3
3
|
import { composePatternTransform as n, decomposePatternTransform as r } from "@weasel-js/core";
|
|
4
4
|
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
@@ -132,4 +132,4 @@ function _(n) {
|
|
|
132
132
|
//#endregion
|
|
133
133
|
export { g as n, _ as t };
|
|
134
134
|
|
|
135
|
-
//# sourceMappingURL=PatternPicker-
|
|
135
|
+
//# sourceMappingURL=PatternPicker-82DCUvUk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PatternPicker-
|
|
1
|
+
{"version":3,"file":"PatternPicker-82DCUvUk.js","names":["s","ToggleBar","NumberField","PatternPicker_module_default","TILES","TILE_SIZES","DEFAULT_TILE_SIZE","PREVIEW_SIZE","DEGREES","toDegrees","folded","rad","withRotation","parts","decomposePatternTransform","value","b","c","d","composePatternTransform","degrees","_drop","rest","specOf","fill","seedPattern","spec","from","tile","PatternPicker","props","size","pick","seeded","color","resize","onChange","nextSize","className","preview","selected","tilePreviewCssUrl","v","deg"],"sources":["../../src/components/PatternPicker/PatternPicker.module.css","../../src/components/PatternPicker/PatternPicker.tsx"],"sourcesContent":["/* Tile grid over the size switch. */\n.root {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-3);\n min-inline-size: 0;\n}\n\n.grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(var(--wzl-swatch-size, 28px), 1fr));\n gap: 0;\n}\n\n/* The swatch's whole face is its own tile, so it must not carry a flat\n background — and the tile repeats at its own scale, not the swatch's. */\n.swatch {\n width: 100%;\n aspect-ratio: 1 / 1;\n min-width: 0;\n padding: 0;\n border: 0.5px solid var(--wzl-border);\n border-radius: 0;\n /* Not the UA's buttontext: the hover edge is --wzl-fg-muted, a step down from the text beside it. */\n color: inherit;\n cursor: pointer;\n background-color: var(--wzl-surface-sunken);\n background-image: var(--tile-preview);\n background-repeat: repeat;\n background-size: 16px 16px;\n background-clip: padding-box;\n}\n\n.swatch:hover {\n border-color: var(--wzl-fg-muted);\n}\n\n.swatchActive {\n border-color: var(--wzl-accent);\n box-shadow: 0 0 0 1px var(--wzl-accent);\n}\n","import type { ReactElement } from 'react';\nimport type { CSSProperties } from 'react';\nimport {\n composePatternTransform,\n decomposePatternTransform,\n type FillStyle,\n type TilePatternSpec,\n} from '@weasel-js/core';\nimport { tilePreviewCssUrl } from '@weasel-js/svg';\nimport { NumberField } from '../NumberField';\nimport { ToggleBar } from '../ToggleBar';\nimport s from './PatternPicker.module.css';\n\n/** The `pattern` member of the paint union. */\nexport type PatternFill = Extract<FillStyle, { fill: 'pattern' }>;\n\nconst TILES: readonly TilePatternSpec['tile'][] = ['hatch', 'crosshatch', 'dots', 'chunks'];\n\n/** Tile sizes the picker offers, coarse enough that each reads as a\n * distinct texture rather than a nudge. */\nconst TILE_SIZES: readonly { value: number; label: string }[] = [\n { value: 4, label: 'S' },\n { value: 8, label: 'M' },\n { value: 16, label: 'L' },\n { value: 32, label: 'XL' },\n];\n\nconst DEFAULT_TILE_SIZE = 8;\n\n/** Every swatch previews at one size so the grid compares tiles, not scales. */\nconst PREVIEW_SIZE = 16;\n\nconst DEGREES: Intl.NumberFormatOptions = { style: 'unit', unit: 'degree', unitDisplay: 'narrow', maximumFractionDigits: 1 };\n\n/** Rotation in degrees, folded into (-180, 180]. */\nfunction toDegrees(rad: number): number {\n const deg = (rad * 180) / Math.PI;\n const folded = ((((deg + 180) % 360) + 360) % 360) - 180;\n return folded === -180 ? 180 : folded;\n}\n\n/** `value` with its transform's rotation replaced, the transform dropped when\n * nothing is left of it. */\nfunction withRotation(value: PatternFill, degrees: number): PatternFill {\n const parts = decomposePatternTransform(value.transform);\n const [a, b, c, d] = composePatternTransform({ ...parts, rotation: (degrees * Math.PI) / 180 });\n const { transform: _drop, ...rest } = value;\n const identity = Math.abs(a - 1) < 1e-9 && Math.abs(b) < 1e-9 && Math.abs(c) < 1e-9 && Math.abs(d - 1) < 1e-9;\n return identity ? rest : { ...rest, transform: [a, b, c, d] };\n}\n\n/** The spec a pattern paint carries, if it carries one. A consumer-built\n * `TextureHandle` has no spec, so the picker shows no tile selected and\n * replaces it wholesale on the next click. */\nfunction specOf(fill: PatternFill): TilePatternSpec | null {\n return 'tile' in fill.pattern ? fill.pattern : null;\n}\n\n/**\n * A pattern seeded from a color. `units: 'bounds'` anchors the tile to the\n * node's box, so the texture travels with the shape.\n */\nexport function seedPattern(\n tile: TilePatternSpec['tile'],\n from: string,\n size: number = DEFAULT_TILE_SIZE,\n): PatternFill {\n const spec: TilePatternSpec = { tile, color: from, size };\n // `chunks` is a scatter over a ground rather than a line texture; without a\n // background it reads as loose specks on whatever sits beneath.\n if (tile === 'chunks') spec.bg = '#00000000';\n return { fill: 'pattern', pattern: spec, units: 'bounds' };\n}\n\n/** Props for {@link PatternPicker}. */\nexport interface PatternPickerProps {\n /** The pattern paint being edited. */\n value: PatternFill;\n /** The color new tiles are seeded with — the paint's own, normally. */\n color: string;\n /** Committed value: one call per click. A tile pick, a size change and a\n * committed rotation are each a complete gesture, so there is no `onInput`. */\n onChange: (next: PatternFill) => void;\n className?: string;\n}\n\n/**\n * Grid of tile swatches over a size switch and a rotation field, each swatch\n * previewing the real tile at the current color. Rotation edits only the\n * rotation part of the paint's `transform`; scale and skew survive it.\n *\n * The preview shares its shape mapper with what the renderer paints, so a\n * swatch cannot drift from the texture it selects.\n */\nexport function PatternPicker(props: PatternPickerProps): ReactElement {\n const { value, color, onChange, className } = props;\n const spec = specOf(value);\n const size = spec?.size ?? DEFAULT_TILE_SIZE;\n\n const pick = (tile: TilePatternSpec['tile']): void => {\n const seeded = seedPattern(tile, color, size);\n onChange(value.transform ? { ...seeded, transform: value.transform } : seeded);\n };\n\n const resize = (nextSize: number): void => {\n if (!spec) return;\n onChange({ ...value, pattern: { ...spec, size: nextSize } });\n };\n\n return (\n <div className={[s.root, className].filter(Boolean).join(' ')}>\n <div className={s.grid}>\n {TILES.map((tile) => {\n const preview: TilePatternSpec = { tile, color, size: PREVIEW_SIZE };\n if (tile === 'chunks') preview.bg = '#00000000';\n const selected = spec?.tile === tile;\n return (\n <button\n key={tile}\n type=\"button\"\n className={[s.swatch, selected && s.swatchActive].filter(Boolean).join(' ')}\n style={{ ['--tile-preview' as string]: tilePreviewCssUrl(preview) } as CSSProperties}\n title={tile}\n aria-label={tile}\n aria-pressed={selected}\n onClick={() => pick(tile)}\n />\n );\n })}\n </div>\n <ToggleBar<number>\n items={TILE_SIZES}\n value={size}\n size=\"sm\"\n ariaLabel=\"Tile size\"\n onChange={(v) => v != null && resize(v)}\n />\n <NumberField\n label=\"Rotation\"\n orientation=\"row\"\n width=\"fit\"\n value={toDegrees(decomposePatternTransform(value.transform).rotation)}\n step={15}\n formatOptions={DEGREES}\n onChange={(deg) => Number.isFinite(deg) && onChange(withRotation(value, deg))}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;GCgBMI,IAA4C;CAAC;CAAS;CAAc;CAAQ;AAAQ,GAIpFC,IAA0D;CAC9D;EAAE,OAAO;EAAG,OAAO;CAAI;CACvB;EAAE,OAAO;EAAG,OAAO;CAAI;CACvB;EAAE,OAAO;EAAI,OAAO;CAAI;CACxB;EAAE,OAAO;EAAI,OAAO;CAAK;AAC3B,GAEMC,IAAoB,GAGpBC,IAAe,IAEfC,IAAoC;CAAE,OAAO;CAAQ,MAAM;CAAU,aAAa;CAAU,uBAAuB;AAAE;AAG3H,SAASC,EAAU,GAAqB;CAEtC,IAAMC,MADOC,IAAM,MAAO,KAAK,KACN,OAAO,MAAO,OAAO,MAAO;CACrD,OAAOD,MAAW,OAAO,MAAMA;AACjC;AAIA,SAASE,EAAa,GAAoB,GAA8B;CACtE,IAAMC,IAAQC,EAA0BC,EAAM,SAAS,GACjD,CAAC,GAAGC,GAAGC,GAAGC,KAAKC,EAAwB;EAAE,GAAGN;EAAO,UAAWO,IAAU,KAAK,KAAM;CAAI,CAAC,GACxF,EAAE,WAAWC,GAAO,GAAGC,MAASP;CAEtC,OADiB,KAAK,IAAI,IAAI,CAAC,IAAI,QAAQ,KAAK,IAAIC,CAAC,IAAI,QAAQ,KAAK,IAAIC,CAAC,IAAI,QAAQ,KAAK,IAAIC,IAAI,CAAC,IAAI,OACvFI,IAAO;EAAE,GAAGA;EAAM,WAAW;GAAC;GAAGN;GAAGC;GAAGC;EAAC;CAAE;AAC9D;AAKA,SAASK,EAAO,GAA2C;CACzD,OAAO,UAAUC,EAAK,UAAUA,EAAK,UAAU;AACjD;AAMA,SAAgBC,EACd,GACA,GACA,IAAenB,GACF;CACb,IAAMoB,IAAwB;EAAE;EAAM,OAAOC;EAAM;CAAK;CAIxD,OADIC,MAAS,aAAU,EAAK,KAAK,cAC1B;EAAE,MAAM;EAAW,SAASF;EAAM,OAAO;CAAS;AAC3D;AAsBA,SAAgBG,EAAc,GAAyC;CACrE,IAAM,EAAE,UAAO,UAAO,aAAU,iBAAcC,GACxCJ,IAAOH,EAAOR,CAAK,GACnBgB,IAAOL,GAAM,QAAQpB,GAErB0B,KAAQ,MAAwC;EACpD,IAAMC,IAASR,EAAYG,GAAMM,GAAOH,CAAI;EAC5C,EAAShB,EAAM,YAAY;GAAE,GAAGkB;GAAQ,WAAWlB,EAAM;EAAU,IAAIkB,CAAM;CAC/E,GAEME,KAAU,MAA2B;EACzC,AAAKT,KACLU,EAAS;GAAE,GAAGrB;GAAO,SAAS;IAAE,GAAGW;IAAM,MAAMW;GAAS;EAAE,CAAC;CAC7D;CAEA,OACE,kBAAC,OAAD;EAAK,WAAW,CAACrC,EAAE,MAAMsC,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAA5D,UAAA;GACE,kBAAC,OAAD;IAAK,WAAWtC,EAAE;IACf,UAAAI,EAAM,KAAK,MAAS;KACnB,IAAMmC,IAA2B;MAAE;MAAM;MAAO,MAAMhC;KAAa;KACnE,AAAIqB,MAAS,aAAU,EAAQ,KAAK;KACpC,IAAMY,IAAWd,GAAM,SAASE;KAChC,OACE,kBAAC,UAAD;MAEE,MAAK;MACL,WAAW,CAAC5B,EAAE,QAAQwC,KAAYxC,EAAE,YAAY,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;MAC1E,OAAO,EAAG,kBAA6ByC,EAAkBF,CAAO,EAAE;MAClE,OAAOX;MACP,cAAYA;MACZ,gBAAcY;MACd,eAAeR,EAAKJ,CAAI;KACzB,GARMA,CAQN;IAEL,CAAC;GACE,CAAA;GACL,kBAAC3B,GAAD;IACE,OAAOI;IACP,OAAO0B;IACP,MAAK;IACL,WAAU;IACV,WAAW,MAAMW,KAAK,QAAQP,EAAOO,CAAC;GACvC,CAAA;GACD,kBAACxC,GAAD;IACE,OAAM;IACN,aAAY;IACZ,OAAM;IACN,OAAOO,EAAUK,EAA0BC,EAAM,SAAS,CAAC,CAAC,QAAQ;IACpE,MAAM;IACN,eAAeP;IACf,WAAW,MAAQ,OAAO,SAASmC,CAAG,KAAKP,EAASxB,EAAaG,GAAO4B,CAAG,CAAC;GAC7E,CAAA;EACE;;AAET"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./Badge-
|
|
1
|
+
import { t as e } from "./Badge-4ShpqA0h.js";
|
|
2
2
|
import { jsx as t } from "react/jsx-runtime";
|
|
3
3
|
var n = {
|
|
4
4
|
row: "_row_1a09e_1",
|
|
@@ -39,4 +39,4 @@ function r({ segments: r, startCap: i = "flat", size: a, variant: o, depth: s, g
|
|
|
39
39
|
//#endregion
|
|
40
40
|
export { r as t };
|
|
41
41
|
|
|
42
|
-
//# sourceMappingURL=Powerline-
|
|
42
|
+
//# sourceMappingURL=Powerline-CogJv9VU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Powerline-
|
|
1
|
+
{"version":3,"file":"Powerline-CogJv9VU.js","names":["s","Badge","Powerline_module_default","Powerline","rest","cls","className","style","gap","segments","leftEdge","i","startCap","rightEdge","seg","depth","variant","size"],"sources":["../../src/components/Powerline/Powerline.module.css","../../src/components/Powerline/Powerline.tsx"],"sourcesContent":[".row {\n display: inline-flex;\n align-items: stretch;\n gap: var(--powerline-gap, 0.2em);\n}\n\n.matrix {\n display: grid;\n gap: var(--wzl-space-6);\n}\n\n/* Reset Badge's opinionated text defaults — Powerline segments should pick up\n * the surrounding text style instead of forcing uppercase / 10px / extra\n * tracking. Consumers can still override via className on Powerline. */\n.segment {\n font-size: inherit;\n text-transform: none;\n letter-spacing: normal;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { Badge } from '../Badge/Badge';\nimport type { BadgeSize, BadgeStatus, BadgeVariant } from '../Badge/types';\nimport type { StanceProps } from '../stance';\nimport type { EdgeCap } from '../Badge/bases/edgeProfiles';\nimport s from './Powerline.module.css';\n\n/**\n * One segment of a {@link Powerline}. Giving it `onClick` or `href` makes it\n * interactive, the same way it does on a `Badge`.\n */\nexport interface PowerlineSegment extends StanceProps {\n text: ReactNode;\n /** Cap on this segment's right edge. Next segment's left edge adopts the same profile. */\n endCap?: EdgeCap;\n status?: BadgeStatus;\n variant?: BadgeVariant;\n size?: BadgeSize;\n onClick?: () => void;\n href?: string;\n 'aria-label'?: string;\n}\n\n/** Props for {@link Powerline}. */\nexport interface PowerlineProps {\n segments: PowerlineSegment[];\n /** Left edge of the first segment. Defaults to 'flat'. */\n startCap?: EdgeCap;\n /** Default size for every segment (per-segment `size` wins). */\n size?: BadgeSize;\n /** Default variant for every segment (per-segment `variant` wins). */\n variant?: BadgeVariant;\n /** Protrusion depth in CSS px, passed through to every segment's base. */\n depth?: number;\n /** Visible gap between adjacent segments. Number → px; string → literal CSS length.\n * Default: `0.2em` (scales with the row's font size). Pass `0` for flush. */\n gap?: number | string;\n className?: string;\n 'aria-label'?: string;\n}\n\n/**\n * A row of chevron-linked badge segments, in the style of a shell powerline\n * prompt. Each segment's `endCap` shapes both its own right edge and the next\n * segment's left edge, so the run reads as one continuous chain.\n *\n * Built for showing a path through a sequence of steps — the inspector uses\n * it to display how input routes from tool to gesture to action to target.\n */\nexport function Powerline({\n segments,\n startCap = 'flat',\n size,\n variant,\n depth,\n gap,\n className,\n ...rest\n}: PowerlineProps) {\n const cls = [s.row, className].filter(Boolean).join(' ');\n const style: CSSProperties | undefined = gap !== undefined\n ? { ['--powerline-gap' as never]: typeof gap === 'number' ? `${gap}px` : gap }\n : undefined;\n return (\n <span className={cls} style={style} aria-label={rest['aria-label']}>\n {segments.map((seg, i) => {\n const leftEdge: EdgeCap = i === 0 ? startCap : (segments[i - 1].endCap ?? 'flat');\n const rightEdge: EdgeCap = seg.endCap ?? 'flat';\n return (\n <Badge\n key={i}\n base=\"powerline\"\n baseParams={{ leftEdge, rightEdge, ...(depth !== undefined && { depth }) }}\n status={seg.status}\n stance={seg.stance}\n tone={seg.tone}\n variant={seg.variant ?? variant}\n size={seg.size ?? size}\n onClick={seg.onClick}\n href={seg.href}\n aria-label={seg['aria-label']}\n className={s.segment}\n >\n {seg.text}\n </Badge>\n );\n })}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;ACiDA,SAAgBG,EAAU,EACxB,aACA,cAAW,QACX,SACA,YACA,UACA,QACA,cACA,GAAGC,KACc;CACjB,IAAMC,IAAM,CAACL,EAAE,KAAKM,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,GACjDC,IAAmCC,MAAQ,KAAA,IAE7C,KAAA,IADA,EAAG,mBAA6B,OAAOA,KAAQ,WAAW,GAAGA,EAAI,MAAMA,EAAI;CAE/E,OACE,kBAAC,QAAD;EAAM,WAAWH;EAAY;EAAO,cAAYD,EAAK;EAClD,UAAAK,EAAS,KAAK,GAAK,MAAM;GACxB,IAAMC,IAAoBC,MAAM,IAAIC,IAAYH,EAASE,IAAI,EAAE,CAAC,UAAU,QACpEE,IAAqBC,EAAI,UAAU;GACzC,OACE,kBAACb,GAAD;IAEE,MAAK;IACL,YAAY;KAAE;KAAU;KAAW,GAAIc,MAAU,KAAA,KAAa,EAAE,SAAM;IAAG;IACzE,QAAQD,EAAI;IACZ,QAAQA,EAAI;IACZ,MAAMA,EAAI;IACV,SAASA,EAAI,WAAWE;IACxB,MAAMF,EAAI,QAAQG;IAClB,SAASH,EAAI;IACb,MAAMA,EAAI;IACV,cAAYA,EAAI;IAChB,WAAWd,EAAE;IAEZ,UAAAc,EAAI;GACA,GAdAH,CAcA;EAEX,CAAC;CACG,CAAA;AAEV"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as e } from "./Dialog-
|
|
2
|
-
import { c as t, t as n } from "./PropertyField-
|
|
1
|
+
import { t as e } from "./Dialog-Du4POZ52.js";
|
|
2
|
+
import { c as t, t as n } from "./PropertyField-CLbUOynA.js";
|
|
3
3
|
import { t as r } from "./Input-D7SDKbST.js";
|
|
4
4
|
import { t as i } from "./useRovingTabIndex-D7u22Ia_.js";
|
|
5
|
-
import { a, n as o, o as s, r as c, s as l, t as u } from "./prefField-
|
|
5
|
+
import { a, n as o, o as s, r as c, s as l, t as u } from "./prefField-DPPbAmRR.js";
|
|
6
6
|
import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
7
7
|
import { useCallback as m, useEffect as h, useMemo as g, useRef as _, useState as v } from "react";
|
|
8
8
|
//#region src/useScrollSpy.ts
|
|
@@ -67,43 +67,43 @@ function S() {
|
|
|
67
67
|
return typeof matchMedia == "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
68
68
|
}
|
|
69
69
|
var C = {
|
|
70
|
-
columns: "
|
|
71
|
-
column: "
|
|
72
|
-
panel: "
|
|
73
|
-
subpanel: "
|
|
74
|
-
groupHeader: "
|
|
75
|
-
groupTitle: "
|
|
76
|
-
groupDesc: "
|
|
77
|
-
rows: "
|
|
78
|
-
row: "
|
|
79
|
-
rowControl: "
|
|
80
|
-
unrenderable: "
|
|
81
|
-
titleRow: "
|
|
82
|
-
objectLeaf: "
|
|
83
|
-
objectRow: "
|
|
84
|
-
objectGroup: "
|
|
85
|
-
columnsLayout: "
|
|
86
|
-
railLayout: "
|
|
87
|
-
railBody: "
|
|
88
|
-
rail: "
|
|
89
|
-
railList: "
|
|
90
|
-
railItem: "
|
|
91
|
-
railSub: "
|
|
92
|
-
railOpen: "
|
|
93
|
-
railInView: "
|
|
94
|
-
railName: "
|
|
95
|
-
railCount: "
|
|
96
|
-
pane: "
|
|
97
|
-
paneHead: "
|
|
98
|
-
paneTitle: "
|
|
99
|
-
paneDesc: "
|
|
100
|
-
paneSection: "
|
|
101
|
-
paneSubsection: "
|
|
102
|
-
sectionTitle: "
|
|
103
|
-
subsectionTitle: "
|
|
104
|
-
filter: "
|
|
105
|
-
noMatches: "
|
|
106
|
-
clearFilter: "
|
|
70
|
+
columns: "_columns_jrbkm_5",
|
|
71
|
+
column: "_column_jrbkm_5",
|
|
72
|
+
panel: "_panel_jrbkm_23",
|
|
73
|
+
subpanel: "_subpanel_jrbkm_34",
|
|
74
|
+
groupHeader: "_groupHeader_jrbkm_46",
|
|
75
|
+
groupTitle: "_groupTitle_jrbkm_59",
|
|
76
|
+
groupDesc: "_groupDesc_jrbkm_68",
|
|
77
|
+
rows: "_rows_jrbkm_75",
|
|
78
|
+
row: "_row_jrbkm_75",
|
|
79
|
+
rowControl: "_rowControl_jrbkm_90",
|
|
80
|
+
unrenderable: "_unrenderable_jrbkm_97",
|
|
81
|
+
titleRow: "_titleRow_jrbkm_104",
|
|
82
|
+
objectLeaf: "_objectLeaf_jrbkm_118",
|
|
83
|
+
objectRow: "_objectRow_jrbkm_126",
|
|
84
|
+
objectGroup: "_objectGroup_jrbkm_133",
|
|
85
|
+
columnsLayout: "_columnsLayout_jrbkm_148",
|
|
86
|
+
railLayout: "_railLayout_jrbkm_155",
|
|
87
|
+
railBody: "_railBody_jrbkm_168",
|
|
88
|
+
rail: "_rail_jrbkm_155",
|
|
89
|
+
railList: "_railList_jrbkm_208",
|
|
90
|
+
railItem: "_railItem_jrbkm_214",
|
|
91
|
+
railSub: "_railSub_jrbkm_238",
|
|
92
|
+
railOpen: "_railOpen_jrbkm_242",
|
|
93
|
+
railInView: "_railInView_jrbkm_242",
|
|
94
|
+
railName: "_railName_jrbkm_242",
|
|
95
|
+
railCount: "_railCount_jrbkm_267 _numeric_zns9n_4",
|
|
96
|
+
pane: "_pane_jrbkm_23",
|
|
97
|
+
paneHead: "_paneHead_jrbkm_281",
|
|
98
|
+
paneTitle: "_paneTitle_jrbkm_288",
|
|
99
|
+
paneDesc: "_paneDesc_jrbkm_295",
|
|
100
|
+
paneSection: "_paneSection_jrbkm_302",
|
|
101
|
+
paneSubsection: "_paneSubsection_jrbkm_309",
|
|
102
|
+
sectionTitle: "_sectionTitle_jrbkm_318",
|
|
103
|
+
subsectionTitle: "_subsectionTitle_jrbkm_336",
|
|
104
|
+
filter: "_filter_jrbkm_362",
|
|
105
|
+
noMatches: "_noMatches_jrbkm_366",
|
|
106
|
+
clearFilter: "_clearFilter_jrbkm_380"
|
|
107
107
|
};
|
|
108
108
|
//#endregion
|
|
109
109
|
//#region src/components/Prefs/PrefsRow.tsx
|
|
@@ -508,4 +508,4 @@ function R(t) {
|
|
|
508
508
|
//#endregion
|
|
509
509
|
export { y as a, O as i, j as n, x as o, A as r, R as t };
|
|
510
510
|
|
|
511
|
-
//# sourceMappingURL=Prefs-
|
|
511
|
+
//# sourceMappingURL=Prefs-BSSKOvPa.js.map
|