@weasel-js/ui 1.6.0 → 1.6.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-CYvfmEz0.js → ActionBar-DCq16yFA.js} +9 -9
- package/dist/chunks/ActionBar-DCq16yFA.js.map +1 -0
- package/dist/chunks/{Badge-DZ0lFs14.js → Badge-CyAIZSDo.js} +151 -151
- package/dist/chunks/Badge-CyAIZSDo.js.map +1 -0
- package/dist/chunks/{BandEditor-D-nVrVO4.js → BandEditor-Dhm_Xrlr.js} +5 -4
- package/dist/chunks/BandEditor-Dhm_Xrlr.js.map +1 -0
- package/dist/chunks/{Button-Dyp31jMt.js → Button-BIdXHQOx.js} +3 -3
- package/dist/chunks/Button-BIdXHQOx.js.map +1 -0
- package/dist/chunks/{ButtonBar-smZzFuEo.js → ButtonBar-D5Vi0aj_.js} +4 -4
- package/dist/chunks/ButtonBar-D5Vi0aj_.js.map +1 -0
- package/dist/chunks/{Callout-xLjnx7Mp.js → Callout-yEn9iPlh.js} +4 -4
- package/dist/chunks/Callout-yEn9iPlh.js.map +1 -0
- package/dist/chunks/{Checkbox-ChZz30Ds.js → Checkbox-DHXTUHO9.js} +1 -1
- package/dist/chunks/Checkbox-DHXTUHO9.js.map +1 -0
- package/dist/chunks/{Code-v4tDWuuN.js → Code-AsKpgnv6.js} +3 -3
- package/dist/chunks/Code-AsKpgnv6.js.map +1 -0
- package/dist/chunks/{ColorField-DJSCuSJv.js → ColorField-BcMcW8Sa.js} +3 -3
- package/dist/chunks/ColorField-BcMcW8Sa.js.map +1 -0
- package/dist/chunks/{ColorModeControl-JOEiqtE0.js → ColorModeControl-ke5PXbBa.js} +3 -3
- package/dist/chunks/ColorModeControl-ke5PXbBa.js.map +1 -0
- package/dist/chunks/{ComboBox-C1JgIpML.js → ComboBox-DpT8lc3p.js} +3 -3
- package/dist/chunks/ComboBox-DpT8lc3p.js.map +1 -0
- package/dist/chunks/{CurveEditor-f1R4kSbD.js → CurveEditor-BDJXjEvK.js} +35 -35
- package/dist/chunks/CurveEditor-BDJXjEvK.js.map +1 -0
- package/dist/chunks/{DataGrid-CZPrB_3a.js → DataGrid-D-dZj1BD.js} +13 -13
- package/dist/chunks/DataGrid-D-dZj1BD.js.map +1 -0
- package/dist/chunks/{DetailList-DHaXX4TG.js → DetailList-BMER1LUZ.js} +1 -1
- package/dist/chunks/DetailList-BMER1LUZ.js.map +1 -0
- package/dist/chunks/{DetentSlider-BYyaZha6.js → DetentSlider-CL8TlX3S.js} +2 -2
- package/dist/chunks/DetentSlider-CL8TlX3S.js.map +1 -0
- package/dist/chunks/{Dialog-GIvjoDQj.js → Dialog-BWyNMgpf.js} +3 -3
- package/dist/chunks/Dialog-BWyNMgpf.js.map +1 -0
- package/dist/chunks/{Disclosure-D79jhmh2.js → Disclosure-0G0uh2fa.js} +1 -1
- package/dist/chunks/Disclosure-0G0uh2fa.js.map +1 -0
- package/dist/chunks/{DragGhost-DcU7cOwy.js → DragGhost-B5_hb9W9.js} +2 -2
- package/dist/chunks/DragGhost-B5_hb9W9.js.map +1 -0
- package/dist/chunks/{DragHandleGlyph-BtBxHjZS.js → DragHandleGlyph-Dr7Fgo0I.js} +1 -1
- package/dist/chunks/DragHandleGlyph-Dr7Fgo0I.js.map +1 -0
- package/dist/chunks/{Field-xbqRmjsI.js → Field--onYxXTF.js} +7 -6
- package/dist/chunks/Field--onYxXTF.js.map +1 -0
- package/dist/chunks/{FillStrokeSwatch-BViKXIPx.js → FillStrokeSwatch-DNb0KXPk.js} +11 -11
- package/dist/chunks/FillStrokeSwatch-DNb0KXPk.js.map +1 -0
- package/dist/chunks/{FontFamilySelect-r9TV_xIH.js → FontFamilySelect-DXlMKWfK.js} +2 -2
- package/dist/chunks/FontFamilySelect-DXlMKWfK.js.map +1 -0
- package/dist/chunks/{GradientEditor-BRTxHG-W.js → GradientEditor-B3a-MsVJ.js} +8 -6
- package/dist/chunks/GradientEditor-B3a-MsVJ.js.map +1 -0
- package/dist/chunks/{Icon-BW0qv_U7.js → Icon-Cgzy8VgC.js} +2 -2
- package/dist/chunks/Icon-Cgzy8VgC.js.map +1 -0
- package/dist/chunks/{InlineRange-BwGFDhpT.js → InlineRange-eOj6JpJl.js} +1 -1
- package/dist/chunks/InlineRange-eOj6JpJl.js.map +1 -0
- package/dist/chunks/{Input-Bx2cuUbS.js → Input-CHmkfYaD.js} +2 -2
- package/dist/chunks/Input-CHmkfYaD.js.map +1 -0
- package/dist/chunks/{ItemList-DzJ2lK0R.js → ItemList-Cm-HUWCi.js} +6 -7
- package/dist/chunks/ItemList-Cm-HUWCi.js.map +1 -0
- package/dist/chunks/{ItemList.module-DDUXfuZL.js → ItemList.module-BSpCSxan.js} +1 -1
- package/dist/chunks/ItemList.module-BSpCSxan.js.map +1 -0
- package/dist/chunks/{Jog-LPoac9s4.js → Jog-DESxZ44P.js} +4 -4
- package/dist/chunks/Jog-DESxZ44P.js.map +1 -0
- package/dist/chunks/{Keycaps-CKiKOJnJ.js → Keycaps-C0H_v2gO.js} +2 -2
- package/dist/chunks/Keycaps-C0H_v2gO.js.map +1 -0
- package/dist/chunks/{LayerList-BeGrkLb9.js → LayerList-nz-QYvTF.js} +14 -14
- package/dist/chunks/LayerList-nz-QYvTF.js.map +1 -0
- package/dist/chunks/{ListEditor-C6zLzCsJ.js → ListEditor-BQ6AV3Ac.js} +2 -2
- package/dist/chunks/ListEditor-BQ6AV3Ac.js.map +1 -0
- package/dist/chunks/{MenuButton-BcdhrNGh.js → MenuButton-DtaGenKf.js} +3 -3
- package/dist/chunks/MenuButton-DtaGenKf.js.map +1 -0
- package/dist/chunks/{MeshEditor-BOOIFWnz.js → MeshEditor-qqGc6hlD.js} +4 -4
- package/dist/chunks/MeshEditor-qqGc6hlD.js.map +1 -0
- package/dist/chunks/{NumberField-C1Y7zP-a.js → NumberField-CwJOMmQR.js} +3 -3
- package/dist/chunks/NumberField-CwJOMmQR.js.map +1 -0
- package/dist/chunks/{OptionsBar-DlcagPYK.js → OptionsBar-DbzAgIln.js} +3 -3
- package/dist/chunks/OptionsBar-DbzAgIln.js.map +1 -0
- package/dist/chunks/{PaintField-B2mLRZa4.js → PaintField-DaJukRc6.js} +4 -4
- package/dist/chunks/PaintField-DaJukRc6.js.map +1 -0
- package/dist/chunks/{PaintInput-BFKhd83I.js → PaintInput-Byhna3H-.js} +7 -7
- package/dist/chunks/PaintInput-Byhna3H-.js.map +1 -0
- package/dist/chunks/{PatternPicker-DdfpxoQy.js → PatternPicker-B-cUt-JT.js} +2 -2
- package/dist/chunks/PatternPicker-B-cUt-JT.js.map +1 -0
- package/dist/chunks/{Plot2D-lyO7waPQ.js → Plot2D-CTXHkL5p.js} +13 -13
- package/dist/chunks/Plot2D-CTXHkL5p.js.map +1 -0
- package/dist/chunks/{PointPlotter-DGs9i5P-.js → PointPlotter-Bxo6haKe.js} +5 -4
- package/dist/chunks/PointPlotter-Bxo6haKe.js.map +1 -0
- package/dist/chunks/Powerline-ExO5GwEr.js +42 -0
- package/dist/chunks/Powerline-ExO5GwEr.js.map +1 -0
- package/dist/chunks/{Prefs-Ctu0H4-b.js → Prefs-DpqFKiwY.js} +18 -17
- package/dist/chunks/Prefs-DpqFKiwY.js.map +1 -0
- package/dist/chunks/{Properties-Bbneh1ws.js → Properties-D_KzDN9K.js} +13 -12
- package/dist/chunks/Properties-D_KzDN9K.js.map +1 -0
- package/dist/chunks/{PropertyField-CDb19d3F.js → PropertyField-DGCecAnV.js} +22 -20
- package/dist/chunks/PropertyField-DGCecAnV.js.map +1 -0
- package/dist/chunks/{RadioGroup-BK2mD6Q0.js → RadioGroup-Bh4-12e-.js} +2 -2
- package/dist/chunks/RadioGroup-Bh4-12e-.js.map +1 -0
- package/dist/chunks/{RangeSlider-BiRAOsTh.js → RangeSlider-BKRRTPTZ.js} +1 -1
- package/dist/chunks/RangeSlider-BKRRTPTZ.js.map +1 -0
- package/dist/chunks/{ResizeHandle-Cc6EOehs.js → ResizeHandle-BKT0XYpx.js} +7 -7
- package/dist/chunks/ResizeHandle-BKT0XYpx.js.map +1 -0
- package/dist/chunks/{Select-DVValBe1.js → Select-CzyfaXzp.js} +4 -4
- package/dist/chunks/Select-CzyfaXzp.js.map +1 -0
- package/dist/chunks/{SelectionPanel-C5LmZA7b.js → SelectionPanel-BgUM1h03.js} +2 -2
- package/dist/chunks/SelectionPanel-BgUM1h03.js.map +1 -0
- package/dist/chunks/{Sidebar-DKKd4R-x.js → Sidebar-BZ0m4afn.js} +8 -8
- package/dist/chunks/Sidebar-BZ0m4afn.js.map +1 -0
- package/dist/chunks/{SidebarPanel-u5NsuAZY.js → SidebarPanel-aoIqxbtq.js} +3 -3
- package/dist/chunks/SidebarPanel-aoIqxbtq.js.map +1 -0
- package/dist/chunks/{Slider-BwRrWHFW.js → Slider-CFwQYQ10.js} +60 -58
- package/dist/chunks/Slider-CFwQYQ10.js.map +1 -0
- package/dist/chunks/{StatusBar-CdPdmmda.js → StatusBar-DzoPDY4k.js} +8 -8
- package/dist/chunks/StatusBar-DzoPDY4k.js.map +1 -0
- package/dist/chunks/{SwatchGrid-C-Zx2Exd.js → SwatchGrid-BARC3rnF.js} +1 -1
- package/dist/chunks/SwatchGrid-BARC3rnF.js.map +1 -0
- package/dist/chunks/{Switch-DxF7TsEu.js → Switch-CSYmcM8y.js} +1 -1
- package/dist/chunks/Switch-CSYmcM8y.js.map +1 -0
- package/dist/chunks/{Tabs-GXEfoe3o.js → Tabs-BbpzLLdY.js} +1 -1
- package/dist/chunks/Tabs-BbpzLLdY.js.map +1 -0
- package/dist/chunks/{Timeline-SgmpQtUV.js → Timeline--58F7MED.js} +21 -21
- package/dist/chunks/Timeline--58F7MED.js.map +1 -0
- package/dist/chunks/{Toast-BfcljZz6.js → Toast-DNBb-24H.js} +1 -1
- package/dist/chunks/Toast-DNBb-24H.js.map +1 -0
- package/dist/chunks/{ToggleBar-Btnl5r7F.js → ToggleBar-DTjGeS0Q.js} +13 -11
- package/dist/chunks/ToggleBar-DTjGeS0Q.js.map +1 -0
- package/dist/chunks/{TokenPanel-5ajHEHha.js → TokenPanel-CMq7uydV.js} +21 -18
- package/dist/chunks/TokenPanel-CMq7uydV.js.map +1 -0
- package/dist/chunks/{ToolButton-rzqlFlAc.js → ToolButton-CR4sQlxF.js} +2 -2
- package/dist/chunks/ToolButton-CR4sQlxF.js.map +1 -0
- package/dist/chunks/{ToolGroup-4bUBV5k6.js → ToolGroup-Dpg1LN0l.js} +7 -7
- package/dist/chunks/ToolGroup-Dpg1LN0l.js.map +1 -0
- package/dist/chunks/{ToolOptionsBar-BF3TNXA3.js → ToolOptionsBar-CtzTlaN2.js} +6 -5
- package/dist/chunks/ToolOptionsBar-CtzTlaN2.js.map +1 -0
- package/dist/chunks/{ToolPalette-Uw4PvWwa.js → ToolPalette-CKG9qY6P.js} +6 -6
- package/dist/chunks/ToolPalette-CKG9qY6P.js.map +1 -0
- package/dist/chunks/{Tooltip-9XiJF937.js → Tooltip-Clg2mhSt.js} +2 -2
- package/dist/chunks/Tooltip-Clg2mhSt.js.map +1 -0
- package/dist/chunks/{Tree-BGt6P8tI.js → Tree-DVOtc9R5.js} +3 -3
- package/dist/chunks/Tree-DVOtc9R5.js.map +1 -0
- package/dist/chunks/{createKeyframeLayer-BzDRCrrh.js → createKeyframeLayer-Czj6Y235.js} +32 -32
- package/dist/chunks/createKeyframeLayer-Czj6Y235.js.map +1 -0
- package/dist/chunks/{dlog-CMYiRF3Q.js → dlog-F0I8KsIW.js} +2 -2
- package/dist/chunks/dlog-F0I8KsIW.js.map +1 -0
- package/dist/chunks/{formatShortcut-BoGqUoWi.js → formatShortcut-DRQrVThu.js} +2 -2
- package/dist/chunks/formatShortcut-DRQrVThu.js.map +1 -0
- package/dist/chunks/icons-Dk8SRS8g.js +162 -0
- package/dist/chunks/icons-Dk8SRS8g.js.map +1 -0
- package/dist/chunks/{interactiveTarget-C7QUBaJN.js → interactiveTarget-BNZmTow2.js} +1 -1
- package/dist/chunks/{interactiveTarget-C7QUBaJN.js.map → interactiveTarget-BNZmTow2.js.map} +1 -1
- package/dist/chunks/{keyGlyph-CLvUHU8c.js → keyGlyph-C0qTakG-.js} +1 -1
- package/dist/chunks/keyGlyph-C0qTakG-.js.map +1 -0
- package/dist/chunks/{model-BQMvTLnW.js → model-Du7Lta4C.js} +5 -5
- package/dist/chunks/model-Du7Lta4C.js.map +1 -0
- package/dist/chunks/{number-6S8IzXVt.js → number-D3NEx_8r.js} +1 -1
- package/dist/chunks/number-D3NEx_8r.js.map +1 -0
- package/dist/chunks/{paintPreview-DPtZS4yU.js → paintPreview-CuSZiHpR.js} +1 -1
- package/dist/chunks/paintPreview-CuSZiHpR.js.map +1 -0
- package/dist/chunks/{paintValue-Bz6AVuh3.js → paintValue-BpaGPjV3.js} +3 -3
- package/dist/chunks/paintValue-BpaGPjV3.js.map +1 -0
- package/dist/chunks/{portalHost-CjpCnuGU.js → portalHost-yTOVuCej.js} +1 -1
- package/dist/chunks/portalHost-yTOVuCej.js.map +1 -0
- package/dist/chunks/{prefField-CLkhrvYl.js → prefField-Dnl7nmjQ.js} +3 -3
- package/dist/chunks/prefField-Dnl7nmjQ.js.map +1 -0
- package/dist/chunks/{segmentTooltip-CAkZlW-t.js → segmentTooltip-CStYHKzd.js} +2 -2
- package/dist/chunks/segmentTooltip-CStYHKzd.js.map +1 -0
- package/dist/chunks/{segmentedControl.module-D2nw68Yo.js → segmentedControl.module-Bv7DEg8f.js} +1 -1
- package/dist/chunks/segmentedControl.module-Bv7DEg8f.js.map +1 -0
- package/dist/chunks/{snap-DC4Km8xG.js → snap-DRjbOiG9.js} +1 -1
- package/dist/chunks/snap-DRjbOiG9.js.map +1 -0
- package/dist/chunks/{stance-CarrcbbP.js → stance-BFQpS_fL.js} +1 -1
- package/dist/chunks/stance-BFQpS_fL.js.map +1 -0
- package/dist/chunks/{useReorderDragList-Dcezzgix.js → useReorderDragList-B_-5L5Gu.js} +2 -2
- package/dist/chunks/useReorderDragList-B_-5L5Gu.js.map +1 -0
- package/dist/chunks/{useRovingTabIndex-B4uJqiKP.js → useRovingTabIndex-Bp_hYm_h.js} +1 -1
- package/dist/chunks/useRovingTabIndex-Bp_hYm_h.js.map +1 -0
- package/dist/components/ActionBar/ActionBar.d.ts +1 -1
- package/dist/components/ActionBar/ActionBar.d.ts.map +1 -1
- package/dist/components/ActionBar/index.js +1 -1
- package/dist/components/Badge/index.js +1 -1
- package/dist/components/BandEditor/index.js +1 -1
- package/dist/components/Button/index.js +1 -1
- package/dist/components/ButtonBar/index.js +1 -1
- package/dist/components/Callout/Callout.d.ts +1 -1
- package/dist/components/Callout/Callout.d.ts.map +1 -1
- package/dist/components/Callout/index.js +1 -1
- package/dist/components/Checkbox/index.js +1 -1
- package/dist/components/Code/Code.d.ts +1 -1
- package/dist/components/Code/Code.d.ts.map +1 -1
- package/dist/components/Code/index.js +1 -1
- package/dist/components/ColorField/ColorField.d.ts +1 -1
- package/dist/components/ColorField/ColorField.d.ts.map +1 -1
- package/dist/components/ColorField/index.js +1 -1
- package/dist/components/ColorModeControl/index.js +1 -1
- package/dist/components/ComboBox/ComboBox.d.ts +2 -2
- package/dist/components/ComboBox/ComboBox.d.ts.map +1 -1
- package/dist/components/ComboBox/index.js +1 -1
- package/dist/components/CurveEditor/CurveEditor.d.ts +1 -1
- package/dist/components/CurveEditor/CurveEditor.d.ts.map +1 -1
- package/dist/components/CurveEditor/LayeredCurveEditor.d.ts +1 -1
- package/dist/components/CurveEditor/LayeredCurveEditor.d.ts.map +1 -1
- package/dist/components/CurveEditor/index.js +3 -3
- package/dist/components/DataGrid/DataGrid.d.ts +1 -1
- package/dist/components/DataGrid/DataGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/index.js +1 -1
- package/dist/components/DetailList/DetailList.d.ts +2 -2
- package/dist/components/DetailList/DetailList.d.ts.map +1 -1
- package/dist/components/DetailList/index.js +1 -1
- package/dist/components/DetentSlider/index.js +1 -1
- package/dist/components/Dialog/Dialog.d.ts +1 -1
- package/dist/components/Dialog/Dialog.d.ts.map +1 -1
- package/dist/components/Dialog/index.js +1 -1
- package/dist/components/Disclosure/Disclosure.d.ts +3 -3
- package/dist/components/Disclosure/Disclosure.d.ts.map +1 -1
- package/dist/components/Disclosure/index.js +1 -1
- package/dist/components/DragGhost/index.js +1 -1
- package/dist/components/DragHandleGlyph/DragHandleGlyph.d.ts +1 -1
- package/dist/components/DragHandleGlyph/DragHandleGlyph.d.ts.map +1 -1
- package/dist/components/DragHandleGlyph/index.js +1 -1
- package/dist/components/Field/Field.d.ts +1 -1
- package/dist/components/Field/Field.d.ts.map +1 -1
- package/dist/components/Field/index.js +1 -1
- package/dist/components/FillStrokeSwatch/index.js +1 -1
- package/dist/components/FontFamilySelect/FontFamilySelect.d.ts +1 -1
- package/dist/components/FontFamilySelect/FontFamilySelect.d.ts.map +1 -1
- package/dist/components/FontFamilySelect/index.js +1 -1
- package/dist/components/GradientEditor/index.js +1 -1
- package/dist/components/InlineRange/index.js +1 -1
- package/dist/components/Input/index.js +1 -1
- package/dist/components/ItemList/index.js +1 -1
- package/dist/components/Jog/Jog.d.ts +1 -1
- package/dist/components/Jog/Jog.d.ts.map +1 -1
- package/dist/components/Jog/index.js +1 -1
- package/dist/components/Keycaps/Keycap.d.ts +1 -1
- package/dist/components/Keycaps/Keycap.d.ts.map +1 -1
- package/dist/components/Keycaps/Keycaps.d.ts +1 -1
- package/dist/components/Keycaps/Keycaps.d.ts.map +1 -1
- package/dist/components/Keycaps/index.js +2 -2
- package/dist/components/LayerList/LayerList.d.ts +1 -1
- package/dist/components/LayerList/LayerList.d.ts.map +1 -1
- package/dist/components/LayerList/index.js +1 -1
- package/dist/components/ListEditor/ListEditor.d.ts +1 -1
- package/dist/components/ListEditor/ListEditor.d.ts.map +1 -1
- package/dist/components/ListEditor/index.js +1 -1
- package/dist/components/MenuButton/MenuButton.d.ts +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/NumberField/UnitField.d.ts +1 -1
- package/dist/components/NumberField/UnitField.d.ts.map +1 -1
- package/dist/components/NumberField/index.js +1 -1
- package/dist/components/OptionsBar/index.js +1 -1
- package/dist/components/PaintField/index.js +1 -1
- package/dist/components/PaintInput/index.js +1 -1
- package/dist/components/PatternPicker/index.js +1 -1
- package/dist/components/Plot2D/index.js +1 -1
- package/dist/components/PointPlotter/PointPlotter.d.ts +1 -1
- package/dist/components/PointPlotter/PointPlotter.d.ts.map +1 -1
- package/dist/components/PointPlotter/index.js +1 -1
- package/dist/components/Powerline/Powerline.d.ts +1 -1
- package/dist/components/Powerline/Powerline.d.ts.map +1 -1
- package/dist/components/Powerline/index.js +2 -2
- package/dist/components/Prefs/PrefsDialog.d.ts +1 -1
- package/dist/components/Prefs/PrefsDialog.d.ts.map +1 -1
- package/dist/components/Prefs/PrefsForm.d.ts +1 -1
- package/dist/components/Prefs/PrefsForm.d.ts.map +1 -1
- package/dist/components/Prefs/PrefsPane.d.ts +1 -1
- package/dist/components/Prefs/PrefsPane.d.ts.map +1 -1
- package/dist/components/Prefs/PrefsRail.d.ts +1 -1
- package/dist/components/Prefs/PrefsRail.d.ts.map +1 -1
- package/dist/components/Prefs/PrefsRow.d.ts +1 -1
- package/dist/components/Prefs/PrefsRow.d.ts.map +1 -1
- package/dist/components/Prefs/index.js +2 -2
- package/dist/components/Properties/CurveField.d.ts +1 -1
- package/dist/components/Properties/CurveField.d.ts.map +1 -1
- package/dist/components/Properties/DialogRow.d.ts +1 -1
- package/dist/components/Properties/DialogRow.d.ts.map +1 -1
- package/dist/components/Properties/PropertyField.d.ts +2 -2
- package/dist/components/Properties/PropertyField.d.ts.map +1 -1
- package/dist/components/Properties/PropertyGroup.d.ts +1 -1
- package/dist/components/Properties/PropertyGroup.d.ts.map +1 -1
- package/dist/components/Properties/PropertyPanel.d.ts +4 -4
- package/dist/components/Properties/PropertyPanel.d.ts.map +1 -1
- package/dist/components/Properties/Subpanel.d.ts +1 -1
- package/dist/components/Properties/Subpanel.d.ts.map +1 -1
- package/dist/components/Properties/index.js +2 -2
- package/dist/components/Properties/storyLayouts.d.ts +1 -1
- package/dist/components/Properties/storyLayouts.d.ts.map +1 -1
- package/dist/components/RadioGroup/RadioGroup.d.ts +2 -2
- package/dist/components/RadioGroup/RadioGroup.d.ts.map +1 -1
- package/dist/components/RadioGroup/index.js +1 -1
- package/dist/components/RangeSlider/RangeSlider.d.ts +1 -1
- package/dist/components/RangeSlider/RangeSlider.d.ts.map +1 -1
- package/dist/components/RangeSlider/index.js +1 -1
- package/dist/components/ResizeHandle/ResizeHandle.d.ts +1 -1
- package/dist/components/ResizeHandle/ResizeHandle.d.ts.map +1 -1
- package/dist/components/ResizeHandle/index.js +1 -1
- package/dist/components/Select/Select.d.ts +3 -3
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/index.js +1 -1
- package/dist/components/SelectionPanel/SelectionPanel.d.ts +1 -1
- package/dist/components/SelectionPanel/SelectionPanel.d.ts.map +1 -1
- package/dist/components/SelectionPanel/index.js +2 -2
- package/dist/components/Sidebar/Sidebar.d.ts +1 -1
- package/dist/components/Sidebar/Sidebar.d.ts.map +1 -1
- package/dist/components/Sidebar/index.js +1 -1
- package/dist/components/SidebarPanel/SidebarPanel.d.ts +1 -1
- package/dist/components/SidebarPanel/SidebarPanel.d.ts.map +1 -1
- package/dist/components/SidebarPanel/index.js +1 -1
- package/dist/components/Slider/Slider.d.ts +2 -1
- package/dist/components/Slider/Slider.d.ts.map +1 -1
- package/dist/components/Slider/index.js +1 -1
- package/dist/components/StatusBar/StatusBar.d.ts +3 -3
- package/dist/components/StatusBar/StatusBar.d.ts.map +1 -1
- package/dist/components/StatusBar/index.js +1 -1
- package/dist/components/SwatchGrid/index.js +1 -1
- package/dist/components/Switch/index.js +1 -1
- package/dist/components/Tabs/Tabs.d.ts +4 -4
- package/dist/components/Tabs/Tabs.d.ts.map +1 -1
- package/dist/components/Tabs/index.js +1 -1
- package/dist/components/Timeline/index.js +1 -1
- package/dist/components/Toast/Toast.d.ts +1 -1
- package/dist/components/Toast/Toast.d.ts.map +1 -1
- package/dist/components/Toast/index.js +1 -1
- package/dist/components/ToggleBar/index.js +1 -1
- package/dist/components/TokenPanel/TokenPanel.d.ts +1 -1
- package/dist/components/TokenPanel/TokenPanel.d.ts.map +1 -1
- package/dist/components/TokenPanel/index.js +1 -1
- package/dist/components/ToolButton/ToolButton.d.ts +1 -1
- package/dist/components/ToolButton/ToolButton.d.ts.map +1 -1
- package/dist/components/ToolButton/index.js +1 -1
- package/dist/components/ToolGroup/ToolGroup.d.ts +1 -1
- package/dist/components/ToolGroup/ToolGroup.d.ts.map +1 -1
- package/dist/components/ToolGroup/index.js +1 -1
- package/dist/components/ToolOptionsBar/ToolOptionsBar.d.ts +1 -1
- package/dist/components/ToolOptionsBar/ToolOptionsBar.d.ts.map +1 -1
- package/dist/components/ToolOptionsBar/index.js +1 -1
- package/dist/components/ToolPalette/ToolPalette.d.ts +1 -1
- package/dist/components/ToolPalette/ToolPalette.d.ts.map +1 -1
- package/dist/components/ToolPalette/index.js +2 -2
- package/dist/components/Tooltip/Tooltip.d.ts +2 -2
- package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/index.js +1 -1
- package/dist/components/Tree/index.js +1 -1
- package/dist/icons/Icon.d.ts +1 -1
- package/dist/icons/Icon.d.ts.map +1 -1
- package/dist/icons/ShapeKindIcon.d.ts +1 -1
- package/dist/icons/ShapeKindIcon.d.ts.map +1 -1
- package/dist/icons/index.d.ts +52 -52
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +108 -89
- package/dist/index.js.map +1 -1
- package/dist/overlays/portalHost.d.ts +1 -1
- package/dist/overlays/portalHost.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +8 -8
- package/dist/chunks/ActionBar-CYvfmEz0.js.map +0 -1
- package/dist/chunks/Badge-DZ0lFs14.js.map +0 -1
- package/dist/chunks/BandEditor-D-nVrVO4.js.map +0 -1
- package/dist/chunks/Button-Dyp31jMt.js.map +0 -1
- package/dist/chunks/ButtonBar-smZzFuEo.js.map +0 -1
- package/dist/chunks/Callout-xLjnx7Mp.js.map +0 -1
- package/dist/chunks/Checkbox-ChZz30Ds.js.map +0 -1
- package/dist/chunks/Code-v4tDWuuN.js.map +0 -1
- package/dist/chunks/ColorField-DJSCuSJv.js.map +0 -1
- package/dist/chunks/ColorModeControl-JOEiqtE0.js.map +0 -1
- package/dist/chunks/ComboBox-C1JgIpML.js.map +0 -1
- package/dist/chunks/CurveEditor-f1R4kSbD.js.map +0 -1
- package/dist/chunks/DataGrid-CZPrB_3a.js.map +0 -1
- package/dist/chunks/DetailList-DHaXX4TG.js.map +0 -1
- package/dist/chunks/DetentSlider-BYyaZha6.js.map +0 -1
- package/dist/chunks/Dialog-GIvjoDQj.js.map +0 -1
- package/dist/chunks/Disclosure-D79jhmh2.js.map +0 -1
- package/dist/chunks/DragGhost-DcU7cOwy.js.map +0 -1
- package/dist/chunks/DragHandleGlyph-BtBxHjZS.js.map +0 -1
- package/dist/chunks/Field-xbqRmjsI.js.map +0 -1
- package/dist/chunks/FillStrokeSwatch-BViKXIPx.js.map +0 -1
- package/dist/chunks/FontFamilySelect-r9TV_xIH.js.map +0 -1
- package/dist/chunks/GradientEditor-BRTxHG-W.js.map +0 -1
- package/dist/chunks/Icon-BW0qv_U7.js.map +0 -1
- package/dist/chunks/InlineRange-BwGFDhpT.js.map +0 -1
- package/dist/chunks/Input-Bx2cuUbS.js.map +0 -1
- package/dist/chunks/ItemList-DzJ2lK0R.js.map +0 -1
- package/dist/chunks/ItemList.module-DDUXfuZL.js.map +0 -1
- package/dist/chunks/Jog-LPoac9s4.js.map +0 -1
- package/dist/chunks/Keycaps-CKiKOJnJ.js.map +0 -1
- package/dist/chunks/LayerList-BeGrkLb9.js.map +0 -1
- package/dist/chunks/ListEditor-C6zLzCsJ.js.map +0 -1
- package/dist/chunks/MenuButton-BcdhrNGh.js.map +0 -1
- package/dist/chunks/MeshEditor-BOOIFWnz.js.map +0 -1
- package/dist/chunks/NumberField-C1Y7zP-a.js.map +0 -1
- package/dist/chunks/OptionsBar-DlcagPYK.js.map +0 -1
- package/dist/chunks/PaintField-B2mLRZa4.js.map +0 -1
- package/dist/chunks/PaintInput-BFKhd83I.js.map +0 -1
- package/dist/chunks/PatternPicker-DdfpxoQy.js.map +0 -1
- package/dist/chunks/Plot2D-lyO7waPQ.js.map +0 -1
- package/dist/chunks/PointPlotter-DGs9i5P-.js.map +0 -1
- package/dist/chunks/Powerline-DBEPceLE.js +0 -38
- package/dist/chunks/Powerline-DBEPceLE.js.map +0 -1
- package/dist/chunks/Prefs-Ctu0H4-b.js.map +0 -1
- package/dist/chunks/Properties-Bbneh1ws.js.map +0 -1
- package/dist/chunks/PropertyField-CDb19d3F.js.map +0 -1
- package/dist/chunks/RadioGroup-BK2mD6Q0.js.map +0 -1
- package/dist/chunks/RangeSlider-BiRAOsTh.js.map +0 -1
- package/dist/chunks/ResizeHandle-Cc6EOehs.js.map +0 -1
- package/dist/chunks/Select-DVValBe1.js.map +0 -1
- package/dist/chunks/SelectionPanel-C5LmZA7b.js.map +0 -1
- package/dist/chunks/Sidebar-DKKd4R-x.js.map +0 -1
- package/dist/chunks/SidebarPanel-u5NsuAZY.js.map +0 -1
- package/dist/chunks/Slider-BwRrWHFW.js.map +0 -1
- package/dist/chunks/StatusBar-CdPdmmda.js.map +0 -1
- package/dist/chunks/SwatchGrid-C-Zx2Exd.js.map +0 -1
- package/dist/chunks/Switch-DxF7TsEu.js.map +0 -1
- package/dist/chunks/Tabs-GXEfoe3o.js.map +0 -1
- package/dist/chunks/Timeline-SgmpQtUV.js.map +0 -1
- package/dist/chunks/Toast-BfcljZz6.js.map +0 -1
- package/dist/chunks/ToggleBar-Btnl5r7F.js.map +0 -1
- package/dist/chunks/TokenPanel-5ajHEHha.js.map +0 -1
- package/dist/chunks/ToolButton-rzqlFlAc.js.map +0 -1
- package/dist/chunks/ToolGroup-4bUBV5k6.js.map +0 -1
- package/dist/chunks/ToolOptionsBar-BF3TNXA3.js.map +0 -1
- package/dist/chunks/ToolPalette-Uw4PvWwa.js.map +0 -1
- package/dist/chunks/Tooltip-9XiJF937.js.map +0 -1
- package/dist/chunks/Tree-BGt6P8tI.js.map +0 -1
- package/dist/chunks/createKeyframeLayer-BzDRCrrh.js.map +0 -1
- package/dist/chunks/dlog-CMYiRF3Q.js.map +0 -1
- package/dist/chunks/formatShortcut-BoGqUoWi.js.map +0 -1
- package/dist/chunks/icons-DbScMMqX.js +0 -179
- package/dist/chunks/icons-DbScMMqX.js.map +0 -1
- package/dist/chunks/keyGlyph-CLvUHU8c.js.map +0 -1
- package/dist/chunks/model-BQMvTLnW.js.map +0 -1
- package/dist/chunks/number-6S8IzXVt.js.map +0 -1
- package/dist/chunks/paintPreview-DPtZS4yU.js.map +0 -1
- package/dist/chunks/paintValue-Bz6AVuh3.js.map +0 -1
- package/dist/chunks/portalHost-CjpCnuGU.js.map +0 -1
- package/dist/chunks/prefField-CLkhrvYl.js.map +0 -1
- package/dist/chunks/segmentTooltip-CAkZlW-t.js.map +0 -1
- package/dist/chunks/segmentedControl.module-D2nw68Yo.js.map +0 -1
- package/dist/chunks/snap-DC4Km8xG.js.map +0 -1
- package/dist/chunks/stance-CarrcbbP.js.map +0 -1
- package/dist/chunks/useReorderDragList-Dcezzgix.js.map +0 -1
- package/dist/chunks/useRovingTabIndex-B4uJqiKP.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ToolOptionsBar-BF3TNXA3.js","names":[],"sources":["../../src/components/ToolOptionsBar/ToolOptionsBar.module.css","../../src/components/ToolOptionsBar/ToolOptionsBar.tsx"],"sourcesContent":["/* Horizontal strip reserved above the workspace for contextual tool\n options. Fixed height so mounting/unmounting content never resizes\n the workspace beneath it — that's the whole reason this row exists\n as permanent chrome rather than an on-demand overlay.\n\n Overflow: when controls exceed the available width, `.controls`\n scrolls horizontally rather than wrapping (which would grow the row\n and defeat the fixed-height guarantee above) or clipping (which\n would hide controls with no way to reach them). A flyout/long-press\n affordance was considered and rejected — grouped, directly visible\n layouts are preferred in this repo. */\n\n.root {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-4);\n height: var(--wzl-tb-height, 28px);\n padding: 0 var(--wzl-space-4);\n background: var(--wzl-surface);\n border-bottom: 1px solid var(--wzl-border);\n color: var(--wzl-fg);\n overflow: hidden;\n}\n\n.label {\n flex: 0 0 auto;\n font-size: var(--wzl-font-size-sm);\n font-weight: var(--wzl-font-weight-bold);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--wzl-fg-muted);\n white-space: nowrap;\n}\n\n.controls {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-3);\n flex: 1 1 auto;\n min-width: 0;\n height: 100%;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: thin;\n}\n\n/* Firefox gets a thin scrollbar for free via `scrollbar-width` above.\n * Chromium/WebKit need it spelled out — on a classic (non-overlay)\n * scrollbar theme (default on Windows Chrome/Edge), an unstyled\n * horizontal scrollbar is ~15-17px tall and renders *inside* this box,\n * clipping/off-centering the row's controls. That would reintroduce the\n * exact height instability the scroll-over-wrap overflow choice above\n * exists to avoid — just at the row's inner edge instead of its outer\n * one. Pin it thin and out of the way instead. */\n.controls::-webkit-scrollbar {\n height: 4px;\n}\n.controls::-webkit-scrollbar-track {\n background: transparent;\n}\n.controls::-webkit-scrollbar-thumb {\n background: var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n}\n\n/* A schema-drawn control sits on the line as-is; the cell exists only to keep\n it from being squeezed by the row's flex context. */\n.cell {\n display: flex;\n align-items: center;\n flex: none;\n}\n\n.cellLabel {\n flex: none;\n margin-right: var(--wzl-space-2);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n white-space: nowrap;\n}\n\n/* Fields are read beside their label on one line, so they carry only the\n digits they need rather than the panel's column width. */\n.controls {\n --wzl-number-field-width: 5ch;\n}\n\n/* The strip decides how much room a control gets, because its budget is one\n line rather than a column: a field carries the digits it needs and an\n opacity track stops short of pushing its neighbours off the end. Both are\n the panel's widths otherwise, which are sized for a two-column grid. */\n.cell input[type='text'] {\n inline-size: var(--wzl-number-field-width, 5ch);\n}\n\n.cell input[type='range'] {\n inline-size: 64px;\n flex: none;\n}\n","import type { ReactNode } from 'react';\nimport type { ToolPrefGroup, ToolPrefLeaf } from '@weasel-js/core';\nimport {\n renderBuiltin,\n renderCells,\n type LeafCell,\n type PropertyRenderContext,\n type PropertyRenderer,\n} from '../SelectionPanel/renderLeaf';\nimport { isGroup, pairRows, type PanelLeaf, type PanelRow } from '../SelectionPanel/model';\nimport s from './ToolOptionsBar.module.css';\n\n/** Props for {@link ToolOptionsBar}. */\nexport interface ToolOptionsBarProps {\n /**\n * Context label for the row — e.g. the active tool's name. Rendered\n * before the children and doubles as the toolbar's `aria-label`. Omit\n * it and the row still renders (it's a permanently reserved slot), just\n * without an accessible name.\n *\n * Using `label` for both the visible text and `aria-label` means a\n * screen reader announces it twice when landing on the toolbar (\"Text,\n * toolbar\", then \"Text\" again when browsing into the visible span).\n * `aria-labelledby` would avoid the echo at the cost of id plumbing and\n * an awkward no-`id`-to-point-at case when `label` is omitted. The\n * double-announcement is common enough for labeled landmark regions\n * that it's left as-is — considered, not missed.\n */\n label?: string;\n /**\n * The active tool's options. Leaves draw through the same leaf → control\n * mapping `SelectionPanel` uses, so a kind gets its control decided in one\n * place; groups organize without drawing, since the bar is one line.\n */\n schema?: ToolPrefGroup;\n /** Each leaf's value, keyed by dotted path. A path with no entry is unset. */\n values?: Readonly<Record<string, unknown>>;\n /** A leaf edit, as the dotted path it was declared at and its new value. */\n onChange?: (path: string, value: unknown) => void;\n /** Paths whose sources disagree — drawn as the control's mixed state. */\n mixed?: ReadonlySet<string>;\n /** Control overrides, by dotted path or by leaf kind, as the panel takes. */\n renderers?: Record<string, PropertyRenderer>;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * Horizontal strip reserved above the workspace for contextual tool options.\n * Given a `schema` it draws the active tool's options itself; the children\n * slot stays open for a tenant that is not a tool's options at all, such as\n * loupe controls.\n *\n * The row always renders, even empty, because the app reserves its height\n * permanently rather than mounting it on demand — mounting mid-edit would\n * resize the workspace under a canvas that's sized to the page.\n *\n * `role=\"toolbar\"` without roving tabindex: the ARIA authoring practices\n * expect arrow-key roving focus across a toolbar's items, but a bar of\n * compound controls (`NumberField`, `Select`, `ColorField`) must leave the\n * arrow keys to them — they edit their own value with them. That is true of\n * schema-drawn controls as much as of arbitrary children, so the bar keeps\n * plain DOM tab order and `useRovingTabIndex` documents this as its opt-out.\n */\nexport function ToolOptionsBar(props: ToolOptionsBarProps) {\n const { label, schema, values, onChange, mixed, renderers, children, className } = props;\n const cls = [s.root, className].filter(Boolean).join(' ');\n return (\n <div className={cls} role=\"toolbar\" aria-label={label}>\n {label !== undefined && <span className={s.label}>{label}</span>}\n <div className={s.controls}>\n {schema !== undefined &&\n barRows(schema).map((row) => (\n <BarRow\n key={row.leaves[0]!.path}\n row={row}\n values={values}\n mixed={mixed}\n renderers={renderers}\n onChange={onChange}\n />\n ))}\n {children}\n </div>\n </div>\n );\n}\n\n/**\n * The schema's visible leaves as rows, addressed by dotted path. Groups are\n * organizational here — a bar is one line, so a nested group contributes its\n * leaves and no chrome — but its path segment still names them, so a leaf\n * reads back at the path the tool declared it at.\n */\nfunction barRows(schema: ToolPrefGroup): PanelRow[] {\n const leaves: PanelLeaf[] = [];\n const collect = (group: ToolPrefGroup, prefix: string): void => {\n for (const [key, child] of Object.entries(group.children)) {\n const path = prefix === '' ? key : `${prefix}.${key}`;\n if (isGroup(child)) collect(child, path);\n else if (child.hidden !== true) leaves.push({ path, leaf: child });\n }\n };\n collect(schema, '');\n return pairRows(leaves);\n}\n\n/** One row of the bar: a single control, or a run of flags as one bar. */\nfunction BarRow({\n row,\n values,\n mixed,\n renderers,\n onChange,\n}: {\n row: PanelRow;\n values: Readonly<Record<string, unknown>> | undefined;\n mixed: ReadonlySet<string> | undefined;\n renderers: Record<string, PropertyRenderer> | undefined;\n onChange: ((path: string, value: unknown) => void) | undefined;\n}) {\n // The bar draws no row label, so a control carries its own name rather than\n // the panel's qualified \"<pair> <leaf>\" — the run's bar carries the pair.\n const cells = row.leaves.map((panelLeaf) =>\n barCell(panelLeaf, panelLeaf.leaf.name, values, mixed, renderers, onChange),\n );\n return (\n <>\n {renderCells(cells, renderers).map((cell) => (\n <span key={cell.key} className={s.cell}>\n {needsLabel(cell.leaf) && (\n <span className={s.cellLabel} aria-hidden=\"true\">\n {cell.leaf.short ?? cell.leaf.name}\n </span>\n )}\n {cell.content}\n </span>\n ))}\n </>\n );\n}\n\n/**\n * Whether a control needs telling from its neighbours in words.\n *\n * Only a bare value box does: a number or a string is a box of characters,\n * and two of them side by side are indistinguishable. Everything else shows\n * what it is — a swatch is a color, a font picker names the family, a flag\n * run and a segmented control label their own segments — so a word in front\n * would repeat what the control already says. `name` stays the accessible\n * name either way, so this costs a screen reader nothing.\n */\nfunction needsLabel(leaf: ToolPrefLeaf): boolean {\n return leaf.kind === 'number' || leaf.kind === 'string';\n}\n\nfunction barCell(\n panelLeaf: PanelLeaf,\n ariaLabel: string,\n values: Readonly<Record<string, unknown>> | undefined,\n mixed: ReadonlySet<string> | undefined,\n renderers: Record<string, PropertyRenderer> | undefined,\n onChange: ((path: string, value: unknown) => void) | undefined,\n): LeafCell {\n const { path, leaf } = panelLeaf;\n const isMixed = mixed?.has(path) === true;\n const ctx: PropertyRenderContext = {\n path,\n pref: leaf,\n value: isMixed ? undefined : values?.[path],\n mixed: isMixed,\n unset: !isMixed && values?.[path] === undefined,\n setValue: (v) => onChange?.(path, v),\n valueAt: (p) => ({ value: values?.[p], mixed: mixed?.has(p) === true }),\n };\n return {\n key: path,\n leaf: leaf as ToolPrefLeaf,\n ctx,\n ariaLabel,\n render: () => {\n const custom = renderers?.[path] ?? renderers?.[leaf.kind];\n return custom ? custom(ctx) : renderBuiltin(ctx, ariaLabel, renderers, path);\n },\n };\n}\n"],"mappings":";;;;;;;;;;;ACgEA,SAAgB,EAAe,GAA4B;CACzD,IAAM,EAAE,UAAO,WAAQ,WAAQ,aAAU,UAAO,cAAW,aAAU,iBAAc;AAEnF,QACE,kBAAC,OAAD;EAAK,WAFK,CAAC,EAAE,MAAM,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAEnC;EAAK,MAAK;EAAU,cAAY;YAAhD,CACG,MAAU,KAAA,KAAa,kBAAC,QAAD;GAAM,WAAW,EAAE;aAAQ;GAAa,CAAA,EAChE,kBAAC,OAAD;GAAK,WAAW,EAAE;aAAlB,CACG,MAAW,KAAA,KACV,EAAQ,EAAO,CAAC,KAAK,MACnB,kBAAC,GAAD;IAEO;IACG;IACD;IACI;IACD;IACV,EANK,EAAI,OAAO,GAAI,KAMpB,CACF,EACH,EACG;KACF;;;AAUV,SAAS,EAAQ,GAAmC;CAClD,IAAM,IAAsB,EAAE,EACxB,KAAW,GAAsB,MAAyB;AAC9D,OAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAM,SAAS,EAAE;GACzD,IAAM,IAAO,MAAW,KAAK,IAAM,GAAG,EAAO,GAAG;AAChD,GAAI,EAAQ,EAAM,GAAE,EAAQ,GAAO,EAAK,GAC/B,EAAM,WAAW,MAAM,EAAO,KAAK;IAAE;IAAM,MAAM;IAAO,CAAC;;;AAItE,QADA,EAAQ,GAAQ,GAAG,EACZ,EAAS,EAAO;;AAIzB,SAAS,EAAO,EACd,QACA,WACA,UACA,cACA,eAOC;AAMD,QACE,kBAAA,GAAA,EAAA,UACG,EALS,EAAI,OAAO,KAAK,MAC5B,EAAQ,GAAW,EAAU,KAAK,MAAM,GAAQ,GAAO,GAAW,EAAS,CAI5D,EAAO,EAAU,CAAC,KAAK,MAClC,kBAAC,QAAD;EAAqB,WAAW,EAAE;YAAlC,CACG,EAAW,EAAK,KAAK,IACpB,kBAAC,QAAD;GAAM,WAAW,EAAE;GAAW,eAAY;aACvC,EAAK,KAAK,SAAS,EAAK,KAAK;GACzB,CAAA,EAER,EAAK,QACD;IAPI,EAAK,IAOT,CACP,EACD,CAAA;;AAcP,SAAS,EAAW,GAA6B;AAC/C,QAAO,EAAK,SAAS,YAAY,EAAK,SAAS;;AAGjD,SAAS,EACP,GACA,GACA,GACA,GACA,GACA,GACU;CACV,IAAM,EAAE,SAAM,YAAS,GACjB,IAAU,GAAO,IAAI,EAAK,KAAK,IAC/B,IAA6B;EACjC;EACA,MAAM;EACN,OAAO,IAAU,KAAA,IAAY,IAAS;EACtC,OAAO;EACP,OAAO,CAAC,KAAW,IAAS,OAAU,KAAA;EACtC,WAAW,MAAM,IAAW,GAAM,EAAE;EACpC,UAAU,OAAO;GAAE,OAAO,IAAS;GAAI,OAAO,GAAO,IAAI,EAAE,KAAK;GAAM;EACvE;AACD,QAAO;EACL,KAAK;EACC;EACN;EACA;EACA,cAAc;GACZ,IAAM,IAAS,IAAY,MAAS,IAAY,EAAK;AACrD,UAAO,IAAS,EAAO,EAAI,GAAG,EAAc,GAAK,GAAW,GAAW,EAAK;;EAE/E"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ToolPalette-Uw4PvWwa.js","names":[],"sources":["../../src/components/ToolPalette/ToolPalette.module.css","../../src/components/ToolPalette/ToolPalette.tsx"],"sourcesContent":[".palette {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-2);\n background: var(--wzl-surface);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n padding: var(--wzl-space-2);\n user-select: none;\n}\n.palette.horizontal {\n flex-direction: row;\n}\n\n/* Marker only — `useRovingTabIndex` finds the palette's buttons by this class.\n Carries no styles; deleting it breaks keyboard navigation. */\n.paletteBtn {}\n\n/* Applied to ineligible tool buttons in the active mode. */\n.ineligibleBtn {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.separator {\n background: var(--wzl-border);\n}\n.palette:not(.horizontal) .separator {\n height: 1px;\n margin: var(--wzl-space-1) 0;\n}\n.palette.horizontal .separator {\n width: 1px;\n margin: 0 var(--wzl-space-1);\n}\n","import { Fragment, type ReactNode } from 'react';\nimport { UnknownIcon } from '@weasel-js/core';\nimport type { AnyTool, ToolsApi } from '@weasel-js/core';\nimport { eligibleContribution, type ModeRegistry } from '@weasel-js/modes';\nimport { ToolButton } from '../ToolButton';\nimport { ToolGroup } from '../ToolGroup';\nimport { useRovingTabIndex } from '../../useRovingTabIndex';\nimport s from './ToolPalette.module.css';\nimport { formatShortcut, type ShortcutInput } from './formatShortcut';\n\nconst DEFAULT_GROUP_ORDER = ['select', 'shape', 'draw', 'type', 'view'] as const;\nconst MISC = 'misc';\n\nfunction partitionByGroup(list: AnyTool[]): Map<string, AnyTool[]> {\n const groups = new Map<string, AnyTool[]>();\n for (const tool of list) {\n const g = tool.presentation?.group ?? MISC;\n const bucket = groups.get(g) ?? [];\n bucket.push(tool);\n groups.set(g, bucket);\n }\n return groups;\n}\n\nfunction orderedGroupKeys(\n groups: Map<string, AnyTool[]>,\n groupOrder: readonly string[],\n): string[] {\n const seen = new Set(groups.keys());\n const ordered: string[] = [];\n for (const known of groupOrder) {\n if (seen.has(known)) {\n ordered.push(known);\n seen.delete(known);\n }\n }\n // Unknown groups in insertion order (Map preserves it), misc last.\n for (const key of groups.keys()) {\n if (seen.has(key) && key !== MISC) {\n ordered.push(key);\n seen.delete(key);\n }\n }\n if (seen.has(MISC)) ordered.push(MISC);\n return ordered;\n}\n\nfunction resolveIcon(tool: AnyTool): ReactNode {\n const rawIcon = tool.presentation?.icon;\n if (rawIcon == null) return <UnknownIcon />;\n if (typeof rawIcon === 'function') return rawIcon(undefined);\n return rawIcon;\n}\n\n/** Props for {@link ToolPalette}. */\nexport interface ToolPaletteProps {\n tools: ToolsApi;\n orientation?: 'vertical' | 'horizontal';\n className?: string;\n /** Derive the keyboard shortcut for a tool button from the action registry.\n * Called with the tool's id; return `undefined` to suppress a chip. When\n * omitted, falls back to `tool.keybinding` (legacy path). */\n lookupShortcut?: (toolId: string) => ShortcutInput | undefined;\n /**\n * Optional mode registry. When provided, tools whose\n * `eligibility.capabilities` do not match the current mode are rendered\n * greyed-out, aria-disabled, and their onClick is suppressed. When omitted,\n * all tools are treated as eligible (preserves existing behavior in\n * consumers that haven't wired a registry).\n */\n modeRegistry?: ModeRegistry;\n /**\n * Presentation-group display order. Groups not listed keep their registry\n * insertion order after the listed ones; `misc` always renders last.\n * Defaults to `['select', 'shape', 'draw', 'type', 'view']`.\n */\n groupOrder?: readonly string[];\n}\n\n/**\n * Toolbar of the registered tools, split into separator-divided groups by\n * each tool's presentation group and navigable by arrow keys. Clicking a\n * button makes that tool active.\n *\n * Given a `modeRegistry`, tools whose capabilities the current mode does not\n * allow render greyed out and inert rather than disappearing.\n */\nexport function ToolPalette(props: ToolPaletteProps) {\n const {\n tools, orientation = 'vertical', className, lookupShortcut, modeRegistry,\n groupOrder = DEFAULT_GROUP_ORDER,\n } = props;\n const list = Object.values(tools.registry);\n const groups = partitionByGroup(list);\n const groupKeys = orderedGroupKeys(groups, groupOrder);\n const cls = [s.palette, orientation === 'horizontal' && s.horizontal, className]\n .filter(Boolean).join(' ');\n\n // Flat, in DOM order — the roving-tabindex hook indexes by this order.\n const ordered = groupKeys.flatMap((k) => groups.get(k)!);\n const eligibility = ordered.map(\n (tool) => (modeRegistry ? eligibleContribution(modeRegistry, tool) : true),\n );\n const activeIndex = ordered.findIndex((t) => t.id === tools.active);\n const roving = useRovingTabIndex({\n items: eligibility.map((enabled) => ({ disabled: !enabled })),\n itemClassName: s.paletteBtn,\n // An ineligible active tool can't hold the tab stop; fall back to the\n // hook's first-enabled default.\n ...(activeIndex >= 0 && eligibility[activeIndex] ? { tabStopIndex: activeIndex } : {}),\n });\n let index = -1;\n\n return (\n <div\n ref={roving.rootRef}\n className={cls}\n role=\"toolbar\"\n aria-label=\"Tools\"\n >\n {groupKeys.map((key, i) => (\n <Fragment key={key}>\n {i > 0 && (\n <div\n className={s.separator}\n role=\"separator\"\n aria-orientation={orientation === 'horizontal' ? 'vertical' : 'horizontal'}\n />\n )}\n <ToolGroup orientation={orientation} groupKey={key}>\n {groups.get(key)!.map((tool) => {\n const i = ++index;\n const label = tool.presentation?.label ?? tool.id;\n const shortcut = tool.presentation?.shortcut\n ?? formatShortcut(lookupShortcut ? lookupShortcut(tool.id) : tool.keybinding);\n const enabled = eligibility[i];\n const modeName = modeRegistry ? modeRegistry.current().id : undefined;\n const resolvedTitle = !enabled && modeName\n ? `${label}${shortcut ? ` (${shortcut})` : ''} — disabled in ${modeName} mode`\n : undefined;\n return (\n <ToolButton\n key={tool.id}\n icon={resolveIcon(tool)}\n label={label}\n shortcut={shortcut}\n active={tools.active === tool.id}\n tabbable={roving.tabIndexFor(i) === 0}\n ariaDisabled={!enabled}\n className={[s.paletteBtn, !enabled && s.ineligibleBtn].filter(Boolean).join(' ')}\n title={resolvedTitle}\n onClick={enabled ? () => tools.setActive(tool.id) : () => {}}\n onKeyDown={roving.onKeyDown(i)}\n />\n );\n })}\n </ToolGroup>\n </Fragment>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip-9XiJF937.js","names":[],"sources":["../../src/components/Tooltip/Tooltip.module.css","../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":[".tooltip {\n /* Above Dialog overlay (1000) and ToastRegion (1100) — RAC sets no z-index. */\n z-index: 1200;\n background: var(--wzl-surface);\n border: 1px solid var(--wzl-border);\n border-radius: var(--wzl-radius-sm);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);\n color: var(--wzl-fg);\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size-sm);\n line-height: 1.3;\n padding: var(--wzl-space-2) var(--wzl-space-4);\n max-width: 260px;\n transition: opacity var(--wzl-motion-fast);\n}\n\n.tooltip[data-entering],\n.tooltip[data-exiting] {\n opacity: 0;\n}\n\n.arrow svg {\n display: block;\n fill: var(--wzl-surface);\n stroke: var(--wzl-border);\n stroke-width: 1;\n}\n\n.arrow[data-placement='bottom'] svg {\n transform: rotate(180deg);\n}\n\n.arrow[data-placement='left'] svg {\n transform: rotate(-90deg);\n}\n\n.arrow[data-placement='right'] svg {\n transform: rotate(90deg);\n}\n","import type { ReactNode } from 'react';\nimport {\n TooltipTrigger as RACTooltipTrigger,\n Tooltip as RACTooltip,\n OverlayArrow,\n type TooltipProps as RACTooltipProps,\n type TooltipTriggerComponentProps,\n} from 'react-aria-components';\nimport { useOverlayPortal, type OverlayPortalProps, type WithoutPortalTarget } from '../../overlays/portalHost';\nimport s from './Tooltip.module.css';\n\n/** Makes a non-RAC element a {@link TooltipTrigger} trigger: supplies\n * `tabIndex`, the hover/focus handlers and `aria-describedby`. The child must\n * forward its ref and DOM props, and carry an interactive role (or `img`). */\nexport { Focusable } from 'react-aria-components';\n\n/**\n * Props for {@link TooltipTrigger} — React Aria's `TooltipTrigger` props\n * unchanged.\n */\nexport type TooltipTriggerProps = TooltipTriggerComponentProps;\n\n/**\n * TooltipTrigger with kit defaults: ~600 ms open delay, instant close.\n * Wrap a focusable trigger plus a `<Tooltip>`. Non-RAC triggers (plain\n * `<button>`, a `Badge` etc.) must be wrapped in {@link Focusable} so\n * hover/focus props reach the DOM node.\n *\n * Caveat: while a tooltip is open, react-aria captures the first Escape\n * keydown (document-level, capture phase) to dismiss it — app-level\n * Escape handlers (deselect, cancel gesture) see only the second press.\n */\nexport function TooltipTrigger(props: TooltipTriggerProps) {\n const { delay = 600, closeDelay = 0, ...rest } = props;\n return <RACTooltipTrigger delay={delay} closeDelay={closeDelay} {...rest} />;\n}\n\n/** Props for {@link Tooltip}, on top of React Aria's `Tooltip` props. */\nexport type TooltipProps = Omit<WithoutPortalTarget<RACTooltipProps>, 'children' | 'className'> &\n OverlayPortalProps & {\n children?: ReactNode;\n className?: string;\n };\n\n/**\n * Tooltip bubble with an arrow pointing at the trigger. Non-interactive\n * content only (ARIA tooltip semantics). Use inside `<TooltipTrigger>`.\n */\nexport function Tooltip(props: TooltipProps) {\n const { children, className, placement = 'top', offset = 8, portalContainer, ...rest } = props;\n const { anchor, portalProps } = useOverlayPortal(portalContainer);\n return (\n <>\n {anchor}\n <RACTooltip\n {...rest}\n placement={placement}\n offset={offset}\n className={[s.tooltip, className].filter(Boolean).join(' ')}\n data-weasel-overlay=\"\"\n {...portalProps}\n >\n <OverlayArrow className={s.arrow}>\n <svg width={8} height={8} viewBox=\"0 0 8 8\" aria-hidden=\"true\">\n <path d=\"M0 0 L4 4 L8 0\" />\n </svg>\n </OverlayArrow>\n {children}\n </RACTooltip>\n </>\n );\n}\n"],"mappings":";;;;;;;;;ACgCA,SAAgB,EAAe,GAA4B;CACzD,IAAM,EAAE,WAAQ,KAAK,gBAAa,GAAG,GAAG,MAAS;AACjD,QAAO,kBAAC,GAAD;EAA0B;EAAmB;EAAY,GAAI;EAAQ,CAAA;;AAc9E,SAAgB,EAAQ,GAAqB;CAC3C,IAAM,EAAE,aAAU,cAAW,eAAY,OAAO,YAAS,GAAG,oBAAiB,GAAG,MAAS,GACnF,EAAE,WAAQ,mBAAgB,EAAiB,EAAgB;AACjE,QACE,kBAAA,GAAA,EAAA,UAAA,CACG,GACD,kBAAC,GAAD;EACE,GAAI;EACO;EACH;EACR,WAAW,CAAC,EAAE,SAAS,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;EAC3D,uBAAoB;EACpB,GAAI;YANN,CAQE,kBAAC,GAAD;GAAc,WAAW,EAAE;aACzB,kBAAC,OAAD;IAAK,OAAO;IAAG,QAAQ;IAAG,SAAQ;IAAU,eAAY;cACtD,kBAAC,QAAD,EAAM,GAAE,kBAAmB,CAAA;IACvB,CAAA;GACO,CAAA,EACd,EACU;IACZ,EAAA,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Tree-BGt6P8tI.js","names":[],"sources":["../../src/components/Tree/Tree.module.css","../../src/components/Tree/Tree.tsx"],"sourcesContent":[".tree,\n.group {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.tree {\n user-select: none;\n -webkit-user-select: none;\n width: 100%;\n}\n\n/* One twisty and one gap, so a child's twisty sits under its parent's label. */\n.group {\n padding-inline-start: var(--wzl-tree-indent, calc(var(--wzl-control-h-xs) + var(--wzl-space-2)));\n}\n\n.item {\n outline: none;\n}\n\n.row {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-2);\n padding: 0 var(--wzl-space-2) 0 0;\n height: var(--wzl-control-h);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg);\n border-radius: var(--wzl-radius-sm);\n cursor: default;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.row:hover {\n background: var(--wzl-surface);\n}\n\n.item:focus-visible > .row {\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: -2px;\n}\n\n.item[aria-selected='true'] > .row {\n background: var(--wzl-border);\n}\n\n.item[data-muted] > .row {\n color: var(--wzl-fg-subtle);\n}\n\n.item[aria-disabled='true'] > .row {\n color: var(--wzl-fg-subtle);\n cursor: not-allowed;\n}\n\n/* A leaf keeps the empty box, so labels at one level line up whether or not\n their rows are branches. */\n.twisty {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--wzl-control-h-xs);\n align-self: stretch;\n color: var(--wzl-fg-muted);\n}\n\n.row:hover > .twisty {\n color: var(--wzl-fg);\n}\n\n.leading {\n flex: none;\n display: inline-flex;\n align-items: center;\n}\n\n.label {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.trailing {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--wzl-space-2);\n}\n\n.empty {\n padding: var(--wzl-space-6) var(--wzl-space-4);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-subtle);\n font-style: italic;\n}\n","/**\n * A hierarchy of rows that expand and collapse: a file tree, a registry\n * browser, an outline.\n *\n * **Semantics.** WAI-ARIA `tree`: each node is a `treeitem` carrying\n * `aria-level`, `aria-setsize` and `aria-posinset`; a branch carries\n * `aria-expanded` and nests its children in a `group`, which is rendered only\n * while the branch is open. `aria-selected` appears only when `selectionMode`\n * is set. A treeitem may not contain interactive content, so `leading` and\n * `trailing` are decoration — an icon, a count — and the twisty is a drawn\n * `DisclosureMark`, not a button.\n *\n * **Keyboard.** One treeitem is in the tab order: the one last focused, else\n * the first selected, else the first. Up/Down move between visible rows,\n * Home/End go to the first and last. Right opens a closed branch, then moves\n * into it; Left closes an open branch, else moves to the parent. Enter and\n * Space activate, as a click does. Typing moves to the next row whose text\n * starts with what was typed.\n *\n * **Activating** a row — click, Enter, Space — toggles it if it is a branch,\n * selects it under `selectionMode`, and calls `onAction`. Clicking the twisty\n * only toggles.\n *\n * **Filtering** is the consumer's: narrow `nodes` with `filterTree`, and pass\n * `treeBranchIds` of the result as `expandedIds` so every match shows.\n */\nimport {\n forwardRef,\n useId,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n} from 'react';\nimport type { PressModifiers } from '../../useReorderDragList';\nimport { DisclosureMark } from '../Disclosure';\nimport s from './Tree.module.css';\n\n/** One node. A node with `children` is a branch, even when the array is empty. */\nexport interface TreeNode {\n /** Unique across the whole tree. */\n id: string;\n label: ReactNode;\n /** What type-ahead matches against. Defaults to `label` when that is a string. */\n textValue?: string;\n /** Decoration before the label — an icon. Not a control. */\n leading?: ReactNode;\n /** Decoration after the label — a count badge. Not a control. Read as part\n * of the row's accessible name. */\n trailing?: ReactNode;\n children?: readonly TreeNode[];\n /** Present but not in effect. */\n muted?: boolean;\n /** Focusable and announced, but cannot be activated, expanded or selected. */\n disabled?: boolean;\n className?: string;\n}\n\n/** Whether and how rows are selectable. */\nexport type TreeSelectionMode = 'none' | 'single' | 'multiple';\n\nexport interface TreeProps {\n nodes: readonly TreeNode[];\n /** Shown in place of the tree when `nodes` is empty. */\n empty?: ReactNode;\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n\n /** Open branches, controlled. */\n expandedIds?: Iterable<string>;\n /** Open branches on first render, when uncontrolled. */\n defaultExpandedIds?: Iterable<string>;\n /** The whole set a toggle would produce. Called whether or not controlled. */\n onExpandedChange?(ids: Set<string>): void;\n\n /** Default `'none'`. `'multiple'` adds to the selection with Cmd/Ctrl and\n * extends it over visible rows with Shift. */\n selectionMode?: TreeSelectionMode;\n /** Selected rows, controlled. */\n selectedIds?: Iterable<string>;\n /** Selected rows on first render, when uncontrolled. */\n defaultSelectedIds?: Iterable<string>;\n /** The whole set an activation would produce, when it differs. */\n onSelectionChange?(ids: Set<string>): void;\n\n /** A row was activated — click, Enter or Space — with the modifiers held. */\n onAction?(id: string, mods: PressModifiers): void;\n}\n\ninterface Visible {\n node: TreeNode;\n parentId: string | null;\n level: number;\n}\n\nconst TYPEAHEAD_MS = 500;\n\nexport const Tree = forwardRef(function Tree(\n {\n nodes, empty, className,\n 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy,\n expandedIds, defaultExpandedIds, onExpandedChange,\n selectionMode = 'none', selectedIds, defaultSelectedIds, onSelectionChange,\n onAction,\n }: TreeProps,\n ref: Ref<HTMLUListElement>,\n) {\n const [expanded, setExpanded] = useControlledSet(expandedIds, defaultExpandedIds, onExpandedChange);\n const [selected, setSelected] = useControlledSet(selectedIds, defaultSelectedIds, onSelectionChange);\n const selectable = selectionMode !== 'none';\n const baseId = useId();\n\n const visible = useMemo(() => {\n const out: Visible[] = [];\n const walk = (list: readonly TreeNode[], parentId: string | null, level: number) => {\n for (const node of list) {\n out.push({ node, parentId, level });\n if (node.children && expanded.has(node.id)) walk(node.children, node.id, level + 1);\n }\n };\n walk(nodes, null, 1);\n return out;\n }, [nodes, expanded]);\n const indexOf = useMemo(() => new Map(visible.map((v, i) => [v.node.id, i])), [visible]);\n\n const items = useRef(new Map<string, HTMLLIElement>());\n const [focusId, setFocusId] = useState<string | null>(null);\n const anchor = useRef<string | null>(null);\n const typed = useRef({ text: '', at: 0 });\n\n const stopId = focusId != null && indexOf.has(focusId)\n ? focusId\n : (visible.find((v) => selectable && selected.has(v.node.id)) ?? visible[0])?.node.id;\n\n if (nodes.length === 0) {\n return <div className={[s.empty, className].filter(Boolean).join(' ')}>{empty ?? '—'}</div>;\n }\n\n const focus = (id: string | undefined) => { if (id != null) items.current.get(id)?.focus(); };\n\n const toggle = (node: TreeNode) => {\n if (!node.children || node.disabled) return;\n const next = new Set(expanded);\n if (next.has(node.id)) next.delete(node.id);\n else next.add(node.id);\n setExpanded(next);\n };\n\n const select = (id: string, mods: PressModifiers) => {\n let next: Set<string>;\n if (selectionMode === 'multiple' && mods.shiftKey && anchor.current != null && indexOf.has(anchor.current)) {\n const a = indexOf.get(anchor.current)!;\n const b = indexOf.get(id)!;\n next = new Set(visible.slice(Math.min(a, b), Math.max(a, b) + 1)\n .filter((v) => !v.node.disabled).map((v) => v.node.id));\n } else if (selectionMode === 'multiple' && (mods.metaKey || mods.ctrlKey)) {\n next = new Set(selected);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n anchor.current = id;\n } else {\n next = new Set([id]);\n anchor.current = id;\n }\n if (next.size !== selected.size || [...next].some((x) => !selected.has(x))) setSelected(next);\n };\n\n const activate = (node: TreeNode, mods: PressModifiers) => {\n if (node.disabled) return;\n toggle(node);\n if (selectable) select(node.id, mods);\n onAction?.(node.id, mods);\n };\n\n const onKeyDown = (v: Visible) => (e: KeyboardEvent<HTMLLIElement>) => {\n if (e.target !== e.currentTarget) return;\n const i = indexOf.get(v.node.id)!;\n const { node } = v;\n const open = !!node.children && expanded.has(node.id);\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n focus(visible[Math.min(i + 1, visible.length - 1)].node.id);\n return;\n case 'ArrowUp':\n e.preventDefault();\n focus(visible[Math.max(i - 1, 0)].node.id);\n return;\n case 'Home':\n e.preventDefault();\n focus(visible[0].node.id);\n return;\n case 'End':\n e.preventDefault();\n focus(visible[visible.length - 1].node.id);\n return;\n case 'ArrowRight':\n if (!node.children) return;\n e.preventDefault();\n if (!open) toggle(node);\n else focus(node.children[0]?.id);\n return;\n case 'ArrowLeft':\n e.preventDefault();\n if (open) toggle(node);\n else focus(v.parentId ?? undefined);\n return;\n case 'Enter':\n case ' ':\n e.preventDefault();\n activate(node, modsOf(e));\n return;\n default:\n if (e.key.length !== 1 || e.ctrlKey || e.metaKey || e.altKey) return;\n typeAhead(e, i);\n }\n };\n\n const typeAhead = (e: KeyboardEvent, from: number) => {\n const now = Date.now();\n const t = typed.current;\n t.text = now - t.at > TYPEAHEAD_MS ? e.key : t.text + e.key;\n t.at = now;\n const want = t.text.toLowerCase();\n // A fresh first letter looks past the current row; a longer prefix may still match it.\n const start = t.text.length === 1 ? from + 1 : from;\n for (let k = 0; k < visible.length; k++) {\n const v = visible[(start + k) % visible.length];\n if (textOf(v.node).toLowerCase().startsWith(want)) {\n e.preventDefault();\n focus(v.node.id);\n return;\n }\n }\n };\n\n const onRowClick = (node: TreeNode) => (e: MouseEvent<HTMLDivElement>) => activate(node, modsOf(e));\n\n const onTwistyClick = (node: TreeNode) => (e: MouseEvent<HTMLSpanElement>) => {\n e.stopPropagation();\n toggle(node);\n };\n\n const itemRef = (id: string) => (el: HTMLLIElement | null) => {\n if (el) items.current.set(id, el);\n else items.current.delete(id);\n };\n\n let seq = 0;\n const renderLevel = (list: readonly TreeNode[], parentId: string | null, level: number): ReactNode =>\n list.map((node, pos) => {\n const n = seq++;\n const branch = !!node.children;\n const open = branch && expanded.has(node.id);\n const labelId = `${baseId}-${n}`;\n const trailingId = node.trailing != null ? `${baseId}-${n}-t` : undefined;\n return (\n <li\n key={node.id}\n ref={itemRef(node.id)}\n role=\"treeitem\"\n className={[s.item, node.className].filter(Boolean).join(' ')}\n aria-level={level}\n aria-setsize={list.length}\n aria-posinset={pos + 1}\n aria-expanded={branch ? open : undefined}\n aria-selected={selectable ? selected.has(node.id) : undefined}\n aria-disabled={node.disabled || undefined}\n aria-labelledby={trailingId ? `${labelId} ${trailingId}` : labelId}\n data-muted={node.muted ? 'true' : undefined}\n tabIndex={node.id === stopId ? 0 : -1}\n onKeyDown={onKeyDown({ node, parentId, level })}\n onFocus={(e) => { if (e.target === e.currentTarget) setFocusId(node.id); }}\n >\n <div className={s.row} onClick={onRowClick(node)}>\n <span className={s.twisty} aria-hidden=\"true\" onClick={branch ? onTwistyClick(node) : undefined}>\n {branch && <DisclosureMark open={open} />}\n </span>\n {node.leading != null && <span className={s.leading}>{node.leading}</span>}\n <span id={labelId} className={s.label}>{node.label}</span>\n {trailingId && <span id={trailingId} className={s.trailing}>{node.trailing}</span>}\n </div>\n {open && node.children!.length > 0 && (\n <ul role=\"group\" className={s.group}>\n {renderLevel(node.children!, node.id, level + 1)}\n </ul>\n )}\n </li>\n );\n });\n\n return (\n <ul\n ref={ref}\n role=\"tree\"\n className={[s.tree, className].filter(Boolean).join(' ')}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-multiselectable={selectionMode === 'multiple' || undefined}\n >\n {renderLevel(nodes, null, 1)}\n </ul>\n );\n});\n\n/**\n * `nodes` narrowed to those `match` accepts, plus their ancestors. A matching\n * node keeps its whole subtree; a branch with no match inside it is dropped.\n * Returns `nodes` itself when nothing is dropped.\n */\nexport function filterTree(\n nodes: readonly TreeNode[],\n match: (node: TreeNode) => boolean,\n): readonly TreeNode[] {\n let changed = false;\n const out: TreeNode[] = [];\n for (const node of nodes) {\n if (match(node)) {\n out.push(node);\n continue;\n }\n const kids = node.children ? filterTree(node.children, match) : [];\n if (kids.length === 0) {\n changed = true;\n continue;\n }\n if (kids !== node.children) changed = true;\n out.push(kids === node.children ? node : { ...node, children: kids });\n }\n return changed ? out : nodes;\n}\n\n/** Every branch id in `nodes`, depth first — `expandedIds` for a tree with everything open. */\nexport function treeBranchIds(nodes: readonly TreeNode[]): string[] {\n const out: string[] = [];\n const walk = (list: readonly TreeNode[]) => {\n for (const node of list) {\n if (!node.children) continue;\n out.push(node.id);\n walk(node.children);\n }\n };\n walk(nodes);\n return out;\n}\n\nfunction textOf(node: TreeNode): string {\n return node.textValue ?? (typeof node.label === 'string' ? node.label : '');\n}\n\nfunction modsOf(e: { shiftKey: boolean; ctrlKey: boolean; metaKey: boolean; altKey: boolean }): PressModifiers {\n return { shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, altKey: e.altKey };\n}\n\nfunction useControlledSet(\n value: Iterable<string> | undefined,\n initial: Iterable<string> | undefined,\n onChange: ((ids: Set<string>) => void) | undefined,\n): [ReadonlySet<string>, (next: Set<string>) => void] {\n const [own, setOwn] = useState<ReadonlySet<string>>(() => new Set(initial));\n const controlled = useMemo(() => (value === undefined ? undefined : new Set(value)), [value]);\n const set = (next: Set<string>) => {\n if (value === undefined) setOwn(next);\n onChange?.(next);\n };\n return [controlled ?? own, set];\n}\n"],"mappings":";;;;;;;;;;;;;GCmGM,IAAe,KAER,IAAO,EAAW,SAC7B,EACE,UAAO,UAAO,cACd,cAAc,GAAW,mBAAmB,GAC5C,gBAAa,uBAAoB,qBACjC,mBAAgB,QAAQ,gBAAa,uBAAoB,sBACzD,eAEF,GACA;CACA,IAAM,CAAC,GAAU,KAAe,EAAiB,GAAa,GAAoB,EAAiB,EAC7F,CAAC,GAAU,KAAe,EAAiB,GAAa,GAAoB,EAAkB,EAC9F,IAAa,MAAkB,QAC/B,IAAS,GAAO,EAEhB,IAAU,QAAc;EAC5B,IAAM,IAAiB,EAAE,EACnB,KAAQ,GAA2B,GAAyB,MAAkB;AAClF,QAAK,IAAM,KAAQ,EAEjB,CADA,EAAI,KAAK;IAAE;IAAM;IAAU;IAAO,CAAC,EAC/B,EAAK,YAAY,EAAS,IAAI,EAAK,GAAG,IAAE,EAAK,EAAK,UAAU,EAAK,IAAI,IAAQ,EAAE;;AAIvF,SADA,EAAK,GAAO,MAAM,EAAE,EACb;IACN,CAAC,GAAO,EAAS,CAAC,EACf,IAAU,QAAc,IAAI,IAAI,EAAQ,KAAK,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAQ,CAAC,EAElF,IAAQ,kBAAO,IAAI,KAA4B,CAAC,EAChD,CAAC,GAAS,KAAc,EAAwB,KAAK,EACrD,IAAS,EAAsB,KAAK,EACpC,IAAQ,EAAO;EAAE,MAAM;EAAI,IAAI;EAAG,CAAC,EAEnC,IAAS,KAAW,QAAQ,EAAQ,IAAI,EAAQ,GAClD,KACC,EAAQ,MAAM,MAAM,KAAc,EAAS,IAAI,EAAE,KAAK,GAAG,CAAC,IAAI,EAAQ,KAAK,KAAK;AAErF,KAAI,EAAM,WAAW,EACnB,QAAO,kBAAC,OAAD;EAAK,WAAW,CAAC,EAAE,OAAO,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;YAAG,KAAS;EAAU,CAAA;CAG7F,IAAM,KAAS,MAA2B;AAAE,EAAI,KAAM,QAAM,EAAM,QAAQ,IAAI,EAAG,EAAE,OAAO;IAEpF,KAAU,MAAmB;AACjC,MAAI,CAAC,EAAK,YAAY,EAAK,SAAU;EACrC,IAAM,IAAO,IAAI,IAAI,EAAS;AAG9B,EAFI,EAAK,IAAI,EAAK,GAAG,GAAE,EAAK,OAAO,EAAK,GAAG,GACtC,EAAK,IAAI,EAAK,GAAG,EACtB,EAAY,EAAK;IAGb,KAAU,GAAY,MAAyB;EACnD,IAAI;AACJ,MAAI,MAAkB,cAAc,EAAK,YAAY,EAAO,WAAW,QAAQ,EAAQ,IAAI,EAAO,QAAQ,EAAE;GAC1G,IAAM,IAAI,EAAQ,IAAI,EAAO,QAAQ,EAC/B,IAAI,EAAQ,IAAI,EAAG;AACzB,OAAO,IAAI,IAAI,EAAQ,MAAM,KAAK,IAAI,GAAG,EAAE,EAAE,KAAK,IAAI,GAAG,EAAE,GAAG,EAAE,CAC7D,QAAQ,MAAM,CAAC,EAAE,KAAK,SAAS,CAAC,KAAK,MAAM,EAAE,KAAK,GAAG,CAAC;SAChD,MAAkB,eAAe,EAAK,WAAW,EAAK,YAC/D,IAAO,IAAI,IAAI,EAAS,EACpB,EAAK,IAAI,EAAG,GAAE,EAAK,OAAO,EAAG,GAC5B,EAAK,IAAI,EAAG,EACjB,EAAO,UAAU,MAEjB,IAAO,IAAI,IAAI,CAAC,EAAG,CAAC,EACpB,EAAO,UAAU;AAEnB,GAAI,EAAK,SAAS,EAAS,QAAQ,CAAC,GAAG,EAAK,CAAC,MAAM,MAAM,CAAC,EAAS,IAAI,EAAE,CAAC,KAAE,EAAY,EAAK;IAGzF,KAAY,GAAgB,MAAyB;AACrD,IAAK,aACT,EAAO,EAAK,EACR,KAAY,EAAO,EAAK,IAAI,EAAK,EACrC,IAAW,EAAK,IAAI,EAAK;IAGrB,KAAa,OAAgB,MAAoC;AACrE,MAAI,EAAE,WAAW,EAAE,cAAe;EAClC,IAAM,IAAI,EAAQ,IAAI,EAAE,KAAK,GAAG,EAC1B,EAAE,YAAS,GACX,IAAO,CAAC,CAAC,EAAK,YAAY,EAAS,IAAI,EAAK,GAAG;AACrD,UAAQ,EAAE,KAAV;GACE,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,EAAM,EAAQ,KAAK,IAAI,IAAI,GAAG,EAAQ,SAAS,EAAE,EAAE,KAAK,GAAG;AAC3D;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,EAAM,EAAQ,KAAK,IAAI,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG;AAC1C;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,EAAM,EAAQ,GAAG,KAAK,GAAG;AACzB;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,EAAM,EAAQ,EAAQ,SAAS,GAAG,KAAK,GAAG;AAC1C;GACF,KAAK;AACH,QAAI,CAAC,EAAK,SAAU;AAEpB,IADA,EAAE,gBAAgB,EACb,IACA,EAAM,EAAK,SAAS,IAAI,GAAG,GADrB,EAAO,EAAK;AAEvB;GACF,KAAK;AAEH,IADA,EAAE,gBAAgB,EACd,IAAM,EAAO,EAAK,GACjB,EAAM,EAAE,YAAY,KAAA,EAAU;AACnC;GACF,KAAK;GACL,KAAK;AAEH,IADA,EAAE,gBAAgB,EAClB,EAAS,GAAM,EAAO,EAAE,CAAC;AACzB;GACF;AACE,QAAI,EAAE,IAAI,WAAW,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,OAAQ;AAC9D,MAAU,GAAG,EAAE;;IAIf,KAAa,GAAkB,MAAiB;EACpD,IAAM,IAAM,KAAK,KAAK,EAChB,IAAI,EAAM;AAEhB,EADA,EAAE,OAAO,IAAM,EAAE,KAAK,IAAe,EAAE,MAAM,EAAE,OAAO,EAAE,KACxD,EAAE,KAAK;EACP,IAAM,IAAO,EAAE,KAAK,aAAa,EAE3B,IAAQ,EAAE,KAAK,WAAW,IAAI,IAAO,IAAI;AAC/C,OAAK,IAAI,IAAI,GAAG,IAAI,EAAQ,QAAQ,KAAK;GACvC,IAAM,IAAI,GAAS,IAAQ,KAAK,EAAQ;AACxC,OAAI,EAAO,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,EAAK,EAAE;AAEjD,IADA,EAAE,gBAAgB,EAClB,EAAM,EAAE,KAAK,GAAG;AAChB;;;IAKA,KAAc,OAAoB,MAAkC,EAAS,GAAM,EAAO,EAAE,CAAC,EAE7F,KAAiB,OAAoB,MAAmC;AAE5E,EADA,EAAE,iBAAiB,EACnB,EAAO,EAAK;IAGR,KAAW,OAAgB,MAA6B;AAC5D,EAAI,IAAI,EAAM,QAAQ,IAAI,GAAI,EAAG,GAC5B,EAAM,QAAQ,OAAO,EAAG;IAG3B,IAAM,GACJ,KAAe,GAA2B,GAAyB,MACvE,EAAK,KAAK,GAAM,MAAQ;EACtB,IAAM,IAAI,KACJ,IAAS,CAAC,CAAC,EAAK,UAChB,IAAO,KAAU,EAAS,IAAI,EAAK,GAAG,EACtC,IAAU,GAAG,EAAO,GAAG,KACvB,IAAa,EAAK,YAAY,OAA4B,KAAA,IAArB,GAAG,EAAO,GAAG,EAAE;AAC1D,SACE,kBAAC,MAAD;GAEE,KAAK,EAAQ,EAAK,GAAG;GACrB,MAAK;GACL,WAAW,CAAC,EAAE,MAAM,EAAK,UAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;GAC7D,cAAY;GACZ,gBAAc,EAAK;GACnB,iBAAe,IAAM;GACrB,iBAAe,IAAS,IAAO,KAAA;GAC/B,iBAAe,IAAa,EAAS,IAAI,EAAK,GAAG,GAAG,KAAA;GACpD,iBAAe,EAAK,YAAY,KAAA;GAChC,mBAAiB,IAAa,GAAG,EAAQ,GAAG,MAAe;GAC3D,cAAY,EAAK,QAAQ,SAAS,KAAA;GAClC,UAAU,EAAK,OAAO,IAAS,IAAI;GACnC,WAAW,EAAU;IAAE;IAAM;IAAU;IAAO,CAAC;GAC/C,UAAU,MAAM;AAAE,IAAI,EAAE,WAAW,EAAE,iBAAe,EAAW,EAAK,GAAG;;aAfzE,CAiBE,kBAAC,OAAD;IAAK,WAAW,EAAE;IAAK,SAAS,EAAW,EAAK;cAAhD;KACE,kBAAC,QAAD;MAAM,WAAW,EAAE;MAAQ,eAAY;MAAO,SAAS,IAAS,EAAc,EAAK,GAAG,KAAA;gBACnF,KAAU,kBAAC,GAAD,EAAsB,SAAQ,CAAA;MACpC,CAAA;KACN,EAAK,WAAW,QAAQ,kBAAC,QAAD;MAAM,WAAW,EAAE;gBAAU,EAAK;MAAe,CAAA;KAC1E,kBAAC,QAAD;MAAM,IAAI;MAAS,WAAW,EAAE;gBAAQ,EAAK;MAAa,CAAA;KACzD,KAAc,kBAAC,QAAD;MAAM,IAAI;MAAY,WAAW,EAAE;gBAAW,EAAK;MAAgB,CAAA;KAC9E;OACL,KAAQ,EAAK,SAAU,SAAS,KAC/B,kBAAC,MAAD;IAAI,MAAK;IAAQ,WAAW,EAAE;cAC3B,EAAY,EAAK,UAAW,EAAK,IAAI,IAAQ,EAAE;IAC7C,CAAA,CAEJ;KA7BE,EAAK,GA6BP;GAEP;AAEJ,QACE,kBAAC,MAAD;EACO;EACL,MAAK;EACL,WAAW,CAAC,EAAE,MAAM,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;EACxD,cAAY;EACZ,mBAAiB;EACjB,wBAAsB,MAAkB,cAAc,KAAA;YAErD,EAAY,GAAO,MAAM,EAAE;EACzB,CAAA;EAEP;AAOF,SAAgB,EACd,GACA,GACqB;CACrB,IAAI,IAAU,IACR,IAAkB,EAAE;AAC1B,MAAK,IAAM,KAAQ,GAAO;AACxB,MAAI,EAAM,EAAK,EAAE;AACf,KAAI,KAAK,EAAK;AACd;;EAEF,IAAM,IAAO,EAAK,WAAW,EAAW,EAAK,UAAU,EAAM,GAAG,EAAE;AAClE,MAAI,EAAK,WAAW,GAAG;AACrB,OAAU;AACV;;AAGF,EADI,MAAS,EAAK,aAAU,IAAU,KACtC,EAAI,KAAK,MAAS,EAAK,WAAW,IAAO;GAAE,GAAG;GAAM,UAAU;GAAM,CAAC;;AAEvE,QAAO,IAAU,IAAM;;AAIzB,SAAgB,EAAc,GAAsC;CAClE,IAAM,IAAgB,EAAE,EAClB,KAAQ,MAA8B;AAC1C,OAAK,IAAM,KAAQ,EACZ,GAAK,aACV,EAAI,KAAK,EAAK,GAAG,EACjB,EAAK,EAAK,SAAS;;AAIvB,QADA,EAAK,EAAM,EACJ;;AAGT,SAAS,EAAO,GAAwB;AACtC,QAAO,EAAK,cAAc,OAAO,EAAK,SAAU,WAAW,EAAK,QAAQ;;AAG1E,SAAS,EAAO,GAA+F;AAC7G,QAAO;EAAE,UAAU,EAAE;EAAU,SAAS,EAAE;EAAS,SAAS,EAAE;EAAS,QAAQ,EAAE;EAAQ;;AAG3F,SAAS,EACP,GACA,GACA,GACoD;CACpD,IAAM,CAAC,GAAK,KAAU,QAAoC,IAAI,IAAI,EAAQ,CAAC;AAM3E,QAAO,CALY,QAAe,MAAU,KAAA,IAAY,KAAA,IAAY,IAAI,IAAI,EAAM,EAAG,CAAC,EAAM,CAKpF,IAAc,IAJT,MAAsB;AAEjC,EADI,MAAU,KAAA,KAAW,EAAO,EAAK,EACrC,IAAW,EAAK;GAEa"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createKeyframeLayer-BzDRCrrh.js","names":[],"sources":["../../src/components/CurveEditor/hitTest.ts","../../src/handles.ts","../../src/components/CurveEditor/CurveEditor.module.css","../../src/components/CurveEditor/LayeredCurveEditor.tsx","../../src/components/CurveEditor/createKeyframeLayer.tsx"],"sourcesContent":["/**\n * Curve-specific hit tests. Generic coord transforms live in\n * `../Plot2D/geometry`; what's here is curve-only (anchor / polyline\n * proximity).\n */\nimport type { Point } from '../Plot2D/geometry';\n\n/**\n * Nearest-anchor hit test. Anchors are already in plot/screen coords.\n * Returns the index of the nearest anchor whose squared distance to\n * the pointer is ≤ radius². Null if no anchor is within radius.\n */\nexport function hitTestAnchor(\n anchors: readonly Point[],\n pointer: Point,\n radius: number,\n): { index: number } | null {\n const r2 = radius * radius;\n let best: { index: number; d2: number } | null = null;\n for (let i = 0; i < anchors.length; i++) {\n const a = anchors[i];\n const dx = a.x - pointer.x;\n const dy = a.y - pointer.y;\n const d2 = dx * dx + dy * dy;\n if (d2 > r2) continue;\n if (best === null || d2 < best.d2) best = { index: i, d2 };\n }\n return best ? { index: best.index } : null;\n}\n\n/**\n * Hit test against a per-segment sampled polyline. Each entry in\n * `segments` is the sample list for one segment (inclusive of\n * endpoints). Returns segment index + t (∈ [0, 1]) of the closest\n * point on the polyline within radius. Null if nothing is in range.\n *\n * Distance is measured to the line-segment chords between adjacent\n * samples, not just to the samples themselves — so sparse sampling\n * still produces accurate hits along the chord.\n */\nexport function hitTestCurve(\n segments: readonly (readonly Point[])[],\n pointer: Point,\n radius: number,\n): { segIdx: number; t: number } | null {\n const r2 = radius * radius;\n let best: { segIdx: number; t: number; d2: number } | null = null;\n for (let segIdx = 0; segIdx < segments.length; segIdx++) {\n const samples = segments[segIdx];\n if (samples.length < 2) continue;\n const last = samples.length - 1;\n for (let i = 0; i < last; i++) {\n const a = samples[i];\n const b = samples[i + 1];\n const abx = b.x - a.x;\n const aby = b.y - a.y;\n const apx = pointer.x - a.x;\n const apy = pointer.y - a.y;\n const ab2 = abx * abx + aby * aby;\n let u = ab2 > 0 ? (apx * abx + apy * aby) / ab2 : 0;\n if (u < 0) u = 0;\n else if (u > 1) u = 1;\n const cx = a.x + u * abx;\n const cy = a.y + u * aby;\n const dx = cx - pointer.x;\n const dy = cy - pointer.y;\n const d2 = dx * dx + dy * dy;\n if (d2 > r2) continue;\n const t = (i + u) / last;\n if (best === null || d2 < best.d2) best = { segIdx, t, d2 };\n }\n }\n return best ? { segIdx: best.segIdx, t: best.t } : null;\n}\n","import { tokenPx } from '@weasel-js/theme';\nimport type { ResolvedTheme } from '@weasel-js/theme';\n\n/**\n * The handle sizes the theme publishes: the default rank, the inert one a\n * locked or pinned point wears, and the emphasized one for a handle that is\n * its own category.\n */\nexport const HANDLE_SIZE_TOKENS = [\n '--wzl-handle-size', '--wzl-handle-size-sm', '--wzl-handle-size-lg',\n] as const;\n\n/** One of {@link HANDLE_SIZE_TOKENS}. */\nexport type HandleSizeToken = (typeof HANDLE_SIZE_TOKENS)[number];\n\n/**\n * A handle's edge in px, for code that draws a handle instead of styling one.\n *\n * CSS reaches `--wzl-handle-*` directly; SVG geometry attributes and canvas\n * cannot, so they come through here and the number stays written once, in the\n * theme definition.\n */\nexport function handleSize(token: HandleSizeToken, resolved?: ResolvedTheme): number {\n return tokenPx(token, resolved);\n}\n\n/** Half a handle's edge — what an SVG rect centered on a point offsets by. */\nexport function handleHalf(token: HandleSizeToken, resolved?: ResolvedTheme): number {\n return handleSize(token, resolved) / 2;\n}\n",".root {\n /* Component-local vars layered over the theme tokens. Each var resolves\n * to a semantic token from @weasel-js/theme; consumers override\n * either the curve-* var (component scope) or the wzl-* token (app\n * scope) without touching this file.\n *\n * Background / grid / axis tokens live on Plot2D now (this component\n * composes Plot2D, which paints the background and chrome). */\n --curve-line: var(--wzl-curve-color);\n --curve-line-width: var(--wzl-curve-width);\n --curve-fill: color-mix(in srgb, var(--curve-line) 30%, transparent);\n --curve-anchor-fill: var(--wzl-surface);\n --curve-anchor-stroke: var(--curve-line);\n --curve-anchor-active-fill: var(--curve-line);\n --curve-pinned-fill: var(--wzl-fg-subtle);\n}\n\n.fill {\n fill: var(--curve-fill);\n stroke: none;\n pointer-events: none;\n}\n\n.curve {\n stroke: var(--curve-line);\n stroke-width: var(--curve-line-width);\n fill: none;\n pointer-events: stroke;\n}\n\n.anchor {\n fill: var(--curve-anchor-fill);\n stroke: var(--curve-anchor-stroke);\n stroke-width: 1.5;\n cursor: grab;\n}\n\n.anchor:hover {\n fill: var(--curve-anchor-active-fill);\n}\n\n.anchor.active {\n fill: var(--curve-anchor-active-fill);\n cursor: grabbing;\n}\n\n.anchor.pinned {\n fill: var(--curve-pinned-fill);\n cursor: default;\n}\n\n/* Caller-set locked anchors share the gray pinned fill but signal\n * \"not interactive at all\" via the not-allowed cursor. */\n.anchor.locked {\n cursor: not-allowed;\n}\n\n/* Endpoint vertices render as diamonds (rotated squares) instead of\n * circles, so they read as a different category of handle. The shape\n * is enforced inline via SVG <rect transform>; this class only adds\n * the hover/active styling. */\n.endpoint {\n /* No fill / stroke overrides — endpoint visuals reuse .anchor /\n * .anchor.pinned / .anchor.active styling. The class exists as a\n * marker for future per-endpoint styling needs. */\n}\n\n/* When the consumer opts into hiding non-interactive handles, pinned\n * endpoints disappear entirely. */\n.hidden {\n display: none;\n}\n\n/* Focus is drawn on the mark itself: an outline on an SVG shape rings its\n bounding box, which the nearest scroll container clips. */\n.anchor:focus-visible {\n outline: none;\n stroke: var(--wzl-focus-ring);\n stroke-width: 2;\n}\n\n/* ── keyframe layer ─────────────────────────────────────────────────── */\n\n.keyframe {\n fill: var(--curve-key-fill, var(--wzl-fg-muted));\n cursor: grab;\n}\n\n.keyframe[aria-current='true'] { fill: var(--curve-selected, var(--wzl-accent-strong)); }\n.keyframe:focus-visible,\n.handle:focus-visible {\n outline: none;\n stroke: var(--wzl-focus-ring);\n stroke-width: 2;\n}\n\n.segmentTarget:focus-visible {\n outline: none;\n stroke: var(--wzl-focus-ring);\n stroke-opacity: 0.5;\n}\n\n/* The committed key holds while its ghost tracks the pointer, so a drag\n reads as a move from somewhere to somewhere. */\n.keyframe[data-dragging='true'] { opacity: 0.4; }\n\n.keyframeGhost {\n fill: var(--curve-selected-soft, var(--wzl-accent-soft));\n stroke: var(--curve-selected, var(--wzl-accent-strong));\n stroke-width: 1;\n stroke-dasharray: 2 2;\n pointer-events: none;\n}\n\n.segmentBand {\n fill: var(--curve-selected-soft, var(--wzl-accent-soft));\n pointer-events: none;\n}\n\n/* Carries focus and a name for each segment; hit testing is geometric. */\n.segmentTarget {\n fill: none;\n stroke: transparent;\n stroke-width: 8;\n pointer-events: none;\n}\n\n.handle {\n fill: var(--wzl-surface);\n stroke: var(--curve-selected, var(--wzl-accent-strong));\n stroke-width: 1;\n cursor: grab;\n}\n\n.handleStem {\n stroke: var(--curve-selected, var(--wzl-accent-strong));\n stroke-width: 1;\n pointer-events: none;\n}\n","import {\n useCallback, useEffect, useMemo, useRef, useState,\n type CSSProperties,\n type KeyboardEvent as ReactKeyboardEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactNode,\n} from 'react';\nimport { openPointerSession, type PointerSession } from '@weasel-js/core';\nimport {\n Plot2D,\n type Plot2DHandle,\n type GridSettings,\n type AxesSettings,\n type TickSettings,\n} from '../Plot2D';\nimport {\n modelToPlot, plotToModel,\n type ModelRange,\n} from '../Plot2D/geometry';\nimport { dlog } from '../../dlog';\nimport s from './CurveEditor.module.css';\nimport type {\n CurveLayer, LayerCtx, LayerGesture, LayerModifiers, ModelPoint, PlotPoint,\n} from './layerTypes';\n\n/**\n * A layer paired with the state the consumer holds for it. The editor never\n * stores layer state itself.\n */\nexport interface LayerBinding<S = unknown> {\n layer: CurveLayer<S>;\n state: S;\n}\n\n/** Props for {@link LayeredCurveEditor}. */\nexport interface LayeredCurveEditorProps {\n /** Bottom-to-top render order: `layers[0]` paints first, `layers[N-1]`\n * paints on top. Hit-testing runs in reverse (topmost claim wins). */\n layers: ReadonlyArray<LayerBinding<unknown>>;\n\n /** Fires every frame during a gesture with the live in-flight state\n * for the layer that owns the gesture. */\n onLayerChange(id: string, next: unknown): void;\n\n /** Fires once per discrete user action (drag-end, one-shot insert,\n * delete) for the layer that produced the change. `prev` is the\n * layer's state at gesture start. */\n onLayerCommit?(id: string, next: unknown, prev: unknown): void;\n\n width: number;\n height: number;\n /** Model-space x range. Default [0, 1]. */\n xRange?: readonly [number, number];\n /** Model-space y range. Default [0, 1]. */\n yRange?: readonly [number, number];\n grid?: GridSettings | false | null;\n axes?: AxesSettings | false | null;\n /** Ticks at x values. See `Plot2D.xTicks`. */\n xTicks?: TickSettings | false | null;\n /** Ticks at y values. See `Plot2D.yTicks`. */\n yTicks?: TickSettings | false | null;\n\n /** Built-in undo/redo via Cmd/Ctrl+Z (Shift+Z or Y for redo) on the\n * focused SVG. Snapshots every layer's state on each commit; undo\n * fires `onLayerChange(id, prevState)` for each layer whose state\n * changed. Default `true`. */\n history?: boolean;\n\n /** Accessible name for the plot, which is exposed as a group so the\n * focusable marks layers render inside it stay reachable. */\n 'aria-label'?: string;\n className?: string;\n style?: CSSProperties;\n\n /** Extra SVG content rendered behind all layers (under the lowest\n * layer but above grid/axes). Use this for static chrome that isn't\n * worth modeling as a layer. */\n children?: ReactNode;\n}\n\ninterface ActiveGesture {\n layerId: string;\n gesture: LayerGesture<unknown>;\n startStates: Map<string, unknown>;\n startSelfState: unknown;\n}\n\n/** A cancel carries no event, so a layer's `onCancel` sees no modifiers held. */\nconst NO_MODIFIERS: LayerModifiers = { shift: false, alt: false, meta: false, ctrl: false };\n\nfunction readModifiers(e: PointerEvent | ReactPointerEvent | KeyboardEvent | ReactKeyboardEvent): LayerModifiers {\n return {\n shift: e.shiftKey,\n alt: e.altKey,\n meta: e.metaKey,\n ctrl: e.ctrlKey,\n };\n}\n\n/**\n * A `Plot2D` that hosts a stack of composable curve layers. It owns the\n * pointer gestures and the coordinate mapping; each layer supplies its own\n * drawing, hit testing and gesture behavior.\n *\n * Layer state stays with the consumer: the editor reports changes through\n * `onLayerChange` during a gesture and `onLayerCommit` at its end, and reads\n * the state back from props each frame. That is what lets one layer's drag\n * update another layer's state mid-gesture.\n */\nexport function LayeredCurveEditor(props: LayeredCurveEditorProps) {\n const {\n layers, onLayerChange, onLayerCommit,\n width, height,\n xRange = [0, 1], yRange = [0, 1],\n grid, axes, xTicks, yTicks,\n className, style, children,\n } = props;\n\n const historyEnabled = props.history !== false;\n\n const modelRange: ModelRange = useMemo(\n () => ({ xMin: xRange[0], xMax: xRange[1], yMin: yRange[0], yMax: yRange[1] }),\n [xRange, yRange],\n );\n const plotSize = useMemo(() => ({ width, height }), [width, height]);\n\n // Refs that always hold the latest props — gesture handlers and\n // window listeners close over these refs, never over render-time\n // values, so mid-drag re-renders (including cross-layer state\n // updates) are visible to the next pointermove tick.\n const layersRef = useRef(layers);\n layersRef.current = layers;\n const modelRangeRef = useRef(modelRange);\n modelRangeRef.current = modelRange;\n const plotSizeRef = useRef(plotSize);\n plotSizeRef.current = plotSize;\n\n const plotRef = useRef<Plot2DHandle | null>(null);\n\n // ── Coord helpers ──────────────────────────────────────────────────\n const makeCtx = useCallback((modifiers: LayerModifiers): LayerCtx => {\n const mr = modelRangeRef.current;\n const ps = plotSizeRef.current;\n return {\n modelRange: mr,\n plotSize: ps,\n toPlot: (p) => modelToPlot(p, mr, ps),\n toModel: (p) => plotToModel(p, mr, ps),\n modifiers,\n };\n }, []);\n\n // ── Gesture routing ────────────────────────────────────────────────\n const activeRef = useRef(null as ActiveGesture | null);\n const [activeLayerId, setActiveLayerId] = useState<string | null>(null);\n\n // ── History (whole-state snapshots) ────────────────────────────────\n const pastRef = useRef<Map<string, unknown>[]>([]);\n const futureRef = useRef<Map<string, unknown>[]>([]);\n\n const snapshot = useCallback((): Map<string, unknown> => {\n const m = new Map<string, unknown>();\n for (const b of layersRef.current) m.set(b.layer.id, b.state);\n return m;\n }, []);\n\n const restore = useCallback((snap: Map<string, unknown>) => {\n const current = layersRef.current;\n for (const b of current) {\n const prev = snap.get(b.layer.id);\n if (prev !== undefined && prev !== b.state) {\n onLayerChange(b.layer.id, prev);\n }\n }\n }, [onLayerChange]);\n\n const undo = useCallback(() => {\n if (!historyEnabled) return;\n const past = pastRef.current;\n if (past.length === 0) return;\n const prev = past.pop()!;\n futureRef.current.push(snapshot());\n restore(prev);\n }, [historyEnabled, snapshot, restore]);\n\n const redo = useCallback(() => {\n if (!historyEnabled) return;\n const future = futureRef.current;\n if (future.length === 0) return;\n const next = future.pop()!;\n pastRef.current.push(snapshot());\n restore(next);\n }, [historyEnabled, snapshot, restore]);\n\n // ── Pointer routing during an active gesture ───────────────────────\n // The session's callbacks are fixed at gesture start, so they delegate\n // through refs holding the latest per-render impl — a mid-drag re-render\n // must reach the next pointermove tick.\n const onGestureMoveRef = useRef<(e: PointerEvent) => void>(() => {});\n const onGestureEndRef = useRef<(e: PointerEvent) => void>(() => {});\n const onGestureCancelRef = useRef<() => void>(() => {});\n\n const sessionRef = useRef<PointerSession | null>(null);\n\n const cleanupGesture = useCallback(() => {\n sessionRef.current = null;\n activeRef.current = null;\n setActiveLayerId(null);\n }, []);\n\n const findLayerState = useCallback((id: string): unknown | undefined => {\n for (const b of layersRef.current) if (b.layer.id === id) return b.state;\n return undefined;\n }, []);\n\n onGestureMoveRef.current = (e: PointerEvent) => {\n const a = activeRef.current;\n if (!a) return;\n const h = plotRef.current;\n if (!h) return;\n const model = h.clientToModel(e);\n const current = findLayerState(a.layerId);\n if (current === undefined) return;\n const ctx = makeCtx(readModifiers(e));\n const next = a.gesture.onMove(current, model, e, ctx);\n if (next !== current) onLayerChange(a.layerId, next);\n };\n\n onGestureEndRef.current = (e: PointerEvent) => {\n const a = activeRef.current;\n if (!a) return;\n const current = findLayerState(a.layerId);\n if (current === undefined) { cleanupGesture(); return; }\n const ctx = makeCtx(readModifiers(e));\n const finalState = a.gesture.onCommit ? a.gesture.onCommit(current, ctx) : current;\n if (finalState !== current) onLayerChange(a.layerId, finalState);\n if (historyEnabled) {\n pastRef.current.push(a.startStates);\n futureRef.current = [];\n }\n if (onLayerCommit) onLayerCommit(a.layerId, finalState, a.startSelfState);\n cleanupGesture();\n };\n\n onGestureCancelRef.current = () => {\n const a = activeRef.current;\n if (!a) return;\n const current = findLayerState(a.layerId);\n if (current === undefined) { cleanupGesture(); return; }\n const ctx = makeCtx(NO_MODIFIERS);\n const restored = a.gesture.onCancel ? a.gesture.onCancel(current, ctx) : a.startSelfState;\n if (restored !== current) onLayerChange(a.layerId, restored);\n cleanupGesture();\n };\n\n // No pointer capture: consumers render their own SVG chrome into the plot\n // through `children`, and capture would retarget pointerup away from it.\n const installGesture = useCallback((\n layerId: string,\n down: ReactPointerEvent<SVGSVGElement>,\n gesture: LayerGesture<unknown>,\n ) => {\n const startStates = snapshot();\n const startSelfState = startStates.get(layerId);\n activeRef.current = {\n layerId, gesture,\n startStates,\n startSelfState,\n };\n setActiveLayerId(layerId);\n sessionRef.current = openPointerSession(down.currentTarget, down, {\n onMove: (e) => onGestureMoveRef.current(e),\n onEnd: (e) => onGestureEndRef.current(e),\n onCancel: () => onGestureCancelRef.current(),\n }, { capture: false });\n }, [snapshot]);\n\n // ── pointerdown dispatch ───────────────────────────────────────────\n const onSvgPointerDown = useCallback((\n e: ReactPointerEvent<SVGSVGElement>,\n coords: { plot: PlotPoint; model: ModelPoint },\n ) => {\n if (activeRef.current) return; // ignore secondary touches mid-gesture\n const modifiers = readModifiers(e);\n const ctx = makeCtx(modifiers);\n const ls = layersRef.current;\n const nativeEvent = e.nativeEvent;\n\n dlog('layered-curve-editor', 'pointerdown', { plot: coords.plot, model: coords.model, layers: ls.length });\n\n // Capture the pre-event snapshot once; reuse for history if any\n // path produces a commit (gesture-start commit or one-shot).\n const preEventSnapshot = snapshot();\n\n // Top-to-bottom hit test.\n for (let i = ls.length - 1; i >= 0; i--) {\n const b = ls[i];\n const hit = b.layer.hitTest?.(b.state, coords.plot, ctx);\n if (!hit) continue;\n // Found a claim. onPointerDown may start a gesture, absorb the\n // click, or commit a one-shot edit via extra.commit.\n const prevState = b.state;\n let committed: unknown = undefined;\n const gesture = b.layer.onPointerDown?.(\n prevState, hit, nativeEvent, ctx,\n {\n plot: coords.plot,\n model: coords.model,\n commit(next) { committed = next; onLayerChange(b.layer.id, next); },\n },\n );\n e.stopPropagation();\n if (gesture) {\n installGesture(b.layer.id, e, gesture);\n return;\n }\n if (committed !== undefined) {\n if (historyEnabled) {\n pastRef.current.push(preEventSnapshot);\n futureRef.current = [];\n }\n onLayerCommit?.(b.layer.id, committed, prevState);\n }\n return;\n }\n\n // No hit — empty space dispatch, top-to-bottom.\n let pendingCommit: { id: string; next: unknown; prev: unknown } | null = null;\n for (let i = ls.length - 1; i >= 0; i--) {\n const b = ls[i];\n if (!b.layer.onEmptyPointerDown) continue;\n const prevState = b.state;\n let committed: unknown = undefined;\n const gesture = b.layer.onEmptyPointerDown(\n prevState, coords.model, nativeEvent, ctx,\n {\n plot: coords.plot,\n model: coords.model,\n commit(next) {\n committed = next;\n onLayerChange(b.layer.id, next);\n },\n },\n );\n if (gesture) {\n // If onEmptyPointerDown also published a commit (e.g. click-curve\n // insert publishes the new point then drags it), the gesture's\n // startStates already capture the post-insert state; the commit\n // for history is the *pre*-event snapshot, written when the\n // gesture eventually finishes via the gesture-commit path. We\n // override the gesture's startStates so undo restores correctly.\n installGesture(b.layer.id, e, gesture);\n if (committed !== undefined && activeRef.current !== null) {\n (activeRef.current as ActiveGesture).startStates = preEventSnapshot;\n (activeRef.current as ActiveGesture).startSelfState = preEventSnapshot.get(b.layer.id);\n }\n return;\n }\n if (committed !== undefined) {\n pendingCommit = { id: b.layer.id, next: committed, prev: prevState };\n break;\n }\n }\n if (pendingCommit) {\n if (historyEnabled) {\n pastRef.current.push(preEventSnapshot);\n futureRef.current = [];\n }\n onLayerCommit?.(pendingCommit.id, pendingCommit.next, pendingCommit.prev);\n }\n }, [makeCtx, installGesture, onLayerChange, onLayerCommit, historyEnabled, snapshot]);\n\n // ── keyboard ───────────────────────────────────────────────────────\n const onSvgKeyDown = useCallback((e: ReactKeyboardEvent<SVGSVGElement>) => {\n const modifiers = readModifiers(e);\n const ctx = makeCtx(modifiers);\n const ls = layersRef.current;\n // History first.\n if (historyEnabled && (e.metaKey || e.ctrlKey)) {\n const k = e.key.toLowerCase();\n if (k === 'z') {\n if (e.shiftKey) redo();\n else undo();\n e.preventDefault();\n return;\n }\n if (k === 'y') { redo(); e.preventDefault(); return; }\n }\n // Then layers (top-to-bottom).\n for (let i = ls.length - 1; i >= 0; i--) {\n const b = ls[i];\n if (!b.layer.onKeyDown) continue;\n const preEventSnapshot = snapshot();\n let committed: unknown = undefined;\n b.layer.onKeyDown(b.state, e.nativeEvent, ctx, {\n commit(next) { committed = next; onLayerChange(b.layer.id, next); },\n });\n if (committed !== undefined) {\n if (historyEnabled) {\n pastRef.current.push(preEventSnapshot);\n futureRef.current = [];\n }\n onLayerCommit?.(b.layer.id, committed, b.state);\n }\n // The layer prevents default on the native event, which the synthetic\n // event's `isDefaultPrevented` does not observe.\n if (e.nativeEvent.defaultPrevented) return;\n }\n }, [historyEnabled, undo, redo, makeCtx, snapshot, onLayerChange, onLayerCommit]);\n\n useEffect(() => () => { sessionRef.current?.cancel(); }, []);\n\n // ── render ─────────────────────────────────────────────────────────\n const renderCtxBase: Omit<LayerCtx, 'modifiers'> = useMemo(() => ({\n modelRange,\n plotSize,\n toPlot: (p) => modelToPlot(p, modelRange, plotSize),\n toModel: (p) => plotToModel(p, modelRange, plotSize),\n }), [modelRange, plotSize]);\n\n const cls = [s.root, className].filter(Boolean).join(' ');\n\n return (\n <Plot2D\n ref={plotRef}\n className={cls}\n style={style}\n width={width}\n height={height}\n xRange={xRange}\n yRange={yRange}\n grid={grid}\n axes={axes}\n xTicks={xTicks}\n yTicks={yTicks}\n tabIndex={historyEnabled ? 0 : undefined}\n role=\"group\"\n aria-label={props['aria-label']}\n onPointerDown={onSvgPointerDown}\n onKeyDown={onSvgKeyDown}\n >\n {children}\n {layers.map((b) => {\n const ctx = {\n ...renderCtxBase,\n modifiers: { shift: false, alt: false, meta: false, ctrl: false },\n isActive: activeLayerId === b.layer.id,\n };\n return (\n <g key={b.layer.id} data-layer-id={b.layer.id}>\n {b.layer.render(b.state, ctx)}\n </g>\n );\n })}\n </Plot2D>\n );\n}\n","/**\n * Keyframe layer for LayeredCurveEditor: a value-over-time curve whose shape\n * between two keys is the easing on the later one, with draggable keys and\n * draggable cubic-bezier handles on the selected segment.\n *\n * Distinct from `createFunctionLayer`, which interpolates a spline through\n * its anchors. Here the keys are exact and the easing approximates between\n * them, so the two do not share curve maths.\n */\nimport type { ReactNode } from 'react';\nimport { cubicBezierEasing, resolveEasing, type EasingFn, type Keyframe } from '@weasel-js/core';\nimport { hitTestAnchor, hitTestCurve } from './hitTest';\nimport { handleHalf } from '../../handles';\nimport { SNAP_RADIUS_PX, snapToNearest } from '../../snap';\nimport s from './CurveEditor.module.css';\nimport type {\n CurveLayer, EmptyDownArgs, KeyDownArgs, LayerCtx, LayerGesture, LayerHit, LayerRenderCtx, PlotPoint,\n} from './layerTypes';\n\ntype Bezier = readonly [number, number, number, number];\n\n/** A gesture in flight. The committed keys hold still underneath it. */\nexport type KeyframeDrag =\n | { kind: 'key'; index: number; t: number; value: number }\n | { kind: 'handle'; segment: number; bezier: Bezier };\n\n/**\n * The state a keyframe layer owns, held by the consumer and round-tripped\n * through `LayeredCurveEditor`'s `onLayerChange`.\n */\nexport interface KeyframeLayerState {\n /** Sorted ascending by `t`. */\n keys: readonly Keyframe<number>[];\n selectedKey: number | null;\n /** Index of the key the selected segment runs into. Its bezier handles show. */\n selectedSegment: number | null;\n drag: KeyframeDrag | null;\n}\n\n/** Configuration for {@link createKeyframeLayer}. */\nexport interface KeyframeLayerConfig {\n /** Layer id; default `'keyframes'`. */\n id?: string;\n /** Names the curve in each mark's accessible name. Default `'Curve'`. */\n label?: string;\n /** Formats a key time for accessible names. Default: rounded number. */\n formatX?: (x: number) => string;\n /** Times a dragged key snaps to. Holding alt defeats the snap. */\n snapX?: readonly number[];\n /** Snap reach, in plot pixels. Default 6. */\n snapRadiusPx?: number;\n /** Bounds for a key's time. Default: unbounded. */\n xClamp?: readonly [number, number];\n /** Bounds for a key's value. Default: unbounded. */\n yClamp?: readonly [number, number];\n /** One arrow-key step in model units; shift takes ten. Default: 1% of the\n * plot's range on that axis. */\n step?: { x?: number; y?: number };\n}\n\nconst SAMPLES_PER_SEGMENT = 16;\nconst KEY_HIT_PX = 8;\nconst HANDLE_HIT_PX = 8;\nconst CURVE_HIT_PX = 6;\nconst KEY_HALF = handleHalf('--wzl-handle-size');\nconst HANDLE_RADIUS = 3.5;\nconst SHIFT_MULTIPLIER = 10;\nconst HANDLE_STEP = 0.01;\n\n/** A keyframe layer state with nothing selected and no gesture in flight. */\nexport function keyframeLayerState(keys: readonly Keyframe<number>[]): KeyframeLayerState {\n return { keys, selectedKey: null, selectedSegment: null, drag: null };\n}\n\nfunction clampTo(v: number, range?: readonly [number, number]): number {\n return range ? Math.min(range[1], Math.max(range[0], v)) : v;\n}\n\nfunction bezierOf(key: Keyframe<number> | undefined): Bezier | null {\n const e = key?.easing;\n return typeof e === 'object' && e !== null && 'bezier' in e ? e.bezier : null;\n}\n\nfunction moveKeyTo(\n keys: readonly Keyframe<number>[], index: number, t: number, value: number,\n): { keys: Keyframe<number>[]; selectedKey: number } {\n const moved = { ...keys[index], t, value };\n const rest = keys.filter((_, i) => i !== index);\n const at = rest.findIndex((k) => k.t > t);\n const selectedKey = at === -1 ? rest.length : at;\n rest.splice(selectedKey, 0, moved);\n return { keys: rest, selectedKey };\n}\n\n/**\n * The keys a state's drag would leave behind: a dragged key re-sorted into\n * place, or a dragged handle's control points written onto the key its\n * segment runs into. `selectedKey` follows a moved key to its new index; a\n * key dropped where it started returns the same `keys` array.\n */\nexport function applyKeyframeDrag(\n state: KeyframeLayerState,\n): { keys: readonly Keyframe<number>[]; selectedKey: number | null } {\n const { drag, keys } = state;\n if (!drag) return { keys, selectedKey: state.selectedKey };\n if (drag.kind === 'key') {\n const k = keys[drag.index];\n if (k && k.t === drag.t && k.value === drag.value) return { keys, selectedKey: drag.index };\n return moveKeyTo(keys, drag.index, drag.t, drag.value);\n }\n const next = keys.slice();\n next[drag.segment] = { ...keys[drag.segment], easing: { bezier: drag.bezier } };\n return { keys: next, selectedKey: state.selectedKey };\n}\n\n/**\n * Builds a keyframe layer for `LayeredCurveEditor`. Model x is time and model\n * y is value; each segment is drawn through the easing on the key it runs\n * into. Every key, segment and handle is focusable and named, and the arrow\n * keys move whichever one has focus.\n */\nexport function createKeyframeLayer(cfg: KeyframeLayerConfig = {}): CurveLayer<KeyframeLayerState> {\n const id = cfg.id ?? 'keyframes';\n const label = cfg.label ?? 'Curve';\n const formatX = cfg.formatX ?? ((x: number) => String(Math.round(x)));\n const snapRadiusPx = cfg.snapRadiusPx ?? SNAP_RADIUS_PX;\n\n // A live handle drag is previewed straight from its control points: a\n // fresh spec per pointermove through `resolveEasing` would leave one\n // permanent cache entry per pixel of drag.\n function easingInto(state: KeyframeLayerState, keys: readonly Keyframe<number>[], seg: number): EasingFn {\n const d = state.drag;\n if (d?.kind === 'handle' && d.segment === seg) return cubicBezierEasing(...d.bezier);\n return resolveEasing(keys[seg].easing);\n }\n\n function segmentSamples(state: KeyframeLayerState, keys: readonly Keyframe<number>[], ctx: LayerCtx): PlotPoint[][] {\n const out: PlotPoint[][] = [];\n for (let i = 1; i < keys.length; i++) {\n const a = keys[i - 1];\n const b = keys[i];\n const ease = easingInto(state, keys, i);\n const pts: PlotPoint[] = [];\n for (let j = 0; j <= SAMPLES_PER_SEGMENT; j++) {\n const u = j / SAMPLES_PER_SEGMENT;\n pts.push(ctx.toPlot({ x: a.t + (b.t - a.t) * u, y: a.value + (b.value - a.value) * ease(u) }));\n }\n out.push(pts);\n }\n return out;\n }\n\n function activeBezier(state: KeyframeLayerState): Bezier | null {\n const seg = state.selectedSegment;\n if (seg === null || seg < 1 || seg >= state.keys.length) return null;\n const d = state.drag;\n if (d?.kind === 'handle' && d.segment === seg) return d.bezier;\n return bezierOf(state.keys[seg]);\n }\n\n function handlePoints(state: KeyframeLayerState, bezier: Bezier, ctx: LayerCtx): [PlotPoint, PlotPoint] {\n const a = state.keys[state.selectedSegment! - 1];\n const b = state.keys[state.selectedSegment!];\n const at = (xf: number, yf: number) =>\n ctx.toPlot({ x: a.t + xf * (b.t - a.t), y: a.value + yf * (b.value - a.value) });\n return [at(bezier[0], bezier[1]), at(bezier[2], bezier[3])];\n }\n\n const path = (pts: readonly PlotPoint[]): string =>\n pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x.toFixed(2)},${p.y.toFixed(2)}`).join('');\n\n // ── render ──────────────────────────────────────────────────────────\n function render(state: KeyframeLayerState, ctx: LayerRenderCtx): ReactNode {\n const shown = state.drag?.kind === 'key' ? applyKeyframeDrag(state).keys : state.keys;\n const segments = segmentSamples(state, shown, ctx);\n const curve = segments.flatMap((pts, i) => (i === 0 ? pts : pts.slice(1)));\n const seg = state.selectedSegment;\n const bezier = activeBezier(state);\n const dragIndex = state.drag?.kind === 'key' ? state.drag.index : null;\n\n return (\n <>\n {seg !== null && seg >= 1 && seg < shown.length ? (() => {\n const x0 = ctx.toPlot({ x: shown[seg - 1].t, y: 0 }).x;\n const x1 = ctx.toPlot({ x: shown[seg].t, y: 0 }).x;\n return (\n <rect\n className={s.segmentBand}\n x={Math.min(x0, x1)}\n y={0}\n width={Math.abs(x1 - x0)}\n height={ctx.plotSize.height}\n />\n );\n })() : null}\n {curve.length > 1 ? <path data-curve-element=\"curve\" className={s.curve} d={path(curve)} /> : null}\n {segments.map((pts, i) => (\n <path\n key={`seg-${i + 1}`}\n className={s.segmentTarget}\n d={path(pts)}\n role=\"button\"\n tabIndex={0}\n aria-label={`${label} segment into ${formatX(shown[i + 1].t)}`}\n aria-current={seg === i + 1 ? 'true' : undefined}\n data-segment-index={i + 1}\n />\n ))}\n {bezier ? (() => {\n const [h1, h2] = handlePoints(state, bezier, ctx);\n const a = ctx.toPlot({ x: state.keys[seg! - 1].t, y: state.keys[seg! - 1].value });\n const b = ctx.toPlot({ x: state.keys[seg!].t, y: state.keys[seg!].value });\n return (\n <>\n <line className={s.handleStem} x1={a.x} y1={a.y} x2={h1.x} y2={h1.y} />\n <line className={s.handleStem} x1={b.x} y1={b.y} x2={h2.x} y2={h2.y} />\n {[h1, h2].map((h, i) => (\n <circle\n key={`handle-${i}`}\n className={s.handle}\n cx={h.x}\n cy={h.y}\n r={HANDLE_RADIUS}\n role=\"button\"\n tabIndex={0}\n aria-label={`${label} bezier handle ${i + 1}`}\n data-handle-index={i}\n />\n ))}\n </>\n );\n })() : null}\n {state.keys.map((k, i) => {\n const p = ctx.toPlot({ x: k.t, y: k.value });\n return (\n <rect\n key={`key-${i}`}\n className={s.keyframe}\n x={p.x - KEY_HALF}\n y={p.y - KEY_HALF}\n width={KEY_HALF * 2}\n height={KEY_HALF * 2}\n transform={`rotate(45 ${p.x} ${p.y})`}\n role=\"button\"\n tabIndex={0}\n aria-label={`${label} key at ${formatX(k.t)}`}\n aria-current={state.selectedKey === i ? 'true' : undefined}\n data-keyframe-index={i}\n data-dragging={dragIndex === i ? 'true' : undefined}\n />\n );\n })}\n {state.drag?.kind === 'key' ? (() => {\n const p = ctx.toPlot({ x: state.drag.t, y: state.drag.value });\n return (\n <rect\n aria-hidden=\"true\"\n className={s.keyframeGhost}\n x={p.x - KEY_HALF}\n y={p.y - KEY_HALF}\n width={KEY_HALF * 2}\n height={KEY_HALF * 2}\n transform={`rotate(45 ${p.x} ${p.y})`}\n data-keyframe-ghost=\"\"\n />\n );\n })() : null}\n </>\n );\n }\n\n // ── hit test ────────────────────────────────────────────────────────\n function hitTest(state: KeyframeLayerState, plot: PlotPoint, ctx: LayerCtx): LayerHit | null {\n const bezier = activeBezier(state);\n if (bezier) {\n const h = hitTestAnchor(handlePoints(state, bezier, ctx), plot, HANDLE_HIT_PX);\n if (h) return { kind: 'handle', payload: { handle: h.index } };\n }\n const k = hitTestAnchor(state.keys.map((key) => ctx.toPlot({ x: key.t, y: key.value })), plot, KEY_HIT_PX);\n if (k) return { kind: 'key', payload: { index: k.index } };\n const c = hitTestCurve(segmentSamples(state, state.keys, ctx), plot, CURVE_HIT_PX);\n if (c) return { kind: 'segment', payload: { segment: c.segIdx + 1 } };\n return null;\n }\n\n // ── gestures ────────────────────────────────────────────────────────\n function keyGesture(index: number): LayerGesture<KeyframeLayerState> {\n return {\n onMove(state, model, e, ctx) {\n let t = clampTo(model.x, cfg.xClamp);\n if (cfg.snapX && !e.altKey) {\n const perPx = (ctx.modelRange.xMax - ctx.modelRange.xMin) / ctx.plotSize.width;\n t = clampTo(snapToNearest(t, cfg.snapX, Math.abs(perPx) * snapRadiusPx), cfg.xClamp);\n }\n return { ...state, drag: { kind: 'key', index, t, value: clampTo(model.y, cfg.yClamp) } };\n },\n onCommit(state) { return { ...state, ...applyKeyframeDrag(state), drag: null }; },\n onCancel(state) { return { ...state, drag: null }; },\n };\n }\n\n function handleGesture(segment: number, handle: 0 | 1): LayerGesture<KeyframeLayerState> {\n return {\n onMove(state, model) {\n const a = state.keys[segment - 1];\n const b = state.keys[segment];\n const d = state.drag;\n if (!a || !b || d?.kind !== 'handle') return state;\n const xf = b.t === a.t ? 0 : Math.min(1, Math.max(0, (model.x - a.t) / (b.t - a.t)));\n const yf = b.value === a.value ? 0 : (model.y - a.value) / (b.value - a.value);\n const bezier = [...d.bezier] as [number, number, number, number];\n bezier[handle * 2] = xf;\n bezier[handle * 2 + 1] = yf;\n return { ...state, drag: { kind: 'handle', segment, bezier } };\n },\n onCommit(state) { return { ...state, ...applyKeyframeDrag(state), drag: null }; },\n onCancel(state) { return { ...state, drag: null }; },\n };\n }\n\n function onPointerDown(\n state: KeyframeLayerState,\n hit: LayerHit,\n e: PointerEvent,\n _ctx: LayerCtx,\n extra: EmptyDownArgs<KeyframeLayerState>,\n ): LayerGesture<KeyframeLayerState> | void {\n if (e.button !== 0) return;\n if (hit.kind === 'handle') {\n const bezier = activeBezier(state);\n const segment = state.selectedSegment;\n if (!bezier || segment === null) return;\n const { handle } = hit.payload as { handle: 0 | 1 };\n extra.commit({ ...state, drag: { kind: 'handle', segment, bezier } });\n return handleGesture(segment, handle);\n }\n if (hit.kind === 'key') {\n const { index } = hit.payload as { index: number };\n const k = state.keys[index];\n extra.commit({ ...state, selectedKey: index, drag: { kind: 'key', index, t: k.t, value: k.value } });\n return keyGesture(index);\n }\n if (hit.kind === 'segment') {\n const { segment } = hit.payload as { segment: number };\n extra.commit({ ...state, selectedSegment: segment });\n }\n }\n\n // ── keyboard ────────────────────────────────────────────────────────\n function onKeyDown(\n state: KeyframeLayerState,\n e: KeyboardEvent,\n ctx: LayerCtx,\n extra: KeyDownArgs<KeyframeLayerState>,\n ): void {\n const target = e.target as Element | null;\n if (target?.closest?.('[data-layer-id]')?.getAttribute('data-layer-id') !== id) return;\n const activate = e.key === 'Enter' || e.key === ' ';\n const dx = e.key === 'ArrowRight' ? 1 : e.key === 'ArrowLeft' ? -1 : 0;\n const dy = e.key === 'ArrowUp' ? 1 : e.key === 'ArrowDown' ? -1 : 0;\n const mult = e.shiftKey ? SHIFT_MULTIPLIER : 1;\n\n const keyEl = target.closest('[data-keyframe-index]');\n if (keyEl) {\n const index = Number(keyEl.getAttribute('data-keyframe-index'));\n const k = state.keys[index];\n if (!k) return;\n if (activate) {\n e.preventDefault();\n extra.commit({ ...state, selectedKey: index });\n return;\n }\n if (dx === 0 && dy === 0) return;\n e.preventDefault();\n const m = ctx.modelRange;\n const stepX = (cfg.step?.x ?? Math.abs(m.xMax - m.xMin) / 100) * mult;\n const stepY = (cfg.step?.y ?? Math.abs(m.yMax - m.yMin) / 100) * mult;\n const t = clampTo(k.t + dx * stepX, cfg.xClamp);\n const value = clampTo(k.value + dy * stepY, cfg.yClamp);\n if (t === k.t && value === k.value) return;\n extra.commit({ ...state, ...moveKeyTo(state.keys, index, t, value), drag: null });\n return;\n }\n\n const segEl = target.closest('[data-segment-index]');\n if (segEl && activate) {\n e.preventDefault();\n extra.commit({ ...state, selectedSegment: Number(segEl.getAttribute('data-segment-index')) });\n return;\n }\n\n const handleEl = target.closest('[data-handle-index]');\n const bezier = activeBezier(state);\n if (handleEl && bezier && state.selectedSegment !== null && (dx !== 0 || dy !== 0)) {\n e.preventDefault();\n const h = Number(handleEl.getAttribute('data-handle-index'));\n const next = [...bezier] as [number, number, number, number];\n next[h * 2] = Math.min(1, Math.max(0, next[h * 2] + dx * HANDLE_STEP * mult));\n next[h * 2 + 1] += dy * HANDLE_STEP * mult;\n const drag: KeyframeDrag = { kind: 'handle', segment: state.selectedSegment, bezier: next };\n extra.commit({ ...state, ...applyKeyframeDrag({ ...state, drag }), drag: null });\n }\n }\n\n return { id, render, hitTest, onPointerDown, onKeyDown };\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dlog-CMYiRF3Q.js","names":[],"sources":["../../src/dlog.ts"],"sourcesContent":["/**\n * Namespaced, opt-in console tracing. Off by default; production builds\n * may strip the calls entirely depending on the bundler.\n *\n * Enable in the browser:\n *\n * localStorage.setItem('weasel.debug', '*') // all namespaces\n * localStorage.setItem('weasel.debug', 'curve-editor') // just curve editor\n * localStorage.setItem('weasel.debug', 'curve-editor,layer-stack')\n *\n * Each component picks a stable namespace and calls `dlog(namespace, ...)`.\n * Useful for tracing pointer/event flows that are hard to capture\n * post-hoc (drag handlers, gesture sequences, selection mutations).\n *\n * The flag is read once and cached for the page session — reload to\n * pick up changes. Cheap hot-path checks (one nullish-coalesce + Set\n * lookup) so leaving calls in place is fine.\n *\n * Mirrors `src/debug/flag.ts` in the kit. Two impls live here because\n * weasel-ui doesn't depend on the kit, but both read the same\n * localStorage keys so behavior is uniform. See the kit copy for the\n * canonical list of kit-level namespaces.\n *\n * Known weasel-ui namespaces:\n * - plot2d — Plot2D mount / unmount\n * - curve-editor — CurveEditor pointer flow\n */\n\nconst KEYS = ['weasel.debug', 'weaseldraw.debug'] as const;\n\ninterface Cached {\n all: boolean;\n set: Set<string>;\n}\n\nlet cached: Cached | null = null;\n\nfunction read(): Cached {\n const empty: Cached = { all: false, set: new Set() };\n if (typeof localStorage === 'undefined') return empty;\n try {\n for (const k of KEYS) {\n const v = localStorage.getItem(k);\n if (v == null || v === '') continue;\n if (v === '1' || v === 'true' || v === '*') return { all: true, set: new Set() };\n return { all: false, set: new Set(v.split(/[\\s,]+/).filter(Boolean)) };\n }\n return empty;\n } catch {\n return empty;\n }\n}\n\nfunction get(): Cached {\n if (cached === null) cached = read();\n return cached;\n}\n\n/** True when `namespace` (or `*`) is enabled. */\nexport function isDebugEnabled(namespace: string): boolean {\n const c = get();\n return c.all || c.set.has(namespace);\n}\n\n/** Conditional `console.debug` — no-op unless `namespace` (or `*`) is enabled.\n * Each call is prefixed with `[namespace]` so the source is searchable. */\nexport function dlog(namespace: string, ...args: unknown[]): void {\n if (!isDebugEnabled(namespace)) return;\n // eslint-disable-next-line no-console\n console.debug(`[${namespace}]`, ...args);\n}\n"],"mappings":";AA4BA,IAAM,IAAO,CAAC,gBAAgB,mBAAmB,EAO7C,IAAwB;AAE5B,SAAS,IAAe;CACtB,IAAM,IAAgB;EAAE,KAAK;EAAO,qBAAK,IAAI,KAAK;EAAE;AACpD,KAAI,OAAO,eAAiB,IAAa,QAAO;AAChD,KAAI;AACF,OAAK,IAAM,KAAK,GAAM;GACpB,IAAM,IAAI,aAAa,QAAQ,EAAE;AAC7B,cAAK,QAAQ,MAAM,IAEvB,QADI,MAAM,OAAO,MAAM,UAAU,MAAM,MAAY;IAAE,KAAK;IAAM,qBAAK,IAAI,KAAK;IAAE,GACzE;IAAE,KAAK;IAAO,KAAK,IAAI,IAAI,EAAE,MAAM,SAAS,CAAC,OAAO,QAAQ,CAAC;IAAE;;AAExE,SAAO;SACD;AACN,SAAO;;;AAIX,SAAS,IAAc;AAErB,QADI,MAAW,SAAM,IAAS,GAAM,GAC7B;;AAIT,SAAgB,EAAe,GAA4B;CACzD,IAAM,IAAI,GAAK;AACf,QAAO,EAAE,OAAO,EAAE,IAAI,IAAI,EAAU;;AAKtC,SAAgB,EAAK,GAAmB,GAAG,GAAuB;AAC3D,GAAe,EAAU,IAE9B,QAAQ,MAAM,IAAI,EAAU,IAAI,GAAG,EAAK"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatShortcut-BoGqUoWi.js","names":[],"sources":["../../src/components/ToolPalette/formatShortcut.ts"],"sourcesContent":["import { keyGlyph } from '../Keycaps/keyGlyph';\n\nexport interface ShortcutInput {\n key: string | readonly string[];\n mod?: boolean;\n alt?: boolean;\n shift?: boolean | 'optional';\n}\n\n/** Format a shortcut as an array of display chips, one per key — modifier\n * icons (⌘, ↑, ⌥) followed by the key glyph. UIs that want a boxed\n * per-key look render each chip in its own element. `shift: 'optional'` is\n * treated as falsy. */\nexport function formatShortcutParts(b: ShortcutInput | undefined): readonly string[] | undefined {\n if (!b) return undefined;\n const rawKey = Array.isArray(b.key) ? b.key[0] : (b.key as string);\n const parts: string[] = [];\n if (b.mod) parts.push('⌘');\n if (b.shift === true) parts.push('⇧');\n if (b.alt) parts.push('⌥');\n parts.push(keyGlyph(rawKey));\n return parts;\n}\n\n/** Format a shortcut as a single display string. Order: mod, shift, alt,\n * key. Returns `undefined` for `undefined` input so callers can `??` a\n * fallback. When `key` is an array, the first element is used. `shift: 'optional'`\n * is treated as falsy. */\nexport function formatShortcut(b: ShortcutInput | undefined): string | undefined {\n const parts = formatShortcutParts(b);\n return parts ? parts.join('') : undefined;\n}\n"],"mappings":";;AAaA,SAAgB,EAAoB,GAA6D;AAC/F,KAAI,CAAC,EAAG;CACR,IAAM,IAAS,MAAM,QAAQ,EAAE,IAAI,GAAG,EAAE,IAAI,KAAM,EAAE,KAC9C,IAAkB,EAAE;AAK1B,QAJI,EAAE,OAAK,EAAM,KAAK,IAAI,EACtB,EAAE,UAAU,MAAM,EAAM,KAAK,IAAI,EACjC,EAAE,OAAK,EAAM,KAAK,IAAI,EAC1B,EAAM,KAAK,EAAS,EAAO,CAAC,EACrB;;AAOT,SAAgB,EAAe,GAAkD;CAC/E,IAAM,IAAQ,EAAoB,EAAE;AACpC,QAAO,IAAQ,EAAM,KAAK,GAAG,GAAG,KAAA"}
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import { t as e } from "./Icon-BW0qv_U7.js";
|
|
2
|
-
import { AlignBottomIcon as t, AlignCenterXIcon as n, AlignCenterYIcon as ee, AlignLeftIcon as te, AlignRightIcon as ne, AlignTopIcon as r, ArrowIcon as i, BringForwardIcon as a, BringToFrontIcon as o, CopyIcon as s, CutIcon as c, DeleteIcon as l, DistributeHorizontalIcon as u, DistributeVerticalIcon as d, DuplicateIcon as f, EllipseIcon as p, EllipseIcon as m, EyedropperIcon as h, FlipXIcon as g, FlipYIcon as _, GroupIcon as v, HandIcon as y, ImageIcon as b, ImageIcon as x, LassoIcon as S, LassoIcon as C, LineIcon as w, LineIcon as T, PasteIcon as E, PenIcon as D, PenIcon as O, PencilIcon as k, PencilIcon as A, PolygonIcon as j, PolygonIcon as M, RectIcon as N, RectIcon as P, RedoIcon as F, SelectIcon as I, SendBackwardIcon as L, SendToBackIcon as R, StarIcon as z, StarIcon as B, TextIcon as V, TextIcon as H, UndoIcon as U, UngroupIcon as W, UnknownIcon as G, UnknownIcon as K } from "@weasel-js/core";
|
|
3
|
-
import { jsx as q } from "react/jsx-runtime";
|
|
4
|
-
//#region src/icons/ShapeKindIcon.tsx
|
|
5
|
-
var J = {
|
|
6
|
-
rect: N,
|
|
7
|
-
ellipse: p,
|
|
8
|
-
line: w,
|
|
9
|
-
polygon: j,
|
|
10
|
-
star: z,
|
|
11
|
-
pen: D,
|
|
12
|
-
pencil: k,
|
|
13
|
-
lasso: S,
|
|
14
|
-
text: V,
|
|
15
|
-
image: b
|
|
16
|
-
};
|
|
17
|
-
function Y({ kind: e, ...t }) {
|
|
18
|
-
return /* @__PURE__ */ q(J[e] ?? G, { ...t });
|
|
19
|
-
}
|
|
20
|
-
//#endregion
|
|
21
|
-
//#region src/icons/index.tsx
|
|
22
|
-
var X = (t) => /* @__PURE__ */ q(e, {
|
|
23
|
-
name: "clone",
|
|
24
|
-
...t
|
|
25
|
-
}), Z = (t) => /* @__PURE__ */ q(e, {
|
|
26
|
-
name: "reset",
|
|
27
|
-
...t
|
|
28
|
-
}), re = (t) => /* @__PURE__ */ q(e, {
|
|
29
|
-
name: "close",
|
|
30
|
-
...t
|
|
31
|
-
}), Q = (t) => /* @__PURE__ */ q(e, {
|
|
32
|
-
name: "export",
|
|
33
|
-
...t
|
|
34
|
-
}), ie = (t) => /* @__PURE__ */ q(e, {
|
|
35
|
-
name: "zoomIn",
|
|
36
|
-
...t
|
|
37
|
-
}), ae = (t) => /* @__PURE__ */ q(e, {
|
|
38
|
-
name: "pan",
|
|
39
|
-
...t
|
|
40
|
-
}), oe = (t) => /* @__PURE__ */ q(e, {
|
|
41
|
-
name: "add",
|
|
42
|
-
...t
|
|
43
|
-
}), se = (t) => /* @__PURE__ */ q(e, {
|
|
44
|
-
name: "modeLight",
|
|
45
|
-
...t
|
|
46
|
-
}), ce = (t) => /* @__PURE__ */ q(e, {
|
|
47
|
-
name: "modeDark",
|
|
48
|
-
...t
|
|
49
|
-
}), le = (t) => /* @__PURE__ */ q(e, {
|
|
50
|
-
name: "modeAuto",
|
|
51
|
-
...t
|
|
52
|
-
}), ue = (t) => /* @__PURE__ */ q(e, {
|
|
53
|
-
name: "remove",
|
|
54
|
-
...t
|
|
55
|
-
}), de = (t) => /* @__PURE__ */ q(e, {
|
|
56
|
-
name: "sort",
|
|
57
|
-
...t
|
|
58
|
-
}), fe = (t) => /* @__PURE__ */ q(e, {
|
|
59
|
-
name: "zoomOut",
|
|
60
|
-
...t
|
|
61
|
-
}), pe = (t) => /* @__PURE__ */ q(e, {
|
|
62
|
-
name: "fit",
|
|
63
|
-
...t
|
|
64
|
-
}), me = (t) => /* @__PURE__ */ q(e, {
|
|
65
|
-
name: "snapshot",
|
|
66
|
-
...t
|
|
67
|
-
}), he = (t) => /* @__PURE__ */ q(e, {
|
|
68
|
-
name: "play",
|
|
69
|
-
...t
|
|
70
|
-
}), ge = (t) => /* @__PURE__ */ q(e, {
|
|
71
|
-
name: "pause",
|
|
72
|
-
...t
|
|
73
|
-
}), _e = (t) => /* @__PURE__ */ q(e, {
|
|
74
|
-
name: "stop",
|
|
75
|
-
...t
|
|
76
|
-
}), ve = (t) => /* @__PURE__ */ q(e, {
|
|
77
|
-
name: "stepBack",
|
|
78
|
-
...t
|
|
79
|
-
}), $ = (t) => /* @__PURE__ */ q(e, {
|
|
80
|
-
name: "stepForward",
|
|
81
|
-
...t
|
|
82
|
-
}), ye = $, be = (t) => /* @__PURE__ */ q(e, {
|
|
83
|
-
name: "crosshair",
|
|
84
|
-
...t
|
|
85
|
-
}), xe = (t) => /* @__PURE__ */ q(e, {
|
|
86
|
-
name: "fullscreen",
|
|
87
|
-
...t
|
|
88
|
-
}), Se = (t) => /* @__PURE__ */ q(e, {
|
|
89
|
-
name: "compare",
|
|
90
|
-
...t
|
|
91
|
-
}), Ce = (t) => /* @__PURE__ */ q(e, {
|
|
92
|
-
name: "filter",
|
|
93
|
-
...t
|
|
94
|
-
}), we = (t) => /* @__PURE__ */ q(e, {
|
|
95
|
-
name: "search",
|
|
96
|
-
...t
|
|
97
|
-
}), Te = (t) => /* @__PURE__ */ q(e, {
|
|
98
|
-
name: "loupe",
|
|
99
|
-
...t
|
|
100
|
-
}), Ee = (t) => /* @__PURE__ */ q(e, {
|
|
101
|
-
name: "layers",
|
|
102
|
-
...t
|
|
103
|
-
}), De = (t) => /* @__PURE__ */ q(e, {
|
|
104
|
-
name: "page",
|
|
105
|
-
...t
|
|
106
|
-
}), Oe = (t) => /* @__PURE__ */ q(e, {
|
|
107
|
-
name: "lock",
|
|
108
|
-
...t
|
|
109
|
-
}), ke = (t) => /* @__PURE__ */ q(e, {
|
|
110
|
-
name: "unlock",
|
|
111
|
-
...t
|
|
112
|
-
}), Ae = (t) => /* @__PURE__ */ q(e, {
|
|
113
|
-
name: "visible",
|
|
114
|
-
...t
|
|
115
|
-
}), je = (t) => /* @__PURE__ */ q(e, {
|
|
116
|
-
name: "hidden",
|
|
117
|
-
...t
|
|
118
|
-
}), Me = (t) => /* @__PURE__ */ q(e, {
|
|
119
|
-
name: "pin",
|
|
120
|
-
...t
|
|
121
|
-
}), Ne = (t) => /* @__PURE__ */ q(e, {
|
|
122
|
-
name: "link",
|
|
123
|
-
...t
|
|
124
|
-
}), Pe = (t) => /* @__PURE__ */ q(e, {
|
|
125
|
-
name: "collapse",
|
|
126
|
-
...t
|
|
127
|
-
}), Fe = (t) => /* @__PURE__ */ q(e, {
|
|
128
|
-
name: "expand",
|
|
129
|
-
...t
|
|
130
|
-
}), Ie = (t) => /* @__PURE__ */ q(e, {
|
|
131
|
-
name: "chevron",
|
|
132
|
-
...t
|
|
133
|
-
}), Le = (t) => /* @__PURE__ */ q(e, {
|
|
134
|
-
name: "tune",
|
|
135
|
-
...t
|
|
136
|
-
}), Re = (t) => /* @__PURE__ */ q(e, {
|
|
137
|
-
name: "grid",
|
|
138
|
-
...t
|
|
139
|
-
}), ze = (t) => /* @__PURE__ */ q(e, {
|
|
140
|
-
name: "snap",
|
|
141
|
-
...t
|
|
142
|
-
}), Be = (t) => /* @__PURE__ */ q(e, {
|
|
143
|
-
name: "measure",
|
|
144
|
-
...t
|
|
145
|
-
}), Ve = (t) => /* @__PURE__ */ q(e, {
|
|
146
|
-
name: "randomize",
|
|
147
|
-
...t
|
|
148
|
-
}), He = (t) => /* @__PURE__ */ q(e, {
|
|
149
|
-
name: "refresh",
|
|
150
|
-
...t
|
|
151
|
-
}), Ue = (t) => /* @__PURE__ */ q(e, {
|
|
152
|
-
name: "info",
|
|
153
|
-
...t
|
|
154
|
-
}), We = (t) => /* @__PURE__ */ q(e, {
|
|
155
|
-
name: "warning",
|
|
156
|
-
...t
|
|
157
|
-
}), Ge = (t) => /* @__PURE__ */ q(e, {
|
|
158
|
-
name: "error",
|
|
159
|
-
...t
|
|
160
|
-
}), Ke = (t) => /* @__PURE__ */ q(e, {
|
|
161
|
-
name: "busy",
|
|
162
|
-
...t
|
|
163
|
-
}), qe = (t) => /* @__PURE__ */ q(e, {
|
|
164
|
-
name: "check",
|
|
165
|
-
...t
|
|
166
|
-
}), Je = (t) => /* @__PURE__ */ q(e, {
|
|
167
|
-
name: "layoutRows",
|
|
168
|
-
...t
|
|
169
|
-
}), Ye = (t) => /* @__PURE__ */ q(e, {
|
|
170
|
-
name: "layoutColumns",
|
|
171
|
-
...t
|
|
172
|
-
}), Xe = (t) => /* @__PURE__ */ q(e, {
|
|
173
|
-
name: "layoutGrid",
|
|
174
|
-
...t
|
|
175
|
-
});
|
|
176
|
-
//#endregion
|
|
177
|
-
export { se as $, Ce as A, W as At, Ue as B, d as C, ve as Ct, Fe as D, H as Dt, Ge as E, _e as Et, Re as F, ie as Ft, Je as G, Ee as H, v as I, fe as It, Oe as J, T as K, y as L, Y as Lt, g as M, ke as Mt, _ as N, Ae as Nt, Q as O, Le as Ot, xe as P, We as Pt, ce as Q, je as R, u as S, B as St, m as T, ye as Tt, Ye as U, C as V, Xe as W, Be as X, Te as Y, le as Z, Se as _, L as _t, te as a, A as at, c as b, me as bt, i as c, M as ct, Ke as d, F as dt, De as et, qe as f, He as ft, Pe as g, I as gt, re as h, we as ht, ee as i, O as it, pe as j, K as jt, h as k, U as kt, a as l, Ve as lt, X as m, Z as mt, t as n, E as nt, ne as o, Me as ot, Ie as p, ue as pt, Ne as q, n as r, ge as rt, r as s, he as st, oe as t, ae as tt, o as u, P as ut, s as v, R as vt, f as w, $ as wt, l as x, de as xt, be as y, ze as yt, x as z };
|
|
178
|
-
|
|
179
|
-
//# sourceMappingURL=icons-DbScMMqX.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"icons-DbScMMqX.js","names":[],"sources":["../../src/icons/ShapeKindIcon.tsx","../../src/icons/index.tsx"],"sourcesContent":["import type { ComponentType } from 'react';\nimport {\n EllipseIcon, ImageIcon, LassoIcon, LineIcon, PenIcon, PencilIcon, PolygonIcon, RectIcon,\n StarIcon, TextIcon, UnknownIcon,\n type IconProps, type ShapeKind,\n} from '@weasel-js/core';\n\nconst BY_KIND = {\n rect: RectIcon,\n ellipse: EllipseIcon,\n line: LineIcon,\n polygon: PolygonIcon,\n star: StarIcon,\n pen: PenIcon,\n pencil: PencilIcon,\n lasso: LassoIcon,\n text: TextIcon,\n image: ImageIcon,\n} satisfies Record<ShapeKind, ComponentType<IconProps>>;\n\nexport interface ShapeKindIconProps extends IconProps {\n /** A built-in shape kind. Any other string draws `UnknownIcon`, so a\n * consumer-defined kind still gets a glyph. */\n kind: ShapeKind | (string & {});\n}\n\n/** The glyph for a shape kind — the same one its insertion tool shows, so a\n * row in a layer list or inspector matches the palette that made it. */\nexport function ShapeKindIcon({ kind, ...props }: ShapeKindIconProps) {\n const Glyph = (BY_KIND as Record<string, ComponentType<IconProps>>)[kind] ?? UnknownIcon;\n return <Glyph {...props} />;\n}\n","import { Icon, type IconProps } from './Icon';\n\nexport { Icon, isFillable } from './Icon';\nexport type { IconProps } from './Icon';\nexport { ICON_FILLS, ICON_GROUPS, ICON_PATHS } from './paths';\nexport { ShapeKindIcon } from './ShapeKindIcon';\nexport type { ShapeKindIconProps } from './ShapeKindIcon';\nexport type { FillableIconName, IconName } from './paths';\n\n// Tool glyphs live in @weasel-js/core because core needs them for\n// `Tool.presentation.icon` defaults and cannot depend on this package.\n// Re-exported here so consumers have one import site for the whole set.\nexport {\n SelectIcon, LassoIcon, RectIcon, EllipseIcon, ImageIcon, EyedropperIcon,\n LineIcon, ArrowIcon, PolygonIcon, StarIcon, PencilIcon, TextIcon, PenIcon, HandIcon,\n UnknownIcon,\n} from '@weasel-js/core';\n// The standard edit actions' glyphs live beside those actions in core, for the\n// same reason.\nexport {\n CutIcon, CopyIcon, PasteIcon, DuplicateIcon, GroupIcon, UngroupIcon,\n BringForwardIcon, BringToFrontIcon, SendBackwardIcon, SendToBackIcon, FlipXIcon, FlipYIcon,\n UndoIcon, RedoIcon, DeleteIcon,\n AlignLeftIcon, AlignCenterXIcon, AlignRightIcon, AlignTopIcon, AlignCenterYIcon, AlignBottomIcon,\n DistributeHorizontalIcon, DistributeVerticalIcon,\n} from '@weasel-js/core';\n\nexport const CloneIcon = (p: IconProps) => <Icon name=\"clone\" {...p} />;\nexport const ResetIcon = (p: IconProps) => <Icon name=\"reset\" {...p} />;\nexport const CloseIcon = (p: IconProps) => <Icon name=\"close\" {...p} />;\nexport const ExportIcon = (p: IconProps) => <Icon name=\"export\" {...p} />;\nexport const ZoomInIcon = (p: IconProps) => <Icon name=\"zoomIn\" {...p} />;\nexport const PanIcon = (p: IconProps) => <Icon name=\"pan\" {...p} />;\nexport const AddIcon = (p: IconProps) => <Icon name=\"add\" {...p} />;\nexport const ModeLightIcon = (p: IconProps) => <Icon name=\"modeLight\" {...p} />;\nexport const ModeDarkIcon = (p: IconProps) => <Icon name=\"modeDark\" {...p} />;\nexport const ModeAutoIcon = (p: IconProps) => <Icon name=\"modeAuto\" {...p} />;\nexport const RemoveIcon = (p: IconProps) => <Icon name=\"remove\" {...p} />;\nexport const SortIcon = (p: IconProps) => <Icon name=\"sort\" {...p} />;\nexport const ZoomOutIcon = (p: IconProps) => <Icon name=\"zoomOut\" {...p} />;\nexport const FitIcon = (p: IconProps) => <Icon name=\"fit\" {...p} />;\nexport const SnapshotIcon = (p: IconProps) => <Icon name=\"snapshot\" {...p} />;\nexport const PlayIcon = (p: IconProps) => <Icon name=\"play\" {...p} />;\nexport const PauseIcon = (p: IconProps) => <Icon name=\"pause\" {...p} />;\nexport const StopIcon = (p: IconProps) => <Icon name=\"stop\" {...p} />;\nexport const StepBackIcon = (p: IconProps) => <Icon name=\"stepBack\" {...p} />;\nexport const StepForwardIcon = (p: IconProps) => <Icon name=\"stepForward\" {...p} />;\n/** @deprecated Use {@link StepForwardIcon}; `step` alone stopped naming a direction. */\nexport const StepIcon = StepForwardIcon;\nexport const CrosshairIcon = (p: IconProps) => <Icon name=\"crosshair\" {...p} />;\nexport const FullscreenIcon = (p: IconProps) => <Icon name=\"fullscreen\" {...p} />;\nexport const CompareIcon = (p: IconProps) => <Icon name=\"compare\" {...p} />;\nexport const FilterIcon = (p: IconProps) => <Icon name=\"filter\" {...p} />;\nexport const SearchIcon = (p: IconProps) => <Icon name=\"search\" {...p} />;\nexport const LoupeIcon = (p: IconProps) => <Icon name=\"loupe\" {...p} />;\nexport const LayersIcon = (p: IconProps) => <Icon name=\"layers\" {...p} />;\nexport const PageIcon = (p: IconProps) => <Icon name=\"page\" {...p} />;\nexport const LockIcon = (p: IconProps) => <Icon name=\"lock\" {...p} />;\nexport const UnlockIcon = (p: IconProps) => <Icon name=\"unlock\" {...p} />;\nexport const VisibleIcon = (p: IconProps) => <Icon name=\"visible\" {...p} />;\nexport const HiddenIcon = (p: IconProps) => <Icon name=\"hidden\" {...p} />;\nexport const PinIcon = (p: IconProps) => <Icon name=\"pin\" {...p} />;\nexport const LinkIcon = (p: IconProps) => <Icon name=\"link\" {...p} />;\nexport const CollapseIcon = (p: IconProps) => <Icon name=\"collapse\" {...p} />;\nexport const ExpandIcon = (p: IconProps) => <Icon name=\"expand\" {...p} />;\nexport const ChevronIcon = (p: IconProps) => <Icon name=\"chevron\" {...p} />;\nexport const TuneIcon = (p: IconProps) => <Icon name=\"tune\" {...p} />;\nexport const GridIcon = (p: IconProps) => <Icon name=\"grid\" {...p} />;\nexport const SnapIcon = (p: IconProps) => <Icon name=\"snap\" {...p} />;\nexport const MeasureIcon = (p: IconProps) => <Icon name=\"measure\" {...p} />;\nexport const RandomizeIcon = (p: IconProps) => <Icon name=\"randomize\" {...p} />;\nexport const RefreshIcon = (p: IconProps) => <Icon name=\"refresh\" {...p} />;\nexport const InfoIcon = (p: IconProps) => <Icon name=\"info\" {...p} />;\nexport const WarningIcon = (p: IconProps) => <Icon name=\"warning\" {...p} />;\nexport const ErrorIcon = (p: IconProps) => <Icon name=\"error\" {...p} />;\nexport const BusyIcon = (p: IconProps) => <Icon name=\"busy\" {...p} />;\nexport const CheckIcon = (p: IconProps) => <Icon name=\"check\" {...p} />;\nexport const LayoutRowsIcon = (p: IconProps) => <Icon name=\"layoutRows\" {...p} />;\nexport const LayoutColumnsIcon = (p: IconProps) => <Icon name=\"layoutColumns\" {...p} />;\nexport const LayoutGridIcon = (p: IconProps) => <Icon name=\"layoutGrid\" {...p} />;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"keyGlyph-CLvUHU8c.js","names":[],"sources":["../../src/components/Keycaps/keyGlyph.ts"],"sourcesContent":["/** Apple-style glyph for a DOM `KeyboardEvent.key` value. Covers escape,\n * delete/backspace, arrows, enter/return, tab, space. Unknown keys are\n * upper-cased (so `'a'` reads as `A` on a keycap) and returned unchanged\n * otherwise — making this safe to apply uniformly without a `has-glyph`\n * check at the call site. */\nexport function keyGlyph(rawKey: string): string {\n switch (rawKey) {\n case 'Escape': return '⎋';\n case 'Backspace': return '⌫';\n case 'Delete': return '⌦';\n case 'ArrowUp': return '↑';\n case 'ArrowDown': return '↓';\n case 'ArrowLeft': return '←';\n case 'ArrowRight': return '→';\n case 'Enter':\n case 'Return': return '↵';\n case 'Tab': return '⇥';\n case ' ':\n case 'Space': return '␣';\n default: return rawKey.toUpperCase();\n }\n}\n"],"mappings":";AAKA,SAAgB,EAAS,GAAwB;AAC/C,SAAQ,GAAR;EACE,KAAK,SAAU,QAAO;EACtB,KAAK,YAAa,QAAO;EACzB,KAAK,SAAU,QAAO;EACtB,KAAK,UAAW,QAAO;EACvB,KAAK,YAAa,QAAO;EACzB,KAAK,YAAa,QAAO;EACzB,KAAK,aAAc,QAAO;EAC1B,KAAK;EACL,KAAK,SAAU,QAAO;EACtB,KAAK,MAAO,QAAO;EACnB,KAAK;EACL,KAAK,QAAS,QAAO;EACrB,QAAS,QAAO,EAAO,aAAa"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model-BQMvTLnW.js","names":[],"sources":["../../src/components/SelectionPanel/SelectionPanel.module.css","../../src/components/SelectionPanel/renderLeaf.tsx","../../src/components/SelectionPanel/model.ts"],"sourcesContent":[".root {\n display: flex;\n flex-direction: column;\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg);\n}\n\n.header {\n display: flex;\n align-items: baseline;\n gap: var(--wzl-space-4);\n padding: var(--wzl-space-4) 0;\n border-block-end: 1px solid var(--wzl-border);\n}\n\n.kind {\n font-weight: var(--wzl-font-weight-bold);\n font-size: var(--wzl-font-size);\n}\n\n.breakdown {\n font-size: var(--wzl-font-size-sm);\n opacity: 0.6;\n}\n\n.section {\n padding: var(--wzl-space-3) 0 var(--wzl-space-4);\n border-block-end: 1px solid var(--wzl-border);\n}\n\n.section:last-child {\n border-block-end: none;\n}\n\n.sectionTitle {\n margin: 0 0 var(--wzl-space-3);\n font-size: var(--wzl-font-size-xs);\n font-weight: var(--wzl-font-weight-bold);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n opacity: 0.55;\n}\n\n.row {\n display: grid;\n grid-template-columns: 64px 1fr;\n gap: var(--wzl-space-3);\n align-items: center;\n margin-block-end: 5px;\n}\n\n.rowLabel {\n opacity: 0.75;\n}\n\n.rowControls {\n display: flex;\n flex-wrap: wrap;\n gap: var(--wzl-space-3);\n align-items: center;\n min-inline-size: 0;\n}\n\n/* Glyph plus its control, held together so the pair row wraps between\n fields rather than between a field and the icon naming it. */\n.namedField {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-2);\n min-inline-size: 0;\n}\n\n.namedField > svg {\n flex: none;\n opacity: 0.75;\n}\n\n.blockRow {\n margin-block-end: 5px;\n}\n\n/* Fields paired into one row split it evenly, the way Position's x/y do. */\n.rowControls > .namedField {\n flex: 1 1 0;\n}\n\n/* Except around a segmented bar, which is sized by its segments: an equal\n share of the row is wider than the buttons want to be. */\n.rowControls > .namedField:has(> .toggle) {\n flex: 0 1 auto;\n}\n\n.rowControls > * {\n flex: 1;\n min-inline-size: 0;\n}\n\n/* Bars sharing a row split the leftover between them, so the gap stays fixed\n and the width lands on the segments. A bar with the row to itself is sized\n by its segments instead — a third of 240px is a plate, not a button. */\n.rowControls > .toggle {\n flex: 1 1 auto;\n}\n\n.rowControls > .toggle:only-child {\n flex: 0 1 auto;\n}\n\n/* A flag bar is sized by its glyphs rather than by a share of the row: an\n even split would fling one-letter segments to the margins. */\n.rowControls > .flagToggle {\n flex: 0 0 auto;\n}\n\n.number :global(input),\n.select {\n font-size: var(--wzl-font-size-sm);\n}\n\n.unrenderable {\n font-size: var(--wzl-font-size-sm);\n opacity: 0.5;\n font-style: italic;\n}\n\n/* A `block` leaf that renders its own rows — an object leaf's fields. */\n.objectLeaf {\n margin-block: var(--wzl-space-4) var(--wzl-space-2);\n}\n\n.objectLeaf .sectionTitle {\n margin-block: 7px 5px;\n}\n\n/* Fields under a heading inside an object read as belonging to it. */\n.objectGroup {\n padding-inline-start: var(--wzl-space-4);\n border-inline-start: 1px solid var(--wzl-border);\n margin-block-end: var(--wzl-space-2);\n}\n\n/* The slider's track; the row only says how it shares the space. */\n.slider {\n flex: 1;\n}\n","/**\n * A selection's leaves as cells: one `ToolPrefLeaf` and its aggregated value\n * in, one rendered cell out, plus the run logic that turns a row of paired\n * toggles into a single segmented bar and the rows of an object leaf.\n *\n * The control itself is `PropertyControl`'s, through `prefFieldProps`; what\n * is decided here is how a selection surface sizes and composes it.\n * `ToolOptionsBar` renders a tool's options through the same functions.\n */\nimport { Fragment, type ReactNode } from 'react';\nimport type {\n ToolPrefBoolean,\n ToolPrefGroup,\n ToolPrefLeaf,\n ToolPrefObject,\n} from '@weasel-js/core';\nimport { prefFieldProps } from '../Prefs/prefField';\nimport { PropertyControl } from '../Properties/PropertyField';\nimport { ToggleBar } from '../ToggleBar';\nimport { Icon } from '../../icons/Icon';\nimport { ICON_PATHS, type IconName } from '../../icons/paths';\nimport s from './SelectionPanel.module.css';\n\n\n/** What a {@link PropertyRenderer} is given for the property it is rendering. */\nexport interface PropertyRenderContext {\n /** Dotted node path of the leaf (`pose.x`, `data.fill`). */\n path: string;\n /** The schema leaf. App renderers narrow it to their own kind shape. */\n pref: ToolPrefLeaf;\n /** Aggregated value across the selection; `undefined` when mixed or unset. */\n value: unknown;\n /** True when selected nodes disagree at this path. */\n mixed: boolean;\n /**\n * True when the nodes agree and what they agree on is nothing — the field\n * is absent, and whatever paints comes from a fallback further down.\n *\n * Distinct from `mixed`, and both leave `value` undefined. A control must\n * not substitute its schema default here: doing so shows a value the node\n * does not hold, and the next edit writes that invention back.\n */\n unset: boolean;\n /**\n * The fields of the object this leaf is a field of — `undefined` for a\n * top-level leaf, and for a field of an object the node does not hold.\n *\n * What a control needs when its own field doesn't carry the whole answer:\n * a stroke's dash lengths are multiples of the stroke's width, so reading\n * the array as a style takes both.\n */\n siblings?: Record<string, unknown>;\n /** Commit a value — fans out to every selected node in one undo step. */\n setValue: (value: unknown) => void;\n /**\n * The aggregated value at another node path — what `value` and `mixed` are\n * for this leaf's own path, for any path.\n *\n * A control whose subject spans more than one field needs it: a font picker\n * reporting which variant will actually paint has to read the node's weight\n * and style. Reading it off `value` is impossible — a leaf is handed one\n * field.\n */\n valueAt: (path: string) => { value: unknown; mixed: boolean };\n /**\n * The ids of the nodes the values were read from, joined. It changes exactly\n * when the selection does, so a control holding scratch that belongs to one\n * selection can key on it and be remounted rather than carry it to the next.\n * Absent where the values come from no selection, as in a tool options bar.\n */\n selectionKey?: string;\n}\n\n/**\n * Renders the control for one property across the whole selection.\n * Returning `null` collapses the leaf.\n */\nexport type PropertyRenderer = (ctx: PropertyRenderContext) => ReactNode;\n\n\n/**\n * One leaf with its context built but nothing rendered yet.\n *\n * Deferring the render is what lets a run of sibling flags become one bar:\n * whether a leaf joins its neighbors is a fact about the run, which no leaf\n * rendering itself can see.\n */\nexport interface LeafCell {\n key: string;\n leaf: ToolPrefLeaf;\n ctx: PropertyRenderContext;\n /** The accessible name this leaf's control carries — qualified by the row's\n * pair where the row holds more than one leaf. */\n ariaLabel: string;\n /** Renders the leaf on its own, chrome and all. */\n render: () => ReactNode;\n}\n\n/** A cell's content, once the run it belongs to has been decided. */\nexport interface RenderedCell {\n key: string;\n /** The leaf that names the cell — the run's first, for a flag bar. */\n leaf: ToolPrefLeaf;\n block: boolean;\n content: ReactNode;\n}\n\n/**\n * True for a leaf that can join a flag bar: a paired toggle boolean the\n * consumer has not claimed with a renderer of its own.\n */\nexport function isFlagCell(cell: LeafCell, renderers?: Record<string, PropertyRenderer>): boolean {\n const { leaf } = cell;\n return (\n leaf.kind === 'boolean' &&\n (leaf as ToolPrefBoolean).control === 'toggle' &&\n leaf.pair !== undefined &&\n renderers?.[cell.ctx.path] === undefined &&\n renderers?.[leaf.kind] === undefined\n );\n}\n\n/**\n * Renders a row's cells, collapsing each run of adjacent same-`pair` toggle\n * booleans into one segmented bar — the idiom the enum toggle a row away\n * already uses, rather than one detached pill per flag.\n */\nexport function renderCells(\n cells: readonly LeafCell[],\n renderers?: Record<string, PropertyRenderer>,\n): RenderedCell[] {\n const out: RenderedCell[] = [];\n for (let i = 0; i < cells.length; ) {\n const cell = cells[i];\n if (!isFlagCell(cell, renderers)) {\n const content = cell.render();\n if (content != null) {\n out.push({ key: cell.key, leaf: cell.leaf, block: cell.leaf.block === true, content });\n }\n i += 1;\n continue;\n }\n let j = i + 1;\n while (\n j < cells.length &&\n isFlagCell(cells[j], renderers) &&\n cells[j].leaf.pair === cell.leaf.pair\n ) {\n j += 1;\n }\n const run = cells.slice(i, j);\n out.push({\n key: cell.key,\n leaf: cell.leaf,\n block: run.every((c) => c.leaf.block === true),\n content: <FlagBar run={run} ariaLabel={cell.leaf.pair as string} />,\n });\n i = j;\n }\n return out;\n}\n\n/**\n * A run of paired boolean flags as one multi-select bar — U / S / O, the way\n * every text editor draws them.\n */\nfunction FlagBar({ run, ariaLabel }: { run: readonly LeafCell[]; ariaLabel: string }): ReactNode {\n const on = run.filter((c) => c.ctx.value === true).map((c) => c.key);\n return (\n <ToggleBar<string>\n mode=\"multiple\"\n size=\"sm\"\n variant=\"flat\"\n className={s.flagToggle}\n ariaLabel={ariaLabel}\n items={run.map((c) => {\n const p = c.leaf as ToolPrefBoolean;\n return {\n value: c.key,\n label:\n p.icon && p.icon in ICON_PATHS ? (\n <Icon name={p.icon as IconName} size={14} />\n ) : (\n (p.short ?? p.name.slice(0, 1))\n ),\n ariaLabel: c.ariaLabel,\n };\n })}\n value={on}\n // Each flag owns its own path, so only the segment that moved is\n // written — committing the run would write two fields nobody touched,\n // and inside an object leaf would fabricate values for the other two.\n mixedValues={run.filter((c) => c.ctx.mixed).map((c) => c.key)}\n onChange={(next) => {\n for (const c of run) {\n const now = next.includes(c.key);\n if (now !== on.includes(c.key)) c.ctx.setValue(now);\n }\n }}\n />\n );\n}\n\nexport function renderBuiltin(\n ctx: PropertyRenderContext,\n ariaLabel: string,\n renderers?: Record<string, PropertyRenderer>,\n /** Identifies the current selection, so a control holding per-selection\n * scratch (the paint kind memory) is remounted rather than carried over. */\n selectionKey = '',\n /** True for a field of an object leaf. Such a field writes itself into its\n * parent, so it can only hold values its parent's type permits — which is\n * what rules \"none\" out for a nested paint. */\n nested = false,\n): ReactNode {\n const { pref, value, mixed, unset, setValue } = ctx;\n if (pref.kind === 'object') {\n // One value with fields hanging off it. Each child writes the parent\n // whole, so a field is never set on a half-built object.\n return <ObjectLeaf ctx={ctx} renderers={renderers} selectionKey={selectionKey} />;\n }\n const field = prefFieldProps(pref, {\n value,\n mixed,\n unset,\n siblings: ctx.siblings,\n setValue,\n // The substitution probe runs at the node's own weight and style, so the\n // picker names the variant that will actually paint. A mixed selection\n // has no single one; the probe falls back to 400/normal there.\n fontVariant: {\n weight: ctx.valueAt('data.style.fontWeight').value,\n style: ctx.valueAt('data.style.fontStyle').value,\n },\n });\n if (field === null) {\n return <span className={s.unrenderable}>({pref.kind}: no renderer)</span>;\n }\n switch (field.kind) {\n case 'boolean':\n // A panel's flag is a switch unless it asks otherwise.\n return (\n <PropertyControl\n {...field}\n {...framed(ariaLabel)}\n control={field.control ?? 'switch'}\n className={field.control === 'toggle' ? s.flagToggle : undefined}\n />\n );\n case 'number':\n return (\n <PropertyControl\n {...field}\n {...framed(ariaLabel)}\n className={field.control === 'slider' ? s.slider : s.number}\n steppers={false}\n />\n );\n case 'string':\n // Settled values only: a live write per keystroke would be one undo\n // step per character.\n return <PropertyControl {...field} {...framed(ariaLabel)} onInput={settledOnly} />;\n case 'enum':\n return (\n <PropertyControl\n {...field}\n {...framed(ariaLabel)}\n className={field.control === 'toggle' ? s.toggle : field.control === 'radio' ? undefined : s.select}\n />\n );\n case 'font-family':\n return <PropertyControl {...field} {...framed(ariaLabel)} className={s.select} />;\n case 'paint':\n return (\n <PropertyControl\n {...field}\n {...framed(ariaLabel)}\n // Per-kind switch memory is scratch for one selection; carrying it\n // across would recall the previous node's gradient.\n key={selectionKey}\n control=\"inline\"\n // A nested paint writes one field of its parent, and no kit paint\n // field is optional — `Stroke.paint` is required. Removing the\n // whole parent is a different edit than repainting it, so the\n // control must not offer one as the other.\n allowNone={!nested}\n />\n );\n default:\n return <PropertyControl {...field} {...framed(ariaLabel)} />;\n }\n}\n\nconst framed = (name: string) => ({ chrome: 'framed' as const, name });\n\nconst settledOnly = (): void => {};\n\n/**\n * Renders an object leaf: a titled block whose rows are the object's own\n * fields. A child's edit commits the parent object, never the child's path —\n * writing into a path whose value is not an object yet would corrupt it.\n */\n/** One labeled row inside an object leaf; `pair` merges adjacent fields into\n * it, exactly as the section rows merge theirs. */\ninterface ObjectRow {\n key: string;\n pair?: string;\n label: string;\n title?: string;\n /** Every field in the row brought its own chrome, so the row drops the\n * label column and spans the block. One unlabeled field in an otherwise\n * labeled pair would leave the row named after half of itself. */\n block: boolean;\n controls: ReactNode[];\n}\n\n/**\n * Renders an object leaf: the object's own fields, as rows. A child's edit\n * commits the parent object, never the child's path — writing into a path\n * whose value is not an object yet would corrupt it.\n */\nfunction ObjectLeaf({\n ctx,\n renderers,\n selectionKey = '',\n}: {\n ctx: PropertyRenderContext;\n renderers?: Record<string, PropertyRenderer>;\n selectionKey?: string;\n}): ReactNode {\n const pref = ctx.pref as ToolPrefObject;\n const held = typeof ctx.value === 'object' && ctx.value !== null\n ? (ctx.value as Record<string, unknown>)\n : undefined;\n\n // A value whose fields are entirely grouped is titled by those groups — its\n // own heading would stack onto the first one and name nothing new.\n const allGrouped = Object.values(pref.children).every((child) => !('kind' in child));\n\n // `indent` is false when nothing visible sits above these rows: depth is\n // drawn only where a label marks it.\n const rowsOf = (\n children: Record<string, ToolPrefLeaf | ToolPrefGroup>,\n indent: boolean,\n ): ReactNode[] => {\n const out: (ReactNode | ObjectRow)[] = [];\n const isRow = (v: ReactNode | ObjectRow): v is ObjectRow =>\n typeof v === 'object' && v !== null && 'controls' in v;\n\n // Cells accumulate unrendered so a run of adjacent same-`pair` flags can\n // be seen as a run before any of them draws; a group heading between two\n // fields ends the run, exactly as it ends a paired row.\n let pending: LeafCell[] = [];\n const flush = (): void => {\n for (const { key, leaf, block, content } of renderCells(pending, renderers)) {\n const prev = out[out.length - 1];\n if (leaf.pair !== undefined && isRow(prev) && prev.pair === leaf.pair) {\n prev.controls.push(<Fragment key={key}>{content}</Fragment>);\n prev.block &&= block;\n continue;\n }\n out.push({\n key,\n pair: leaf.pair,\n label: leaf.pair ?? leaf.name,\n title: leaf.description,\n block,\n controls: [<Fragment key={key}>{content}</Fragment>],\n });\n }\n pending = [];\n };\n\n for (const [key, child] of Object.entries(children)) {\n // A group among the children organises the fields under a heading\n // without contributing to the path — the rule group keys follow at the\n // top level.\n if (!('kind' in child)) {\n const labeled = child.name !== '';\n const inner = rowsOf(child.children, labeled);\n if (inner.length === 0) continue;\n flush();\n out.push(\n <div key={`group:${key}`} className={labeled && indent ? s.objectGroup : undefined}>\n {labeled && <h5 className={s.sectionTitle}>{child.name}</h5>}\n {inner}\n </div>,\n );\n continue;\n }\n const childPath = `${ctx.path}.${key}`;\n const childCtx: PropertyRenderContext = {\n path: childPath,\n pref: child,\n value: held?.[key],\n mixed: ctx.mixed,\n // A field of an object the node does not hold is unset, and so is one\n // the object omits — `data.stroke` absent leaves every stroke field\n // with nothing behind it, not with the schema's defaults.\n unset: !ctx.mixed && held?.[key] === undefined,\n siblings: held,\n valueAt: ctx.valueAt,\n selectionKey: ctx.selectionKey,\n setValue: (v) => {\n // The node holds no object yet, so writing one field has to\n // materialize the rest: the leaf's `default` is what a complete\n // value looks like. Starting from `{}` instead committed the one\n // field on its own — a `data.stroke` of `{ width: 2 }` with no\n // `paint`, which the type forbids and the painter threw on, taking\n // the whole frame and the visible document with it.\n const base = held\n ?? pref.fromScalar?.(ctx.value)\n ?? (typeof pref.default === 'object' && pref.default !== null\n ? { ...(pref.default as Record<string, unknown>) }\n : {});\n if (v === undefined) {\n // A field written as absent is absent — leaving the key holding\n // `undefined` says the object has a dash of nothing.\n const { [key]: _dropped, ...rest } = base;\n ctx.setValue(rest);\n return;\n }\n ctx.setValue({ ...base, [key]: v });\n },\n };\n pending.push({\n key: childPath,\n leaf: child,\n ctx: childCtx,\n ariaLabel: child.name,\n render: () => {\n const custom = renderers?.[childPath] ?? renderers?.[child.kind];\n const rendered = custom\n ? custom(childCtx)\n : renderBuiltin(childCtx, child.name, renderers, selectionKey, true);\n if (rendered == null) return null;\n // Neither a paired row nor a block one gives a field its own label\n // column, so the glyph is all that names it on screen. The control\n // already carries `name` as its accessible name, which leaves the\n // glyph decorative.\n const unlabeled = child.pair !== undefined || child.block === true;\n const glyph = unlabeled && child.icon && child.icon in ICON_PATHS;\n if (!glyph) return rendered;\n return (\n <span className={s.namedField}>\n <Icon name={child.icon as IconName} size={14} />\n {rendered}\n </span>\n );\n },\n });\n }\n flush();\n return out.map((entry) =>\n typeof entry === 'object' && entry !== null && 'controls' in entry ? (\n entry.block ? (\n <div key={entry.key} className={`${s.rowControls} ${s.blockRow}`} title={entry.title}>\n {entry.controls}\n </div>\n ) : (\n <div key={entry.key} className={s.row}>\n <span className={s.rowLabel} title={entry.title}>{entry.label}</span>\n <span className={s.rowControls}>{entry.controls}</span>\n </div>\n )\n ) : (\n entry\n ),\n );\n };\n\n const rows = rowsOf(pref.children, !allGrouped);\n if (rows.length === 0) return null;\n return (\n <div className={s.objectLeaf}>\n {!allGrouped && <h4 className={s.sectionTitle}>{pref.name}</h4>}\n {rows}\n </div>\n );\n}\n","// Pure selection→panel derivations for SelectionPanel. Kept free of\n// React so intersection/aggregation semantics are unit-testable.\n//\n// Path convention (see core `NodePropertiesEntry`): a leaf's OWN KEY in\n// the schema is its node path — a dotted path of any depth rooted at\n// `pose` or `data` (`pose.x`, `data.fill`, `data.style.fontSize`). Group\n// keys are organizational only.\n\nimport {\n MIXED,\n type Mixed,\n type NodePropertiesEntry,\n type NodeRoutingEntry,\n type SceneNode,\n type ToolPrefGroup,\n type ToolPrefLeaf,\n} from '@weasel-js/core';\n\n// Re-exported under its existing public name here: the kit-wide \"these\n// values disagree\" sentinel (`@weasel-js/core`'s `MIXED`) also covers\n// multi-node aggregation, so this panel doesn't get its own symbol.\nexport { MIXED };\nexport type { Mixed };\n\nexport type AnyNode = SceneNode<unknown, string, unknown>;\n\n/**\n * One editable property in a {@link SelectionPanel}, paired with the dotted\n * node path it reads and writes.\n */\nexport interface PanelLeaf {\n /** Dotted node path — the leaf's key in the schema. */\n path: string;\n leaf: ToolPrefLeaf;\n}\n\n/**\n * One labeled row of a panel section. Holds several leaves when the schema\n * paired them.\n */\nexport interface PanelRow {\n label: string;\n leaves: PanelLeaf[];\n}\n\n/**\n * A titled block of rows, derived from one top-level group of a properties\n * schema. `key` is that group's schema key.\n */\nexport interface PanelSection {\n key: string;\n name: string;\n rows: PanelRow[];\n}\n\n/** Derive a node's kind: containers are `'group'`; leaves classify their\n * `data` through the routing entries (first match wins, `'unknown'`\n * otherwise) — same semantics as core's `NodeRouting.classify`. */\nexport function classifyKind(\n node: AnyNode,\n routing: readonly NodeRoutingEntry[],\n): string {\n if (node.kind === 'container') return 'group';\n for (const entry of routing) {\n if (entry.matches(node.data)) return entry.name;\n }\n return 'unknown';\n}\n\nexport function isGroup(n: ToolPrefLeaf | ToolPrefGroup): n is ToolPrefGroup {\n return !('kind' in n);\n}\n\n/** Flatten a schema to sections of leaves. Nested groups fold into their\n * top-level section; top-level leaves get an untitled leading section. */\nfunction flatten(schema: ToolPrefGroup): PanelSection[] {\n const sections: PanelSection[] = [];\n const untitled: PanelLeaf[] = [];\n\n const collect = (group: ToolPrefGroup, into: PanelLeaf[]): void => {\n for (const [key, child] of Object.entries(group.children)) {\n if (isGroup(child)) collect(child, into);\n else into.push({ path: key, leaf: child });\n }\n };\n\n for (const [key, child] of Object.entries(schema.children)) {\n if (isGroup(child)) {\n const leaves: PanelLeaf[] = [];\n collect(child, leaves);\n sections.push({ key, name: child.name, rows: pairRows(leaves) });\n } else {\n untitled.push({ path: key, leaf: child });\n }\n }\n if (untitled.length > 0) {\n sections.unshift({ key: '', name: '', rows: pairRows(untitled) });\n }\n return sections;\n}\n\n/** Merge consecutive leaves sharing a `pair` id into one labeled row. */\nexport function pairRows(leaves: readonly PanelLeaf[]): PanelRow[] {\n const rows: PanelRow[] = [];\n for (const item of leaves) {\n const pair = item.leaf.pair;\n const prev = rows[rows.length - 1];\n if (pair !== undefined && prev !== undefined && prev.label === pair) {\n prev.leaves.push(item);\n } else {\n rows.push({ label: pair ?? item.leaf.name, leaves: [item] });\n }\n }\n return rows;\n}\n\n/**\n * The schema the panel shows for a set of kinds: one kind → its full\n * schema; several → the intersection by (path, leaf kind), shaped by the\n * first kind's section/row layout. Kinds without a registered schema\n * contribute nothing, so their presence collapses the intersection.\n */\nexport function effectiveSections(\n kinds: readonly string[],\n entries: readonly NodePropertiesEntry[],\n): PanelSection[] {\n const uniq = [...new Set(kinds)];\n if (uniq.length === 0) return [];\n const byName = new Map(entries.map((e) => [e.name, e]));\n const schemas = uniq.map((k) => byName.get(k)?.schema);\n if (schemas.some((s) => s === undefined)) return [];\n const [first, ...rest] = schemas as ToolPrefGroup[];\n\n const flatFirst = flatten(first);\n if (rest.length === 0) return flatFirst;\n\n // '\\0' delimiter: path and kind strings are unconstrained, so a\n // printable separator could collide with real content.\n const leafKey = (l: PanelLeaf): string => `${l.path}\\0${l.leaf.kind}`;\n const restKeys = rest.map(\n (schema) =>\n new Set(\n flatten(schema)\n .flatMap((s) => s.rows)\n .flatMap((r) => r.leaves)\n .map(leafKey),\n ),\n );\n const keep = (l: PanelLeaf): boolean =>\n restKeys.every((set) => set.has(leafKey(l)));\n\n return flatFirst\n .map((section) => ({\n ...section,\n rows: section.rows\n .map((row) => ({ ...row, leaves: row.leaves.filter(keep) }))\n .filter((row) => row.leaves.length > 0),\n }))\n .filter((section) => section.rows.length > 0);\n}\n\n/** Read a node value at a dotted path of any depth (`pose.x`,\n * `data.style.fontSize`, `data.style.fill.color`). Returns `undefined` if\n * the path is dotless (mirrors `commit`'s no-op on a malformed schema\n * key) or if any intermediate segment is missing or not an object. */\nexport function nodeValueAt(node: AnyNode, path: string): unknown {\n const segments = path.split('.');\n if (segments.length < 2) return undefined;\n const head = segments[0];\n let cursor: unknown = head === 'pose' ? node.pose : head === 'data' ? node.data : undefined;\n for (let i = 1; i < segments.length; i++) {\n if (cursor == null || typeof cursor !== 'object') return undefined;\n cursor = (cursor as Record<string, unknown>)[segments[i]];\n }\n return cursor;\n}\n\n/** Immutably set `value` at a dotted path within `root`, cloning each level\n * on the way down so React sees new object identities. Arrays stay arrays\n * (an array intermediate is shallow-copied, not flattened into `{0: ...}`)\n * — this is the write-side twin of `nodeValueAt`, so a schema author who\n * gets a working read gets a working write. */\nexport function setAtPath(root: object, segments: readonly string[], value: unknown): object {\n const [head, ...rest] = segments;\n if (rest.length === 0) {\n return Array.isArray(root)\n ? Object.assign([...root], { [head]: value })\n : { ...root, [head]: value };\n }\n const child = (root as Record<string, unknown>)[head];\n const childObj = Array.isArray(child)\n ? [...child]\n : child != null && typeof child === 'object'\n ? { ...child }\n : {};\n const nested = setAtPath(childObj, rest, value);\n return Array.isArray(root)\n ? Object.assign([...root], { [head]: nested })\n : { ...root, [head]: nested };\n}\n\n/** Aggregate a path across nodes: the shared value, or `MIXED`. */\nexport function aggregateValue(\n nodes: readonly AnyNode[],\n path: string,\n): unknown | Mixed {\n let value: unknown;\n let first = true;\n for (const node of nodes) {\n const v = nodeValueAt(node, path);\n if (first) {\n value = v;\n first = false;\n } else if (!Object.is(v, value)) {\n return MIXED;\n }\n }\n return value;\n}\n\n/** `'rect ×2 · text'` — kinds in first-seen order with counts. */\nexport function kindBreakdown(kinds: readonly string[]): string {\n const counts = new Map<string, number>();\n for (const k of kinds) counts.set(k, (counts.get(k) ?? 0) + 1);\n return [...counts.entries()]\n .map(([k, n]) => (n > 1 ? `${k} ×${n}` : k))\n .join(' · ');\n}\n"],"mappings":"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"}
|