@weasel-js/ui 1.7.0 → 1.7.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.
Files changed (391) hide show
  1. package/dist/chunks/ActionBar-xA73vzzF.js +64 -0
  2. package/dist/chunks/ActionBar-xA73vzzF.js.map +1 -0
  3. package/dist/chunks/{Badge-D2aD7xVL.js → Badge-jYQjrTKc.js} +235 -264
  4. package/dist/chunks/{Badge-D2aD7xVL.js.map → Badge-jYQjrTKc.js.map} +1 -1
  5. package/dist/chunks/BandEditor-Dd0egAgE.js.map +1 -1
  6. package/dist/chunks/{Button-BIdXHQOx.js → Button-XB-T75YL.js} +2 -2
  7. package/dist/chunks/{Button-BIdXHQOx.js.map → Button-XB-T75YL.js.map} +1 -1
  8. package/dist/chunks/{ButtonBar-DIQTe5GQ.js → ButtonBar-CIMKPPRS.js} +7 -9
  9. package/dist/chunks/{ButtonBar-DIQTe5GQ.js.map → ButtonBar-CIMKPPRS.js.map} +1 -1
  10. package/dist/chunks/Callout-BUn0dP_S.js +115 -0
  11. package/dist/chunks/Callout-BUn0dP_S.js.map +1 -0
  12. package/dist/chunks/Checkbox-DFn-x0JO.js +37 -0
  13. package/dist/chunks/Checkbox-DFn-x0JO.js.map +1 -0
  14. package/dist/chunks/{CloseButton-C2J7wVfo.js → CloseButton-BmNmRVtb.js} +3 -3
  15. package/dist/chunks/{CloseButton-C2J7wVfo.js.map → CloseButton-BmNmRVtb.js.map} +1 -1
  16. package/dist/chunks/ColorField-BLs9fbeq.js +90 -0
  17. package/dist/chunks/ColorField-BLs9fbeq.js.map +1 -0
  18. package/dist/chunks/{ColorModeControl-BewxA0rX.js → ColorModeControl-DaVJ-SyX.js} +3 -3
  19. package/dist/chunks/{ColorModeControl-BewxA0rX.js.map → ColorModeControl-DaVJ-SyX.js.map} +1 -1
  20. package/dist/chunks/ComboBox-CuTLRmUg.js +138 -0
  21. package/dist/chunks/ComboBox-CuTLRmUg.js.map +1 -0
  22. package/dist/chunks/{CurveEditor-DUVjd25R.js → CurveEditor-jVBEqqdv.js} +90 -87
  23. package/dist/chunks/CurveEditor-jVBEqqdv.js.map +1 -0
  24. package/dist/chunks/{DataGrid-LZ2JgY2Y.js → DataGrid-BklgBqS0.js} +2 -2
  25. package/dist/chunks/{DataGrid-LZ2JgY2Y.js.map → DataGrid-BklgBqS0.js.map} +1 -1
  26. package/dist/chunks/{DetailList-BKomDzg5.js → DetailList-DFtqdOJj.js} +7 -7
  27. package/dist/chunks/DetailList-DFtqdOJj.js.map +1 -0
  28. package/dist/chunks/{DetentSlider-5uQPFucv.js → DetentSlider-Bh7EpMqT.js} +2 -2
  29. package/dist/chunks/{DetentSlider-5uQPFucv.js.map → DetentSlider-Bh7EpMqT.js.map} +1 -1
  30. package/dist/chunks/{Dialog-DGFutQ--.js → Dialog-DKfsk5VN.js} +3 -3
  31. package/dist/chunks/{Dialog-DGFutQ--.js.map → Dialog-DKfsk5VN.js.map} +1 -1
  32. package/dist/chunks/{DragGhost-B5_hb9W9.js → DragGhost-BeYDJyLZ.js} +2 -2
  33. package/dist/chunks/{DragGhost-B5_hb9W9.js.map → DragGhost-BeYDJyLZ.js.map} +1 -1
  34. package/dist/chunks/{FallthroughDiagram-BEHiM5IS.js → FallthroughDiagram-C7BUe8eU.js} +3 -3
  35. package/dist/chunks/{FallthroughDiagram-BEHiM5IS.js.map → FallthroughDiagram-C7BUe8eU.js.map} +1 -1
  36. package/dist/chunks/Field-DsBlnFKf.js +25 -0
  37. package/dist/chunks/Field-DsBlnFKf.js.map +1 -0
  38. package/dist/chunks/FillStrokeSwatch-CgsYQgew.js +112 -0
  39. package/dist/chunks/FillStrokeSwatch-CgsYQgew.js.map +1 -0
  40. package/dist/chunks/{FontFamilySelect-DkRgNtag.js → FontFamilySelect-CGJ5OIOy.js} +2 -2
  41. package/dist/chunks/FontFamilySelect-CGJ5OIOy.js.map +1 -0
  42. package/dist/chunks/FontWeightSelect-RbcXYJPS.js +49 -0
  43. package/dist/chunks/FontWeightSelect-RbcXYJPS.js.map +1 -0
  44. package/dist/chunks/{GestureRoute-C_YGl7bJ.js → GestureRoute-BXESrHI0.js} +2 -2
  45. package/dist/chunks/{GestureRoute-C_YGl7bJ.js.map → GestureRoute-BXESrHI0.js.map} +1 -1
  46. package/dist/chunks/GradientEditor-DypXzMc-.js +325 -0
  47. package/dist/chunks/GradientEditor-DypXzMc-.js.map +1 -0
  48. package/dist/chunks/{Icon-CcVjdq2C.js → Icon--B1ME-6c.js} +3 -1
  49. package/dist/chunks/Icon--B1ME-6c.js.map +1 -0
  50. package/dist/chunks/{Input-CHmkfYaD.js → Input-CzwvCZs_.js} +10 -15
  51. package/dist/chunks/Input-CzwvCZs_.js.map +1 -0
  52. package/dist/chunks/{ItemList-Cm-HUWCi.js → ItemList-CRu9y7hL.js} +2 -2
  53. package/dist/chunks/ItemList-CRu9y7hL.js.map +1 -0
  54. package/dist/chunks/{Jog-DRmfrkCg.js → Jog-DfNUYejm.js} +8 -8
  55. package/dist/chunks/Jog-DfNUYejm.js.map +1 -0
  56. package/dist/chunks/{LayerList-wCI1EueM.js → LayerList-CsDqwYh-.js} +151 -153
  57. package/dist/chunks/LayerList-CsDqwYh-.js.map +1 -0
  58. package/dist/chunks/ListEditor-BnGzqERm.js +72 -0
  59. package/dist/chunks/ListEditor-BnGzqERm.js.map +1 -0
  60. package/dist/chunks/MenuButton-L9f5vido.js +75 -0
  61. package/dist/chunks/MenuButton-L9f5vido.js.map +1 -0
  62. package/dist/chunks/MeshEditor-GbqqiPk8.js +199 -0
  63. package/dist/chunks/MeshEditor-GbqqiPk8.js.map +1 -0
  64. package/dist/chunks/{NumberField-BnJxcazc.js → NumberField-DLXXgh48.js} +26 -23
  65. package/dist/chunks/NumberField-DLXXgh48.js.map +1 -0
  66. package/dist/chunks/{OptionsBar-ujxYidhj.js → OptionsBar-DeTAjVb7.js} +6 -8
  67. package/dist/chunks/{OptionsBar-ujxYidhj.js.map → OptionsBar-DeTAjVb7.js.map} +1 -1
  68. package/dist/chunks/PaintField-C0hoXc0Y.js +63 -0
  69. package/dist/chunks/PaintField-C0hoXc0Y.js.map +1 -0
  70. package/dist/chunks/PaintInput-jQRxM95Y.js +132 -0
  71. package/dist/chunks/PaintInput-jQRxM95Y.js.map +1 -0
  72. package/dist/chunks/PatternPicker-CaMYXzhF.js +135 -0
  73. package/dist/chunks/PatternPicker-CaMYXzhF.js.map +1 -0
  74. package/dist/chunks/{Plot2D-CTXHkL5p.js → Plot2D-BHNbgCAl.js} +7 -7
  75. package/dist/chunks/Plot2D-BHNbgCAl.js.map +1 -0
  76. package/dist/chunks/{PointPlotter-ldI4RrU1.js → PointPlotter-BZ_vk6gV.js} +2 -2
  77. package/dist/chunks/{PointPlotter-ldI4RrU1.js.map → PointPlotter-BZ_vk6gV.js.map} +1 -1
  78. package/dist/chunks/{Powerline-DNyH885r.js → Powerline-6wIFmDik.js} +2 -2
  79. package/dist/chunks/{Powerline-DNyH885r.js.map → Powerline-6wIFmDik.js.map} +1 -1
  80. package/dist/chunks/{Prefs-ByA-x51i.js → Prefs-CkyldX-e.js} +83 -70
  81. package/dist/chunks/Prefs-CkyldX-e.js.map +1 -0
  82. package/dist/chunks/{Properties-DmAeQ3mk.js → Properties-D15c8NP-.js} +25 -25
  83. package/dist/chunks/{Properties-DmAeQ3mk.js.map → Properties-D15c8NP-.js.map} +1 -1
  84. package/dist/chunks/PropertyField-CV_Gw57S.js +686 -0
  85. package/dist/chunks/PropertyField-CV_Gw57S.js.map +1 -0
  86. package/dist/chunks/{RadioGroup-Bh4-12e-.js → RadioGroup-4dbzqvGy.js} +2 -2
  87. package/dist/chunks/{RadioGroup-Bh4-12e-.js.map → RadioGroup-4dbzqvGy.js.map} +1 -1
  88. package/dist/chunks/{RangeSlider-SEGE-7VF.js → RangeSlider-BxokZViJ.js} +8 -8
  89. package/dist/chunks/RangeSlider-BxokZViJ.js.map +1 -0
  90. package/dist/chunks/RecentColorsProvider-DHcfk25u.js +84 -0
  91. package/dist/chunks/RecentColorsProvider-DHcfk25u.js.map +1 -0
  92. package/dist/chunks/ResizeHandle-CbAgCQOt.js +81 -0
  93. package/dist/chunks/ResizeHandle-CbAgCQOt.js.map +1 -0
  94. package/dist/chunks/Select-BppLsJTz.js +236 -0
  95. package/dist/chunks/Select-BppLsJTz.js.map +1 -0
  96. package/dist/chunks/{SelectionPanel-BaQnX4Bs.js → SelectionPanel-Cm1qu-ZX.js} +14 -13
  97. package/dist/chunks/{SelectionPanel-BaQnX4Bs.js.map → SelectionPanel-Cm1qu-ZX.js.map} +1 -1
  98. package/dist/chunks/{SidebarPanel-BblDEz4G.js → SidebarPanel-AXQ0jRDx.js} +2 -2
  99. package/dist/chunks/{SidebarPanel-BblDEz4G.js.map → SidebarPanel-AXQ0jRDx.js.map} +1 -1
  100. package/dist/chunks/{Slider-YofwGOI4.js → Slider-Cl5RCeZ7.js} +19 -19
  101. package/dist/chunks/Slider-Cl5RCeZ7.js.map +1 -0
  102. package/dist/chunks/SwatchGrid-9ZPiDmxd.js +78 -0
  103. package/dist/chunks/SwatchGrid-9ZPiDmxd.js.map +1 -0
  104. package/dist/chunks/SwatchStrip-Cw0l8Om7.js +577 -0
  105. package/dist/chunks/SwatchStrip-Cw0l8Om7.js.map +1 -0
  106. package/dist/chunks/{ThemeSwitcher-BlsInAmR.js → ThemeSwitcher-DiBmMh_B.js} +3 -3
  107. package/dist/chunks/{ThemeSwitcher-BlsInAmR.js.map → ThemeSwitcher-DiBmMh_B.js.map} +1 -1
  108. package/dist/chunks/{Timeline-B39cwfMB.js → Timeline-pqnYk5cV.js} +244 -246
  109. package/dist/chunks/Timeline-pqnYk5cV.js.map +1 -0
  110. package/dist/chunks/Toast-C3ozq11V.js +170 -0
  111. package/dist/chunks/Toast-C3ozq11V.js.map +1 -0
  112. package/dist/chunks/{ToggleBar-BTYkBXU9.js → ToggleBar-Z2jZiguF.js} +6 -8
  113. package/dist/chunks/{ToggleBar-BTYkBXU9.js.map → ToggleBar-Z2jZiguF.js.map} +1 -1
  114. package/dist/chunks/{TokenPanel-CMDAOfYH.js → TokenPanel-DAkL6vwQ.js} +32 -32
  115. package/dist/chunks/TokenPanel-DAkL6vwQ.js.map +1 -0
  116. package/dist/chunks/{ToolButton-CAHBa08P.js → ToolButton-BURp4YIO.js} +7 -9
  117. package/dist/chunks/ToolButton-BURp4YIO.js.map +1 -0
  118. package/dist/chunks/{ToolOptionsBar-D_GCrBAN.js → ToolOptionsBar-COsTJ1cu.js} +3 -2
  119. package/dist/chunks/{ToolOptionsBar-D_GCrBAN.js.map → ToolOptionsBar-COsTJ1cu.js.map} +1 -1
  120. package/dist/chunks/{ToolPalette-OOWN51Xx.js → ToolPalette-DKDFWOX-.js} +7 -9
  121. package/dist/chunks/{ToolPalette-OOWN51Xx.js.map → ToolPalette-DKDFWOX-.js.map} +1 -1
  122. package/dist/chunks/{Tooltip-Clg2mhSt.js → Tooltip-C6eFCYxw.js} +2 -2
  123. package/dist/chunks/{Tooltip-Clg2mhSt.js.map → Tooltip-C6eFCYxw.js.map} +1 -1
  124. package/dist/chunks/Tree-Cc8lIzgM.js.map +1 -1
  125. package/dist/chunks/checkbox.module-DLQV9tMX.js +5 -0
  126. package/dist/chunks/checkbox.module-DLQV9tMX.js.map +1 -0
  127. package/dist/chunks/{createKeyframeLayer-DVl321_l.js → createKeyframeLayer-BTa4LyJE.js} +194 -208
  128. package/dist/chunks/createKeyframeLayer-BTa4LyJE.js.map +1 -0
  129. package/dist/chunks/field.module-Bh7BTKMh.js +15 -0
  130. package/dist/chunks/field.module-Bh7BTKMh.js.map +1 -0
  131. package/dist/chunks/formatShortcut-DRQrVThu.js.map +1 -1
  132. package/dist/chunks/handles-CqVANLtu.js +17 -0
  133. package/dist/chunks/handles-CqVANLtu.js.map +1 -0
  134. package/dist/chunks/{icons-BhcR1l64.js → icons-Dr2-r30x.js} +2 -2
  135. package/dist/chunks/icons-Dr2-r30x.js.map +1 -0
  136. package/dist/chunks/listbox.module-BcdVJMbm.js +8 -0
  137. package/dist/chunks/listbox.module-BcdVJMbm.js.map +1 -0
  138. package/dist/chunks/model-B1-gMBIW.js +386 -0
  139. package/dist/chunks/model-B1-gMBIW.js.map +1 -0
  140. package/dist/chunks/{portalHost-yTOVuCej.js → portalHost-CE70wLzo.js} +10 -6
  141. package/dist/chunks/portalHost-CE70wLzo.js.map +1 -0
  142. package/dist/chunks/prefField-BE_Ytr2H.js +229 -0
  143. package/dist/chunks/prefField-BE_Ytr2H.js.map +1 -0
  144. package/dist/chunks/{segmentTooltip-CStYHKzd.js → segmentTooltip-CGxCOWNz.js} +2 -2
  145. package/dist/chunks/{segmentTooltip-CStYHKzd.js.map → segmentTooltip-CGxCOWNz.js.map} +1 -1
  146. package/dist/chunks/segmentedControl.module-BzGXUL5G.js +11 -0
  147. package/dist/chunks/segmentedControl.module-BzGXUL5G.js.map +1 -0
  148. package/dist/chunks/useReorderDragList-CStYKjHl.js +133 -0
  149. package/dist/chunks/useReorderDragList-CStYKjHl.js.map +1 -0
  150. package/dist/chunks/useRovingTabIndex-D7u22Ia_.js +91 -0
  151. package/dist/chunks/useRovingTabIndex-D7u22Ia_.js.map +1 -0
  152. package/dist/components/ActionBar/ActionBar.d.ts.map +1 -1
  153. package/dist/components/ActionBar/index.js +1 -1
  154. package/dist/components/Badge/bases/ChamferedRect.d.ts.map +1 -1
  155. package/dist/components/Badge/index.js +1 -1
  156. package/dist/components/BandEditor/BandEditor.d.ts +1 -0
  157. package/dist/components/BandEditor/BandEditor.d.ts.map +1 -1
  158. package/dist/components/Button/index.js +1 -1
  159. package/dist/components/ButtonBar/ButtonBar.d.ts.map +1 -1
  160. package/dist/components/ButtonBar/index.js +1 -1
  161. package/dist/components/Callout/Callout.d.ts.map +1 -1
  162. package/dist/components/Callout/index.js +1 -1
  163. package/dist/components/Checkbox/Checkbox.d.ts +28 -13
  164. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
  165. package/dist/components/Checkbox/index.js +1 -1
  166. package/dist/components/CloseButton/index.js +1 -1
  167. package/dist/components/ColorField/ColorField.d.ts.map +1 -1
  168. package/dist/components/ColorField/OpacityRange.d.ts +18 -0
  169. package/dist/components/ColorField/OpacityRange.d.ts.map +1 -0
  170. package/dist/components/ColorField/index.js +1 -1
  171. package/dist/components/ColorModeControl/index.js +1 -1
  172. package/dist/components/ComboBox/ComboBox.d.ts +7 -0
  173. package/dist/components/ComboBox/ComboBox.d.ts.map +1 -1
  174. package/dist/components/ComboBox/index.js +1 -1
  175. package/dist/components/CurveEditor/CurveEditor.d.ts.map +1 -1
  176. package/dist/components/CurveEditor/LayeredCurveEditor.d.ts.map +1 -1
  177. package/dist/components/CurveEditor/index.js +2 -2
  178. package/dist/components/DataGrid/index.js +1 -1
  179. package/dist/components/DetailList/index.js +1 -1
  180. package/dist/components/DetentSlider/index.js +1 -1
  181. package/dist/components/Dialog/index.js +1 -1
  182. package/dist/components/DragGhost/index.js +1 -1
  183. package/dist/components/FallthroughDiagram/index.js +1 -1
  184. package/dist/components/Field/index.js +1 -1
  185. package/dist/components/FillStrokeSwatch/FillStrokeSwatch.d.ts.map +1 -1
  186. package/dist/components/FillStrokeSwatch/index.js +1 -1
  187. package/dist/components/FontFamilySelect/FontFamilySelect.d.ts +20 -0
  188. package/dist/components/FontFamilySelect/FontFamilySelect.d.ts.map +1 -1
  189. package/dist/components/FontFamilySelect/index.js +1 -1
  190. package/dist/components/FontWeightSelect/FontWeightSelect.d.ts +26 -0
  191. package/dist/components/FontWeightSelect/FontWeightSelect.d.ts.map +1 -0
  192. package/dist/components/FontWeightSelect/index.d.ts +3 -0
  193. package/dist/components/FontWeightSelect/index.d.ts.map +1 -0
  194. package/dist/components/FontWeightSelect/index.js +2 -0
  195. package/dist/components/GestureRoute/index.js +1 -1
  196. package/dist/components/GradientEditor/GradientHandles.d.ts +1 -8
  197. package/dist/components/GradientEditor/GradientHandles.d.ts.map +1 -1
  198. package/dist/components/GradientEditor/SceneGradientHandles.d.ts +7 -5
  199. package/dist/components/GradientEditor/SceneGradientHandles.d.ts.map +1 -1
  200. package/dist/components/GradientEditor/handleOverlay.d.ts +41 -0
  201. package/dist/components/GradientEditor/handleOverlay.d.ts.map +1 -0
  202. package/dist/components/GradientEditor/index.js +1 -1
  203. package/dist/components/Input/Input.d.ts +1 -1
  204. package/dist/components/Input/Input.d.ts.map +1 -1
  205. package/dist/components/Input/index.js +1 -1
  206. package/dist/components/ItemList/ItemList.d.ts +32 -31
  207. package/dist/components/ItemList/ItemList.d.ts.map +1 -1
  208. package/dist/components/ItemList/index.js +1 -1
  209. package/dist/components/Jog/index.js +1 -1
  210. package/dist/components/LayerList/LayerList.d.ts.map +1 -1
  211. package/dist/components/LayerList/index.js +1 -1
  212. package/dist/components/ListEditor/ListEditor.d.ts.map +1 -1
  213. package/dist/components/ListEditor/index.js +1 -1
  214. package/dist/components/MenuButton/MenuButton.d.ts.map +1 -1
  215. package/dist/components/MenuButton/index.js +1 -1
  216. package/dist/components/MeshEditor/MeshEditor.d.ts +4 -3
  217. package/dist/components/MeshEditor/MeshEditor.d.ts.map +1 -1
  218. package/dist/components/MeshEditor/MeshHandles.d.ts +38 -0
  219. package/dist/components/MeshEditor/MeshHandles.d.ts.map +1 -0
  220. package/dist/components/MeshEditor/index.d.ts +2 -0
  221. package/dist/components/MeshEditor/index.d.ts.map +1 -1
  222. package/dist/components/MeshEditor/index.js +2 -2
  223. package/dist/components/NumberField/NumberField.d.ts +1 -1
  224. package/dist/components/NumberField/NumberField.d.ts.map +1 -1
  225. package/dist/components/NumberField/index.js +1 -1
  226. package/dist/components/OptionsBar/OptionsBar.d.ts.map +1 -1
  227. package/dist/components/OptionsBar/index.js +1 -1
  228. package/dist/components/PaintField/PaintField.d.ts.map +1 -1
  229. package/dist/components/PaintField/index.js +1 -1
  230. package/dist/components/PaintInput/PaintInput.d.ts.map +1 -1
  231. package/dist/components/PaintInput/index.js +1 -1
  232. package/dist/components/PatternPicker/PatternPicker.d.ts +6 -5
  233. package/dist/components/PatternPicker/PatternPicker.d.ts.map +1 -1
  234. package/dist/components/PatternPicker/index.js +1 -1
  235. package/dist/components/Plot2D/index.js +1 -1
  236. package/dist/components/PointPlotter/index.js +1 -1
  237. package/dist/components/Powerline/index.js +2 -2
  238. package/dist/components/Prefs/PrefsForm.d.ts +8 -0
  239. package/dist/components/Prefs/PrefsForm.d.ts.map +1 -1
  240. package/dist/components/Prefs/PrefsRail.d.ts +3 -2
  241. package/dist/components/Prefs/PrefsRail.d.ts.map +1 -1
  242. package/dist/components/Prefs/index.js +2 -2
  243. package/dist/components/Prefs/prefField.d.ts +13 -0
  244. package/dist/components/Prefs/prefField.d.ts.map +1 -1
  245. package/dist/components/Properties/PropertyField.d.ts +13 -2
  246. package/dist/components/Properties/PropertyField.d.ts.map +1 -1
  247. package/dist/components/Properties/index.js +3 -3
  248. package/dist/components/RadioGroup/index.js +1 -1
  249. package/dist/components/RangeSlider/index.js +1 -1
  250. package/dist/components/RecentColors/RecentColorsProvider.d.ts +24 -0
  251. package/dist/components/RecentColors/RecentColorsProvider.d.ts.map +1 -0
  252. package/dist/components/RecentColors/index.d.ts +5 -0
  253. package/dist/components/RecentColors/index.d.ts.map +1 -0
  254. package/dist/components/RecentColors/index.js +2 -0
  255. package/dist/components/RecentColors/recentColors.d.ts +39 -0
  256. package/dist/components/RecentColors/recentColors.d.ts.map +1 -0
  257. package/dist/components/ResizeHandle/ResizeHandle.d.ts.map +1 -1
  258. package/dist/components/ResizeHandle/index.js +1 -1
  259. package/dist/components/Select/Select.d.ts +6 -2
  260. package/dist/components/Select/Select.d.ts.map +1 -1
  261. package/dist/components/Select/index.js +1 -1
  262. package/dist/components/SelectionPanel/index.js +2 -2
  263. package/dist/components/SelectionPanel/renderLeaf.d.ts +12 -2
  264. package/dist/components/SelectionPanel/renderLeaf.d.ts.map +1 -1
  265. package/dist/components/SidebarPanel/index.js +1 -1
  266. package/dist/components/Slider/index.js +1 -1
  267. package/dist/components/SwatchGrid/SwatchGrid.d.ts.map +1 -1
  268. package/dist/components/SwatchGrid/index.js +1 -1
  269. package/dist/components/SwatchStrip/SwatchStrip.d.ts +44 -0
  270. package/dist/components/SwatchStrip/SwatchStrip.d.ts.map +1 -0
  271. package/dist/components/SwatchStrip/index.d.ts +5 -0
  272. package/dist/components/SwatchStrip/index.d.ts.map +1 -0
  273. package/dist/components/SwatchStrip/index.js +2 -0
  274. package/dist/components/SwatchStrip/palettes.d.ts +21 -0
  275. package/dist/components/SwatchStrip/palettes.d.ts.map +1 -0
  276. package/dist/components/ThemeSwitcher/index.js +1 -1
  277. package/dist/components/Timeline/AnimatedTimeline.d.ts +1 -0
  278. package/dist/components/Timeline/AnimatedTimeline.d.ts.map +1 -1
  279. package/dist/components/Timeline/EasingPicker.d.ts +3 -0
  280. package/dist/components/Timeline/EasingPicker.d.ts.map +1 -1
  281. package/dist/components/Timeline/LaneGraph.d.ts +1 -1
  282. package/dist/components/Timeline/LaneGraph.d.ts.map +1 -1
  283. package/dist/components/Timeline/Timeline.d.ts +10 -1
  284. package/dist/components/Timeline/Timeline.d.ts.map +1 -1
  285. package/dist/components/Timeline/Transport.d.ts +6 -0
  286. package/dist/components/Timeline/Transport.d.ts.map +1 -1
  287. package/dist/components/Timeline/index.js +1 -1
  288. package/dist/components/Timeline/keys.d.ts +1 -0
  289. package/dist/components/Timeline/keys.d.ts.map +1 -1
  290. package/dist/components/Toast/Toast.d.ts +12 -3
  291. package/dist/components/Toast/Toast.d.ts.map +1 -1
  292. package/dist/components/Toast/index.js +1 -1
  293. package/dist/components/ToggleBar/ToggleBar.d.ts.map +1 -1
  294. package/dist/components/ToggleBar/index.js +1 -1
  295. package/dist/components/TokenPanel/index.js +1 -1
  296. package/dist/components/TokenPanel/tokenTypes.d.ts +1 -0
  297. package/dist/components/TokenPanel/tokenTypes.d.ts.map +1 -1
  298. package/dist/components/ToolButton/ToolButton.d.ts +1 -10
  299. package/dist/components/ToolButton/ToolButton.d.ts.map +1 -1
  300. package/dist/components/ToolButton/index.js +1 -1
  301. package/dist/components/ToolOptionsBar/index.js +1 -1
  302. package/dist/components/ToolPalette/ToolPalette.d.ts.map +1 -1
  303. package/dist/components/ToolPalette/formatShortcut.d.ts +2 -0
  304. package/dist/components/ToolPalette/formatShortcut.d.ts.map +1 -1
  305. package/dist/components/ToolPalette/index.js +1 -1
  306. package/dist/components/Tooltip/index.js +1 -1
  307. package/dist/components/Tree/Tree.d.ts +27 -26
  308. package/dist/components/Tree/Tree.d.ts.map +1 -1
  309. package/dist/icons/index.d.ts +51 -0
  310. package/dist/icons/index.d.ts.map +1 -1
  311. package/dist/icons/paths.d.ts +2 -0
  312. package/dist/icons/paths.d.ts.map +1 -1
  313. package/dist/index.d.ts +4 -1
  314. package/dist/index.d.ts.map +1 -1
  315. package/dist/index.js +98 -95
  316. package/dist/index.js.map +1 -1
  317. package/dist/overlays/portalHost.d.ts +6 -0
  318. package/dist/overlays/portalHost.d.ts.map +1 -1
  319. package/dist/style.css +1 -1
  320. package/dist/useAsyncOptions.d.ts.map +1 -1
  321. package/dist/useReorderDragList.d.ts.map +1 -1
  322. package/dist/useRovingTabIndex.d.ts +40 -39
  323. package/dist/useRovingTabIndex.d.ts.map +1 -1
  324. package/package.json +9 -9
  325. package/dist/chunks/ActionBar-DCq16yFA.js +0 -57
  326. package/dist/chunks/ActionBar-DCq16yFA.js.map +0 -1
  327. package/dist/chunks/Callout-ndW5_Bqx.js +0 -116
  328. package/dist/chunks/Callout-ndW5_Bqx.js.map +0 -1
  329. package/dist/chunks/Checkbox-DHXTUHO9.js +0 -47
  330. package/dist/chunks/Checkbox-DHXTUHO9.js.map +0 -1
  331. package/dist/chunks/ColorField-Yz_BkcCT.js +0 -69
  332. package/dist/chunks/ColorField-Yz_BkcCT.js.map +0 -1
  333. package/dist/chunks/ComboBox-B34H76CW.js +0 -138
  334. package/dist/chunks/ComboBox-B34H76CW.js.map +0 -1
  335. package/dist/chunks/CurveEditor-DUVjd25R.js.map +0 -1
  336. package/dist/chunks/DetailList-BKomDzg5.js.map +0 -1
  337. package/dist/chunks/Field--onYxXTF.js +0 -32
  338. package/dist/chunks/Field--onYxXTF.js.map +0 -1
  339. package/dist/chunks/FillStrokeSwatch-DNb0KXPk.js +0 -111
  340. package/dist/chunks/FillStrokeSwatch-DNb0KXPk.js.map +0 -1
  341. package/dist/chunks/FontFamilySelect-DkRgNtag.js.map +0 -1
  342. package/dist/chunks/GradientEditor-b7v4Ph3i.js +0 -363
  343. package/dist/chunks/GradientEditor-b7v4Ph3i.js.map +0 -1
  344. package/dist/chunks/Icon-CcVjdq2C.js.map +0 -1
  345. package/dist/chunks/Input-CHmkfYaD.js.map +0 -1
  346. package/dist/chunks/ItemList-Cm-HUWCi.js.map +0 -1
  347. package/dist/chunks/Jog-DRmfrkCg.js.map +0 -1
  348. package/dist/chunks/LayerList-wCI1EueM.js.map +0 -1
  349. package/dist/chunks/ListEditor-BeA60TAA.js +0 -71
  350. package/dist/chunks/ListEditor-BeA60TAA.js.map +0 -1
  351. package/dist/chunks/MenuButton-BSqEChJE.js +0 -70
  352. package/dist/chunks/MenuButton-BSqEChJE.js.map +0 -1
  353. package/dist/chunks/MeshEditor-D1HLZcAh.js +0 -87
  354. package/dist/chunks/MeshEditor-D1HLZcAh.js.map +0 -1
  355. package/dist/chunks/NumberField-BnJxcazc.js.map +0 -1
  356. package/dist/chunks/PaintField-DadOELMg.js +0 -62
  357. package/dist/chunks/PaintField-DadOELMg.js.map +0 -1
  358. package/dist/chunks/PaintInput-v8Y7MDbH.js +0 -121
  359. package/dist/chunks/PaintInput-v8Y7MDbH.js.map +0 -1
  360. package/dist/chunks/PatternPicker-R_EQtw2Q.js +0 -93
  361. package/dist/chunks/PatternPicker-R_EQtw2Q.js.map +0 -1
  362. package/dist/chunks/Plot2D-CTXHkL5p.js.map +0 -1
  363. package/dist/chunks/Prefs-ByA-x51i.js.map +0 -1
  364. package/dist/chunks/PropertyField-DfIJJ5GS.js +0 -673
  365. package/dist/chunks/PropertyField-DfIJJ5GS.js.map +0 -1
  366. package/dist/chunks/RangeSlider-SEGE-7VF.js.map +0 -1
  367. package/dist/chunks/ResizeHandle-rKVWyeTG.js +0 -79
  368. package/dist/chunks/ResizeHandle-rKVWyeTG.js.map +0 -1
  369. package/dist/chunks/Select-ClmKtyWg.js +0 -229
  370. package/dist/chunks/Select-ClmKtyWg.js.map +0 -1
  371. package/dist/chunks/Slider-YofwGOI4.js.map +0 -1
  372. package/dist/chunks/SwatchGrid-BYvA8Bmh.js +0 -73
  373. package/dist/chunks/SwatchGrid-BYvA8Bmh.js.map +0 -1
  374. package/dist/chunks/Timeline-B39cwfMB.js.map +0 -1
  375. package/dist/chunks/Toast-BF9GE0HC.js +0 -126
  376. package/dist/chunks/Toast-BF9GE0HC.js.map +0 -1
  377. package/dist/chunks/TokenPanel-CMDAOfYH.js.map +0 -1
  378. package/dist/chunks/ToolButton-CAHBa08P.js.map +0 -1
  379. package/dist/chunks/createKeyframeLayer-DVl321_l.js.map +0 -1
  380. package/dist/chunks/icons-BhcR1l64.js.map +0 -1
  381. package/dist/chunks/model-BaF65rnX.js +0 -365
  382. package/dist/chunks/model-BaF65rnX.js.map +0 -1
  383. package/dist/chunks/portalHost-yTOVuCej.js.map +0 -1
  384. package/dist/chunks/prefField-BopW9bjx.js +0 -201
  385. package/dist/chunks/prefField-BopW9bjx.js.map +0 -1
  386. package/dist/chunks/segmentedControl.module-D6SzYJD7.js +0 -11
  387. package/dist/chunks/segmentedControl.module-D6SzYJD7.js.map +0 -1
  388. package/dist/chunks/useReorderDragList-FCMoFIzH.js +0 -131
  389. package/dist/chunks/useReorderDragList-FCMoFIzH.js.map +0 -1
  390. package/dist/chunks/useRovingTabIndex-Bp_hYm_h.js +0 -65
  391. package/dist/chunks/useRovingTabIndex-Bp_hYm_h.js.map +0 -1
@@ -1,10 +1,10 @@
1
- import { n as e, r as t } from "./Tooltip-Clg2mhSt.js";
2
- import { t as n } from "./Button-BIdXHQOx.js";
1
+ import { n as e, r as t } from "./Tooltip-C6eFCYxw.js";
2
+ import { t as n } from "./Button-XB-T75YL.js";
3
3
  import { r } from "./Disclosure-Ch2KxYuB.js";
4
- import { t as i } from "./Select-ClmKtyWg.js";
5
- import { t as a } from "./Input-CHmkfYaD.js";
6
- import { r as o } from "./NumberField-BnJxcazc.js";
7
- import { t as s } from "./ToggleBar-BTYkBXU9.js";
4
+ import { t as i } from "./Select-BppLsJTz.js";
5
+ import { t as a } from "./Input-CzwvCZs_.js";
6
+ import { r as o } from "./NumberField-DLXXgh48.js";
7
+ import { t as s } from "./ToggleBar-Z2jZiguF.js";
8
8
  import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
9
9
  import { memo as d, useCallback as f, useMemo as p, useState as m } from "react";
10
10
  import { Focusable as h } from "react-aria-components";
@@ -65,31 +65,31 @@ function T(e) {
65
65
  return r && r !== t ? S(r) : null;
66
66
  }
67
67
  var E = {
68
- panel: "_panel_j873d_1",
69
- section: "_section_j873d_7",
70
- sectionHead: "_sectionHead_j873d_17",
71
- sectionBody: "_sectionBody_j873d_26",
72
- row: "_row_j873d_33",
73
- family: "_family_j873d_34",
74
- name: "_name_j873d_41",
75
- edit: "_edit_j873d_50",
76
- field: "_field_j873d_57",
77
- number: "_number_j873d_63",
78
- unit: "_unit_j873d_69",
79
- swatchInput: "_swatchInput_j873d_76",
80
- chip: "_chip_j873d_88",
81
- curve: "_curve_j873d_97",
82
- strip: "_strip_j873d_105",
83
- swatch: "_swatch_j873d_76",
84
- scale: "_scale_j873d_137",
85
- scaleHead: "_scaleHead_j873d_144",
86
- steps: "_steps_j873d_151",
87
- rule: "_rule_j873d_157",
88
- ruleLabel: "_ruleLabel_j873d_165",
89
- step: "_step_j873d_151",
90
- stepLabel: "_stepLabel_j873d_183",
91
- stepEdit: "_stepEdit_j873d_197",
92
- tight: "_tight_j873d_216"
68
+ panel: "_panel_mspmc_1",
69
+ section: "_section_mspmc_7",
70
+ sectionHead: "_sectionHead_mspmc_17",
71
+ sectionBody: "_sectionBody_mspmc_26",
72
+ row: "_row_mspmc_33",
73
+ family: "_family_mspmc_34",
74
+ name: "_name_mspmc_41",
75
+ edit: "_edit_mspmc_50",
76
+ field: "_field_mspmc_57",
77
+ number: "_number_mspmc_63",
78
+ unit: "_unit_mspmc_69",
79
+ swatchInput: "_swatchInput_mspmc_76",
80
+ chip: "_chip_mspmc_88",
81
+ curve: "_curve_mspmc_97",
82
+ strip: "_strip_mspmc_105",
83
+ swatch: "_swatch_mspmc_76",
84
+ scale: "_scale_mspmc_137",
85
+ scaleHead: "_scaleHead_mspmc_144",
86
+ steps: "_steps_mspmc_151",
87
+ rule: "_rule_mspmc_157",
88
+ ruleLabel: "_ruleLabel_mspmc_165",
89
+ step: "_step_mspmc_151",
90
+ stepLabel: "_stepLabel_mspmc_184",
91
+ stepEdit: "_stepEdit_mspmc_198",
92
+ tight: "_tight_mspmc_218"
93
93
  }, D = (e) => Math.round(e * 100) / 100;
94
94
  function O(e, t, n) {
95
95
  let r = n[0] ?? e.base, i = n.at(-1) ?? r, a = Math.max(1, n.length - 1);
@@ -634,4 +634,4 @@ function oe({ tokens: e, onChange: t, collapsed: n, onCollapsedChange: r, scales
634
634
  //#endregion
635
635
  export { j as a, O as i, k as n, H as r, oe as t };
636
636
 
637
- //# sourceMappingURL=TokenPanel-CMDAOfYH.js.map
637
+ //# sourceMappingURL=TokenPanel-DAkL6vwQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenPanel-DAkL6vwQ.js","names":["s","_Fragment","NumberField","Select","Input","Button","TooltipTrigger","Tooltip","Tooltip$1","TooltipTrigger$1","Button$1","Select$1","Input$1","NumberField$1","ToggleBar","HEX","RGB","COLOR_FUNCTION","KEYWORDS","browserSupports","value","parsesAsColor","v","supports","hexOf","digits","d","rgb","n","paint","serialized","onBlack","toHex","direct","browser","TokenPanel_module_default","round2","refitScale","first","amounts","scale","last","spans","kind","a","TOKEN_CATEGORIES","TYPE_SCALE","tokenCategory","token","AMOUNT","DIMENSION","DURATION","NUMBER","LENGTH","BEZIER","GRADIENT","LAYERS","PARTS","isShadow","parts","layer","lengths","part","rest","inferTokenType","splitUnit","match","bezierPoints","x1","y1","x2","y2","WEIGHTS","NUMBER_FORMAT","SCALAR","familyKindOf","itemsOf","counts","tokens","families","items","key","familySize","family","stepLabels","split","names","name","shared","segments","Curve","points","top","bottom","label","TokenControl","hex","useMemo","type","Fragment","amount","set","options","weight","event","TokenRow","memo","useCallback","onChange","b","Family","picked","setPicked","useState","t","group","Focusable","current","ScaleStep","showUnit","factor","onFactorChange","next","RULES","ScaleRuleControls","param","rule","base","onScaleChange","unit","Scale","labels","units","overridden","generator","at","i","j","f","Section","title","DisclosureRow","open","item","scales","TokenPanel","ownCollapsed","setOwnCollapsed","closed","collapsed","byCategory","sections","category","categorize","density","className","inSection","id","prev","onCollapsedChange"],"sources":["../../src/components/TokenPanel/color.ts","../../src/components/TokenPanel/TokenPanel.module.css","../../src/components/TokenPanel/tokenTypes.ts","../../src/components/TokenPanel/TokenPanel.tsx"],"sourcesContent":["const HEX = /^#(?:[\\da-f]{3,4}|[\\da-f]{6}|[\\da-f]{8})$/i;\nconst RGB = /^rgba?\\(\\s*(\\d{1,3})[\\s,]+(\\d{1,3})[\\s,]+(\\d{1,3})\\b/i;\nconst COLOR_FUNCTION = /^(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color|color-mix)\\(.+\\)$/i;\nconst KEYWORDS = new Set([\n 'transparent',\n 'currentcolor',\n 'black',\n 'white',\n 'gray',\n 'silver',\n 'red',\n 'orange',\n 'yellow',\n 'gold',\n 'lime',\n 'green',\n 'teal',\n 'cyan',\n 'blue',\n 'navy',\n 'purple',\n 'magenta',\n 'pink',\n 'brown',\n]);\n\ntype Supports = ((value: string) => boolean) | null;\n\nfunction browserSupports(): Supports {\n return typeof CSS !== 'undefined' && typeof CSS.supports === 'function'\n ? (value) => CSS.supports('color', value)\n : null;\n}\n\n/** Whether `value` is a CSS color — the browser's answer where it has `CSS.supports`, a small parser's otherwise. */\nexport function parsesAsColor(value: string, supports: Supports = browserSupports()): boolean {\n const v = value.trim();\n // `CSS.supports` accepts any `var()` for any property.\n if (!v || v.includes('var(')) return false;\n if (supports) return supports(v);\n return HEX.test(v) || COLOR_FUNCTION.test(v) || KEYWORDS.has(v.toLowerCase());\n}\n\nfunction hexOf(v: string): string | null {\n if (HEX.test(v)) {\n const digits = v.slice(1).toLowerCase();\n return `#${digits.length <= 4 ? [...digits.slice(0, 3)].map((d) => d + d).join('') : digits.slice(0, 6)}`;\n }\n const rgb = RGB.exec(v);\n return rgb\n ? `#${rgb\n .slice(1, 4)\n .map((n) => Math.min(255, Number(n)).toString(16).padStart(2, '0'))\n .join('')}`\n : null;\n}\n\nlet paint: CanvasRenderingContext2D | null | undefined;\n\n/** The browser's serialization of a color, through a canvas fill style; null where it has none or rejects `value`. */\nfunction serialized(value: string): string | null {\n if (paint === undefined) {\n try {\n paint = document.createElement('canvas').getContext('2d');\n } catch {\n paint = null;\n }\n }\n if (!paint) return null;\n // A rejected value leaves the previous fill style, so two different ones tell a rejection apart.\n paint.fillStyle = '#000000';\n paint.fillStyle = value;\n const onBlack = String(paint.fillStyle);\n paint.fillStyle = '#ffffff';\n paint.fillStyle = value;\n return onBlack === String(paint.fillStyle) ? onBlack : null;\n}\n\n/** `value` as the `#rrggbb` a color input takes, alpha dropped; null when it cannot be converted. */\nexport function toHex(value: string): string | null {\n const v = value.trim();\n const direct = hexOf(v);\n if (direct) return direct;\n const browser = typeof document === 'undefined' ? null : serialized(v);\n return browser && browser !== v ? hexOf(browser) : null;\n}\n",".panel {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.section {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.section + .section {\n border-top: var(--wzl-border-w) solid var(--wzl-line-subtle);\n}\n\n.sectionHead {\n padding-block: var(--wzl-space-xs);\n color: var(--wzl-fg-muted);\n font-family: var(--wzl-font-display);\n font-size: var(--wzl-font-size-sm);\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.sectionBody {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-sm);\n padding-block-end: var(--wzl-space-sm);\n}\n\n.row,\n.family {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-1);\n min-width: 0;\n}\n\n.name {\n overflow: hidden;\n color: var(--wzl-fg-muted);\n font-family: var(--wzl-font-mono);\n font-size: var(--wzl-font-size-sm);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.edit {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-xs);\n min-width: 0;\n}\n\n.field {\n --wzl-font-ui: var(--wzl-font-mono);\n flex: 1;\n min-width: 0;\n}\n\n.number {\n --wzl-font-ui: var(--wzl-font-mono);\n flex: 1;\n min-width: 0;\n}\n\n.unit {\n color: var(--wzl-fg-muted);\n font-family: var(--wzl-font-mono);\n font-size: var(--wzl-font-size-sm);\n}\n\n/* Padding inflates a native color input past its box in Chrome. */\n.swatchInput {\n box-sizing: border-box;\n flex-shrink: 0;\n width: 18px;\n height: 14px;\n padding: 0;\n background: transparent;\n border: 0;\n border-radius: var(--wzl-radius-sm);\n cursor: pointer;\n}\n\n.chip {\n flex-shrink: 0;\n width: 18px;\n height: 14px;\n background: var(--token-color);\n border-radius: var(--wzl-radius-sm);\n box-shadow: inset 0 0 0 1px var(--wzl-line);\n}\n\n.curve {\n flex-shrink: 0;\n width: 24px;\n /* Square easing-curve artwork: not-a-control */\n height: 24px;\n color: var(--wzl-fg);\n}\n\n.strip {\n display: flex;\n height: var(--wzl-control-h);\n overflow: hidden;\n border: var(--wzl-border-w) solid var(--wzl-line);\n border-radius: var(--wzl-radius-sm);\n}\n\n.swatch {\n flex: 1 1 0;\n min-width: 0;\n height: 100%;\n padding: 0;\n background: var(--token-color);\n border: 0;\n border-radius: 0;\n cursor: pointer;\n}\n\n.swatch[data-overridden] {\n box-shadow: inset 0 -3px 0 var(--wzl-accent);\n}\n\n.swatch[aria-pressed='true'],\n.swatch:focus-visible {\n position: relative;\n z-index: 1;\n outline: 2px solid var(--wzl-focus-ring);\n outline-offset: -2px;\n}\n\n/* A group of sizes: its name over a grid of steps, each labeled by what its name adds. */\n.scale {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-1);\n min-width: 0;\n}\n\n.scaleHead {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-xs);\n min-width: 0;\n}\n\n.steps {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(4rem, 1fr));\n gap: var(--wzl-space-1) var(--wzl-space-xs);\n}\n\n.rule {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wzl-space-xs) var(--wzl-space-sm);\n min-width: 0;\n}\n\n.ruleLabel {\n color: var(--wzl-fg-subtle);\n font-family: var(--wzl-font-mono);\n font-size: var(--wzl-font-size-2xs);\n}\n\n.rule .number {\n flex: 0 1 5ch;\n font-variant-numeric: tabular-nums;\n font-family: var(--wzl-font-numeric);\n text-align: end;\n}\n\n.step {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.stepLabel {\n overflow: hidden;\n text-align: end;\n color: var(--wzl-fg-subtle);\n font-family: var(--wzl-font-mono);\n font-size: var(--wzl-font-size-2xs);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.step[data-overridden] .stepLabel {\n color: var(--wzl-accent-fg);\n}\n\n.stepEdit {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-1);\n min-width: 0;\n}\n\n.step > .stepEdit + .stepEdit {\n margin-block-start: var(--wzl-space-1);\n}\n\n.stepEdit .number {\n font-variant-numeric: tabular-nums;\n font-family: var(--wzl-font-numeric);\n text-align: end;\n}\n\n/* Tight: a token to a line, with the names on a fixed rail so the values read\n down the panel as a column. A stacked row spends its height on the name and\n lets the field take the whole width, which a set of ninety cannot afford. */\n.tight .sectionBody {\n gap: var(--wzl-space-1);\n padding-block-end: var(--wzl-space-xs);\n}\n\n.tight .row {\n flex-direction: row;\n align-items: center;\n gap: var(--wzl-space-xs);\n}\n\n.tight .row > .name {\n flex: 0 0 11rem;\n}\n\n.tight .edit {\n flex: 1 1 auto;\n}\n\n.tight .field,\n.tight .number {\n flex: 0 1 16rem;\n font-variant-numeric: tabular-nums;\n font-family: var(--wzl-font-numeric);\n}\n\n.tight .unit {\n font-variant-numeric: tabular-nums;\n font-family: var(--wzl-font-numeric);\n}\n\n.tight .scale {\n display: grid;\n grid-template-columns: 11rem minmax(0, 1fr);\n align-items: start;\n column-gap: var(--wzl-space-xs);\n}\n\n/* Grid rather than a row, so a picked swatch's editor still spans the full width. */\n.tight .family {\n display: grid;\n grid-template-columns: 11rem minmax(0, 1fr);\n align-items: center;\n column-gap: var(--wzl-space-xs);\n row-gap: var(--wzl-space-1);\n}\n\n.tight .family > .row {\n grid-column: 1 / -1;\n}\n\n.tight .strip {\n height: 16px;\n}\n\n.tight .curve {\n width: 16px;\n height: 16px;\n}\n","import { parsesAsColor } from './color';\n\n/** A design token as `TokenPanel` edits it. */\nexport interface TokenEntry {\n /** The custom property, e.g. `--wzl-gray-50`. */\n name: string;\n /** A DTCG type name. A type the panel has no control for edits as text. */\n type: string;\n /** Tokens sharing a group sit together; a color group large enough draws as one row of swatches. */\n group: string;\n value: string;\n /** Whether `value` overrides the token's own, which offers Reset. */\n overridden?: boolean;\n description?: string;\n}\n\n/** How a scale's steps follow from its base: one multiplier per step, a constant ratio, or a constant step. */\nexport type TokenScaleRule =\n | { kind: 'factors'; factors: readonly number[] }\n | { kind: 'ratio'; ratio: number }\n | { kind: 'step'; step: number };\n\n/** A group whose steps are generated from a base, so the panel edits the base and the rule rather than each step. */\nexport interface TokenScale {\n /** The generated tokens, smallest first. Anything else in the group draws as an ordinary step. */\n tokens: readonly string[];\n base: number;\n rule: TokenScaleRule;\n}\n\nconst round2 = (n: number) => Math.round(n * 100) / 100;\n\n/**\n * The same scale under another rule, fitted to the amounts its steps have now.\n * A ratio or step counts from the first step, so switching to one moves the\n * base there.\n */\nexport function refitScale(scale: TokenScale, kind: TokenScaleRule['kind'], amounts: readonly number[]): TokenScale {\n const first = amounts[0] ?? scale.base;\n const last = amounts.at(-1) ?? first;\n const spans = Math.max(1, amounts.length - 1);\n switch (kind) {\n case 'factors':\n return { ...scale, rule: { kind, factors: amounts.map((a) => (scale.base ? round2(a / scale.base) : 1)) } };\n case 'ratio':\n return { ...scale, base: first, rule: { kind, ratio: first > 0 ? round2((last / first) ** (1 / spans)) : 1 } };\n case 'step':\n return { ...scale, base: first, rule: { kind, step: round2((last - first) / spans) } };\n }\n}\n\n/** A section of the token panel; `tokenCategory` files each token under one. */\nexport type TokenCategory ='color' | 'type' | 'size' | 'motion' | 'depth' | 'other';\n\n/** The panel's sections, in the order it draws them. */\nexport const TOKEN_CATEGORIES: readonly { id: TokenCategory; title: string }[] = [\n { id: 'color', title: 'Color' },\n { id: 'type', title: 'Type' },\n { id: 'size', title: 'Size' },\n { id: 'motion', title: 'Motion' },\n { id: 'depth', title: 'Depth' },\n { id: 'other', title: 'Other' },\n];\n\nconst TYPE_SCALE = /^(?:font|tracking|leading|letter|line-height)/;\n\n/** The section a token is filed under: by its type, and for a bare dimension or number by its group. */\nexport function tokenCategory(token: TokenEntry): TokenCategory {\n switch (token.type) {\n case 'color':\n return 'color';\n case 'fontFamily':\n case 'fontWeight':\n return 'type';\n case 'duration':\n case 'cubicBezier':\n return 'motion';\n case 'shadow':\n case 'gradient':\n return 'depth';\n case 'dimension':\n case 'number':\n if (TYPE_SCALE.test(token.group)) return 'type';\n if (token.type === 'number' && (token.group === 'z' || token.group === 'z-index')) return 'depth';\n return 'size';\n default:\n return 'other';\n }\n}\n\nconst AMOUNT = String.raw`-?(?:\\d+\\.?\\d*|\\.\\d+)`;\nconst DIMENSION = new RegExp(\n `^${AMOUNT}(?:px|rem|em|%|ch|ex|lh|rlh|vh|vw|vmin|vmax|svh|lvh|dvh|cqw|cqh|pt|pc|cm|mm|in|q)$`,\n 'i',\n);\nconst DURATION = new RegExp(`^${AMOUNT}m?s$`);\nconst NUMBER = new RegExp(`^${AMOUNT}$`);\nconst LENGTH = new RegExp(`^${AMOUNT}(?:px|rem|em)?$`);\nconst BEZIER = new RegExp(`^cubic-bezier\\\\(\\\\s*(${AMOUNT})\\\\s*,\\\\s*(${AMOUNT})\\\\s*,\\\\s*(${AMOUNT})\\\\s*,\\\\s*(${AMOUNT})\\\\s*\\\\)$`, 'i');\nconst GRADIENT = /^(?:repeating-)?(?:linear|radial|conic)-gradient\\(/i;\n/** Commas outside parentheses: a shadow's layers, not a color function's arguments. */\nconst LAYERS = /,(?![^(]*\\))/;\nconst PARTS = /[a-z-]+\\([^)]*\\)|\\S+/gi;\n\nfunction isShadow(value: string): boolean {\n return value.split(LAYERS).every((layer) => {\n const parts = layer.trim().replace(/^inset\\s+/i, '').match(PARTS) ?? [];\n const lengths = parts.filter((part) => LENGTH.test(part));\n const rest = parts.filter((part) => !LENGTH.test(part));\n return lengths.length >= 2 && lengths.length <= 4 && rest.length <= 1 && rest.every((part) => parsesAsColor(part));\n });\n}\n\n/** A DTCG type read off the shape of a value, for a token that arrives without one. `'string'` when nothing fits. */\nexport function inferTokenType(value: string): string {\n const v = value.trim();\n if (!v) return 'string';\n if (DURATION.test(v)) return 'duration';\n if (DIMENSION.test(v)) return 'dimension';\n if (NUMBER.test(v)) return 'number';\n if (BEZIER.test(v)) return 'cubicBezier';\n if (GRADIENT.test(v)) return 'gradient';\n if (parsesAsColor(v)) return 'color';\n if (isShadow(v)) return 'shadow';\n return 'string';\n}\n\n/** A number and its unit, or null for a value that is not one. */\nexport function splitUnit(value: string): { amount: number; unit: string } | null {\n const match = new RegExp(`^(${AMOUNT})([a-z%]*)$`, 'i').exec(value.trim());\n return match ? { amount: Number(match[1]), unit: match[2] ?? '' } : null;\n}\n\n/** The four control points of a `cubic-bezier()`, or null for any other easing. */\nexport function bezierPoints(value: string): readonly [number, number, number, number] | null {\n const match = BEZIER.exec(value.trim());\n if (!match) return null;\n const [x1, y1, x2, y2] = match.slice(1, 5).map(Number) as [number, number, number, number];\n return [x1, y1, x2, y2];\n}\n","import { type CSSProperties, memo, useCallback, useMemo, useState } from 'react';\nimport { Focusable } from 'react-aria-components';\nimport { Button } from '../Button';\nimport { DisclosureRow } from '../Disclosure';\nimport { Input } from '../Input';\nimport { NumberField } from '../NumberField';\nimport { Select } from '../Select';\nimport { ToggleBar, type ToggleBarItem } from '../ToggleBar';\nimport { Tooltip, TooltipTrigger } from '../Tooltip';\nimport { toHex } from './color';\nimport s from './TokenPanel.module.css';\nimport {\n bezierPoints,\n refitScale,\n splitUnit,\n TOKEN_CATEGORIES,\n type TokenCategory,\n type TokenEntry,\n type TokenScale,\n type TokenScaleRule,\n tokenCategory,\n} from './tokenTypes';\n\ntype OnChange = (name: string, value: string | null) => void;\n\n/** Props for `<TokenPanel>`. */\nexport interface TokenPanelProps {\n tokens: readonly TokenEntry[];\n /** A token's new value, or null to drop its override. Keep it stable: rows re-render only when it or their token changes. */\n onChange: OnChange;\n /** Sections held closed, by category. Omit to let the panel keep that state itself. */\n collapsed?: Readonly<Partial<Record<TokenCategory, boolean>>>;\n onCollapsedChange?: (category: TokenCategory, collapsed: boolean) => void;\n /** Groups generated from a base, by group name. Such a group edits its base and rule above its steps. */\n scales?: Readonly<Record<string, TokenScale>>;\n /** A scale's new base or rule. The panel does not regenerate the steps; the consumer does, through `onChange`. */\n onScaleChange?: (group: string, scale: TokenScale) => void;\n /** Files a token under a section. Defaults to `tokenCategory`. */\n categorize?: (token: TokenEntry) => TokenCategory;\n /** The fewest colors, or sizes, sharing a group that draw as one row of swatches or one grid of steps. Default 3. */\n familySize?: number;\n /**\n * Row layout. `tight` puts a token on one line — name, control, Reset — with the\n * names on a fixed rail so the values read down the panel as a column, and caps\n * the field rather than letting it span the panel. Default `normal` stacks the\n * control under its name.\n */\n density?: 'tight' | 'normal';\n className?: string;\n}\n\nconst WEIGHTS = ['100', '200', '300', '400', '500', '600', '700', '800', '900'];\nconst NUMBER_FORMAT = { maximumFractionDigits: 4, useGrouping: false } as const;\n\ntype FamilyKind = 'family' | 'scale';\ntype Item = { kind: 'row'; token: TokenEntry } | { kind: FamilyKind; group: string; tokens: TokenEntry[] };\n\nconst SCALAR = new Set(['dimension', 'duration', 'number']);\n\nfunction familyKindOf(token: TokenEntry): FamilyKind | null {\n if (token.type === 'color') return 'family';\n return SCALAR.has(token.type) && splitUnit(token.value) ? 'scale' : null;\n}\n\nfunction itemsOf(tokens: readonly TokenEntry[], familySize: number): Item[] {\n const counts = new Map<string, number>();\n for (const token of tokens) {\n const kind = familyKindOf(token);\n if (kind) counts.set(`${kind}:${token.group}`, (counts.get(`${kind}:${token.group}`) ?? 0) + 1);\n }\n const families = new Map<string, Extract<Item, { kind: FamilyKind }>>();\n const items: Item[] = [];\n for (const token of tokens) {\n const kind = familyKindOf(token);\n const key = `${kind}:${token.group}`;\n if (!kind || (counts.get(key) ?? 0) < familySize) {\n items.push({ kind: 'row', token });\n continue;\n }\n let family = families.get(key);\n if (!family) {\n family = { kind, group: token.group, tokens: [] };\n families.set(key, family);\n items.push(family);\n }\n family.tokens.push(token);\n }\n return items;\n}\n\n/** Each name's segments past those every name in the set shares; a name that is all shared keeps its last. */\nfunction stepLabels(names: readonly string[]): string[] {\n const split = names.map((name) => name.replace(/^--/, '').split('-'));\n let shared = 0;\n while (split.every((segments) => segments.length > shared && segments[shared] === split[0]?.[shared])) shared++;\n return split.map((segments) => segments.slice(shared).join('-') || (segments.at(-1) ?? ''));\n}\n\nfunction Curve({ points, label }: { points: readonly [number, number, number, number]; label: string }) {\n const [x1, y1, x2, y2] = points;\n // y is flipped so the curve rises, and the box grows to hold an overshoot.\n const top = Math.min(0, 1 - y1, 1 - y2);\n const bottom = Math.max(1, 1 - y1, 1 - y2);\n return (\n <svg className={s.curve} viewBox={`-0.1 ${top - 0.1} 1.2 ${bottom - top + 0.2}`} role=\"img\" aria-label={label}>\n <path d={`M0 1 C${x1} ${1 - y1} ${x2} ${1 - y2} 1 0`} fill=\"none\" stroke=\"currentColor\" strokeWidth={0.08} />\n </svg>\n );\n}\n\nfunction TokenControl({ token, set }: { token: TokenEntry; set: (value: string) => void }) {\n const { name, type, value } = token;\n const label = `${name} value`;\n const hex = useMemo(() => (type === 'color' ? toHex(value) : null), [type, value]);\n\n if (type === 'dimension' || type === 'duration' || type === 'number') {\n const split = splitUnit(value);\n if (split) {\n return (\n <>\n <NumberField\n className={s.number}\n aria-label={label}\n value={split.amount}\n hideSteppers\n formatOptions={NUMBER_FORMAT}\n onChange={(amount) => {\n if (Number.isFinite(amount)) set(`${amount}${split.unit}`);\n }}\n />\n {split.unit ? <span className={s.unit}>{split.unit}</span> : null}\n </>\n );\n }\n }\n\n if (type === 'fontWeight') {\n const options = (WEIGHTS.includes(value) ? WEIGHTS : [...WEIGHTS, value]).map((weight) => ({\n value: weight,\n label: weight,\n }));\n return <Select aria-label={name} width=\"fit\" selectedKey={value} options={options} onSelectionChange={set} />;\n }\n\n const points = type === 'cubicBezier' ? bezierPoints(value) : null;\n return (\n <>\n {points ? <Curve points={points} label={`${name} curve`} /> : null}\n <Input\n className={s.field}\n aria-label={label}\n value={value}\n onChange={set}\n leadingAdornment={\n type !== 'color' ? undefined : hex ? (\n <input\n type=\"color\"\n className={s.swatchInput}\n aria-label={`${name} color`}\n value={hex}\n onChange={(event) => set(event.target.value)}\n />\n ) : (\n <span className={s.chip} style={{ '--token-color': value } as CSSProperties} aria-hidden=\"true\" />\n )\n }\n />\n </>\n );\n}\n\nconst TokenRow = memo(\n function TokenRow({ token, onChange }: { token: TokenEntry; onChange: OnChange }) {\n const set = useCallback((value: string) => onChange(token.name, value), [onChange, token.name]);\n return (\n <div className={s.row} role=\"group\" aria-label={token.name}>\n <span className={s.name} title={token.description || token.name}>\n {token.name}\n </span>\n <div className={s.edit}>\n <TokenControl token={token} set={set} />\n {token.overridden ? (\n <Button variant=\"ghost\" size=\"sm\" ariaLabel={`Reset ${token.name}`} onClick={() => onChange(token.name, null)}>\n Reset\n </Button>\n ) : null}\n </div>\n </div>\n );\n },\n // Consumers rebuild their entries each render; a row only has to redraw when what it shows changed.\n (a, b) =>\n a.onChange === b.onChange &&\n a.token.name === b.token.name &&\n a.token.type === b.token.type &&\n a.token.value === b.token.value &&\n a.token.overridden === b.token.overridden &&\n a.token.description === b.token.description,\n);\n\nfunction Family({ group, tokens, onChange }: { group: string; tokens: readonly TokenEntry[]; onChange: OnChange }) {\n const [picked, setPicked] = useState<string | null>(null);\n const token = tokens.find((t) => t.name === picked) ?? null;\n return (\n <div className={s.family} role=\"group\" aria-label={group}>\n <span className={s.name}>{group}</span>\n <div className={s.strip}>\n {tokens.map((t) => (\n <TooltipTrigger key={t.name} delay={0}>\n <Focusable>\n <button\n type=\"button\"\n className={s.swatch}\n style={{ '--token-color': t.value } as CSSProperties}\n aria-label={t.name}\n aria-pressed={t.name === picked}\n data-overridden={t.overridden ? '' : undefined}\n onClick={() => setPicked((current) => (current === t.name ? null : t.name))}\n />\n </Focusable>\n <Tooltip>{t.name}</Tooltip>\n </TooltipTrigger>\n ))}\n </div>\n {token ? <TokenRow token={token} onChange={onChange} /> : null}\n </div>\n );\n}\n\nfunction ScaleStep({\n token,\n label,\n showUnit,\n factor,\n onChange,\n onFactorChange,\n}: {\n token: TokenEntry;\n label: string;\n showUnit: boolean;\n factor?: number;\n onChange: OnChange;\n onFactorChange?: (factor: number) => void;\n}) {\n const split = splitUnit(token.value);\n if (!split) return null;\n return (\n <div className={s.step} title={token.description || token.name} data-overridden={token.overridden ? '' : undefined}>\n <span className={s.stepLabel}>{label}</span>\n <span className={s.stepEdit}>\n <NumberField\n className={s.number}\n aria-label={`${token.name} value`}\n value={split.amount}\n hideSteppers\n formatOptions={NUMBER_FORMAT}\n onChange={(amount) => {\n if (Number.isFinite(amount)) onChange(token.name, `${amount}${split.unit}`);\n }}\n />\n {showUnit && split.unit ? <span className={s.unit}>{split.unit}</span> : null}\n </span>\n {factor !== undefined && onFactorChange ? (\n <span className={s.stepEdit}>\n <span className={s.unit}>×</span>\n <NumberField\n className={s.number}\n aria-label={`${token.name} factor`}\n value={factor}\n hideSteppers\n formatOptions={NUMBER_FORMAT}\n onChange={(next) => {\n if (Number.isFinite(next)) onFactorChange(next);\n }}\n />\n </span>\n ) : null}\n </div>\n );\n}\n\nconst RULES: readonly ToggleBarItem<TokenScaleRule['kind']>[] = [\n { value: 'factors', label: 'each', ariaLabel: 'factors' },\n { value: 'ratio', label: 'ratio' },\n { value: 'step', label: 'step' },\n];\n\nfunction ScaleRuleControls({\n group,\n scale,\n unit,\n amounts,\n onScaleChange,\n}: {\n group: string;\n scale: TokenScale;\n unit: string;\n amounts: readonly number[];\n onScaleChange: (scale: TokenScale) => void;\n}) {\n const { rule } = scale;\n const param =\n rule.kind === 'ratio'\n ? { key: 'ratio' as const, value: rule.ratio }\n : rule.kind === 'step'\n ? { key: 'step' as const, value: rule.step }\n : null;\n return (\n <div className={s.rule}>\n <span className={s.stepEdit}>\n <span className={s.ruleLabel}>base</span>\n <NumberField\n className={s.number}\n aria-label={`${group} base`}\n value={scale.base}\n hideSteppers\n formatOptions={NUMBER_FORMAT}\n onChange={(base) => {\n if (Number.isFinite(base)) onScaleChange({ ...scale, base });\n }}\n />\n {unit ? <span className={s.unit}>{unit}</span> : null}\n </span>\n <ToggleBar\n ariaLabel={`${group} rule`}\n size=\"sm\"\n items={RULES}\n value={rule.kind}\n onChange={(kind) => {\n if (kind && kind !== rule.kind) onScaleChange(refitScale(scale, kind, amounts));\n }}\n />\n {param ? (\n <span className={s.stepEdit}>\n {param.key === 'ratio' ? <span className={s.unit}>×</span> : <span className={s.unit}>+</span>}\n <NumberField\n className={s.number}\n aria-label={`${group} ${param.key}`}\n value={param.value}\n hideSteppers\n formatOptions={NUMBER_FORMAT}\n onChange={(value) => {\n if (Number.isFinite(value)) onScaleChange({ ...scale, rule: { kind: param.key, [param.key]: value } as TokenScaleRule });\n }}\n />\n </span>\n ) : null}\n </div>\n );\n}\n\nfunction Scale({\n group,\n tokens,\n generator,\n onChange,\n onScaleChange,\n}: {\n group: string;\n tokens: readonly TokenEntry[];\n generator?: TokenScale;\n onChange: OnChange;\n onScaleChange?: (group: string, scale: TokenScale) => void;\n}) {\n const labels = useMemo(() => stepLabels(tokens.map((t) => t.name)), [tokens]);\n const units = new Set(tokens.map((t) => splitUnit(t.value)?.unit ?? ''));\n const unit = units.size === 1 ? [...units][0] : null;\n const overridden = tokens.filter((t) => t.overridden);\n return (\n <div className={s.scale} role=\"group\" aria-label={group}>\n <span className={s.scaleHead}>\n <span className={s.name}>{group}</span>\n {unit ? <span className={s.unit}>{unit}</span> : null}\n {overridden.length > 0 ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n ariaLabel={`Reset ${group}`}\n onClick={() => {\n for (const t of overridden) onChange(t.name, null);\n }}\n >\n Reset\n </Button>\n ) : null}\n </span>\n {generator && onScaleChange ? (\n <ScaleRuleControls\n group={group}\n scale={generator}\n unit={unit ?? ''}\n amounts={generator.tokens.map(\n (name) => splitUnit(tokens.find((t) => t.name === name)?.value ?? '')?.amount ?? generator.base,\n )}\n onScaleChange={(next) => onScaleChange(group, next)}\n />\n ) : null}\n <div className={s.steps}>\n {tokens.map((t, i) => {\n const rule = generator?.rule;\n const at = generator ? generator.tokens.indexOf(t.name) : -1;\n const factor = rule?.kind === 'factors' && at >= 0 ? rule.factors[at] : undefined;\n return (\n <ScaleStep\n key={t.name}\n token={t}\n label={labels[i] ?? t.name}\n showUnit={unit === null}\n factor={factor}\n onChange={onChange}\n onFactorChange={\n generator && onScaleChange && rule?.kind === 'factors'\n ? (next) =>\n onScaleChange(group, {\n ...generator,\n rule: { kind: 'factors', factors: rule.factors.map((f, j) => (j === at ? next : f)) },\n })\n : undefined\n }\n />\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction Section({\n title,\n open,\n onToggle,\n tokens,\n familySize,\n scales,\n onChange,\n onScaleChange,\n}: {\n title: string;\n open: boolean;\n onToggle: () => void;\n tokens: readonly TokenEntry[];\n familySize: number;\n scales?: Readonly<Record<string, TokenScale>>;\n onChange: OnChange;\n onScaleChange?: (group: string, scale: TokenScale) => void;\n}) {\n const items = useMemo(() => itemsOf(tokens, familySize), [tokens, familySize]);\n return (\n <section className={s.section} aria-label={title}>\n <DisclosureRow className={s.sectionHead} open={open} onToggle={onToggle} label={title}>\n <span aria-hidden=\"true\">{title}</span>\n </DisclosureRow>\n {open ? (\n <div className={s.sectionBody}>\n {items.map((item) =>\n item.kind === 'row' ? (\n <TokenRow key={item.token.name} token={item.token} onChange={onChange} />\n ) : item.kind === 'scale' ? (\n <Scale\n key={`scale:${item.group}`}\n group={item.group}\n tokens={item.tokens}\n generator={scales?.[item.group]}\n onChange={onChange}\n onScaleChange={onScaleChange}\n />\n ) : (\n <Family key={`family:${item.group}`} group={item.group} tokens={item.tokens} onChange={onChange} />\n ),\n )}\n </div>\n ) : null}\n </section>\n );\n}\n\n/**\n * Edits a set of design tokens by type: collapsible sections by category, a\n * color group drawn as one row of swatches sized to fit, a group of sizes drawn\n * as one grid of numbers labeled by step — with its base and rule above it when\n * `scales` says how it is generated — and a control for each\n * type — a number with its unit for dimensions and durations, the nine weights\n * for a font weight, a curve beside a `cubic-bezier()`, a swatch beside a color,\n * and text for everything else.\n */\nexport function TokenPanel({\n tokens,\n onChange,\n collapsed,\n onCollapsedChange,\n scales,\n onScaleChange,\n categorize = tokenCategory,\n familySize = 3,\n density = 'normal',\n className,\n}: TokenPanelProps) {\n const [ownCollapsed, setOwnCollapsed] = useState<Partial<Record<TokenCategory, boolean>>>({});\n const closed = collapsed ?? ownCollapsed;\n const byCategory = useMemo(() => {\n const sections = new Map<TokenCategory, TokenEntry[]>();\n for (const token of tokens) {\n const category = categorize(token);\n sections.set(category, [...(sections.get(category) ?? []), token]);\n }\n return sections;\n }, [tokens, categorize]);\n\n return (\n <div className={[s.panel, density === 'tight' && s.tight, className].filter(Boolean).join(' ')}>\n {TOKEN_CATEGORIES.map(({ id, title }) => {\n const inSection = byCategory.get(id);\n if (!inSection) return null;\n const open = !closed[id];\n return (\n <Section\n key={id}\n title={title}\n open={open}\n onToggle={() => {\n if (collapsed === undefined) setOwnCollapsed((prev) => ({ ...prev, [id]: open }));\n onCollapsedChange?.(id, open);\n }}\n tokens={inSection}\n familySize={familySize}\n scales={scales}\n onChange={onChange}\n onScaleChange={onScaleChange}\n />\n );\n })}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { n as e, r as t } from "./Tooltip-Clg2mhSt.js";
1
+ import { n as e, r as t } from "./Tooltip-C6eFCYxw.js";
2
2
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
3
3
  import { Focusable as i } from "react-aria-components";
4
4
  var a = {
@@ -11,10 +11,10 @@ var a = {
11
11
  //#endregion
12
12
  //#region src/components/ToolButton/ToolButton.tsx
13
13
  function o(o) {
14
- let { icon: s, label: c, shortcut: l, active: u, disabled: d, ariaDisabled: f, tabbable: p, onClick: m, onKeyDown: h, title: g, className: _ } = o, v = g ?? (l ? `${c} (${l})` : c), y = [
14
+ let { icon: s, label: c, shortcut: l, active: u, disabled: d, ariaDisabled: f, onClick: p, title: m, className: h } = o, g = m ?? (l ? `${c} (${l})` : c), _ = [
15
15
  a.button,
16
16
  u && a.active,
17
- _
17
+ h
18
18
  ].filter(Boolean).join(" ");
19
19
  return /* @__PURE__ */ r(t, {
20
20
  isDisabled: d,
@@ -22,13 +22,11 @@ function o(o) {
22
22
  isDisabled: d,
23
23
  children: /* @__PURE__ */ r("button", {
24
24
  type: "button",
25
- tabIndex: p ? 0 : -1,
26
- className: y,
25
+ className: _,
27
26
  "aria-current": u ? "true" : void 0,
28
27
  "aria-disabled": f ? "true" : void 0,
29
28
  disabled: d,
30
- onClick: m,
31
- onKeyDown: h,
29
+ onClick: p,
32
30
  children: [
33
31
  /* @__PURE__ */ n("span", {
34
32
  className: a.icon,
@@ -45,10 +43,10 @@ function o(o) {
45
43
  })
46
44
  ]
47
45
  })
48
- }), /* @__PURE__ */ n(e, { children: v })]
46
+ }), /* @__PURE__ */ n(e, { children: g })]
49
47
  });
50
48
  }
51
49
  //#endregion
52
50
  export { o as t };
53
51
 
54
- //# sourceMappingURL=ToolButton-CAHBa08P.js.map
52
+ //# sourceMappingURL=ToolButton-BURp4YIO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolButton-BURp4YIO.js","names":["s","TooltipTrigger","Tooltip","Tooltip$1","TooltipTrigger$1","ToolButton_module_default","ToolButton","props","resolvedTitle","title","shortcut","label","cls","active","className","disabled","Focusable","ariaDisabled","icon"],"sources":["../../src/components/ToolButton/ToolButton.module.css","../../src/components/ToolButton/ToolButton.tsx"],"sourcesContent":[".button {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--wzl-space-1);\n min-width: 44px;\n padding: var(--wzl-space-3) var(--wzl-space-2);\n background: transparent;\n border: 1px solid transparent;\n border-radius: var(--wzl-radius-sm);\n color: var(--wzl-fg);\n cursor: default;\n font-family: inherit;\n font-size: var(--wzl-font-size-xs);\n line-height: 1.1;\n}\n.button:hover:not([disabled]) {\n background: var(--wzl-surface-hover);\n color: var(--wzl-fg);\n}\n.button:focus-visible {\n outline: 2px solid var(--wzl-accent);\n outline-offset: -2px;\n}\n.button.active {\n background: var(--wzl-surface-pressed);\n border-color: var(--wzl-accent);\n color: var(--wzl-fg);\n}\n.button[disabled] {\n opacity: 0.4;\n}\n\n.icon { display: block; }\n.icon > svg { display: block; }\n.label { font-size: var(--wzl-font-size-xs); }\n.shortcut {\n color: var(--wzl-fg-muted);\n font-family: var(--wzl-font-mono);\n font-size: var(--wzl-font-size-2xs);\n}\n","import type { ReactNode } from 'react';\nimport { Focusable } from 'react-aria-components';\nimport { Tooltip, TooltipTrigger } from '../Tooltip';\nimport s from './ToolButton.module.css';\n\n/** Props for {@link ToolButton}. */\nexport interface ToolButtonProps {\n /** Icon node (typically an SVG component). */\n icon: ReactNode;\n /** Human-readable label shown under the icon. */\n label: string;\n /** Optional shortcut hint (e.g. \"V\" or \"⌘Z\"). */\n shortcut?: string;\n /** Selected/active state — toggles the active visual treatment. */\n active?: boolean;\n /** Disabled state — passes through to the underlying button. */\n disabled?: boolean;\n /**\n * When true, sets `aria-disabled=\"true\"` on the button without using the\n * native `disabled` attribute. This keeps the button focusable and reachable\n * by keyboard (roving-tabindex still applies) while marking it as ineligible\n * to screen readers. The caller is responsible for making `onClick` a no-op.\n */\n ariaDisabled?: boolean;\n /** Click handler. */\n onClick(): void;\n /**\n * Tooltip content. Defaults to `label` (plus `shortcut` if provided).\n */\n title?: string;\n /** Additional class for the root button. */\n className?: string;\n}\n\n/**\n * Generic icon-+-label toolbar button — building block for `ToolPalette`\n * and similar surfaces. Headless about layout direction (parent group\n * supplies flex direction via `ToolGroup`). Theme via `--wzl-*` tokens.\n */\nexport function ToolButton(props: ToolButtonProps) {\n const {\n icon, label, shortcut, active, disabled, ariaDisabled,\n onClick, title, className,\n } = props;\n const resolvedTitle = title ?? (shortcut ? `${label} (${shortcut})` : label);\n const cls = [s.button, active && s.active, className].filter(Boolean).join(' ');\n return (\n <TooltipTrigger isDisabled={disabled}>\n <Focusable isDisabled={disabled}>\n <button\n type=\"button\"\n className={cls}\n aria-current={active ? 'true' : undefined}\n aria-disabled={ariaDisabled ? 'true' : undefined}\n disabled={disabled}\n onClick={onClick}\n >\n <span className={s.icon} aria-hidden=\"true\">{icon}</span>\n <span className={s.label}>{label}</span>\n {shortcut && <span className={s.shortcut}>{shortcut}</span>}\n </button>\n </Focusable>\n <Tooltip>{resolvedTitle}</Tooltip>\n </TooltipTrigger>\n );\n}\n"],"mappings":";;;;;;;;;;;;ACuCA,SAAgBM,EAAW,GAAwB;CACjD,IAAM,EACJ,SAAM,UAAO,aAAU,WAAQ,aAAU,iBACzC,YAAS,UAAO,iBACdC,GACEC,IAAgBC,MAAUC,IAAW,GAAGC,EAAM,IAAID,EAAS,KAAKC,IAChEC,IAAM;EAACZ,EAAE;EAAQa,KAAUb,EAAE;EAAQc;CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAC9E,OACE,kBAACb,GAAD;EAAgB,YAAYc;EAA5B,UAAA,CACE,kBAACC,GAAD;GAAW,YAAYD;GACrB,UAAA,kBAAC,UAAD;IACE,MAAK;IACL,WAAWH;IACX,gBAAcC,IAAS,SAAS,KAAA;IAChC,iBAAeI,IAAe,SAAS,KAAA;IAC7B;IACD;IANX,UAAA;KAQE,kBAAC,QAAD;MAAM,WAAWjB,EAAE;MAAM,eAAY;MAAQ,UAAAkB;KAAW,CAAA;KACxD,kBAAC,QAAD;MAAM,WAAWlB,EAAE;MAAQ,UAAAW;KAAY,CAAA;KACtCD,KAAY,kBAAC,QAAD;MAAM,WAAWV,EAAE;MAAW,UAAAU;KAAe,CAAA;IACpD;;EACC,CAAA,GACX,kBAACR,GAAD,EAAA,UAAUM,EAAuB,CAAA,CACnB;;AAEpB"}
@@ -1,4 +1,4 @@
1
- import { a as e, c as t, d as n, u as r } from "./model-BaF65rnX.js";
1
+ import { a as e, c as t, d as n, u as r } from "./model-B1-gMBIW.js";
2
2
  import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
3
3
  var s = {
4
4
  root: "_root_1h7p0_13",
@@ -63,6 +63,7 @@ function f(e, t, n, i, a, o) {
63
63
  value: l ? void 0 : n?.[s],
64
64
  mixed: l,
65
65
  unset: !l && n?.[s] === void 0,
66
+ each: l ? [] : [n?.[s]],
66
67
  setValue: (e) => o?.(s, e),
67
68
  update: (e) => o?.(s, e(l ? void 0 : n?.[s])),
68
69
  valueAt: (e) => ({
@@ -84,4 +85,4 @@ function f(e, t, n, i, a, o) {
84
85
  //#endregion
85
86
  export { c as t };
86
87
 
87
- //# sourceMappingURL=ToolOptionsBar-D_GCrBAN.js.map
88
+ //# sourceMappingURL=ToolOptionsBar-COsTJ1cu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolOptionsBar-D_GCrBAN.js","names":["s","_Fragment","isGroup","pairRows","renderCells","renderBuiltin","ToolOptionsBar_module_default","ToolOptionsBar","props","cls","className","label","schema","barRows","BarRow","row","children","leaves","collect","key","child","group","path","prefix","cells","barCell","panelLeaf","values","mixed","renderers","onChange","Fragment","needsLabel","cell","leaf","isMixed","ctx","v","fn","p","custom","ariaLabel"],"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);\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 // One set of values, so there is one prior value to derive from.\n update: (fn) => onChange?.(path, fn(isMixed ? undefined : values?.[path])),\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,SAAgBO,EAAe,GAA4B;CACzD,IAAM,EAAE,UAAO,WAAQ,WAAQ,aAAU,UAAO,cAAW,aAAU,iBAAcC,GAC7EC,IAAM,CAACT,EAAE,MAAMU,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CACxD,OACE,kBAAC,OAAD;EAAK,WAAWD;EAAK,MAAK;EAAU,cAAYE;EAAhD,UAAA,CACGA,MAAU,KAAA,KAAa,kBAAC,QAAD;GAAM,WAAWX,EAAE;GAAQ,UAAAW;EAAY,CAAA,GAC/D,kBAAC,OAAD;GAAK,WAAWX,EAAE;GAAlB,UAAA,CACGY,MAAW,KAAA,KACVC,EAAQD,CAAM,CAAC,CAAC,KAAK,MACnB,kBAACE,GAAD;IAEO;IACG;IACD;IACI;IACD;GACX,GANMC,EAAI,OAAO,EAAE,CAAE,IAMrB,CACF,GACFC,CACE;EACF,CAAA,CAAA;;AAET;AAQA,SAASH,EAAQ,GAAmC;CAClD,IAAMI,IAAsB,CAAC,GACvBC,KAAW,GAAsB,MAAyB;EAC9D,KAAK,IAAM,CAACC,GAAKC,MAAU,OAAO,QAAQC,EAAM,QAAQ,GAAG;GACzD,IAAMC,IAAOC,MAAW,KAAKJ,IAAM,GAAGI,EAAO,GAAGJ;GAChD,AAAIjB,EAAQkB,CAAK,IAAGF,EAAQE,GAAOE,CAAI,IAC9BF,EAAM,WAAW,MAAMH,EAAO,KAAK;IAAE;IAAM,MAAMG;GAAM,CAAC;EACnE;CACF;CAEA,OADAF,EAAQN,GAAQ,EAAE,GACXT,EAASc,CAAM;AACxB;AAGA,SAASH,EAAO,EACd,QACA,WACA,UACA,cACA,eAOC;CAGD,IAAMU,IAAQT,EAAI,OAAO,KAAK,MAC5BU,EAAQC,GAAWA,EAAU,KAAK,MAAMC,GAAQC,GAAOC,GAAWC,CAAQ,CAC5E;CACA,OACE,kBAAA7B,GAAA,EAAA,UACGG,EAAYoB,GAAOK,CAAS,CAAC,CAAC,KAAK,MAClC,kBAAC,QAAD;EAAqB,WAAW7B,EAAE;EAAlC,UAAA,CACGgC,EAAWC,EAAK,IAAI,KACnB,kBAAC,QAAD;GAAM,WAAWjC,EAAE;GAAW,eAAY;GACvC,UAAAiC,EAAK,KAAK,SAASA,EAAK,KAAK;EAC1B,CAAA,GAEPA,EAAK,OACF;CAPK,GAAAA,EAAK,GAOV,CACP,EACD,CAAA;AAEN;AAYA,SAASD,EAAW,GAA6B;CAC/C,OAAOE,EAAK,SAAS,YAAYA,EAAK,SAAS;AACjD;AAEA,SAAST,EACP,GACA,GACA,GACA,GACA,GACA,GACU;CACV,IAAM,EAAE,SAAM,YAASC,GACjBS,IAAUP,GAAO,IAAIN,CAAI,MAAM,IAC/Bc,IAA6B;EACjC;EACA,MAAMF;EACN,OAAOC,IAAU,KAAA,IAAYR,IAASL;EACtC,OAAOa;EACP,OAAO,CAACA,KAAWR,IAASL,OAAU,KAAA;EACtC,WAAW,MAAMQ,IAAWR,GAAMe,CAAC;EAEnC,SAAS,MAAOP,IAAWR,GAAMgB,EAAGH,IAAU,KAAA,IAAYR,IAASL,EAAK,CAAC;EACzE,UAAU,OAAO;GAAE,OAAOK,IAASY;GAAI,OAAOX,GAAO,IAAIW,CAAC,MAAM;EAAK;CACvE;CACA,OAAO;EACL,KAAKjB;EACC;EACN;EACA;EACA,cAAc;GACZ,IAAMkB,IAASX,IAAYP,MAASO,IAAYK,EAAK;GACrD,OAAOM,IAASA,EAAOJ,CAAG,IAAI/B,EAAc+B,GAAKK,GAAWZ,GAAWP,CAAI;EAC7E;CACF;AACF"}
1
+ {"version":3,"file":"ToolOptionsBar-COsTJ1cu.js","names":["s","_Fragment","isGroup","pairRows","renderCells","renderBuiltin","ToolOptionsBar_module_default","ToolOptionsBar","props","cls","className","label","schema","barRows","BarRow","row","children","leaves","collect","key","child","group","path","prefix","cells","barCell","panelLeaf","values","mixed","renderers","onChange","Fragment","needsLabel","cell","leaf","isMixed","ctx","v","fn","p","custom","ariaLabel"],"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);\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 each: isMixed ? [] : [values?.[path]],\n setValue: (v) => onChange?.(path, v),\n // One set of values, so there is one prior value to derive from.\n update: (fn) => onChange?.(path, fn(isMixed ? undefined : values?.[path])),\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,SAAgBO,EAAe,GAA4B;CACzD,IAAM,EAAE,UAAO,WAAQ,WAAQ,aAAU,UAAO,cAAW,aAAU,iBAAcC,GAC7EC,IAAM,CAACT,EAAE,MAAMU,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CACxD,OACE,kBAAC,OAAD;EAAK,WAAWD;EAAK,MAAK;EAAU,cAAYE;EAAhD,UAAA,CACGA,MAAU,KAAA,KAAa,kBAAC,QAAD;GAAM,WAAWX,EAAE;GAAQ,UAAAW;EAAY,CAAA,GAC/D,kBAAC,OAAD;GAAK,WAAWX,EAAE;GAAlB,UAAA,CACGY,MAAW,KAAA,KACVC,EAAQD,CAAM,CAAC,CAAC,KAAK,MACnB,kBAACE,GAAD;IAEO;IACG;IACD;IACI;IACD;GACX,GANMC,EAAI,OAAO,EAAE,CAAE,IAMrB,CACF,GACFC,CACE;EACF,CAAA,CAAA;;AAET;AAQA,SAASH,EAAQ,GAAmC;CAClD,IAAMI,IAAsB,CAAC,GACvBC,KAAW,GAAsB,MAAyB;EAC9D,KAAK,IAAM,CAACC,GAAKC,MAAU,OAAO,QAAQC,EAAM,QAAQ,GAAG;GACzD,IAAMC,IAAOC,MAAW,KAAKJ,IAAM,GAAGI,EAAO,GAAGJ;GAChD,AAAIjB,EAAQkB,CAAK,IAAGF,EAAQE,GAAOE,CAAI,IAC9BF,EAAM,WAAW,MAAMH,EAAO,KAAK;IAAE;IAAM,MAAMG;GAAM,CAAC;EACnE;CACF;CAEA,OADAF,EAAQN,GAAQ,EAAE,GACXT,EAASc,CAAM;AACxB;AAGA,SAASH,EAAO,EACd,QACA,WACA,UACA,cACA,eAOC;CAGD,IAAMU,IAAQT,EAAI,OAAO,KAAK,MAC5BU,EAAQC,GAAWA,EAAU,KAAK,MAAMC,GAAQC,GAAOC,GAAWC,CAAQ,CAC5E;CACA,OACE,kBAAA7B,GAAA,EAAA,UACGG,EAAYoB,GAAOK,CAAS,CAAC,CAAC,KAAK,MAClC,kBAAC,QAAD;EAAqB,WAAW7B,EAAE;EAAlC,UAAA,CACGgC,EAAWC,EAAK,IAAI,KACnB,kBAAC,QAAD;GAAM,WAAWjC,EAAE;GAAW,eAAY;GACvC,UAAAiC,EAAK,KAAK,SAASA,EAAK,KAAK;EAC1B,CAAA,GAEPA,EAAK,OACF;CAPK,GAAAA,EAAK,GAOV,CACP,EACD,CAAA;AAEN;AAYA,SAASD,EAAW,GAA6B;CAC/C,OAAOE,EAAK,SAAS,YAAYA,EAAK,SAAS;AACjD;AAEA,SAAST,EACP,GACA,GACA,GACA,GACA,GACA,GACU;CACV,IAAM,EAAE,SAAM,YAASC,GACjBS,IAAUP,GAAO,IAAIN,CAAI,MAAM,IAC/Bc,IAA6B;EACjC;EACA,MAAMF;EACN,OAAOC,IAAU,KAAA,IAAYR,IAASL;EACtC,OAAOa;EACP,OAAO,CAACA,KAAWR,IAASL,OAAU,KAAA;EACtC,MAAMa,IAAU,CAAC,IAAI,CAACR,IAASL,EAAK;EACpC,WAAW,MAAMQ,IAAWR,GAAMe,CAAC;EAEnC,SAAS,MAAOP,IAAWR,GAAMgB,EAAGH,IAAU,KAAA,IAAYR,IAASL,EAAK,CAAC;EACzE,UAAU,OAAO;GAAE,OAAOK,IAASY;GAAI,OAAOX,GAAO,IAAIW,CAAC,MAAM;EAAK;CACvE;CACA,OAAO;EACL,KAAKjB;EACC;EACN;EACA;EACA,cAAc;GACZ,IAAMkB,IAASX,IAAYP,MAASO,IAAYK,EAAK;GACrD,OAAOM,IAASA,EAAOJ,CAAG,IAAI/B,EAAc+B,GAAKK,GAAWZ,GAAWP,CAAI;EAC7E;CACF;AACF"}
@@ -1,6 +1,6 @@
1
1
  import { t as e } from "./formatShortcut-DRQrVThu.js";
2
- import { t } from "./useRovingTabIndex-Bp_hYm_h.js";
3
- import { t as n } from "./ToolButton-CAHBa08P.js";
2
+ import { t } from "./useRovingTabIndex-D7u22Ia_.js";
3
+ import { t as n } from "./ToolButton-BURp4YIO.js";
4
4
  import { t as r } from "./ToolGroup-Dpg1LN0l.js";
5
5
  import { UnknownIcon as i } from "@weasel-js/core";
6
6
  import { jsx as a, jsxs as o } from "react/jsx-runtime";
@@ -43,12 +43,12 @@ function h(i) {
43
43
  h === "horizontal" && l.horizontal,
44
44
  g
45
45
  ].filter(Boolean).join(" "), C = x.flatMap((e) => b.get(e)), w = C.map((e) => !v || c(v, e)), T = C.findIndex((e) => e.id === d.active), E = t({
46
- items: w.map((e) => ({ disabled: !e })),
47
- itemClassName: l.paletteBtn,
48
- ...T >= 0 && w[T] ? { tabStopIndex: T } : {}
46
+ itemSelector: `.${l.paletteBtn}`,
47
+ tabStopIndex: T >= 0 ? T : void 0
49
48
  }), D = -1;
50
49
  return /* @__PURE__ */ a("div", {
51
50
  ref: E.rootRef,
51
+ onKeyDown: E.onKeyDown,
52
52
  className: S,
53
53
  role: "toolbar",
54
54
  "aria-label": "Tools",
@@ -66,12 +66,10 @@ function h(i) {
66
66
  label: i,
67
67
  shortcut: o,
68
68
  active: d.active === t.id,
69
- tabbable: E.tabIndexFor(r) === 0,
70
69
  ariaDisabled: !s,
71
70
  className: [l.paletteBtn, !s && l.ineligibleBtn].filter(Boolean).join(" "),
72
71
  title: u,
73
- onClick: s ? () => d.setActive(t.id) : () => {},
74
- onKeyDown: E.onKeyDown(r)
72
+ onClick: s ? () => d.setActive(t.id) : () => {}
75
73
  }, t.id);
76
74
  })
77
75
  })] }, t))
@@ -80,4 +78,4 @@ function h(i) {
80
78
  //#endregion
81
79
  export { h as t };
82
80
 
83
- //# sourceMappingURL=ToolPalette-OOWN51Xx.js.map
81
+ //# sourceMappingURL=ToolPalette-DKDFWOX-.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolPalette-OOWN51Xx.js","names":["s","Fragment","formatShortcut","ToolButton","ToolGroup","Fragment$1","ToolPalette_module_default","DEFAULT_GROUP_ORDER","MISC","partitionByGroup","groups","tool","list","g","bucket","orderedGroupKeys","seen","ordered","known","groupOrder","key","resolveIcon","rawIcon","UnknownIcon","ToolPalette","props","tools","t","groupKeys","cls","orientation","className","k","eligibility","eligibleContribution","modeRegistry","activeIndex","roving","useRovingTabIndex","enabled","index","i","label","shortcut","lookupShortcut","modeName","resolvedTitle"],"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. A tool whose presentation sets `hide` is\n * left out.\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).filter((t) => !t.presentation?.hide);\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":";;;;;;;;;;;;;;GCUMO,IAAsB;CAAC;CAAU;CAAS;CAAQ;CAAQ;AAAM,GAChEC,IAAO;AAEb,SAASC,EAAiB,GAAyC;CACjE,IAAMC,oBAAS,IAAI,IAAuB;CAC1C,KAAK,IAAMC,KAAQC,GAAM;EACvB,IAAMC,IAAIF,EAAK,cAAc,SAASH,GAChCM,IAASJ,EAAO,IAAIG,CAAC,KAAK,CAAC;EAEjC,AADAC,EAAO,KAAKH,CAAI,GAChBD,EAAO,IAAIG,GAAGC,CAAM;CACtB;CACA,OAAOJ;AACT;AAEA,SAASK,EACP,GACA,GACU;CACV,IAAMC,IAAO,IAAI,IAAIN,EAAO,KAAK,CAAC,GAC5BO,IAAoB,CAAC;CAC3B,KAAK,IAAMC,KAASC,GAClB,AAAIH,EAAK,IAAIE,CAAK,MAChBD,EAAQ,KAAKC,CAAK,GAClBF,EAAK,OAAOE,CAAK;CAIrB,KAAK,IAAME,KAAOV,EAAO,KAAK,GAC5B,AAAIM,EAAK,IAAII,CAAG,KAAKA,MAAQZ,MAC3BS,EAAQ,KAAKG,CAAG,GAChBJ,EAAK,OAAOI,CAAG;CAInB,OADIJ,EAAK,IAAIR,CAAI,KAAGS,EAAQ,KAAKT,CAAI,GAC9BS;AACT;AAEA,SAASI,EAAY,GAA0B;CAC7C,IAAMC,IAAUX,EAAK,cAAc;CAGnC,OAFIW,KAAW,OAAa,kBAACC,GAAD,CAAc,CAAA,IACtC,OAAOD,KAAY,aAAmBA,EAAQ,KAAA,CAAS,IACpDA;AACT;AAoCA,SAAgBE,EAAY,GAAyB;CACnD,IAAM,EACJ,UAAO,iBAAc,YAAY,cAAW,mBAAgB,iBAC5D,gBAAajB,MACXkB,GAEEf,IAASD,EADF,OAAO,OAAOiB,EAAM,QAAQ,CAAC,CAAC,QAAQ,MAAM,CAACC,EAAE,cAAc,IAC1C,CAAI,GAC9BC,IAAYb,EAAiBL,GAAQS,CAAU,GAC/CU,IAAM;EAAC7B,EAAE;EAAS8B,MAAgB,gBAAgB9B,EAAE;EAAY+B;CAAS,CAAC,CAC7E,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,GAGrBd,IAAUW,EAAU,SAAS,MAAMlB,EAAO,IAAIsB,CAAC,CAAE,GACjDC,IAAchB,EAAQ,KACzB,MAAU,MAAeiB,EAAqBC,GAAcxB,CAAI,CACnE,GACMyB,IAAcnB,EAAQ,WAAW,MAAMU,EAAE,OAAOD,EAAM,MAAM,GAC5DW,IAASC,EAAkB;EAC/B,OAAOL,EAAY,KAAK,OAAa,EAAE,UAAU,CAACM,EAAQ,EAAE;EAC5D,eAAevC,EAAE;EAGjB,GAAIoC,KAAe,KAAKH,EAAYG,KAAe,EAAE,cAAcA,EAAY,IAAI,CAAC;CACtF,CAAC,GACGI,IAAQ;CAEZ,OACE,kBAAC,OAAD;EACE,KAAKH,EAAO;EACZ,WAAWR;EACX,MAAK;EACL,cAAW;EAEV,UAAAD,EAAU,KAAK,GAAK,MACnB,kBAAC3B,GAAD,EAAA,UAAA,CACG,IAAI,KACH,kBAAC,OAAD;GACE,WAAWD,EAAE;GACb,MAAK;GACL,oBAAkB8B,MAAgB,eAAe,aAAa;EAC/D,CAAA,GAEH,kBAAC1B,GAAD;GAAwB;GAAa,UAAUgB;GAC5C,UAAAV,EAAO,IAAIU,CAAG,CAAC,CAAE,KAAK,MAAS;IAC9B,IAAMqB,IAAI,EAAED,GACNE,IAAQ/B,EAAK,cAAc,SAASA,EAAK,IACzCgC,IAAWhC,EAAK,cAAc,YAC/BT,EAAe0C,IAAiBA,EAAejC,EAAK,EAAE,IAAIA,EAAK,UAAU,GACxE4B,IAAUN,EAAYQ,IACtBI,IAAWV,IAAeA,EAAa,QAAQ,CAAC,CAAC,KAAK,KAAA,GACtDW,IAAgB,CAACP,KAAWM,IAC9B,GAAGH,IAAQC,IAAW,KAAKA,EAAS,KAAK,GAAG,iBAAiBE,EAAS,SACtE,KAAA;IACJ,OACE,kBAAC1C,GAAD;KAEE,MAAMkB,EAAYV,CAAI;KACf;KACG;KACV,QAAQe,EAAM,WAAWf,EAAK;KAC9B,UAAU0B,EAAO,YAAYI,CAAC,MAAM;KACpC,cAAc,CAACF;KACf,WAAW,CAACvC,EAAE,YAAY,CAACuC,KAAWvC,EAAE,aAAa,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;KAC/E,OAAO8C;KACP,SAASP,UAAgBb,EAAM,UAAUf,EAAK,EAAE,UAAU,CAAC;KAC3D,WAAW0B,EAAO,UAAUI,CAAC;IAC9B,GAXM9B,EAAK,EAWX;GAEL,CAAC;EACQ,CAAA,CACH,EAAA,GApCKS,CAoCL,CACX;CACE,CAAA;AAET"}
1
+ {"version":3,"file":"ToolPalette-DKDFWOX-.js","names":["s","Fragment","formatShortcut","ToolButton","ToolGroup","Fragment$1","ToolPalette_module_default","DEFAULT_GROUP_ORDER","MISC","partitionByGroup","groups","tool","list","g","bucket","orderedGroupKeys","seen","ordered","known","groupOrder","key","resolveIcon","rawIcon","UnknownIcon","ToolPalette","props","tools","t","groupKeys","cls","orientation","className","k","eligibility","eligibleContribution","modeRegistry","activeIndex","roving","useRovingTabIndex","index","i","label","shortcut","lookupShortcut","enabled","modeName","resolvedTitle"],"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. A tool whose presentation sets `hide` is\n * left out.\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).filter((t) => !t.presentation?.hide);\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 itemSelector: `.${s.paletteBtn}`,\n tabStopIndex: activeIndex >= 0 ? activeIndex : undefined,\n });\n let index = -1;\n\n return (\n <div\n ref={roving.rootRef}\n onKeyDown={roving.onKeyDown}\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 ariaDisabled={!enabled}\n className={[s.paletteBtn, !enabled && s.ineligibleBtn].filter(Boolean).join(' ')}\n title={resolvedTitle}\n onClick={enabled ? () => tools.setActive(tool.id) : () => {}}\n />\n );\n })}\n </ToolGroup>\n </Fragment>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { r as e } from "./portalHost-yTOVuCej.js";
1
+ import { i as e } from "./portalHost-CE70wLzo.js";
2
2
  import { Fragment as t, jsx as n, jsxs as r } from "react/jsx-runtime";
3
3
  import { Focusable as i, OverlayArrow as a, Tooltip as o, TooltipTrigger as s } from "react-aria-components";
4
4
  var c = {
@@ -39,4 +39,4 @@ function u(i) {
39
39
  //#endregion
40
40
  export { u as n, l as r, i as t };
41
41
 
42
- //# sourceMappingURL=Tooltip-Clg2mhSt.js.map
42
+ //# sourceMappingURL=Tooltip-C6eFCYxw.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip-Clg2mhSt.js","names":["TooltipTrigger","RACTooltipTrigger","Tooltip","_Fragment","RACTooltip","s","useOverlayPortal","Focusable$1","Tooltip_module_default","TooltipTrigger$1","rest","props","TooltipTrigger","Tooltip$1","portalContainer","Fragment","anchor","Tooltip","className","portalProps","OverlayArrow","children"],"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,SAAgBA,EAAe,GAA4B;CACzD,IAAM,EAAE,WAAQ,KAAK,gBAAa,GAAG,GAAGU,MAASC;CACjD,OAAO,kBAACV,GAAD;EAA0B;EAAmB;EAAY,GAAIS;CAAO,CAAA;AAC7E;AAaA,SAAgBR,EAAQ,GAAqB;CAC3C,IAAM,EAAE,aAAU,cAAW,eAAY,OAAO,YAAS,GAAG,oBAAiB,GAAGQ,MAASC,GACnF,EAAE,WAAQ,mBAAgBL,EAAiBQ,CAAe;CAChE,OACE,kBAAAX,GAAA,EAAA,UAAA,CACGa,GACD,kBAACZ,GAAD;EACE,GAAIM;EACO;EACH;EACR,WAAW,CAACL,EAAE,SAASa,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAC1D,uBAAoB;EACpB,GAAIC;EANN,UAAA,CAQE,kBAACC,GAAD;GAAc,WAAWf,EAAE;GACzB,UAAA,kBAAC,OAAD;IAAK,OAAO;IAAG,QAAQ;IAAG,SAAQ;IAAU,eAAY;IACtD,UAAA,kBAAC,QAAD,EAAM,GAAE,iBAAkB,CAAA;GACvB,CAAA;EACO,CAAA,GACbgB,CACS;CACZ,CAAA,CAAA,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"Tooltip-C6eFCYxw.js","names":["TooltipTrigger","RACTooltipTrigger","Tooltip","_Fragment","RACTooltip","s","useOverlayPortal","Focusable$1","Tooltip_module_default","TooltipTrigger$1","rest","props","TooltipTrigger","Tooltip$1","portalContainer","Fragment","anchor","Tooltip","className","portalProps","OverlayArrow","children"],"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,SAAgBA,EAAe,GAA4B;CACzD,IAAM,EAAE,WAAQ,KAAK,gBAAa,GAAG,GAAGU,MAASC;CACjD,OAAO,kBAACV,GAAD;EAA0B;EAAmB;EAAY,GAAIS;CAAO,CAAA;AAC7E;AAaA,SAAgBR,EAAQ,GAAqB;CAC3C,IAAM,EAAE,aAAU,cAAW,eAAY,OAAO,YAAS,GAAG,oBAAiB,GAAGQ,MAASC,GACnF,EAAE,WAAQ,mBAAgBL,EAAiBQ,CAAe;CAChE,OACE,kBAAAX,GAAA,EAAA,UAAA,CACGa,GACD,kBAACZ,GAAD;EACE,GAAIM;EACO;EACH;EACR,WAAW,CAACL,EAAE,SAASa,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAC1D,uBAAoB;EACpB,GAAIC;EANN,UAAA,CAQE,kBAACC,GAAD;GAAc,WAAWf,EAAE;GACzB,UAAA,kBAAC,OAAD;IAAK,OAAO;IAAG,QAAQ;IAAG,SAAQ;IAAU,eAAY;IACtD,UAAA,kBAAC,QAAD,EAAM,GAAE,iBAAkB,CAAA;GACvB,CAAA;EACO,CAAA,GACbgB,CACS;CACZ,CAAA,CAAA,EAAA,CAAA;AAEN"}