@weasel-js/ui 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/dist/chunks/{ActionBar-xA73vzzF.js → ActionBar-CfXS7-9f.js} +2 -2
  2. package/dist/chunks/{ActionBar-xA73vzzF.js.map → ActionBar-CfXS7-9f.js.map} +1 -1
  3. package/dist/chunks/{Badge-jYQjrTKc.js → Badge-4ShpqA0h.js} +2 -2
  4. package/dist/chunks/{Badge-jYQjrTKc.js.map → Badge-4ShpqA0h.js.map} +1 -1
  5. package/dist/chunks/{Badge-CTc9Lkwn.js → Badge-qkV9EqKs.js} +6 -2
  6. package/dist/chunks/Badge-qkV9EqKs.js.map +1 -0
  7. package/dist/chunks/{Button-XB-T75YL.js → Button-CQA-K1g9.js} +17 -17
  8. package/dist/chunks/Button-CQA-K1g9.js.map +1 -0
  9. package/dist/chunks/Button-KF-qSGtA.js +11 -0
  10. package/dist/chunks/Button-KF-qSGtA.js.map +1 -0
  11. package/dist/chunks/{ButtonBar-CIMKPPRS.js → ButtonBar-B-cYuoem.js} +10 -4
  12. package/dist/chunks/ButtonBar-B-cYuoem.js.map +1 -0
  13. package/dist/chunks/{Callout-DpTO3fkb.js → Callout-VyYDIP7w.js} +18 -18
  14. package/dist/chunks/Callout-VyYDIP7w.js.map +1 -0
  15. package/dist/chunks/{CloseButton-wb7Or5Eg.js → CloseButton-CKarkTT9.js} +3 -3
  16. package/dist/chunks/{CloseButton-wb7Or5Eg.js.map → CloseButton-CKarkTT9.js.map} +1 -1
  17. package/dist/chunks/{Code-AsKpgnv6.js → Code-ChwKP1V0.js} +8 -2
  18. package/dist/chunks/Code-ChwKP1V0.js.map +1 -0
  19. package/dist/chunks/{ColorModeControl-DET6Itwq.js → ColorModeControl-CH9PmDlT.js} +6 -6
  20. package/dist/chunks/{ColorModeControl-DET6Itwq.js.map → ColorModeControl-CH9PmDlT.js.map} +1 -1
  21. package/dist/chunks/{ComboBox-DKln_mOd.js → ComboBox-BMj_IKBj.js} +4 -4
  22. package/dist/chunks/ComboBox-BMj_IKBj.js.map +1 -0
  23. package/dist/chunks/{DataGrid-B6IS9vUk.js → DataGrid-CjiVKoaA.js} +2 -2
  24. package/dist/chunks/{DataGrid-B6IS9vUk.js.map → DataGrid-CjiVKoaA.js.map} +1 -1
  25. package/dist/chunks/{Dialog-h-5MeYpu.js → Dialog-Du4POZ52.js} +5 -5
  26. package/dist/chunks/Dialog-Du4POZ52.js.map +1 -0
  27. package/dist/chunks/{DragGhost-BeYDJyLZ.js → DragGhost-_IpuN_xM.js} +2 -2
  28. package/dist/chunks/{DragGhost-BeYDJyLZ.js.map → DragGhost-_IpuN_xM.js.map} +1 -1
  29. package/dist/chunks/{FallthroughDiagram-CS1IhQaU.js → FallthroughDiagram-Cn6QLWKA.js} +9 -9
  30. package/dist/chunks/{FallthroughDiagram-CS1IhQaU.js.map → FallthroughDiagram-Cn6QLWKA.js.map} +1 -1
  31. package/dist/chunks/{FillStrokeSwatch-C4h3rUFM.js → FillStrokeSwatch-BkUhlpQL.js} +2 -2
  32. package/dist/chunks/{FillStrokeSwatch-C4h3rUFM.js.map → FillStrokeSwatch-BkUhlpQL.js.map} +1 -1
  33. package/dist/chunks/{FontFamilySelect-DEvMXyZd.js → FontFamilySelect-CXN7O2-p.js} +2 -2
  34. package/dist/chunks/{FontFamilySelect-DEvMXyZd.js.map → FontFamilySelect-CXN7O2-p.js.map} +1 -1
  35. package/dist/chunks/{FontWeightSelect-BLQ_LMJF.js → FontWeightSelect-BBuJGe_2.js} +2 -2
  36. package/dist/chunks/{FontWeightSelect-BLQ_LMJF.js.map → FontWeightSelect-BBuJGe_2.js.map} +1 -1
  37. package/dist/chunks/{GestureRoute-BXESrHI0.js → GestureRoute-BqHUrGeQ.js} +13 -13
  38. package/dist/chunks/{GestureRoute-BXESrHI0.js.map → GestureRoute-BqHUrGeQ.js.map} +1 -1
  39. package/dist/chunks/{GradientEditor-vz771M-N.js → GradientEditor-DX4sb1Hf.js} +3 -3
  40. package/dist/chunks/{GradientEditor-vz771M-N.js.map → GradientEditor-DX4sb1Hf.js.map} +1 -1
  41. package/dist/chunks/{Icon-DPRUIo3G.js → Icon-BfqYtAX5.js} +30 -1
  42. package/dist/chunks/Icon-BfqYtAX5.js.map +1 -0
  43. package/dist/chunks/{ItemList-CRu9y7hL.js → ItemList-nbakLf3N.js} +32 -32
  44. package/dist/chunks/ItemList-nbakLf3N.js.map +1 -0
  45. package/dist/chunks/{Jog-TE6QI9i1.js → Jog-BU0xuM3G.js} +6 -6
  46. package/dist/chunks/{Jog-TE6QI9i1.js.map → Jog-BU0xuM3G.js.map} +1 -1
  47. package/dist/chunks/{Keycaps-C-FJyG8k.js → Keycaps-CM-gOj0e.js} +8 -2
  48. package/dist/chunks/Keycaps-CM-gOj0e.js.map +1 -0
  49. package/dist/chunks/LayerList-vfAoImxX.js +432 -0
  50. package/dist/chunks/LayerList-vfAoImxX.js.map +1 -0
  51. package/dist/chunks/{ListEditor-DGtwj99m.js → ListEditor-BAKs47bN.js} +3 -3
  52. package/dist/chunks/{ListEditor-DGtwj99m.js.map → ListEditor-BAKs47bN.js.map} +1 -1
  53. package/dist/chunks/{MenuButton-TAFg88Lp.js → MenuButton-CJGdhwGr.js} +5 -5
  54. package/dist/chunks/MenuButton-CJGdhwGr.js.map +1 -0
  55. package/dist/chunks/{MeshEditor-8CRsu-Td.js → MeshEditor-rhf7cXfG.js} +2 -2
  56. package/dist/chunks/{MeshEditor-8CRsu-Td.js.map → MeshEditor-rhf7cXfG.js.map} +1 -1
  57. package/dist/chunks/{OptionsBar-DeTAjVb7.js → OptionsBar-DyTXbev-.js} +9 -3
  58. package/dist/chunks/OptionsBar-DyTXbev-.js.map +1 -0
  59. package/dist/chunks/{PaintField-DX4uYlF9.js → PaintField--GbF8sL7.js} +7 -7
  60. package/dist/chunks/PaintField--GbF8sL7.js.map +1 -0
  61. package/dist/chunks/{PaintInput-CWyOJXUM.js → PaintInput-DSS5IjXn.js} +5 -5
  62. package/dist/chunks/{PaintInput-CWyOJXUM.js.map → PaintInput-DSS5IjXn.js.map} +1 -1
  63. package/dist/chunks/{PatternPicker-0j51aDJ3.js → PatternPicker-82DCUvUk.js} +2 -2
  64. package/dist/chunks/{PatternPicker-0j51aDJ3.js.map → PatternPicker-82DCUvUk.js.map} +1 -1
  65. package/dist/chunks/{Powerline-6wIFmDik.js → Powerline-CogJv9VU.js} +2 -2
  66. package/dist/chunks/{Powerline-6wIFmDik.js.map → Powerline-CogJv9VU.js.map} +1 -1
  67. package/dist/chunks/{Prefs-gbjYqvSD.js → Prefs-BSSKOvPa.js} +41 -41
  68. package/dist/chunks/Prefs-BSSKOvPa.js.map +1 -0
  69. package/dist/chunks/{Properties-BbNuMiic.js → Properties-DteSVEWs.js} +4 -4
  70. package/dist/chunks/{Properties-BbNuMiic.js.map → Properties-DteSVEWs.js.map} +1 -1
  71. package/dist/chunks/{PropertyField-CWUtNK1w.js → PropertyField-CLbUOynA.js} +67 -67
  72. package/dist/chunks/PropertyField-CLbUOynA.js.map +1 -0
  73. package/dist/chunks/{Select-ouV8O6cp.js → Select-BhHwjNsb.js} +13 -13
  74. package/dist/chunks/Select-BhHwjNsb.js.map +1 -0
  75. package/dist/chunks/{SelectionPanel-BpUqP75b.js → SelectionPanel-B6HinSdB.js} +2 -2
  76. package/dist/chunks/{SelectionPanel-BpUqP75b.js.map → SelectionPanel-B6HinSdB.js.map} +1 -1
  77. package/dist/chunks/{SidebarPanel--dJ-k9-V.js → SidebarPanel-P3a8tIIj.js} +2 -2
  78. package/dist/chunks/{SidebarPanel--dJ-k9-V.js.map → SidebarPanel-P3a8tIIj.js.map} +1 -1
  79. package/dist/chunks/{StatusBar-BEOfOX0D.js → StatusBar-DEh7J2Gj.js} +14 -9
  80. package/dist/chunks/StatusBar-DEh7J2Gj.js.map +1 -0
  81. package/dist/chunks/{SwatchStrip-BY6A511W.js → SwatchStrip-D7YNn_p0.js} +2 -2
  82. package/dist/chunks/{SwatchStrip-BY6A511W.js.map → SwatchStrip-D7YNn_p0.js.map} +1 -1
  83. package/dist/chunks/{ThemeSwitcher-tnATkIo1.js → ThemeSwitcher-BJWP1l87.js} +6 -6
  84. package/dist/chunks/{ThemeSwitcher-tnATkIo1.js.map → ThemeSwitcher-BJWP1l87.js.map} +1 -1
  85. package/dist/chunks/{Timeline-FlLUm8nd.js → Timeline-CisRg82u.js} +2 -2
  86. package/dist/chunks/{Timeline-FlLUm8nd.js.map → Timeline-CisRg82u.js.map} +1 -1
  87. package/dist/chunks/{Toast-CuHkT0x0.js → Toast-DhkU9Z0b.js} +3 -3
  88. package/dist/chunks/{Toast-CuHkT0x0.js.map → Toast-DhkU9Z0b.js.map} +1 -1
  89. package/dist/chunks/ToggleBar-CRc2k89_.js +10 -0
  90. package/dist/chunks/ToggleBar-CRc2k89_.js.map +1 -0
  91. package/dist/chunks/{ToggleBar-BZ4Gk1IU.js → ToggleBar-CfYbMK3x.js} +9 -9
  92. package/dist/chunks/ToggleBar-CfYbMK3x.js.map +1 -0
  93. package/dist/chunks/{TokenPanel-DongdiZM.js → TokenPanel-cL37E39j.js} +5 -5
  94. package/dist/chunks/{TokenPanel-DongdiZM.js.map → TokenPanel-cL37E39j.js.map} +1 -1
  95. package/dist/chunks/{ToolButton-BURp4YIO.js → ToolButton-Bo7WH1wt.js} +2 -2
  96. package/dist/chunks/{ToolButton-BURp4YIO.js.map → ToolButton-Bo7WH1wt.js.map} +1 -1
  97. package/dist/chunks/{ToolOptionsBar-wTPJFfOn.js → ToolOptionsBar-DmhzrOmd.js} +2 -2
  98. package/dist/chunks/{ToolOptionsBar-wTPJFfOn.js.map → ToolOptionsBar-DmhzrOmd.js.map} +1 -1
  99. package/dist/chunks/{ToolPalette-DKDFWOX-.js → ToolPalette-BTD84k9C.js} +2 -2
  100. package/dist/chunks/{ToolPalette-DKDFWOX-.js.map → ToolPalette-BTD84k9C.js.map} +1 -1
  101. package/dist/chunks/{Tooltip-C6eFCYxw.js → Tooltip-DljsPEQG.js} +4 -4
  102. package/dist/chunks/Tooltip-DljsPEQG.js.map +1 -0
  103. package/dist/chunks/Tree-B_PW6K-W.js +215 -0
  104. package/dist/chunks/Tree-B_PW6K-W.js.map +1 -0
  105. package/dist/chunks/{icons-CofIOTiI.js → icons-B_fPKEis.js} +52 -43
  106. package/dist/chunks/icons-B_fPKEis.js.map +1 -0
  107. package/dist/chunks/{model-qQj8Ny9w.js → model-Ca0f95r0.js} +5 -5
  108. package/dist/chunks/{model-qQj8Ny9w.js.map → model-Ca0f95r0.js.map} +1 -1
  109. package/dist/chunks/{portalHost-CE70wLzo.js → portalHost-RUQPxIoW.js} +3 -2
  110. package/dist/chunks/{portalHost-CE70wLzo.js.map → portalHost-RUQPxIoW.js.map} +1 -1
  111. package/dist/chunks/{prefField-CCm_nzlM.js → prefField-DPPbAmRR.js} +3 -3
  112. package/dist/chunks/{prefField-CCm_nzlM.js.map → prefField-DPPbAmRR.js.map} +1 -1
  113. package/dist/chunks/{segmentTooltip-CGxCOWNz.js → segmentTooltip-8VBPNgEc.js} +2 -2
  114. package/dist/chunks/{segmentTooltip-CGxCOWNz.js.map → segmentTooltip-8VBPNgEc.js.map} +1 -1
  115. package/dist/chunks/segmentedControl.module-62qjNWJk.js +11 -0
  116. package/dist/chunks/{segmentedControl.module-BzGXUL5G.js.map → segmentedControl.module-62qjNWJk.js.map} +1 -1
  117. package/dist/chunks/{useReorderDragList-CStYKjHl.js → useReorderDragList-DnqqvRGK.js} +38 -30
  118. package/dist/chunks/useReorderDragList-DnqqvRGK.js.map +1 -0
  119. package/dist/components/ActionBar/index.js +1 -1
  120. package/dist/components/Badge/index.d.ts +1 -0
  121. package/dist/components/Badge/index.d.ts.map +1 -1
  122. package/dist/components/Badge/index.js +3 -3
  123. package/dist/components/Badge/variantIcons.d.ts +5 -0
  124. package/dist/components/Badge/variantIcons.d.ts.map +1 -0
  125. package/dist/components/Button/index.d.ts +1 -0
  126. package/dist/components/Button/index.d.ts.map +1 -1
  127. package/dist/components/Button/index.js +3 -2
  128. package/dist/components/Button/variantIcons.d.ts +5 -0
  129. package/dist/components/Button/variantIcons.d.ts.map +1 -0
  130. package/dist/components/ButtonBar/index.d.ts +1 -0
  131. package/dist/components/ButtonBar/index.d.ts.map +1 -1
  132. package/dist/components/ButtonBar/index.js +2 -2
  133. package/dist/components/ButtonBar/variantIcons.d.ts +5 -0
  134. package/dist/components/ButtonBar/variantIcons.d.ts.map +1 -0
  135. package/dist/components/Callout/Callout.d.ts.map +1 -1
  136. package/dist/components/Callout/index.js +1 -1
  137. package/dist/components/CloseButton/index.js +1 -1
  138. package/dist/components/Code/index.d.ts +1 -0
  139. package/dist/components/Code/index.d.ts.map +1 -1
  140. package/dist/components/Code/index.js +2 -2
  141. package/dist/components/Code/variantIcons.d.ts +5 -0
  142. package/dist/components/Code/variantIcons.d.ts.map +1 -0
  143. package/dist/components/ColorModeControl/index.js +1 -1
  144. package/dist/components/ComboBox/ComboBox.d.ts.map +1 -1
  145. package/dist/components/ComboBox/index.js +1 -1
  146. package/dist/components/DataGrid/index.js +1 -1
  147. package/dist/components/Dialog/Dialog.d.ts.map +1 -1
  148. package/dist/components/Dialog/index.js +1 -1
  149. package/dist/components/DragGhost/index.js +1 -1
  150. package/dist/components/FallthroughDiagram/index.js +1 -1
  151. package/dist/components/FillStrokeSwatch/index.js +1 -1
  152. package/dist/components/FontFamilySelect/index.js +1 -1
  153. package/dist/components/FontWeightSelect/index.js +1 -1
  154. package/dist/components/GestureRoute/index.js +1 -1
  155. package/dist/components/GradientEditor/index.js +1 -1
  156. package/dist/components/ItemList/index.js +1 -1
  157. package/dist/components/Jog/index.js +1 -1
  158. package/dist/components/Keycaps/index.d.ts +1 -0
  159. package/dist/components/Keycaps/index.d.ts.map +1 -1
  160. package/dist/components/Keycaps/index.js +2 -2
  161. package/dist/components/Keycaps/variantIcons.d.ts +5 -0
  162. package/dist/components/Keycaps/variantIcons.d.ts.map +1 -0
  163. package/dist/components/LayerList/LayerList.d.ts.map +1 -1
  164. package/dist/components/LayerList/index.js +1 -1
  165. package/dist/components/ListEditor/index.js +1 -1
  166. package/dist/components/MenuButton/MenuButton.d.ts.map +1 -1
  167. package/dist/components/MenuButton/index.js +1 -1
  168. package/dist/components/MeshEditor/index.js +1 -1
  169. package/dist/components/OptionsBar/index.d.ts +1 -0
  170. package/dist/components/OptionsBar/index.d.ts.map +1 -1
  171. package/dist/components/OptionsBar/index.js +2 -2
  172. package/dist/components/OptionsBar/variantIcons.d.ts +5 -0
  173. package/dist/components/OptionsBar/variantIcons.d.ts.map +1 -0
  174. package/dist/components/PaintField/PaintField.d.ts.map +1 -1
  175. package/dist/components/PaintField/index.js +1 -1
  176. package/dist/components/PaintInput/index.js +1 -1
  177. package/dist/components/PatternPicker/index.js +1 -1
  178. package/dist/components/Powerline/index.js +2 -2
  179. package/dist/components/Prefs/index.js +2 -2
  180. package/dist/components/Properties/index.js +2 -2
  181. package/dist/components/Select/Select.d.ts.map +1 -1
  182. package/dist/components/Select/index.js +1 -1
  183. package/dist/components/SelectionPanel/index.js +2 -2
  184. package/dist/components/SidebarPanel/index.js +1 -1
  185. package/dist/components/StatusBar/StatusBar.d.ts +2 -0
  186. package/dist/components/StatusBar/StatusBar.d.ts.map +1 -1
  187. package/dist/components/StatusBar/index.js +1 -1
  188. package/dist/components/SwatchStrip/index.js +1 -1
  189. package/dist/components/ThemeSwitcher/index.js +1 -1
  190. package/dist/components/Timeline/index.js +1 -1
  191. package/dist/components/Toast/index.js +1 -1
  192. package/dist/components/ToggleBar/index.d.ts +1 -0
  193. package/dist/components/ToggleBar/index.d.ts.map +1 -1
  194. package/dist/components/ToggleBar/index.js +3 -2
  195. package/dist/components/ToggleBar/variantIcons.d.ts +5 -0
  196. package/dist/components/ToggleBar/variantIcons.d.ts.map +1 -0
  197. package/dist/components/TokenPanel/index.js +1 -1
  198. package/dist/components/ToolButton/index.js +1 -1
  199. package/dist/components/ToolOptionsBar/index.js +1 -1
  200. package/dist/components/ToolPalette/index.js +1 -1
  201. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
  202. package/dist/components/Tooltip/index.js +1 -1
  203. package/dist/components/Tree/Tree.d.ts +1 -1
  204. package/dist/components/Tree/Tree.d.ts.map +1 -1
  205. package/dist/components/Tree/index.js +1 -1
  206. package/dist/icons/index.d.ts +6 -0
  207. package/dist/icons/index.d.ts.map +1 -1
  208. package/dist/icons/paths.d.ts +12 -0
  209. package/dist/icons/paths.d.ts.map +1 -1
  210. package/dist/index.js +100 -98
  211. package/dist/index.js.map +1 -1
  212. package/dist/overlays/portalHost.d.ts +10 -4
  213. package/dist/overlays/portalHost.d.ts.map +1 -1
  214. package/dist/style.css +1 -1
  215. package/dist/useReorderDragList.d.ts +3 -0
  216. package/dist/useReorderDragList.d.ts.map +1 -1
  217. package/package.json +10 -9
  218. package/dist/chunks/Badge-CTc9Lkwn.js.map +0 -1
  219. package/dist/chunks/Button-XB-T75YL.js.map +0 -1
  220. package/dist/chunks/ButtonBar-CIMKPPRS.js.map +0 -1
  221. package/dist/chunks/Callout-DpTO3fkb.js.map +0 -1
  222. package/dist/chunks/Code-AsKpgnv6.js.map +0 -1
  223. package/dist/chunks/ComboBox-DKln_mOd.js.map +0 -1
  224. package/dist/chunks/Dialog-h-5MeYpu.js.map +0 -1
  225. package/dist/chunks/Icon-DPRUIo3G.js.map +0 -1
  226. package/dist/chunks/ItemList-CRu9y7hL.js.map +0 -1
  227. package/dist/chunks/Keycaps-C-FJyG8k.js.map +0 -1
  228. package/dist/chunks/LayerList-BXTAjK-4.js +0 -421
  229. package/dist/chunks/LayerList-BXTAjK-4.js.map +0 -1
  230. package/dist/chunks/MenuButton-TAFg88Lp.js.map +0 -1
  231. package/dist/chunks/OptionsBar-DeTAjVb7.js.map +0 -1
  232. package/dist/chunks/PaintField-DX4uYlF9.js.map +0 -1
  233. package/dist/chunks/Prefs-gbjYqvSD.js.map +0 -1
  234. package/dist/chunks/PropertyField-CWUtNK1w.js.map +0 -1
  235. package/dist/chunks/Select-ouV8O6cp.js.map +0 -1
  236. package/dist/chunks/StatusBar-BEOfOX0D.js.map +0 -1
  237. package/dist/chunks/ToggleBar-BZ4Gk1IU.js.map +0 -1
  238. package/dist/chunks/Tooltip-C6eFCYxw.js.map +0 -1
  239. package/dist/chunks/Tree-hzIbj2q1.js +0 -203
  240. package/dist/chunks/Tree-hzIbj2q1.js.map +0 -1
  241. package/dist/chunks/icons-CofIOTiI.js.map +0 -1
  242. package/dist/chunks/interactiveTarget-BNZmTow2.js +0 -24
  243. package/dist/chunks/interactiveTarget-BNZmTow2.js.map +0 -1
  244. package/dist/chunks/segmentedControl.module-BzGXUL5G.js +0 -11
  245. package/dist/chunks/useReorderDragList-CStYKjHl.js.map +0 -1
  246. package/dist/interactiveTarget.d.ts +0 -9
  247. package/dist/interactiveTarget.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionPanel-BpUqP75b.js","names":["s","_Fragment","Fragment","renderCells","SelectionPanel_module_default","effectiveSections","setAtPath","aggregateValue","kindBreakdown","classifyKind","MIXED","renderBuiltin","Fragment$1","defaultKindLabel","kind","SelectionPanel","props","scene","nodes","selection","asNodeId","id","n","kinds","routing","selectionKey","sections","properties","className","emptyState","commit","head","rest","leaf","ids","node","value","next","nodeValueAt","kindLabel","Fragment","rows","section","row","leafCell","panelLeaf","renderers","controls","content","key","aggregated","path","mixed","ctx","v","fn","at","p","custom","ariaLabel"],"sources":["../../src/components/SelectionPanel/SelectionPanel.tsx"],"sourcesContent":["import { Fragment, useSyncExternalStore, type ReactNode } from 'react';\nimport {\n asNodeId,\n type NodePropertiesEntry,\n type NodeRoutingEntry,\n type Scene,\n type SelectionApi,\n} from '@weasel-js/core';\nimport {\n renderBuiltin,\n renderCells,\n type LeafCell,\n type PropertyRenderContext,\n type PropertyRenderer,\n} from './renderLeaf';\nimport {\n MIXED,\n aggregateValue,\n classifyKind,\n effectiveSections,\n kindBreakdown,\n nodeValueAt,\n setAtPath,\n type AnyNode,\n type PanelLeaf,\n} from './model';\nimport s from './SelectionPanel.module.css';\n\nexport type { PropertyRenderContext, PropertyRenderer } from './renderLeaf';\n\n/** Props for {@link SelectionPanel}. */\nexport interface SelectionPanelProps<TData, TLayer extends string, TPose> {\n /** The scene handle (`useScene`). The panel subscribes itself, so it\n * re-renders on scene mutations regardless of parent renders. */\n scene: Scene<TData, TLayer, TPose>;\n /** Selection handle (`useSelection`). Only `current` is read. */\n selection: Pick<SelectionApi, 'current'>;\n /** Properties-trait entries, e.g. core's `defaultNodeProperties` /\n * `inferredNodeProperties` (+ consumer extras). Memoize or hoist. */\n properties: readonly NodePropertiesEntry[];\n /** Routing-trait classifiers used to derive each node's kind — pass\n * the same list the canvas uses. Memoize or hoist. */\n routing: readonly NodeRoutingEntry[];\n /** Control overrides / app-defined kinds (PrefsForm-style). Keys are\n * leaf paths (`data.fill`, checked first) or leaf kinds (`color`).\n * A renderer returning `null` collapses its leaf (and the row, when\n * every leaf in it collapses). */\n renderers?: Record<string, PropertyRenderer>;\n /** Kind → header label. Default: capitalized kind name. */\n kindLabel?: (kind: string) => string;\n /** Rendered when the selection is empty. */\n emptyState?: ReactNode;\n className?: string;\n}\n\nconst defaultKindLabel = (kind: string): string =>\n kind.length === 0 ? kind : kind[0].toUpperCase() + kind.slice(1);\n\n/**\n * Pre-baked selection properties panel. Shows the selected nodes' kind\n * and the properties-trait schema for that kind; multi-selections show\n * the intersection of the kinds' schemas with per-field Mixed state.\n * Edits commit as one labeled `scene.batch` fan-out per gesture.\n */\nexport function SelectionPanel<TData, TLayer extends string, TPose>(\n props: SelectionPanelProps<TData, TLayer, TPose>,\n) {\n const {\n scene,\n selection,\n properties,\n routing,\n renderers,\n kindLabel = defaultKindLabel,\n emptyState = null,\n className,\n } = props;\n\n useSyncExternalStore(scene.subscribe, scene.getVersion, scene.getVersion);\n\n const nodes = selection.current\n .map((id) => scene.get(asNodeId(id)))\n .filter((n): n is NonNullable<typeof n> => n != null) as readonly AnyNode[];\n\n const kinds = nodes.map((n) => classifyKind(n, routing));\n const selectionKey = nodes.map((n) => n.id).join(',');\n const sections = effectiveSections(kinds, properties);\n\n if (nodes.length === 0) {\n return <div className={[s.root, className].filter(Boolean).join(' ')}>{emptyState}</div>;\n }\n\n /** Writes, into every selected node, what `next` derives from the value\n * that node holds at the leaf's path. */\n const commit = (leaf: PanelLeaf, next: (prev: unknown) => unknown): void => {\n const [head, ...rest] = leaf.path.split('.');\n if (rest.length === 0) return;\n const ids = selection.current.map(asNodeId);\n scene.batch(`Edit ${leaf.leaf.name}`, () => {\n for (const id of ids) {\n const node = scene.get(id);\n if (!node) continue;\n const value = next(nodeValueAt(node as AnyNode, leaf.path));\n // `setAtPath` spreads plain objects/arrays down the schema path;\n // consumer `pose`/`data` are assumed plain-object-shaped along\n // that path (a class instance's prototype would be dropped by\n // the spread) — the `as TPose`/`as TData` casts below rely on it.\n if (head === 'pose') {\n scene.setPose(id, setAtPath(node.pose as object, rest, value) as TPose);\n } else if (head === 'data') {\n scene.update(id, { data: setAtPath(node.data as object, rest, value) as TData });\n }\n }\n });\n };\n\n return (\n <div className={[s.root, className].filter(Boolean).join(' ')}>\n <header className={s.header}>\n {nodes.length === 1 ? (\n <span className={s.kind}>{kindLabel(kinds[0])}</span>\n ) : (\n <>\n <span className={s.kind}>{nodes.length} selected</span>\n <span className={s.breakdown}>{kindBreakdown(kinds)}</span>\n </>\n )}\n </header>\n {sections.map((section) => {\n // Render controls before emitting row chrome so a null-rendering\n // leaf (custom renderer opting out) collapses its cell — and the\n // whole row / section when nothing survives. PrefsForm precedent.\n const rows = section.rows\n .map((row) => {\n const controls = renderCells(\n row.leaves.map((panelLeaf) =>\n leafCell(\n panelLeaf,\n row.leaves.length > 1\n ? `${row.label} ${panelLeaf.leaf.name}`\n : panelLeaf.leaf.name,\n nodes,\n renderers,\n commit,\n selectionKey,\n ),\n ),\n renderers,\n );\n return { row, controls };\n })\n .filter(({ controls }) => controls.length > 0);\n if (rows.length === 0) return null;\n return (\n <section key={section.key} className={s.section}>\n {section.name !== '' && <h3 className={s.sectionTitle}>{section.name}</h3>}\n {rows.map(({ row, controls }) => (\n // A `block` leaf brings its own chrome — it spans the section\n // instead of sitting in a labeled row's control cell. Under a\n // headless section nothing else names it, so it heads itself;\n // an object leaf already renders its own heading.\n row.leaves.length === 1 && row.leaves[0].leaf.block ? (\n <div key={row.leaves[0].path}>\n {section.name === '' && row.leaves[0].leaf.kind !== 'object' && (\n <h4 className={s.sectionTitle} title={row.leaves[0].leaf.description}>\n {row.leaves[0].leaf.name}\n </h4>\n )}\n {controls[0].content}\n </div>\n ) : (\n <div key={row.leaves[0].path} className={s.row}>\n <span className={s.rowLabel} title={row.leaves[0].leaf.description}>\n {row.label}\n </span>\n <span className={s.rowControls}>\n {controls.map(({ key, content }) => (\n <Fragment key={key}>{content}</Fragment>\n ))}\n </span>\n </div>\n )\n ))}\n </section>\n );\n })}\n </div>\n );\n}\n\n\nfunction leafCell(\n panelLeaf: PanelLeaf,\n ariaLabel: string,\n nodes: readonly AnyNode[],\n renderers: Record<string, PropertyRenderer> | undefined,\n commit: (leaf: PanelLeaf, next: (prev: unknown) => unknown) => void,\n selectionKey: string,\n): LeafCell {\n const { path, leaf } = panelLeaf;\n const aggregated = aggregateValue(nodes, path);\n const mixed = aggregated === MIXED;\n const value = mixed ? undefined : aggregated;\n\n const ctx: PropertyRenderContext = {\n path,\n pref: leaf,\n value,\n mixed,\n unset: !mixed && aggregated === undefined,\n each: nodes.map((n) => nodeValueAt(n, path)),\n setValue: (v) => commit(panelLeaf, () => v),\n update: (fn) => commit(panelLeaf, fn),\n valueAt: (p) => {\n const at = aggregateValue(nodes, p);\n return at === MIXED ? { value: undefined, mixed: true } : { value: at, mixed: false };\n },\n selectionKey,\n };\n\n return {\n key: path,\n leaf,\n ctx,\n ariaLabel,\n render: () => {\n const custom = renderers?.[path] ?? renderers?.[leaf.kind];\n if (custom) return custom(ctx);\n return renderBuiltin(ctx, ariaLabel, renderers, selectionKey);\n },\n };\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"SelectionPanel-B6HinSdB.js","names":["s","_Fragment","Fragment","renderCells","SelectionPanel_module_default","effectiveSections","setAtPath","aggregateValue","kindBreakdown","classifyKind","MIXED","renderBuiltin","Fragment$1","defaultKindLabel","kind","SelectionPanel","props","scene","nodes","selection","asNodeId","id","n","kinds","routing","selectionKey","sections","properties","className","emptyState","commit","head","rest","leaf","ids","node","value","next","nodeValueAt","kindLabel","Fragment","rows","section","row","leafCell","panelLeaf","renderers","controls","content","key","aggregated","path","mixed","ctx","v","fn","at","p","custom","ariaLabel"],"sources":["../../src/components/SelectionPanel/SelectionPanel.tsx"],"sourcesContent":["import { Fragment, useSyncExternalStore, type ReactNode } from 'react';\nimport {\n asNodeId,\n type NodePropertiesEntry,\n type NodeRoutingEntry,\n type Scene,\n type SelectionApi,\n} from '@weasel-js/core';\nimport {\n renderBuiltin,\n renderCells,\n type LeafCell,\n type PropertyRenderContext,\n type PropertyRenderer,\n} from './renderLeaf';\nimport {\n MIXED,\n aggregateValue,\n classifyKind,\n effectiveSections,\n kindBreakdown,\n nodeValueAt,\n setAtPath,\n type AnyNode,\n type PanelLeaf,\n} from './model';\nimport s from './SelectionPanel.module.css';\n\nexport type { PropertyRenderContext, PropertyRenderer } from './renderLeaf';\n\n/** Props for {@link SelectionPanel}. */\nexport interface SelectionPanelProps<TData, TLayer extends string, TPose> {\n /** The scene handle (`useScene`). The panel subscribes itself, so it\n * re-renders on scene mutations regardless of parent renders. */\n scene: Scene<TData, TLayer, TPose>;\n /** Selection handle (`useSelection`). Only `current` is read. */\n selection: Pick<SelectionApi, 'current'>;\n /** Properties-trait entries, e.g. core's `defaultNodeProperties` /\n * `inferredNodeProperties` (+ consumer extras). Memoize or hoist. */\n properties: readonly NodePropertiesEntry[];\n /** Routing-trait classifiers used to derive each node's kind — pass\n * the same list the canvas uses. Memoize or hoist. */\n routing: readonly NodeRoutingEntry[];\n /** Control overrides / app-defined kinds (PrefsForm-style). Keys are\n * leaf paths (`data.fill`, checked first) or leaf kinds (`color`).\n * A renderer returning `null` collapses its leaf (and the row, when\n * every leaf in it collapses). */\n renderers?: Record<string, PropertyRenderer>;\n /** Kind → header label. Default: capitalized kind name. */\n kindLabel?: (kind: string) => string;\n /** Rendered when the selection is empty. */\n emptyState?: ReactNode;\n className?: string;\n}\n\nconst defaultKindLabel = (kind: string): string =>\n kind.length === 0 ? kind : kind[0].toUpperCase() + kind.slice(1);\n\n/**\n * Pre-baked selection properties panel. Shows the selected nodes' kind\n * and the properties-trait schema for that kind; multi-selections show\n * the intersection of the kinds' schemas with per-field Mixed state.\n * Edits commit as one labeled `scene.batch` fan-out per gesture.\n */\nexport function SelectionPanel<TData, TLayer extends string, TPose>(\n props: SelectionPanelProps<TData, TLayer, TPose>,\n) {\n const {\n scene,\n selection,\n properties,\n routing,\n renderers,\n kindLabel = defaultKindLabel,\n emptyState = null,\n className,\n } = props;\n\n useSyncExternalStore(scene.subscribe, scene.getVersion, scene.getVersion);\n\n const nodes = selection.current\n .map((id) => scene.get(asNodeId(id)))\n .filter((n): n is NonNullable<typeof n> => n != null) as readonly AnyNode[];\n\n const kinds = nodes.map((n) => classifyKind(n, routing));\n const selectionKey = nodes.map((n) => n.id).join(',');\n const sections = effectiveSections(kinds, properties);\n\n if (nodes.length === 0) {\n return <div className={[s.root, className].filter(Boolean).join(' ')}>{emptyState}</div>;\n }\n\n /** Writes, into every selected node, what `next` derives from the value\n * that node holds at the leaf's path. */\n const commit = (leaf: PanelLeaf, next: (prev: unknown) => unknown): void => {\n const [head, ...rest] = leaf.path.split('.');\n if (rest.length === 0) return;\n const ids = selection.current.map(asNodeId);\n scene.batch(`Edit ${leaf.leaf.name}`, () => {\n for (const id of ids) {\n const node = scene.get(id);\n if (!node) continue;\n const value = next(nodeValueAt(node as AnyNode, leaf.path));\n // `setAtPath` spreads plain objects/arrays down the schema path;\n // consumer `pose`/`data` are assumed plain-object-shaped along\n // that path (a class instance's prototype would be dropped by\n // the spread) — the `as TPose`/`as TData` casts below rely on it.\n if (head === 'pose') {\n scene.setPose(id, setAtPath(node.pose as object, rest, value) as TPose);\n } else if (head === 'data') {\n scene.update(id, { data: setAtPath(node.data as object, rest, value) as TData });\n }\n }\n });\n };\n\n return (\n <div className={[s.root, className].filter(Boolean).join(' ')}>\n <header className={s.header}>\n {nodes.length === 1 ? (\n <span className={s.kind}>{kindLabel(kinds[0])}</span>\n ) : (\n <>\n <span className={s.kind}>{nodes.length} selected</span>\n <span className={s.breakdown}>{kindBreakdown(kinds)}</span>\n </>\n )}\n </header>\n {sections.map((section) => {\n // Render controls before emitting row chrome so a null-rendering\n // leaf (custom renderer opting out) collapses its cell — and the\n // whole row / section when nothing survives. PrefsForm precedent.\n const rows = section.rows\n .map((row) => {\n const controls = renderCells(\n row.leaves.map((panelLeaf) =>\n leafCell(\n panelLeaf,\n row.leaves.length > 1\n ? `${row.label} ${panelLeaf.leaf.name}`\n : panelLeaf.leaf.name,\n nodes,\n renderers,\n commit,\n selectionKey,\n ),\n ),\n renderers,\n );\n return { row, controls };\n })\n .filter(({ controls }) => controls.length > 0);\n if (rows.length === 0) return null;\n return (\n <section key={section.key} className={s.section}>\n {section.name !== '' && <h3 className={s.sectionTitle}>{section.name}</h3>}\n {rows.map(({ row, controls }) => (\n // A `block` leaf brings its own chrome — it spans the section\n // instead of sitting in a labeled row's control cell. Under a\n // headless section nothing else names it, so it heads itself;\n // an object leaf already renders its own heading.\n row.leaves.length === 1 && row.leaves[0].leaf.block ? (\n <div key={row.leaves[0].path}>\n {section.name === '' && row.leaves[0].leaf.kind !== 'object' && (\n <h4 className={s.sectionTitle} title={row.leaves[0].leaf.description}>\n {row.leaves[0].leaf.name}\n </h4>\n )}\n {controls[0].content}\n </div>\n ) : (\n <div key={row.leaves[0].path} className={s.row}>\n <span className={s.rowLabel} title={row.leaves[0].leaf.description}>\n {row.label}\n </span>\n <span className={s.rowControls}>\n {controls.map(({ key, content }) => (\n <Fragment key={key}>{content}</Fragment>\n ))}\n </span>\n </div>\n )\n ))}\n </section>\n );\n })}\n </div>\n );\n}\n\n\nfunction leafCell(\n panelLeaf: PanelLeaf,\n ariaLabel: string,\n nodes: readonly AnyNode[],\n renderers: Record<string, PropertyRenderer> | undefined,\n commit: (leaf: PanelLeaf, next: (prev: unknown) => unknown) => void,\n selectionKey: string,\n): LeafCell {\n const { path, leaf } = panelLeaf;\n const aggregated = aggregateValue(nodes, path);\n const mixed = aggregated === MIXED;\n const value = mixed ? undefined : aggregated;\n\n const ctx: PropertyRenderContext = {\n path,\n pref: leaf,\n value,\n mixed,\n unset: !mixed && aggregated === undefined,\n each: nodes.map((n) => nodeValueAt(n, path)),\n setValue: (v) => commit(panelLeaf, () => v),\n update: (fn) => commit(panelLeaf, fn),\n valueAt: (p) => {\n const at = aggregateValue(nodes, p);\n return at === MIXED ? { value: undefined, mixed: true } : { value: at, mixed: false };\n },\n selectionKey,\n };\n\n return {\n key: path,\n leaf,\n ctx,\n ariaLabel,\n render: () => {\n const custom = renderers?.[path] ?? renderers?.[leaf.kind];\n if (custom) return custom(ctx);\n return renderBuiltin(ctx, ariaLabel, renderers, selectionKey);\n },\n };\n}\n\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { t as e } from "./CloseButton-wb7Or5Eg.js";
1
+ import { t as e } from "./CloseButton-CKarkTT9.js";
2
2
  import { n as t } from "./Disclosure-CpWt87nO.js";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
4
  var i = {
@@ -50,4 +50,4 @@ function a(a) {
50
50
  //#endregion
51
51
  export { a as t };
52
52
 
53
- //# sourceMappingURL=SidebarPanel--dJ-k9-V.js.map
53
+ //# sourceMappingURL=SidebarPanel-P3a8tIIj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SidebarPanel--dJ-k9-V.js","names":["s","CloseButton","DisclosureMark","SidebarPanel_module_default","SidebarPanel","props","cls","collapsed","className","headerInteractive","onToggleCollapse","title","onHide"],"sources":["../../src/components/SidebarPanel/SidebarPanel.module.css","../../src/components/SidebarPanel/SidebarPanel.tsx"],"sourcesContent":[".panel {\n /* Vertical only: the body spans the panel's full width, and the title row's\n own controls carry the horizontal inset. */\n padding: var(--wzl-space-4) 0;\n background: var(--wzl-surface);\n color: var(--wzl-fg);\n}\n\n.title {\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}\n\n.titleRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: var(--wzl-space-2);\n padding: 0;\n}\n\n/* The title's inset, shared by the static title and the collapse button so the\n two line up. */\n.titleBox {\n padding: var(--wzl-space-2) var(--wzl-space-4);\n}\n\n.titleButton {\n display: inline-flex;\n align-items: center;\n gap: var(--wzl-space-2);\n flex: 1 1 auto;\n background: transparent;\n border: 0;\n cursor: pointer;\n color: inherit;\n font: inherit;\n text-align: left;\n}\n.titleButton:hover {\n color: var(--wzl-fg);\n}\n\n.hideButton {\n margin-inline-end: var(--wzl-space-2);\n}\n\n.panel.collapsed {\n padding-bottom: var(--wzl-space-2);\n}\n\n.body {\n padding: 0;\n}\n","import type { ReactNode } from 'react';\nimport { CloseButton } from '../CloseButton';\nimport { DisclosureMark } from '../Disclosure';\nimport s from './SidebarPanel.module.css';\n\n/** Props for {@link SidebarPanel}. */\nexport interface SidebarPanelProps {\n /** Title rendered in the panel's header row. */\n title?: ReactNode;\n /**\n * Collapsed state — when true, only the header paints; the body is\n * omitted. Caller owns the state (typically via prefs) and flips it\n * back via `onToggleCollapse`.\n */\n collapsed?: boolean;\n /**\n * Click handler for the title row. When provided, the header renders\n * as a button (fold mark + label) and acts as the collapse toggle.\n * When omitted, the title is static text and the panel can't collapse.\n */\n onToggleCollapse?(): void;\n /**\n * Optional close handler — when provided, the header gains a close\n * button on the trailing edge. Caller flips its \"hidden\" state and\n * conditionally unmounts the panel from the parent.\n */\n onHide?(): void;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * Generic collapsible panel section for sidebars. Pure presentation —\n * caller manages `collapsed`/`hidden` state externally (the pattern is\n * to drive it from app prefs so the Preferences modal and inline\n * fold marks toggle the same map).\n *\n * Pair with `<Sidebar>` for the docked column layout.\n */\nexport function SidebarPanel(props: SidebarPanelProps) {\n const { title, collapsed, onToggleCollapse, onHide, children, className } = props;\n const cls = [s.panel, collapsed && s.collapsed, className].filter(Boolean).join(' ');\n const headerInteractive = onToggleCollapse !== undefined;\n return (\n <div className={cls}>\n {title !== undefined && (\n <div className={s.titleRow}>\n {headerInteractive ? (\n <button\n type=\"button\"\n className={`${s.titleButton} ${s.titleBox}`}\n onClick={onToggleCollapse}\n aria-expanded={!collapsed}\n >\n <DisclosureMark open={!collapsed} />\n <span className={s.title}>{title}</span>\n </button>\n ) : (\n <span className={`${s.title} ${s.titleBox}`}>{title}</span>\n )}\n {onHide !== undefined && (\n <CloseButton\n className={s.hideButton}\n ariaLabel=\"Hide panel\"\n tooltip=\"Hide panel\"\n onClick={onHide}\n />\n )}\n </div>\n )}\n {!collapsed && <div className={s.body}>{children}</div>}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;ACuCA,SAAgBI,EAAa,GAA0B;CACrD,IAAM,EAAE,UAAO,cAAW,qBAAkB,WAAQ,aAAU,iBAAcC,GACtEC,IAAM;EAACN,EAAE;EAAOO,KAAaP,EAAE;EAAWQ;CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,GAC7EC,IAAoBC,MAAqB,KAAA;CAC/C,OACE,kBAAC,OAAD;EAAK,WAAWJ;EAAhB,UAAA,CACGK,MAAU,KAAA,KACT,kBAAC,OAAD;GAAK,WAAWX,EAAE;GAAlB,UAAA,CACGS,IACC,kBAAC,UAAD;IACE,MAAK;IACL,WAAW,GAAGT,EAAE,YAAY,GAAGA,EAAE;IACjC,SAASU;IACT,iBAAe,CAACH;IAJlB,UAAA,CAME,kBAACL,GAAD,EAAgB,MAAM,CAACK,EAAY,CAAA,GACnC,kBAAC,QAAD;KAAM,WAAWP,EAAE;KAAQ,UAAAW;IAAY,CAAA,CACjC;GAER,CAAA,IAAA,kBAAC,QAAD;IAAM,WAAW,GAAGX,EAAE,MAAM,GAAGA,EAAE;IAAa,UAAAW;GAAY,CAAA,GAE3DC,MAAW,KAAA,KACV,kBAACX,GAAD;IACE,WAAWD,EAAE;IACb,WAAU;IACV,SAAQ;IACR,SAASY;GACV,CAAA,CAEA;EAEN,CAAA,GAAA,CAACL,KAAa,kBAAC,OAAD;GAAK,WAAWP,EAAE;GAAO;EAAc,CAAA,CACnD;;AAET"}
1
+ {"version":3,"file":"SidebarPanel-P3a8tIIj.js","names":["s","CloseButton","DisclosureMark","SidebarPanel_module_default","SidebarPanel","props","cls","collapsed","className","headerInteractive","onToggleCollapse","title","onHide"],"sources":["../../src/components/SidebarPanel/SidebarPanel.module.css","../../src/components/SidebarPanel/SidebarPanel.tsx"],"sourcesContent":[".panel {\n /* Vertical only: the body spans the panel's full width, and the title row's\n own controls carry the horizontal inset. */\n padding: var(--wzl-space-4) 0;\n background: var(--wzl-surface);\n color: var(--wzl-fg);\n}\n\n.title {\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}\n\n.titleRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: var(--wzl-space-2);\n padding: 0;\n}\n\n/* The title's inset, shared by the static title and the collapse button so the\n two line up. */\n.titleBox {\n padding: var(--wzl-space-2) var(--wzl-space-4);\n}\n\n.titleButton {\n display: inline-flex;\n align-items: center;\n gap: var(--wzl-space-2);\n flex: 1 1 auto;\n background: transparent;\n border: 0;\n cursor: pointer;\n color: inherit;\n font: inherit;\n text-align: left;\n}\n.titleButton:hover {\n color: var(--wzl-fg);\n}\n\n.hideButton {\n margin-inline-end: var(--wzl-space-2);\n}\n\n.panel.collapsed {\n padding-bottom: var(--wzl-space-2);\n}\n\n.body {\n padding: 0;\n}\n","import type { ReactNode } from 'react';\nimport { CloseButton } from '../CloseButton';\nimport { DisclosureMark } from '../Disclosure';\nimport s from './SidebarPanel.module.css';\n\n/** Props for {@link SidebarPanel}. */\nexport interface SidebarPanelProps {\n /** Title rendered in the panel's header row. */\n title?: ReactNode;\n /**\n * Collapsed state — when true, only the header paints; the body is\n * omitted. Caller owns the state (typically via prefs) and flips it\n * back via `onToggleCollapse`.\n */\n collapsed?: boolean;\n /**\n * Click handler for the title row. When provided, the header renders\n * as a button (fold mark + label) and acts as the collapse toggle.\n * When omitted, the title is static text and the panel can't collapse.\n */\n onToggleCollapse?(): void;\n /**\n * Optional close handler — when provided, the header gains a close\n * button on the trailing edge. Caller flips its \"hidden\" state and\n * conditionally unmounts the panel from the parent.\n */\n onHide?(): void;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * Generic collapsible panel section for sidebars. Pure presentation —\n * caller manages `collapsed`/`hidden` state externally (the pattern is\n * to drive it from app prefs so the Preferences modal and inline\n * fold marks toggle the same map).\n *\n * Pair with `<Sidebar>` for the docked column layout.\n */\nexport function SidebarPanel(props: SidebarPanelProps) {\n const { title, collapsed, onToggleCollapse, onHide, children, className } = props;\n const cls = [s.panel, collapsed && s.collapsed, className].filter(Boolean).join(' ');\n const headerInteractive = onToggleCollapse !== undefined;\n return (\n <div className={cls}>\n {title !== undefined && (\n <div className={s.titleRow}>\n {headerInteractive ? (\n <button\n type=\"button\"\n className={`${s.titleButton} ${s.titleBox}`}\n onClick={onToggleCollapse}\n aria-expanded={!collapsed}\n >\n <DisclosureMark open={!collapsed} />\n <span className={s.title}>{title}</span>\n </button>\n ) : (\n <span className={`${s.title} ${s.titleBox}`}>{title}</span>\n )}\n {onHide !== undefined && (\n <CloseButton\n className={s.hideButton}\n ariaLabel=\"Hide panel\"\n tooltip=\"Hide panel\"\n onClick={onHide}\n />\n )}\n </div>\n )}\n {!collapsed && <div className={s.body}>{children}</div>}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;ACuCA,SAAgBI,EAAa,GAA0B;CACrD,IAAM,EAAE,UAAO,cAAW,qBAAkB,WAAQ,aAAU,iBAAcC,GACtEC,IAAM;EAACN,EAAE;EAAOO,KAAaP,EAAE;EAAWQ;CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,GAC7EC,IAAoBC,MAAqB,KAAA;CAC/C,OACE,kBAAC,OAAD;EAAK,WAAWJ;EAAhB,UAAA,CACGK,MAAU,KAAA,KACT,kBAAC,OAAD;GAAK,WAAWX,EAAE;GAAlB,UAAA,CACGS,IACC,kBAAC,UAAD;IACE,MAAK;IACL,WAAW,GAAGT,EAAE,YAAY,GAAGA,EAAE;IACjC,SAASU;IACT,iBAAe,CAACH;IAJlB,UAAA,CAME,kBAACL,GAAD,EAAgB,MAAM,CAACK,EAAY,CAAA,GACnC,kBAAC,QAAD;KAAM,WAAWP,EAAE;KAAQ,UAAAW;IAAY,CAAA,CACjC;GAER,CAAA,IAAA,kBAAC,QAAD;IAAM,WAAW,GAAGX,EAAE,MAAM,GAAGA,EAAE;IAAa,UAAAW;GAAY,CAAA,GAE3DC,MAAW,KAAA,KACV,kBAACX,GAAD;IACE,WAAWD,EAAE;IACb,WAAU;IACV,SAAQ;IACR,SAASY;GACV,CAAA,CAEA;EAEN,CAAA,GAAA,CAACL,KAAa,kBAAC,OAAD;GAAK,WAAWP,EAAE;GAAO;EAAc,CAAA,CACnD;;AAET"}
@@ -1,19 +1,24 @@
1
1
  import { jsx as e } from "react/jsx-runtime";
2
2
  var t = {
3
- bar: "_bar_6xkzu_1 _numeric_zns9n_4",
4
- item: "_item_6xkzu_14",
5
- muted: "_muted_6xkzu_18",
6
- hasTitle: "_hasTitle_6xkzu_22",
7
- spacer: "_spacer_6xkzu_26"
3
+ bar: "_bar_rlpqd_1 _numeric_zns9n_4",
4
+ item: "_item_rlpqd_18",
5
+ muted: "_muted_rlpqd_22",
6
+ hasTitle: "_hasTitle_rlpqd_26",
7
+ spacer: "_spacer_rlpqd_30",
8
+ divided: "_divided_rlpqd_36"
8
9
  };
9
10
  //#endregion
10
11
  //#region src/components/StatusBar/StatusBar.tsx
11
12
  function n(n) {
12
- let { ariaLabel: r, children: i, className: a } = n;
13
+ let { ariaLabel: r, divided: i, children: a, className: o } = n;
13
14
  return /* @__PURE__ */ e("footer", {
14
- className: [t.bar, a].filter(Boolean).join(" "),
15
+ className: [
16
+ t.bar,
17
+ i && t.divided,
18
+ o
19
+ ].filter(Boolean).join(" "),
15
20
  "aria-label": r,
16
- children: i
21
+ children: a
17
22
  });
18
23
  }
19
24
  function r(n) {
@@ -38,4 +43,4 @@ function i() {
38
43
  //#endregion
39
44
  export { r as n, i as r, n as t };
40
45
 
41
- //# sourceMappingURL=StatusBar-BEOfOX0D.js.map
46
+ //# sourceMappingURL=StatusBar-DEh7J2Gj.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBar-DEh7J2Gj.js","names":["s","StatusBar_module_default","StatusBar","props","divided","className","ariaLabel","StatusBarItem","cls","muted","title","StatusBarSpacer"],"sources":["../../src/components/StatusBar/StatusBar.module.css","../../src/components/StatusBar/StatusBar.tsx"],"sourcesContent":[".bar {\n composes: numeric from '@weasel-js/theme/numeric.module.css';\n display: flex;\n align-items: center;\n gap: var(--wzl-space-8);\n flex-shrink: 0;\n /* One line, always. A bar that grows a second line takes it from the canvas\n above it, and a readout that changes width would do that on and off as it\n ticks. Too narrow for its contents clips them instead. */\n overflow: hidden;\n padding: var(--wzl-space-2) var(--wzl-space-6);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n background: var(--wzl-surface);\n border-top: 1px solid var(--wzl-border);\n}\n\n.item {\n white-space: nowrap;\n}\n\n.muted {\n opacity: 0.6;\n}\n\n.hasTitle {\n cursor: help;\n}\n\n.spacer {\n margin-left: auto;\n}\n\n/* The gap moves into each item's padding so a hairline sits halfway between\n two of them. */\n.divided {\n gap: 0;\n}\n.divided > .item {\n padding: 0 calc(var(--wzl-space-8) / 2);\n}\n.divided > .item + .item {\n border-left: 1px solid var(--wzl-line-subtle);\n}\n","import type { ReactNode } from 'react';\nimport s from './StatusBar.module.css';\n\n/** Props for {@link StatusBar}. */\nexport interface StatusBarProps {\n /**\n * Accessible label for the bar. Deliberately not a live region — a status\n * bar's readouts change on every pointer move (zoom, cursor position,\n * selection count), and announcing each one would make a screen reader\n * unusable. Screen-reader users reach the same facts through the controls\n * that own them.\n */\n ariaLabel?: string;\n /** Draw a hairline between neighboring items. A spacer stands in for one. */\n divided?: boolean;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * The thin readout strip along the bottom of an editor window: monospace,\n * one row, items separated by a fixed gap, with an optional spacer that\n * pushes everything after it to the trailing edge.\n *\n * Pure presentation — it holds whatever the app puts in it. Compose with\n * `<StatusBarItem>` and `<StatusBarSpacer>`.\n */\nexport function StatusBar(props: StatusBarProps) {\n const { ariaLabel, divided, children, className } = props;\n return (\n <footer className={[s.bar, divided && s.divided, className].filter(Boolean).join(' ')} aria-label={ariaLabel}>\n {children}\n </footer>\n );\n}\n\n/** Props for {@link StatusBarItem}. */\nexport interface StatusBarItemProps {\n /**\n * Hover text. Items that carry one also get a `help` cursor, so the\n * affordance is discoverable rather than hidden behind a hover delay.\n */\n title?: string;\n /**\n * Dim the item. For reference material that\n * shouldn't compete with live readouts — build stamps, hints, units.\n */\n muted?: boolean;\n children?: ReactNode;\n className?: string;\n}\n\n/** One readout in a `<StatusBar>`. */\nexport function StatusBarItem(props: StatusBarItemProps) {\n const { title, muted, children, className } = props;\n const cls = [s.item, muted && s.muted, title !== undefined && s.hasTitle, className]\n .filter(Boolean).join(' ');\n return <span className={cls} title={title}>{children}</span>;\n}\n\n/**\n * Splits a status bar into leading and trailing runs — everything after the\n * spacer is pushed to the trailing edge. Decorative, so it's hidden from the\n * accessibility tree.\n */\nexport function StatusBarSpacer() {\n return <span className={s.spacer} aria-hidden=\"true\" />;\n}\n"],"mappings":";;;;;;;;;;;AC2BA,SAAgBE,EAAU,GAAuB;CAC/C,IAAM,EAAE,cAAW,YAAS,aAAU,iBAAcC;CACpD,OACE,kBAAC,UAAD;EAAQ,WAAW;GAACH,EAAE;GAAKI,KAAWJ,EAAE;GAASK;EAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAAG,cAAYC;EAChG;CACK,CAAA;AAEZ;AAmBA,SAAgBC,EAAc,GAA2B;CACvD,IAAM,EAAE,UAAO,UAAO,aAAU,iBAAcJ,GACxCK,IAAM;EAACR,EAAE;EAAMS,KAAST,EAAE;EAAOU,MAAU,KAAA,KAAaV,EAAE;EAAUK;CAAS,CAAC,CACjF,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAC3B,OAAO,kBAAC,QAAD;EAAM,WAAWG;EAAY;EAAQ;CAAe,CAAA;AAC7D;AAOA,SAAgBG,IAAkB;CAChC,OAAO,kBAAC,QAAD;EAAM,WAAWX,EAAE;EAAQ,eAAY;CAAQ,CAAA;AACxD"}
@@ -1,5 +1,5 @@
1
1
  import { n as e, o as t, r as n, t as r } from "./RecentColorsProvider-DHcfk25u.js";
2
- import { t as i } from "./Select-ouV8O6cp.js";
2
+ import { t as i } from "./Select-BhHwjNsb.js";
3
3
  import { t as a } from "./SwatchGrid-DxK9e_IV.js";
4
4
  import { getAlpha01 as o } from "@weasel-js/core";
5
5
  import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
@@ -574,4 +574,4 @@ function v(t) {
574
574
  //#endregion
575
575
  export { f as a, m as i, g as n, p as r, v as t };
576
576
 
577
- //# sourceMappingURL=SwatchStrip-BY6A511W.js.map
577
+ //# sourceMappingURL=SwatchStrip-D7YNn_p0.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SwatchStrip-BY6A511W.js","names":["_Fragment","s","useRecentColors","normalizeRecentColor","useRecentColorsStore","RecentColorsProvider","Select","SwatchGrid","STANDARD_PALETTE","BASIC_PALETTE","BUILTIN_PALETTES","SwatchStrip_module_default","describeColor","c","color","alpha","getAlpha01","same","a","b","SwatchStrip","props","palettes","columns","ctxStore","store","recent","recentHeading","useId","ownPalette","setOwnPalette","useState","paletteId","shown","p","choosePalette","id","recentOptions","currentIn","value","options","o","grids","Fragment","className"],"sources":["../../src/components/SwatchStrip/palettes.ts","../../src/components/SwatchStrip/SwatchStrip.module.css","../../src/components/SwatchStrip/SwatchStrip.tsx"],"sourcesContent":["import type { SwatchGridOption } from '../SwatchGrid';\n\n/** A named set of swatches offered by {@link SwatchStrip}. */\nexport interface SwatchPalette {\n /** Stable key, for the palette choice and for React. */\n id: string;\n /** What the palette picker shows. */\n name: string;\n /** `value: null` is the \"no paint\" swatch. Each `label` is the swatch's\n * accessible name, so it should say the color. */\n colors: readonly SwatchGridOption[];\n /** Swatches per row. Default: the strip's `columns`. */\n columns?: number;\n}\n\n/** No paint, the named primaries and secondaries, a gray ramp, and eight hue\n * ramps of ten shades each (50 → 900). */\nexport const STANDARD_PALETTE: SwatchPalette = {\n id: 'standard',\n name: 'Standard',\n columns: 10,\n colors: [\n { value: null, label: 'None' },\n { value: '#ffffffff', label: 'White' },\n { value: '#000000ff', label: 'Black' },\n { value: '#ff0000ff', label: 'Red' },\n { value: '#00ff00ff', label: 'Green' },\n { value: '#0000ffff', label: 'Blue' },\n { value: '#00ffffff', label: 'Cyan' },\n { value: '#ff00ffff', label: 'Magenta' },\n { value: '#ffff00ff', label: 'Yellow' },\n { value: '#ff8800ff', label: 'Orange' },\n { value: '#fafafaff', label: 'Gray 50' },\n { value: '#f5f5f5ff', label: 'Gray 100' },\n { value: '#e5e5e5ff', label: 'Gray 200' },\n { value: '#d4d4d4ff', label: 'Gray 300' },\n { value: '#a3a3a3ff', label: 'Gray 400' },\n { value: '#737373ff', label: 'Gray 500' },\n { value: '#525252ff', label: 'Gray 600' },\n { value: '#404040ff', label: 'Gray 700' },\n { value: '#262626ff', label: 'Gray 800' },\n { value: '#171717ff', label: 'Gray 900' },\n { value: '#fef2f2ff', label: 'Red 50' },\n { value: '#fee2e2ff', label: 'Red 100' },\n { value: '#fecacaff', label: 'Red 200' },\n { value: '#fca5a5ff', label: 'Red 300' },\n { value: '#f87171ff', label: 'Red 400' },\n { value: '#ef4444ff', label: 'Red 500' },\n { value: '#dc2626ff', label: 'Red 600' },\n { value: '#b91c1cff', label: 'Red 700' },\n { value: '#991b1bff', label: 'Red 800' },\n { value: '#7f1d1dff', label: 'Red 900' },\n { value: '#fff7edff', label: 'Orange 50' },\n { value: '#ffedd5ff', label: 'Orange 100' },\n { value: '#fed7aaff', label: 'Orange 200' },\n { value: '#fdba74ff', label: 'Orange 300' },\n { value: '#fb923cff', label: 'Orange 400' },\n { value: '#f97316ff', label: 'Orange 500' },\n { value: '#ea580cff', label: 'Orange 600' },\n { value: '#c2410cff', label: 'Orange 700' },\n { value: '#9a3412ff', label: 'Orange 800' },\n { value: '#7c2d12ff', label: 'Orange 900' },\n { value: '#fefce8ff', label: 'Yellow 50' },\n { value: '#fef9c3ff', label: 'Yellow 100' },\n { value: '#fef08aff', label: 'Yellow 200' },\n { value: '#fde047ff', label: 'Yellow 300' },\n { value: '#facc15ff', label: 'Yellow 400' },\n { value: '#eab308ff', label: 'Yellow 500' },\n { value: '#ca8a04ff', label: 'Yellow 600' },\n { value: '#a16207ff', label: 'Yellow 700' },\n { value: '#854d0eff', label: 'Yellow 800' },\n { value: '#713f12ff', label: 'Yellow 900' },\n { value: '#f0fdf4ff', label: 'Green 50' },\n { value: '#dcfce7ff', label: 'Green 100' },\n { value: '#bbf7d0ff', label: 'Green 200' },\n { value: '#86efacff', label: 'Green 300' },\n { value: '#4ade80ff', label: 'Green 400' },\n { value: '#22c55eff', label: 'Green 500' },\n { value: '#16a34aff', label: 'Green 600' },\n { value: '#15803dff', label: 'Green 700' },\n { value: '#166534ff', label: 'Green 800' },\n { value: '#14532dff', label: 'Green 900' },\n { value: '#ecfeffff', label: 'Cyan 50' },\n { value: '#cffafeff', label: 'Cyan 100' },\n { value: '#a5f3fcff', label: 'Cyan 200' },\n { value: '#67e8f9ff', label: 'Cyan 300' },\n { value: '#22d3eeff', label: 'Cyan 400' },\n { value: '#06b6d4ff', label: 'Cyan 500' },\n { value: '#0891b2ff', label: 'Cyan 600' },\n { value: '#0e7490ff', label: 'Cyan 700' },\n { value: '#155e75ff', label: 'Cyan 800' },\n { value: '#164e63ff', label: 'Cyan 900' },\n { value: '#eff6ffff', label: 'Blue 50' },\n { value: '#dbeafeff', label: 'Blue 100' },\n { value: '#bfdbfeff', label: 'Blue 200' },\n { value: '#93c5fdff', label: 'Blue 300' },\n { value: '#60a5faff', label: 'Blue 400' },\n { value: '#3b82f6ff', label: 'Blue 500' },\n { value: '#2563ebff', label: 'Blue 600' },\n { value: '#1d4ed8ff', label: 'Blue 700' },\n { value: '#1e40afff', label: 'Blue 800' },\n { value: '#1e3a8aff', label: 'Blue 900' },\n { value: '#faf5ffff', label: 'Purple 50' },\n { value: '#f3e8ffff', label: 'Purple 100' },\n { value: '#e9d5ffff', label: 'Purple 200' },\n { value: '#d8b4feff', label: 'Purple 300' },\n { value: '#c084fcff', label: 'Purple 400' },\n { value: '#a855f7ff', label: 'Purple 500' },\n { value: '#9333eaff', label: 'Purple 600' },\n { value: '#7e22ceff', label: 'Purple 700' },\n { value: '#6b21a8ff', label: 'Purple 800' },\n { value: '#581c87ff', label: 'Purple 900' },\n { value: '#fdf2f8ff', label: 'Pink 50' },\n { value: '#fce7f3ff', label: 'Pink 100' },\n { value: '#fbcfe8ff', label: 'Pink 200' },\n { value: '#f9a8d4ff', label: 'Pink 300' },\n { value: '#f472b6ff', label: 'Pink 400' },\n { value: '#ec4899ff', label: 'Pink 500' },\n { value: '#db2777ff', label: 'Pink 600' },\n { value: '#be185dff', label: 'Pink 700' },\n { value: '#9d174dff', label: 'Pink 800' },\n { value: '#831843ff', label: 'Pink 900' },\n ],\n};\n\n/** No paint and CSS's basic named colors, with pink and brown. */\nexport const BASIC_PALETTE: SwatchPalette = {\n id: 'basic',\n name: 'Basic',\n columns: 10,\n colors: [\n { value: null, label: 'None' },\n { value: '#000000ff', label: 'Black' },\n { value: '#ffffffff', label: 'White' },\n { value: '#808080ff', label: 'Gray' },\n { value: '#c0c0c0ff', label: 'Silver' },\n { value: '#800000ff', label: 'Maroon' },\n { value: '#ff0000ff', label: 'Red' },\n { value: '#ffa500ff', label: 'Orange' },\n { value: '#ffff00ff', label: 'Yellow' },\n { value: '#808000ff', label: 'Olive' },\n { value: '#00ff00ff', label: 'Lime' },\n { value: '#008000ff', label: 'Green' },\n { value: '#008080ff', label: 'Teal' },\n { value: '#00ffffff', label: 'Cyan' },\n { value: '#000080ff', label: 'Navy' },\n { value: '#0000ffff', label: 'Blue' },\n { value: '#800080ff', label: 'Purple' },\n { value: '#ff00ffff', label: 'Magenta' },\n { value: '#ffc0cbff', label: 'Pink' },\n { value: '#a52a2aff', label: 'Brown' },\n ],\n};\n\n/** What {@link SwatchStrip} offers when given no `palettes`. */\nexport const BUILTIN_PALETTES: readonly SwatchPalette[] = [STANDARD_PALETTE, BASIC_PALETTE];\n",".root {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-3);\n min-inline-size: 0;\n}\n\n.section {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-1);\n min-inline-size: 0;\n}\n\n.heading {\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size-xs);\n font-weight: var(--wzl-font-weight-medium);\n text-transform: var(--wzl-params-label-case, uppercase);\n letter-spacing: var(--wzl-params-label-tracking, var(--wzl-tracking-wide));\n color: var(--wzl-fg-muted);\n}\n\n.empty {\n margin: 0;\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n}\n","import { useId, useState, type ReactElement } from 'react';\nimport { getAlpha01 } from '@weasel-js/core';\nimport { SwatchGrid, type SwatchGridOption } from '../SwatchGrid';\nimport { Select } from '../Select';\nimport {\n RecentColorsProvider,\n normalizeRecentColor,\n useRecentColors,\n useRecentColorsStore,\n type RecentColorsStore,\n} from '../RecentColors';\nimport { BUILTIN_PALETTES, type SwatchPalette } from './palettes';\nimport s from './SwatchStrip.module.css';\n\n/** Props for {@link SwatchStrip}. */\nexport interface SwatchStripProps {\n /** The color to mark current, in either row. `null` marks \"no paint\". */\n value?: string | null;\n /** A swatch applied: click, Enter or Space. */\n onChange: (value: string | null) => void;\n /** The alternate target, as on {@link SwatchGrid}: shift-click,\n * right-click, Shift+Enter. */\n onAltChange?: (value: string | null) => void;\n /** The preset palettes on offer. Default {@link BUILTIN_PALETTES}. More\n * than one adds a picker. */\n palettes?: readonly SwatchPalette[];\n /** The shown palette's id, controlled. */\n palette?: string;\n /** The shown palette's id to start on, uncontrolled. Default: the first. */\n defaultPalette?: string;\n onPaletteChange?: (id: string) => void;\n /** Where the recent row reads from and applies record into. Default: the\n * nearest {@link RecentColorsProvider}'s. With neither there is no recent\n * row. */\n store?: RecentColorsStore;\n /** Swatches per row, for the recent row and any palette that sets none.\n * Default 10. */\n columns?: number;\n 'aria-label'?: string;\n className?: string;\n}\n\n/** A color as a screen reader should hear it: the hex, and the opacity\n * when it is not opaque. Any other CSS color reads as written. */\nexport function describeColor(color: string): string {\n const c = normalizeRecentColor(color) ?? color;\n if (!c.startsWith('#') || c.length !== 9) return c;\n const alpha = Math.round(getAlpha01(c) * 100);\n return alpha === 100 ? c.slice(0, 7) : `${c.slice(0, 7)}, ${alpha}% opacity`;\n}\n\nfunction same(a: string | null, b: string | null): boolean {\n if (a === null || b === null) return a === b;\n return normalizeRecentColor(a) === normalizeRecentColor(b);\n}\n\n/**\n * The swatches a color picker sits beside: the recently used colors, most\n * recent first, above a preset palette. Applying any swatch records it, so\n * it moves to the head of the recent row — as does a color committed\n * through any other picker under the same {@link RecentColorsProvider}.\n *\n * Like {@link SwatchGrid} it applies nothing itself; `onChange` and\n * `onAltChange` hand the color to the app.\n */\nexport function SwatchStrip(props: SwatchStripProps): ReactElement {\n const { value, onChange, onAltChange, className } = props;\n const palettes = props.palettes ?? BUILTIN_PALETTES;\n const columns = props.columns ?? 10;\n const ctxStore = useRecentColorsStore();\n const store = props.store ?? ctxStore;\n const recent = useRecentColors(store);\n const recentHeading = useId();\n\n const [ownPalette, setOwnPalette] = useState(props.defaultPalette);\n const paletteId = props.palette ?? ownPalette;\n const shown = palettes.find((p) => p.id === paletteId) ?? palettes[0];\n const choosePalette = (id: string): void => {\n setOwnPalette(id);\n props.onPaletteChange?.(id);\n };\n\n const recentOptions: SwatchGridOption[] = recent.map((c) => ({ value: c, label: describeColor(c) }));\n // Match on the color, not its spelling, so `#F00` lights `#ff0000ff`.\n const currentIn = (options: readonly SwatchGridOption[]): string | null | undefined =>\n value === undefined ? undefined : options.find((o) => same(o.value, value))?.value;\n\n const grids = (\n <>\n {store && (\n <section className={s.section} aria-labelledby={recentHeading}>\n <div id={recentHeading} className={s.heading}>Recent</div>\n {recentOptions.length > 0 ? (\n <SwatchGrid\n aria-label=\"Recent colors\"\n options={recentOptions}\n value={currentIn(recentOptions)}\n columns={columns}\n onChange={onChange}\n onAltChange={onAltChange}\n />\n ) : (\n <p className={s.empty}>No recent colors</p>\n )}\n </section>\n )}\n {shown && (\n <section className={s.section}>\n {palettes.length > 1 ? (\n <Select<string>\n label=\"Palette\"\n orientation=\"row\"\n options={palettes.map((p) => ({ value: p.id, label: p.name }))}\n selectedKey={shown.id}\n onSelectionChange={choosePalette}\n />\n ) : (\n <div className={s.heading}>{shown.name}</div>\n )}\n <SwatchGrid\n key={shown.id}\n aria-label={shown.name}\n options={shown.colors}\n value={currentIn(shown.colors)}\n columns={shown.columns ?? columns}\n onChange={onChange}\n onAltChange={onAltChange}\n />\n </section>\n )}\n </>\n );\n\n return (\n <div\n className={[s.root, className].filter(Boolean).join(' ')}\n role=\"group\"\n aria-label={props['aria-label'] ?? 'Swatches'}\n >\n {/* A store given by prop is where applies here record too. */}\n {props.store && props.store !== ctxStore\n ? <RecentColorsProvider store={props.store}>{grids}</RecentColorsProvider>\n : grids}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SwatchStrip-D7YNn_p0.js","names":["_Fragment","s","useRecentColors","normalizeRecentColor","useRecentColorsStore","RecentColorsProvider","Select","SwatchGrid","STANDARD_PALETTE","BASIC_PALETTE","BUILTIN_PALETTES","SwatchStrip_module_default","describeColor","c","color","alpha","getAlpha01","same","a","b","SwatchStrip","props","palettes","columns","ctxStore","store","recent","recentHeading","useId","ownPalette","setOwnPalette","useState","paletteId","shown","p","choosePalette","id","recentOptions","currentIn","value","options","o","grids","Fragment","className"],"sources":["../../src/components/SwatchStrip/palettes.ts","../../src/components/SwatchStrip/SwatchStrip.module.css","../../src/components/SwatchStrip/SwatchStrip.tsx"],"sourcesContent":["import type { SwatchGridOption } from '../SwatchGrid';\n\n/** A named set of swatches offered by {@link SwatchStrip}. */\nexport interface SwatchPalette {\n /** Stable key, for the palette choice and for React. */\n id: string;\n /** What the palette picker shows. */\n name: string;\n /** `value: null` is the \"no paint\" swatch. Each `label` is the swatch's\n * accessible name, so it should say the color. */\n colors: readonly SwatchGridOption[];\n /** Swatches per row. Default: the strip's `columns`. */\n columns?: number;\n}\n\n/** No paint, the named primaries and secondaries, a gray ramp, and eight hue\n * ramps of ten shades each (50 → 900). */\nexport const STANDARD_PALETTE: SwatchPalette = {\n id: 'standard',\n name: 'Standard',\n columns: 10,\n colors: [\n { value: null, label: 'None' },\n { value: '#ffffffff', label: 'White' },\n { value: '#000000ff', label: 'Black' },\n { value: '#ff0000ff', label: 'Red' },\n { value: '#00ff00ff', label: 'Green' },\n { value: '#0000ffff', label: 'Blue' },\n { value: '#00ffffff', label: 'Cyan' },\n { value: '#ff00ffff', label: 'Magenta' },\n { value: '#ffff00ff', label: 'Yellow' },\n { value: '#ff8800ff', label: 'Orange' },\n { value: '#fafafaff', label: 'Gray 50' },\n { value: '#f5f5f5ff', label: 'Gray 100' },\n { value: '#e5e5e5ff', label: 'Gray 200' },\n { value: '#d4d4d4ff', label: 'Gray 300' },\n { value: '#a3a3a3ff', label: 'Gray 400' },\n { value: '#737373ff', label: 'Gray 500' },\n { value: '#525252ff', label: 'Gray 600' },\n { value: '#404040ff', label: 'Gray 700' },\n { value: '#262626ff', label: 'Gray 800' },\n { value: '#171717ff', label: 'Gray 900' },\n { value: '#fef2f2ff', label: 'Red 50' },\n { value: '#fee2e2ff', label: 'Red 100' },\n { value: '#fecacaff', label: 'Red 200' },\n { value: '#fca5a5ff', label: 'Red 300' },\n { value: '#f87171ff', label: 'Red 400' },\n { value: '#ef4444ff', label: 'Red 500' },\n { value: '#dc2626ff', label: 'Red 600' },\n { value: '#b91c1cff', label: 'Red 700' },\n { value: '#991b1bff', label: 'Red 800' },\n { value: '#7f1d1dff', label: 'Red 900' },\n { value: '#fff7edff', label: 'Orange 50' },\n { value: '#ffedd5ff', label: 'Orange 100' },\n { value: '#fed7aaff', label: 'Orange 200' },\n { value: '#fdba74ff', label: 'Orange 300' },\n { value: '#fb923cff', label: 'Orange 400' },\n { value: '#f97316ff', label: 'Orange 500' },\n { value: '#ea580cff', label: 'Orange 600' },\n { value: '#c2410cff', label: 'Orange 700' },\n { value: '#9a3412ff', label: 'Orange 800' },\n { value: '#7c2d12ff', label: 'Orange 900' },\n { value: '#fefce8ff', label: 'Yellow 50' },\n { value: '#fef9c3ff', label: 'Yellow 100' },\n { value: '#fef08aff', label: 'Yellow 200' },\n { value: '#fde047ff', label: 'Yellow 300' },\n { value: '#facc15ff', label: 'Yellow 400' },\n { value: '#eab308ff', label: 'Yellow 500' },\n { value: '#ca8a04ff', label: 'Yellow 600' },\n { value: '#a16207ff', label: 'Yellow 700' },\n { value: '#854d0eff', label: 'Yellow 800' },\n { value: '#713f12ff', label: 'Yellow 900' },\n { value: '#f0fdf4ff', label: 'Green 50' },\n { value: '#dcfce7ff', label: 'Green 100' },\n { value: '#bbf7d0ff', label: 'Green 200' },\n { value: '#86efacff', label: 'Green 300' },\n { value: '#4ade80ff', label: 'Green 400' },\n { value: '#22c55eff', label: 'Green 500' },\n { value: '#16a34aff', label: 'Green 600' },\n { value: '#15803dff', label: 'Green 700' },\n { value: '#166534ff', label: 'Green 800' },\n { value: '#14532dff', label: 'Green 900' },\n { value: '#ecfeffff', label: 'Cyan 50' },\n { value: '#cffafeff', label: 'Cyan 100' },\n { value: '#a5f3fcff', label: 'Cyan 200' },\n { value: '#67e8f9ff', label: 'Cyan 300' },\n { value: '#22d3eeff', label: 'Cyan 400' },\n { value: '#06b6d4ff', label: 'Cyan 500' },\n { value: '#0891b2ff', label: 'Cyan 600' },\n { value: '#0e7490ff', label: 'Cyan 700' },\n { value: '#155e75ff', label: 'Cyan 800' },\n { value: '#164e63ff', label: 'Cyan 900' },\n { value: '#eff6ffff', label: 'Blue 50' },\n { value: '#dbeafeff', label: 'Blue 100' },\n { value: '#bfdbfeff', label: 'Blue 200' },\n { value: '#93c5fdff', label: 'Blue 300' },\n { value: '#60a5faff', label: 'Blue 400' },\n { value: '#3b82f6ff', label: 'Blue 500' },\n { value: '#2563ebff', label: 'Blue 600' },\n { value: '#1d4ed8ff', label: 'Blue 700' },\n { value: '#1e40afff', label: 'Blue 800' },\n { value: '#1e3a8aff', label: 'Blue 900' },\n { value: '#faf5ffff', label: 'Purple 50' },\n { value: '#f3e8ffff', label: 'Purple 100' },\n { value: '#e9d5ffff', label: 'Purple 200' },\n { value: '#d8b4feff', label: 'Purple 300' },\n { value: '#c084fcff', label: 'Purple 400' },\n { value: '#a855f7ff', label: 'Purple 500' },\n { value: '#9333eaff', label: 'Purple 600' },\n { value: '#7e22ceff', label: 'Purple 700' },\n { value: '#6b21a8ff', label: 'Purple 800' },\n { value: '#581c87ff', label: 'Purple 900' },\n { value: '#fdf2f8ff', label: 'Pink 50' },\n { value: '#fce7f3ff', label: 'Pink 100' },\n { value: '#fbcfe8ff', label: 'Pink 200' },\n { value: '#f9a8d4ff', label: 'Pink 300' },\n { value: '#f472b6ff', label: 'Pink 400' },\n { value: '#ec4899ff', label: 'Pink 500' },\n { value: '#db2777ff', label: 'Pink 600' },\n { value: '#be185dff', label: 'Pink 700' },\n { value: '#9d174dff', label: 'Pink 800' },\n { value: '#831843ff', label: 'Pink 900' },\n ],\n};\n\n/** No paint and CSS's basic named colors, with pink and brown. */\nexport const BASIC_PALETTE: SwatchPalette = {\n id: 'basic',\n name: 'Basic',\n columns: 10,\n colors: [\n { value: null, label: 'None' },\n { value: '#000000ff', label: 'Black' },\n { value: '#ffffffff', label: 'White' },\n { value: '#808080ff', label: 'Gray' },\n { value: '#c0c0c0ff', label: 'Silver' },\n { value: '#800000ff', label: 'Maroon' },\n { value: '#ff0000ff', label: 'Red' },\n { value: '#ffa500ff', label: 'Orange' },\n { value: '#ffff00ff', label: 'Yellow' },\n { value: '#808000ff', label: 'Olive' },\n { value: '#00ff00ff', label: 'Lime' },\n { value: '#008000ff', label: 'Green' },\n { value: '#008080ff', label: 'Teal' },\n { value: '#00ffffff', label: 'Cyan' },\n { value: '#000080ff', label: 'Navy' },\n { value: '#0000ffff', label: 'Blue' },\n { value: '#800080ff', label: 'Purple' },\n { value: '#ff00ffff', label: 'Magenta' },\n { value: '#ffc0cbff', label: 'Pink' },\n { value: '#a52a2aff', label: 'Brown' },\n ],\n};\n\n/** What {@link SwatchStrip} offers when given no `palettes`. */\nexport const BUILTIN_PALETTES: readonly SwatchPalette[] = [STANDARD_PALETTE, BASIC_PALETTE];\n",".root {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-3);\n min-inline-size: 0;\n}\n\n.section {\n display: flex;\n flex-direction: column;\n gap: var(--wzl-space-1);\n min-inline-size: 0;\n}\n\n.heading {\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size-xs);\n font-weight: var(--wzl-font-weight-medium);\n text-transform: var(--wzl-params-label-case, uppercase);\n letter-spacing: var(--wzl-params-label-tracking, var(--wzl-tracking-wide));\n color: var(--wzl-fg-muted);\n}\n\n.empty {\n margin: 0;\n font-family: var(--wzl-font-ui);\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n}\n","import { useId, useState, type ReactElement } from 'react';\nimport { getAlpha01 } from '@weasel-js/core';\nimport { SwatchGrid, type SwatchGridOption } from '../SwatchGrid';\nimport { Select } from '../Select';\nimport {\n RecentColorsProvider,\n normalizeRecentColor,\n useRecentColors,\n useRecentColorsStore,\n type RecentColorsStore,\n} from '../RecentColors';\nimport { BUILTIN_PALETTES, type SwatchPalette } from './palettes';\nimport s from './SwatchStrip.module.css';\n\n/** Props for {@link SwatchStrip}. */\nexport interface SwatchStripProps {\n /** The color to mark current, in either row. `null` marks \"no paint\". */\n value?: string | null;\n /** A swatch applied: click, Enter or Space. */\n onChange: (value: string | null) => void;\n /** The alternate target, as on {@link SwatchGrid}: shift-click,\n * right-click, Shift+Enter. */\n onAltChange?: (value: string | null) => void;\n /** The preset palettes on offer. Default {@link BUILTIN_PALETTES}. More\n * than one adds a picker. */\n palettes?: readonly SwatchPalette[];\n /** The shown palette's id, controlled. */\n palette?: string;\n /** The shown palette's id to start on, uncontrolled. Default: the first. */\n defaultPalette?: string;\n onPaletteChange?: (id: string) => void;\n /** Where the recent row reads from and applies record into. Default: the\n * nearest {@link RecentColorsProvider}'s. With neither there is no recent\n * row. */\n store?: RecentColorsStore;\n /** Swatches per row, for the recent row and any palette that sets none.\n * Default 10. */\n columns?: number;\n 'aria-label'?: string;\n className?: string;\n}\n\n/** A color as a screen reader should hear it: the hex, and the opacity\n * when it is not opaque. Any other CSS color reads as written. */\nexport function describeColor(color: string): string {\n const c = normalizeRecentColor(color) ?? color;\n if (!c.startsWith('#') || c.length !== 9) return c;\n const alpha = Math.round(getAlpha01(c) * 100);\n return alpha === 100 ? c.slice(0, 7) : `${c.slice(0, 7)}, ${alpha}% opacity`;\n}\n\nfunction same(a: string | null, b: string | null): boolean {\n if (a === null || b === null) return a === b;\n return normalizeRecentColor(a) === normalizeRecentColor(b);\n}\n\n/**\n * The swatches a color picker sits beside: the recently used colors, most\n * recent first, above a preset palette. Applying any swatch records it, so\n * it moves to the head of the recent row — as does a color committed\n * through any other picker under the same {@link RecentColorsProvider}.\n *\n * Like {@link SwatchGrid} it applies nothing itself; `onChange` and\n * `onAltChange` hand the color to the app.\n */\nexport function SwatchStrip(props: SwatchStripProps): ReactElement {\n const { value, onChange, onAltChange, className } = props;\n const palettes = props.palettes ?? BUILTIN_PALETTES;\n const columns = props.columns ?? 10;\n const ctxStore = useRecentColorsStore();\n const store = props.store ?? ctxStore;\n const recent = useRecentColors(store);\n const recentHeading = useId();\n\n const [ownPalette, setOwnPalette] = useState(props.defaultPalette);\n const paletteId = props.palette ?? ownPalette;\n const shown = palettes.find((p) => p.id === paletteId) ?? palettes[0];\n const choosePalette = (id: string): void => {\n setOwnPalette(id);\n props.onPaletteChange?.(id);\n };\n\n const recentOptions: SwatchGridOption[] = recent.map((c) => ({ value: c, label: describeColor(c) }));\n // Match on the color, not its spelling, so `#F00` lights `#ff0000ff`.\n const currentIn = (options: readonly SwatchGridOption[]): string | null | undefined =>\n value === undefined ? undefined : options.find((o) => same(o.value, value))?.value;\n\n const grids = (\n <>\n {store && (\n <section className={s.section} aria-labelledby={recentHeading}>\n <div id={recentHeading} className={s.heading}>Recent</div>\n {recentOptions.length > 0 ? (\n <SwatchGrid\n aria-label=\"Recent colors\"\n options={recentOptions}\n value={currentIn(recentOptions)}\n columns={columns}\n onChange={onChange}\n onAltChange={onAltChange}\n />\n ) : (\n <p className={s.empty}>No recent colors</p>\n )}\n </section>\n )}\n {shown && (\n <section className={s.section}>\n {palettes.length > 1 ? (\n <Select<string>\n label=\"Palette\"\n orientation=\"row\"\n options={palettes.map((p) => ({ value: p.id, label: p.name }))}\n selectedKey={shown.id}\n onSelectionChange={choosePalette}\n />\n ) : (\n <div className={s.heading}>{shown.name}</div>\n )}\n <SwatchGrid\n key={shown.id}\n aria-label={shown.name}\n options={shown.colors}\n value={currentIn(shown.colors)}\n columns={shown.columns ?? columns}\n onChange={onChange}\n onAltChange={onAltChange}\n />\n </section>\n )}\n </>\n );\n\n return (\n <div\n className={[s.root, className].filter(Boolean).join(' ')}\n role=\"group\"\n aria-label={props['aria-label'] ?? 'Swatches'}\n >\n {/* A store given by prop is where applies here record too. */}\n {props.store && props.store !== ctxStore\n ? <RecentColorsProvider store={props.store}>{grids}</RecentColorsProvider>\n : grids}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,21 +1,21 @@
1
- import { $ as e, Q as t, Z as n } from "./icons-CofIOTiI.js";
2
- import { t as r } from "./Button-XB-T75YL.js";
1
+ import { et as e, nt as t, tt as n } from "./icons-B_fPKEis.js";
2
+ import { t as r } from "./Button-CQA-K1g9.js";
3
3
  import { jsx as i } from "react/jsx-runtime";
4
4
  //#region src/components/ThemeSwitcher/ThemeSwitcher.tsx
5
5
  var a = [
6
6
  {
7
7
  value: "auto",
8
- icon: /* @__PURE__ */ i(n, { size: 16 }),
8
+ icon: /* @__PURE__ */ i(e, { size: 16 }),
9
9
  label: "Auto"
10
10
  },
11
11
  {
12
12
  value: "light",
13
- icon: /* @__PURE__ */ i(e, { size: 16 }),
13
+ icon: /* @__PURE__ */ i(t, { size: 16 }),
14
14
  label: "Light"
15
15
  },
16
16
  {
17
17
  value: "dark",
18
- icon: /* @__PURE__ */ i(t, { size: 16 }),
18
+ icon: /* @__PURE__ */ i(n, { size: 16 }),
19
19
  label: "Dark"
20
20
  }
21
21
  ];
@@ -35,4 +35,4 @@ function o({ value: e, onChange: t, options: n = a, ariaLabel: o = "Theme", size
35
35
  //#endregion
36
36
  export { o as n, a as t };
37
37
 
38
- //# sourceMappingURL=ThemeSwitcher-tnATkIo1.js.map
38
+ //# sourceMappingURL=ThemeSwitcher-BJWP1l87.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeSwitcher-tnATkIo1.js","names":["ModeLightIcon","ModeDarkIcon","ModeAutoIcon","Button","COLOR_MODE_OPTIONS","ThemeSwitcher","count","options","index","o","value","current","next","previous","name","ariaLabel","onChange","event"],"sources":["../../src/components/ThemeSwitcher/ThemeSwitcher.tsx"],"sourcesContent":["import type { ReactElement, ReactNode } from 'react';\nimport type { ColorModePreference } from '@weasel-js/theme';\nimport { ModeAutoIcon, ModeDarkIcon, ModeLightIcon } from '../../icons';\nimport { Button, type ButtonSize, type ButtonVariant } from '../Button/Button';\n\n/** One stop in a {@link ThemeSwitcher}'s rotation. */\nexport interface ThemeSwitcherOption<T extends string = string> {\n value: T;\n /** Drawn in the button while this option is current. */\n icon: ReactNode;\n /** The option's name, read in the accessible name and tooltip. */\n label: string;\n}\n\n/** The color modes, in rotation order, as {@link ThemeSwitcher} cycles them by default. */\nexport const COLOR_MODE_OPTIONS: readonly ThemeSwitcherOption<ColorModePreference>[] = [\n { value: 'auto', icon: <ModeAutoIcon size={16} />, label: 'Auto' },\n { value: 'light', icon: <ModeLightIcon size={16} />, label: 'Light' },\n { value: 'dark', icon: <ModeDarkIcon size={16} />, label: 'Dark' },\n];\n\n/** Props for {@link ThemeSwitcher}. */\nexport interface ThemeSwitcherProps<T extends string = ColorModePreference> {\n value: T;\n onChange: (next: T) => void;\n /** The rotation, in order. Defaults to {@link COLOR_MODE_OPTIONS}. */\n options?: readonly ThemeSwitcherOption<T>[];\n /** What is being switched, leading the accessible name and tooltip\n * (`Theme: Auto — click for Light`). Defaults to `'Theme'`. */\n ariaLabel?: string;\n /** Defaults to `sm`, the size of a header's icon buttons. */\n size?: ButtonSize;\n /** Defaults to `ghost`. */\n variant?: ButtonVariant;\n className?: string;\n}\n\n/**\n * One icon button that steps through a list of options: a click moves to the\n * next, a shift-click to the previous, both wrapping. It shows the current\n * option's icon, and its name and tooltip say what is current and what a\n * click chooses. The compact alternative to `ColorModeControl`'s three\n * segments. Controlled: pair the default color modes with\n * `useColorModePreference` from `@weasel-js/theme/react`.\n */\nexport function ThemeSwitcher<T extends string = ColorModePreference>({\n value,\n onChange,\n options = COLOR_MODE_OPTIONS as unknown as readonly ThemeSwitcherOption<T>[],\n ariaLabel = 'Theme',\n size = 'sm',\n variant = 'ghost',\n className,\n}: ThemeSwitcherProps<T>): ReactElement {\n const count = options.length;\n const index = Math.max(0, options.findIndex((o) => o.value === value));\n const current = options[index];\n const next = options[(index + 1) % count];\n const previous = options[(index - 1 + count) % count];\n const name = `${ariaLabel}: ${current.label} — click for ${next.label}`;\n\n return (\n <Button\n variant={variant}\n size={size}\n iconOnly\n ariaLabel={name}\n tooltip={name}\n className={className}\n onClick={(event) => onChange((event.shiftKey ? previous : next).value)}\n >\n {current.icon}\n </Button>\n );\n}\n"],"mappings":";;;;AAeA,IAAaI,IAA0E;CACrF;EAAE,OAAO;EAAQ,MAAM,kBAACF,GAAD,EAAc,MAAM,GAAK,CAAA;EAAG,OAAO;CAAO;CACjE;EAAE,OAAO;EAAS,MAAM,kBAACF,GAAD,EAAe,MAAM,GAAK,CAAA;EAAG,OAAO;CAAQ;CACpE;EAAE,OAAO;EAAQ,MAAM,kBAACC,GAAD,EAAc,MAAM,GAAK,CAAA;EAAG,OAAO;CAAO;AACnE;AA0BA,SAAgBI,EAAsD,EACpE,UACA,aACA,aAAUD,GACV,eAAY,SACZ,UAAO,MACP,aAAU,SACV,gBACsC;CACtC,IAAME,IAAQC,EAAQ,QAChBC,IAAQ,KAAK,IAAI,GAAGD,EAAQ,WAAW,MAAME,EAAE,UAAUC,CAAK,CAAC,GAC/DC,IAAUJ,EAAQC,IAClBI,IAAOL,GAASC,IAAQ,KAAKF,IAC7BO,IAAWN,GAASC,IAAQ,IAAIF,KAASA,IACzCQ,IAAO,GAAGC,EAAU,IAAIJ,EAAQ,MAAM,eAAeC,EAAK;CAEhE,OACE,kBAACT,GAAD;EACW;EACH;EACN,UAAA;EACA,WAAWW;EACX,SAASA;EACE;EACX,UAAU,MAAUE,GAAUC,EAAM,WAAWJ,IAAWD,EAAA,CAAM,KAAK;EAEpE,UAAAD,EAAQ;CACH,CAAA;AAEZ"}
1
+ {"version":3,"file":"ThemeSwitcher-BJWP1l87.js","names":["ModeAutoIcon","ModeLightIcon","ModeDarkIcon","Button","COLOR_MODE_OPTIONS","ThemeSwitcher","count","options","index","o","value","current","next","previous","name","ariaLabel","onChange","event"],"sources":["../../src/components/ThemeSwitcher/ThemeSwitcher.tsx"],"sourcesContent":["import type { ReactElement, ReactNode } from 'react';\nimport type { ColorModePreference } from '@weasel-js/theme';\nimport { ModeAutoIcon, ModeDarkIcon, ModeLightIcon } from '../../icons';\nimport { Button, type ButtonSize, type ButtonVariant } from '../Button/Button';\n\n/** One stop in a {@link ThemeSwitcher}'s rotation. */\nexport interface ThemeSwitcherOption<T extends string = string> {\n value: T;\n /** Drawn in the button while this option is current. */\n icon: ReactNode;\n /** The option's name, read in the accessible name and tooltip. */\n label: string;\n}\n\n/** The color modes, in rotation order, as {@link ThemeSwitcher} cycles them by default. */\nexport const COLOR_MODE_OPTIONS: readonly ThemeSwitcherOption<ColorModePreference>[] = [\n { value: 'auto', icon: <ModeAutoIcon size={16} />, label: 'Auto' },\n { value: 'light', icon: <ModeLightIcon size={16} />, label: 'Light' },\n { value: 'dark', icon: <ModeDarkIcon size={16} />, label: 'Dark' },\n];\n\n/** Props for {@link ThemeSwitcher}. */\nexport interface ThemeSwitcherProps<T extends string = ColorModePreference> {\n value: T;\n onChange: (next: T) => void;\n /** The rotation, in order. Defaults to {@link COLOR_MODE_OPTIONS}. */\n options?: readonly ThemeSwitcherOption<T>[];\n /** What is being switched, leading the accessible name and tooltip\n * (`Theme: Auto — click for Light`). Defaults to `'Theme'`. */\n ariaLabel?: string;\n /** Defaults to `sm`, the size of a header's icon buttons. */\n size?: ButtonSize;\n /** Defaults to `ghost`. */\n variant?: ButtonVariant;\n className?: string;\n}\n\n/**\n * One icon button that steps through a list of options: a click moves to the\n * next, a shift-click to the previous, both wrapping. It shows the current\n * option's icon, and its name and tooltip say what is current and what a\n * click chooses. The compact alternative to `ColorModeControl`'s three\n * segments. Controlled: pair the default color modes with\n * `useColorModePreference` from `@weasel-js/theme/react`.\n */\nexport function ThemeSwitcher<T extends string = ColorModePreference>({\n value,\n onChange,\n options = COLOR_MODE_OPTIONS as unknown as readonly ThemeSwitcherOption<T>[],\n ariaLabel = 'Theme',\n size = 'sm',\n variant = 'ghost',\n className,\n}: ThemeSwitcherProps<T>): ReactElement {\n const count = options.length;\n const index = Math.max(0, options.findIndex((o) => o.value === value));\n const current = options[index];\n const next = options[(index + 1) % count];\n const previous = options[(index - 1 + count) % count];\n const name = `${ariaLabel}: ${current.label} — click for ${next.label}`;\n\n return (\n <Button\n variant={variant}\n size={size}\n iconOnly\n ariaLabel={name}\n tooltip={name}\n className={className}\n onClick={(event) => onChange((event.shiftKey ? previous : next).value)}\n >\n {current.icon}\n </Button>\n );\n}\n"],"mappings":";;;;AAeA,IAAaI,IAA0E;CACrF;EAAE,OAAO;EAAQ,MAAM,kBAACJ,GAAD,EAAc,MAAM,GAAK,CAAA;EAAG,OAAO;CAAO;CACjE;EAAE,OAAO;EAAS,MAAM,kBAACC,GAAD,EAAe,MAAM,GAAK,CAAA;EAAG,OAAO;CAAQ;CACpE;EAAE,OAAO;EAAQ,MAAM,kBAACC,GAAD,EAAc,MAAM,GAAK,CAAA;EAAG,OAAO;CAAO;AACnE;AA0BA,SAAgBG,EAAsD,EACpE,UACA,aACA,aAAUD,GACV,eAAY,SACZ,UAAO,MACP,aAAU,SACV,gBACsC;CACtC,IAAME,IAAQC,EAAQ,QAChBC,IAAQ,KAAK,IAAI,GAAGD,EAAQ,WAAW,MAAME,EAAE,UAAUC,CAAK,CAAC,GAC/DC,IAAUJ,EAAQC,IAClBI,IAAOL,GAASC,IAAQ,KAAKF,IAC7BO,IAAWN,GAASC,IAAQ,IAAIF,KAASA,IACzCQ,IAAO,GAAGC,EAAU,IAAIJ,EAAQ,MAAM,eAAeC,EAAK;CAEhE,OACE,kBAACT,GAAD;EACW;EACH;EACN,UAAA;EACA,WAAWW;EACX,SAASA;EACE;EACX,UAAU,MAAUE,GAAUC,EAAM,WAAWJ,IAAWD,EAAA,CAAM,KAAK;EAEpE,UAAAD,EAAQ;CACH,CAAA;AAEZ"}
@@ -1,4 +1,4 @@
1
- import { rt as e, st as t } from "./icons-CofIOTiI.js";
1
+ import { ot as e, ut as t } from "./icons-B_fPKEis.js";
2
2
  import { n } from "./Disclosure-CpWt87nO.js";
3
3
  import { r } from "./Plot2D-BrvQS0dh.js";
4
4
  import { i, n as a, t as o } from "./createKeyframeLayer-DSVf13Su.js";
@@ -926,4 +926,4 @@ function Se(e) {
926
926
  //#endregion
927
927
  export { I as a, A as c, q as i, j as l, xe as n, M as o, Y as r, k as s, Se as t };
928
928
 
929
- //# sourceMappingURL=Timeline-FlLUm8nd.js.map
929
+ //# sourceMappingURL=Timeline-CisRg82u.js.map