@elabs-ai/components-ui 5.1.0 → 5.3.0

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 (237) hide show
  1. package/dist/{chunk-KBWHHAI3.js → chunk-2ZWUTZHE.js} +2 -2
  2. package/dist/{chunk-SSQG36MH.js → chunk-34CYSZ2F.js} +2 -2
  3. package/dist/chunk-34CYSZ2F.js.map +1 -0
  4. package/dist/{chunk-AXHMQOIZ.js → chunk-3GJLYUZ6.js} +3 -3
  5. package/dist/{chunk-CEDK5GM2.js → chunk-5AJQUJ5C.js} +2 -2
  6. package/dist/{chunk-MDQYRES4.js → chunk-5KNLME6F.js} +11 -5
  7. package/dist/chunk-5KNLME6F.js.map +1 -0
  8. package/dist/{chunk-ERTYAID6.js → chunk-5QQFXDUY.js} +5 -3
  9. package/dist/{chunk-ERTYAID6.js.map → chunk-5QQFXDUY.js.map} +1 -1
  10. package/dist/{chunk-E3GNYOLS.js → chunk-64BKIIJC.js} +2 -2
  11. package/dist/{chunk-RHVYRQN4.js → chunk-7ZJLR6RP.js} +2 -2
  12. package/dist/{chunk-HWVU636Q.js → chunk-A3JF66ZC.js} +3 -3
  13. package/dist/{chunk-NZUKZRT7.js → chunk-A3TT32GE.js} +2 -2
  14. package/dist/{chunk-C2ICCCP5.js → chunk-A4ZSNEZD.js} +2 -2
  15. package/dist/{chunk-JTY3REOB.js → chunk-BGXBANS2.js} +3 -3
  16. package/dist/{chunk-MY5H6D5Y.js → chunk-C4FNDXBM.js} +2 -2
  17. package/dist/{chunk-QF6UWWDY.js → chunk-C4FZWPI4.js} +1 -1
  18. package/dist/{chunk-QF6UWWDY.js.map → chunk-C4FZWPI4.js.map} +1 -1
  19. package/dist/{chunk-QLM3KTAQ.js → chunk-C6I5I5LA.js} +3 -3
  20. package/dist/{chunk-IE5GWE72.js → chunk-CF7YSCCA.js} +3 -3
  21. package/dist/chunk-CF7YSCCA.js.map +1 -0
  22. package/dist/{chunk-RYPK72YP.js → chunk-CGY25FAG.js} +2 -2
  23. package/dist/{chunk-HDS64Z5L.js → chunk-DIL73NE3.js} +2 -2
  24. package/dist/{chunk-VC4GKLZL.js → chunk-EHN5ZAHP.js} +2 -2
  25. package/dist/{chunk-HXQ4MDCH.js → chunk-F6FF4EJN.js} +2 -2
  26. package/dist/{chunk-V5QCJHDA.js → chunk-FC2LHNJG.js} +3 -3
  27. package/dist/{chunk-ZRMF4YAS.js → chunk-FCVHZDP7.js} +3 -3
  28. package/dist/{chunk-BYFRDLDL.js → chunk-FKDI2T7X.js} +2 -2
  29. package/dist/{chunk-GWHO5ACE.js → chunk-FNRVVVXX.js} +2 -2
  30. package/dist/{chunk-Y33ZFTMR.js → chunk-FWAFP76U.js} +2 -2
  31. package/dist/{chunk-ZALGMUSW.js → chunk-HUXLE3K3.js} +2 -2
  32. package/dist/{chunk-NRPZ3BH4.js → chunk-I3LBIBVN.js} +2 -2
  33. package/dist/{chunk-GTDCC4YX.js → chunk-IV6OYZTL.js} +2 -2
  34. package/dist/{chunk-4DWIMWR5.js → chunk-JQIXRCLG.js} +2 -2
  35. package/dist/{chunk-M5WPZXBA.js → chunk-JU4KW7JN.js} +3 -3
  36. package/dist/{chunk-PSXUEWUS.js → chunk-LVY7B5PD.js} +2 -2
  37. package/dist/{chunk-FLCQKC64.js → chunk-MIWFBH5S.js} +3 -3
  38. package/dist/{chunk-6TJVJPNU.js → chunk-O6AIFSTX.js} +46 -1
  39. package/dist/chunk-O6AIFSTX.js.map +1 -0
  40. package/dist/{chunk-EJQYE4MY.js → chunk-OFFWEDKY.js} +2 -2
  41. package/dist/{chunk-W7OIVERI.js → chunk-ONXBRQJT.js} +2 -2
  42. package/dist/{chunk-ENL3CCZB.js → chunk-PCNQ6NP2.js} +5 -5
  43. package/dist/{chunk-BRL2HMZJ.js → chunk-PFGQDW3H.js} +2 -2
  44. package/dist/{chunk-GMXSCEYN.js → chunk-R6CITZBB.js} +2 -2
  45. package/dist/{chunk-CY5ISPFB.js → chunk-RHZSAWAU.js} +2 -2
  46. package/dist/{chunk-FXC64HLD.js → chunk-S7YR3FYZ.js} +2 -2
  47. package/dist/{chunk-W35X6J5P.js → chunk-SD5MGHIJ.js} +3 -3
  48. package/dist/{chunk-2DFB4YTK.js → chunk-SJHDX73F.js} +2 -2
  49. package/dist/{chunk-MRBDJASL.js → chunk-SQLEVIAD.js} +3 -3
  50. package/dist/{chunk-3EDNWHWD.js → chunk-SR3SC2Q3.js} +2 -2
  51. package/dist/{chunk-HANBQNW3.js → chunk-U7ADXWTI.js} +26 -14
  52. package/dist/chunk-U7ADXWTI.js.map +1 -0
  53. package/dist/{chunk-CEHCVDYR.js → chunk-U7CSWQAE.js} +3 -3
  54. package/dist/{chunk-SWQCCR6Q.js → chunk-U7FC5J6J.js} +3 -3
  55. package/dist/{chunk-4VCU3GFI.js → chunk-UVVVKPSH.js} +2 -2
  56. package/dist/{chunk-BDOG4YSM.js → chunk-VAWYYETZ.js} +8 -8
  57. package/dist/{chunk-ALNJV4XB.js → chunk-WDZ47ZTX.js} +2 -2
  58. package/dist/{chunk-HHZJALGA.js → chunk-WL2EZDSD.js} +3 -3
  59. package/dist/{chunk-UQPW7INX.js → chunk-XE6GYGWS.js} +2 -2
  60. package/dist/{chunk-OGTILHKP.js → chunk-Y3CKZ7SH.js} +3 -3
  61. package/dist/{chunk-RIYDAMSQ.js → chunk-YA2CG4YL.js} +2 -2
  62. package/dist/{chunk-4DZGAY6R.js → chunk-ZESSUMCO.js} +2 -2
  63. package/dist/{chunk-L6A3RXCU.js → chunk-ZGNWDYSC.js} +3 -3
  64. package/dist/components/advanced-group/advanced-group.js +3 -3
  65. package/dist/components/advanced-group/index.js +3 -3
  66. package/dist/components/app-sidebar/app-sidebar.js +5 -5
  67. package/dist/components/app-sidebar/index.js +5 -5
  68. package/dist/components/attribution-panel/attribution-panel.js +4 -4
  69. package/dist/components/attribution-panel/attributions.generated.js +1 -1
  70. package/dist/components/attribution-panel/index.js +4 -4
  71. package/dist/components/bounded-number/bounded-number.js +4 -4
  72. package/dist/components/bounded-number/index.js +4 -4
  73. package/dist/components/breadcrumb/breadcrumb.js +3 -3
  74. package/dist/components/breadcrumb/index.js +3 -3
  75. package/dist/components/carousel/carousel.js +3 -3
  76. package/dist/components/carousel/index.js +3 -3
  77. package/dist/components/change-review/change-review.js +4 -4
  78. package/dist/components/change-review/index.js +4 -4
  79. package/dist/components/color-picker/color-picker.js +3 -3
  80. package/dist/components/color-picker/index.js +3 -3
  81. package/dist/components/combobox/combobox.js +5 -5
  82. package/dist/components/combobox/index.js +5 -5
  83. package/dist/components/command/command.js +4 -4
  84. package/dist/components/command/index.js +4 -4
  85. package/dist/components/confirm-dialog/confirm-dialog.js +4 -4
  86. package/dist/components/confirm-dialog/index.js +4 -4
  87. package/dist/components/context-rail/context-rail.js +6 -6
  88. package/dist/components/context-rail/index.js +6 -6
  89. package/dist/components/copyable-value/copyable-value.js +3 -3
  90. package/dist/components/copyable-value/index.js +3 -3
  91. package/dist/components/date-picker/date-picker.js +3 -3
  92. package/dist/components/date-picker/index.js +3 -3
  93. package/dist/components/date-range-picker/date-range-picker.js +3 -3
  94. package/dist/components/date-range-picker/index.js +3 -3
  95. package/dist/components/dialog/dialog.js +3 -3
  96. package/dist/components/dialog/index.js +3 -3
  97. package/dist/components/empty-state/empty-state.js +4 -4
  98. package/dist/components/empty-state/index.js +4 -4
  99. package/dist/components/error-state/error-state.js +4 -4
  100. package/dist/components/error-state/index.js +4 -4
  101. package/dist/components/expand-dialog/expand-dialog.js +4 -4
  102. package/dist/components/expand-dialog/index.js +4 -4
  103. package/dist/components/file-upload/file-upload.js +3 -3
  104. package/dist/components/file-upload/index.js +3 -3
  105. package/dist/components/key-value-editor/index.js +3 -3
  106. package/dist/components/key-value-editor/key-value-editor.js +3 -3
  107. package/dist/components/keyboard-shortcuts/index.js +4 -4
  108. package/dist/components/keyboard-shortcuts/keyboard-shortcuts.js +4 -4
  109. package/dist/components/list-editor/index.js +3 -3
  110. package/dist/components/list-editor/list-editor.js +3 -3
  111. package/dist/components/loading-state/index.js +4 -4
  112. package/dist/components/loading-state/loading-state.js +4 -4
  113. package/dist/components/locale-provider/index.js +2 -2
  114. package/dist/components/locale-provider/locale-provider.js +2 -2
  115. package/dist/components/locale-provider/messages.js +1 -1
  116. package/dist/components/mention-input/index.js +3 -3
  117. package/dist/components/mention-input/mention-input.js +3 -3
  118. package/dist/components/metric-card/index.js +4 -4
  119. package/dist/components/metric-card/metric-card.js +4 -4
  120. package/dist/components/model-picker/index.js +5 -5
  121. package/dist/components/model-picker/model-picker.js +5 -5
  122. package/dist/components/nav-main/index.js +5 -5
  123. package/dist/components/nav-main/nav-main.js +5 -5
  124. package/dist/components/nav-notifications/index.js +3 -3
  125. package/dist/components/nav-notifications/nav-notifications.js +3 -3
  126. package/dist/components/nav-user/index.js +5 -5
  127. package/dist/components/nav-user/nav-user.js +5 -5
  128. package/dist/components/number-input/index.js +3 -3
  129. package/dist/components/number-input/number-input.js +3 -3
  130. package/dist/components/pagination/index.js +3 -3
  131. package/dist/components/pagination/pagination.js +3 -3
  132. package/dist/components/revision-timeline/index.js +3 -3
  133. package/dist/components/revision-timeline/revision-timeline.js +3 -3
  134. package/dist/components/schema-form/index.js +9 -9
  135. package/dist/components/schema-form/schema-form.js +9 -9
  136. package/dist/components/sheet/index.js +3 -3
  137. package/dist/components/sheet/sheet.js +3 -3
  138. package/dist/components/side-dock/index.js +4 -4
  139. package/dist/components/side-dock/side-dock.js +4 -4
  140. package/dist/components/sidebar/index.js +4 -4
  141. package/dist/components/sidebar/sidebar.js +4 -4
  142. package/dist/components/slider-number/index.js +4 -4
  143. package/dist/components/slider-number/slider-number.js +4 -4
  144. package/dist/components/spec-playground/index.js +2 -2
  145. package/dist/components/spec-playground/locate-json-path.js +1 -1
  146. package/dist/components/spec-playground/spec-playground.js +2 -2
  147. package/dist/components/spinner/index.js +3 -3
  148. package/dist/components/spinner/spinner.js +3 -3
  149. package/dist/components/state-panel/index.js +3 -3
  150. package/dist/components/state-panel/state-panel.js +3 -3
  151. package/dist/components/table/index.js +3 -3
  152. package/dist/components/table/table.js +3 -3
  153. package/dist/components/team-switcher/index.js +5 -5
  154. package/dist/components/team-switcher/team-switcher.js +5 -5
  155. package/dist/components/theme-switcher/index.js +3 -3
  156. package/dist/components/theme-switcher/theme-switcher.js +3 -3
  157. package/dist/components/toolbar/index.js +1 -1
  158. package/dist/components/toolbar/toolbar.js +1 -1
  159. package/dist/components/transfer/index.js +3 -3
  160. package/dist/components/transfer/transfer.js +3 -3
  161. package/dist/components/tree/index.js +4 -4
  162. package/dist/components/tree/tree.js +4 -4
  163. package/dist/components/tree-select/index.js +5 -5
  164. package/dist/components/tree-select/tree-select.js +5 -5
  165. package/dist/components/view-toolbar/index.js +3 -3
  166. package/dist/components/view-toolbar/view-toolbar.js +3 -3
  167. package/dist/components/virtual-select/index.js +3 -3
  168. package/dist/components/virtual-select/virtual-select.js +3 -3
  169. package/dist/components/workspace-picker/index.js +6 -6
  170. package/dist/components/workspace-picker/workspace-picker.js +6 -6
  171. package/dist/index.d.ts +18 -3
  172. package/dist/index.js +60 -57
  173. package/dist/lib/streamdown-translations.js +3 -3
  174. package/package.json +3 -3
  175. package/src/components/attribution-panel/attributions.generated.ts +26 -14
  176. package/src/components/locale-provider/messages.ts +47 -0
  177. package/src/components/metric-card/metric-card.tsx +1 -1
  178. package/src/components/spec-playground/locate-json-path.ts +1 -1
  179. package/src/components/spec-playground/spec-playground.tsx +1 -1
  180. package/src/components/toolbar/toolbar.tsx +4 -2
  181. package/src/components/tree/tree.stories.tsx +28 -0
  182. package/src/components/tree/tree.tsx +17 -2
  183. package/src/index.ts +3 -0
  184. package/dist/chunk-6TJVJPNU.js.map +0 -1
  185. package/dist/chunk-HANBQNW3.js.map +0 -1
  186. package/dist/chunk-IE5GWE72.js.map +0 -1
  187. package/dist/chunk-MDQYRES4.js.map +0 -1
  188. package/dist/chunk-SSQG36MH.js.map +0 -1
  189. /package/dist/{chunk-KBWHHAI3.js.map → chunk-2ZWUTZHE.js.map} +0 -0
  190. /package/dist/{chunk-AXHMQOIZ.js.map → chunk-3GJLYUZ6.js.map} +0 -0
  191. /package/dist/{chunk-CEDK5GM2.js.map → chunk-5AJQUJ5C.js.map} +0 -0
  192. /package/dist/{chunk-E3GNYOLS.js.map → chunk-64BKIIJC.js.map} +0 -0
  193. /package/dist/{chunk-RHVYRQN4.js.map → chunk-7ZJLR6RP.js.map} +0 -0
  194. /package/dist/{chunk-HWVU636Q.js.map → chunk-A3JF66ZC.js.map} +0 -0
  195. /package/dist/{chunk-NZUKZRT7.js.map → chunk-A3TT32GE.js.map} +0 -0
  196. /package/dist/{chunk-C2ICCCP5.js.map → chunk-A4ZSNEZD.js.map} +0 -0
  197. /package/dist/{chunk-JTY3REOB.js.map → chunk-BGXBANS2.js.map} +0 -0
  198. /package/dist/{chunk-MY5H6D5Y.js.map → chunk-C4FNDXBM.js.map} +0 -0
  199. /package/dist/{chunk-QLM3KTAQ.js.map → chunk-C6I5I5LA.js.map} +0 -0
  200. /package/dist/{chunk-RYPK72YP.js.map → chunk-CGY25FAG.js.map} +0 -0
  201. /package/dist/{chunk-HDS64Z5L.js.map → chunk-DIL73NE3.js.map} +0 -0
  202. /package/dist/{chunk-VC4GKLZL.js.map → chunk-EHN5ZAHP.js.map} +0 -0
  203. /package/dist/{chunk-HXQ4MDCH.js.map → chunk-F6FF4EJN.js.map} +0 -0
  204. /package/dist/{chunk-V5QCJHDA.js.map → chunk-FC2LHNJG.js.map} +0 -0
  205. /package/dist/{chunk-ZRMF4YAS.js.map → chunk-FCVHZDP7.js.map} +0 -0
  206. /package/dist/{chunk-BYFRDLDL.js.map → chunk-FKDI2T7X.js.map} +0 -0
  207. /package/dist/{chunk-GWHO5ACE.js.map → chunk-FNRVVVXX.js.map} +0 -0
  208. /package/dist/{chunk-Y33ZFTMR.js.map → chunk-FWAFP76U.js.map} +0 -0
  209. /package/dist/{chunk-ZALGMUSW.js.map → chunk-HUXLE3K3.js.map} +0 -0
  210. /package/dist/{chunk-NRPZ3BH4.js.map → chunk-I3LBIBVN.js.map} +0 -0
  211. /package/dist/{chunk-GTDCC4YX.js.map → chunk-IV6OYZTL.js.map} +0 -0
  212. /package/dist/{chunk-4DWIMWR5.js.map → chunk-JQIXRCLG.js.map} +0 -0
  213. /package/dist/{chunk-M5WPZXBA.js.map → chunk-JU4KW7JN.js.map} +0 -0
  214. /package/dist/{chunk-PSXUEWUS.js.map → chunk-LVY7B5PD.js.map} +0 -0
  215. /package/dist/{chunk-FLCQKC64.js.map → chunk-MIWFBH5S.js.map} +0 -0
  216. /package/dist/{chunk-EJQYE4MY.js.map → chunk-OFFWEDKY.js.map} +0 -0
  217. /package/dist/{chunk-W7OIVERI.js.map → chunk-ONXBRQJT.js.map} +0 -0
  218. /package/dist/{chunk-ENL3CCZB.js.map → chunk-PCNQ6NP2.js.map} +0 -0
  219. /package/dist/{chunk-BRL2HMZJ.js.map → chunk-PFGQDW3H.js.map} +0 -0
  220. /package/dist/{chunk-GMXSCEYN.js.map → chunk-R6CITZBB.js.map} +0 -0
  221. /package/dist/{chunk-CY5ISPFB.js.map → chunk-RHZSAWAU.js.map} +0 -0
  222. /package/dist/{chunk-FXC64HLD.js.map → chunk-S7YR3FYZ.js.map} +0 -0
  223. /package/dist/{chunk-W35X6J5P.js.map → chunk-SD5MGHIJ.js.map} +0 -0
  224. /package/dist/{chunk-2DFB4YTK.js.map → chunk-SJHDX73F.js.map} +0 -0
  225. /package/dist/{chunk-MRBDJASL.js.map → chunk-SQLEVIAD.js.map} +0 -0
  226. /package/dist/{chunk-3EDNWHWD.js.map → chunk-SR3SC2Q3.js.map} +0 -0
  227. /package/dist/{chunk-CEHCVDYR.js.map → chunk-U7CSWQAE.js.map} +0 -0
  228. /package/dist/{chunk-SWQCCR6Q.js.map → chunk-U7FC5J6J.js.map} +0 -0
  229. /package/dist/{chunk-4VCU3GFI.js.map → chunk-UVVVKPSH.js.map} +0 -0
  230. /package/dist/{chunk-BDOG4YSM.js.map → chunk-VAWYYETZ.js.map} +0 -0
  231. /package/dist/{chunk-ALNJV4XB.js.map → chunk-WDZ47ZTX.js.map} +0 -0
  232. /package/dist/{chunk-HHZJALGA.js.map → chunk-WL2EZDSD.js.map} +0 -0
  233. /package/dist/{chunk-UQPW7INX.js.map → chunk-XE6GYGWS.js.map} +0 -0
  234. /package/dist/{chunk-OGTILHKP.js.map → chunk-Y3CKZ7SH.js.map} +0 -0
  235. /package/dist/{chunk-RIYDAMSQ.js.map → chunk-YA2CG4YL.js.map} +0 -0
  236. /package/dist/{chunk-4DZGAY6R.js.map → chunk-ZESSUMCO.js.map} +0 -0
  237. /package/dist/{chunk-L6A3RXCU.js.map → chunk-ZGNWDYSC.js.map} +0 -0
@@ -20,7 +20,7 @@ import {
20
20
  } from "./chunk-36SY7TID.js";
21
21
  import {
22
22
  useLocale
23
- } from "./chunk-EJQYE4MY.js";
23
+ } from "./chunk-OFFWEDKY.js";
24
24
  import {
25
25
  Button
26
26
  } from "./chunk-C5QBV5RE.js";
@@ -243,4 +243,4 @@ var ThemeSwitcher = forwardRef(
243
243
  export {
244
244
  ThemeSwitcher
245
245
  };
246
- //# sourceMappingURL=chunk-KBWHHAI3.js.map
246
+ //# sourceMappingURL=chunk-2ZWUTZHE.js.map
@@ -3,7 +3,7 @@ import {
3
3
  lineOfParseError,
4
4
  locateJsonPath,
5
5
  offsetOfLine
6
- } from "./chunk-QF6UWWDY.js";
6
+ } from "./chunk-C4FZWPI4.js";
7
7
  import {
8
8
  DropdownMenu,
9
9
  DropdownMenuContent,
@@ -223,4 +223,4 @@ export {
223
223
  DEFAULT_SPEC_PLAYGROUND_LABELS,
224
224
  SpecPlayground
225
225
  };
226
- //# sourceMappingURL=chunk-SSQG36MH.js.map
226
+ //# sourceMappingURL=chunk-34CYSZ2F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/spec-playground/spec-playground.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n forwardRef,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ForwardedRef,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { Braces, ChevronDown, CircleAlert, CircleCheck, RotateCcw } from \"lucide-react\";\nimport { cn } from \"../../lib/cn\";\nimport { useControllableState } from \"../../lib/use-controllable-state\";\nimport { Badge } from \"../badge\";\nimport { Button } from \"../button\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"../dropdown-menu\";\nimport { Textarea } from \"../textarea\";\nimport { lineOfParseError, locateJsonPath, offsetOfLine } from \"./locate-json-path\";\n\n/** One problem a validator reports — the shape the A2UI validator uses. */\nexport interface SpecPlaygroundError {\n /** JSON-path-like address of the problem (`root.children[2].props.label`, `$.tiles[0]`). */\n path: string;\n /** The validator's machine-readable code (`missing-prop`, `overlap`, …). */\n code: string;\n message: string;\n}\n\n/** What `validate` returns: the typed spec, or the validator's own errors. */\nexport type SpecPlaygroundValidation<TSpec> =\n | { ok: true; spec: TSpec }\n | { ok: false; errors: readonly SpecPlaygroundError[] };\n\n/** An entry in the `Load example` menu. */\nexport interface SpecPlaygroundExample {\n id: string;\n label: string;\n /** The JSON text loaded into the editor. */\n value: string;\n}\n\n/** The playground's status: what the last validated text turned out to be. */\nexport type SpecPlaygroundStatus = \"valid\" | \"invalid\" | \"parse-error\";\n\n/** Every string the playground renders — pass your own to localize it. */\nexport interface SpecPlaygroundLabels {\n /** Accessible name of the default textarea editor. */\n editor: string;\n /** Accessible name of the rendered-result region. */\n preview: string;\n /** Accessible name of the error list. */\n errors: string;\n /** Trigger of the examples menu. */\n loadExample: string;\n /** Resets the editor to its initial text. */\n reset: string;\n /** Status chip: the text validates. */\n valid: string;\n /** Status chip: the validator reported `count` errors. */\n errorCount: (count: number) => string;\n /** Status chip: the text is not JSON. */\n parseError: string;\n /** Shown over the render when it is the last valid spec, not the current text. */\n showingLastValid: string;\n /** Shown in the render pane before any text has validated. */\n nothingValid: string;\n /** Suffix naming the editor line an error points at. */\n line: (line: number) => string;\n}\n\nexport const DEFAULT_SPEC_PLAYGROUND_LABELS: SpecPlaygroundLabels = {\n editor: \"Spec (JSON)\",\n preview: \"Rendered result\",\n errors: \"Problems\",\n loadExample: \"Load example\",\n reset: \"Reset\",\n valid: \"Valid\",\n errorCount: (count) => (count === 1 ? \"1 error\" : `${count} errors`),\n parseError: \"Parse error\",\n showingLastValid: \"Showing last valid\",\n nothingValid: \"Nothing valid to render yet.\",\n line: (line) => `line ${line}`,\n};\n\nexport interface SpecPlaygroundProps<TSpec> extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"onChange\" | \"defaultValue\"\n> {\n /** The JSON text (controlled). */\n value?: string;\n /** Initial JSON text (uncontrolled); also what `Reset` restores. Default: the first example. */\n defaultValue?: string;\n /** Called with the new text on every edit, example load and reset. */\n onChange?: (value: string) => void;\n /** Checks the parsed JSON; the errors shown are exactly the ones it returns. */\n validate: (json: unknown) => SpecPlaygroundValidation<TSpec>;\n /** Renders a validated spec. */\n render: (spec: TSpec) => ReactNode;\n /** Entries of the `Load example` menu (the menu is hidden without any). */\n examples?: readonly SpecPlaygroundExample[];\n /**\n * The editor. Bind it to `value`/`onChange` yourself. Default: a `Textarea`, so the\n * playground works without a code editor.\n */\n editor?: ReactNode;\n /**\n * Called when an error is chosen, with the editor line its path resolves to — move a custom\n * editor's caret there. The default textarea handles this itself.\n */\n onErrorSelect?: (error: SpecPlaygroundError, line: number | undefined) => void;\n /** Milliseconds between the last edit and validation. Default 250. */\n debounceMs?: number;\n labels?: Partial<SpecPlaygroundLabels>;\n}\n\ntype Checked<TSpec> =\n | { status: \"valid\"; spec: TSpec; errors: readonly SpecPlaygroundError[] }\n | { status: \"invalid\" | \"parse-error\"; errors: readonly SpecPlaygroundError[] };\n\nfunction check<TSpec>(\n text: string,\n validate: (json: unknown) => SpecPlaygroundValidation<TSpec>,\n): Checked<TSpec> {\n let json: unknown;\n try {\n json = JSON.parse(text);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { status: \"parse-error\", errors: [{ path: \"\", code: \"parse-error\", message }] };\n }\n const result = validate(json);\n return result.ok\n ? { status: \"valid\", spec: result.spec, errors: [] }\n : { status: \"invalid\", errors: result.errors };\n}\n\nfunction SpecPlaygroundInner<TSpec>(\n {\n value: valueProp,\n defaultValue,\n onChange,\n validate,\n render,\n examples = [],\n editor,\n onErrorSelect,\n debounceMs = 250,\n labels: labelsProp,\n className,\n ...props\n }: SpecPlaygroundProps<TSpec>,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const labels = { ...DEFAULT_SPEC_PLAYGROUND_LABELS, ...labelsProp };\n const initial = defaultValue ?? examples[0]?.value ?? \"\";\n const [resetValue] = useState(initial);\n const [value, setValue] = useControllableState(valueProp, initial, onChange);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n // Validation trails the text by `debounceMs`; the first render validates immediately.\n const [settled, setSettled] = useState(value);\n useEffect(() => {\n if (settled === value) return;\n const timer = setTimeout(() => setSettled(value), debounceMs);\n return () => clearTimeout(timer);\n }, [value, settled, debounceMs]);\n\n const checked = useMemo(() => check(settled, validate), [settled, validate]);\n\n // The last spec that validated — kept on screen while the current text does not.\n const lastValidRef = useRef<{ spec: TSpec } | null>(null);\n if (checked.status === \"valid\") lastValidRef.current = { spec: checked.spec };\n const shown = checked.status === \"valid\" ? { spec: checked.spec } : lastValidRef.current;\n const stale = checked.status !== \"valid\" && shown !== null;\n\n const lineOf = (error: SpecPlaygroundError) =>\n error.code === \"parse-error\"\n ? lineOfParseError(settled, error.message)\n : locateJsonPath(settled, error.path);\n\n const selectError = (error: SpecPlaygroundError) => {\n const line = lineOf(error);\n if (onErrorSelect) return onErrorSelect(error, line);\n const textarea = textareaRef.current;\n if (!textarea) return;\n const offset = line === undefined ? 0 : offsetOfLine(textarea.value, line);\n textarea.focus();\n textarea.setSelectionRange(offset, offset);\n };\n\n const errorListId = `${props.id ?? \"spec-playground\"}-errors`;\n const hasErrors = checked.errors.length > 0;\n\n return (\n <div\n ref={ref}\n data-slot=\"spec-playground\"\n data-status={checked.status}\n className={cn(\"grid min-w-0 gap-4 lg:grid-cols-2\", className)}\n {...props}\n >\n <div data-slot=\"spec-playground-source\" className=\"flex min-w-0 flex-col gap-3\">\n <div data-slot=\"spec-playground-toolbar\" className=\"flex flex-wrap items-center gap-2\">\n <span role=\"status\" aria-live=\"polite\" className=\"me-auto\">\n <Badge\n data-slot=\"spec-playground-status\"\n data-status={checked.status}\n variant={\n checked.status === \"valid\"\n ? \"success\"\n : checked.status === \"invalid\"\n ? \"destructive\"\n : \"warning\"\n }\n className=\"gap-1\"\n >\n {checked.status === \"valid\" ? (\n <CircleCheck aria-hidden=\"true\" size={14} />\n ) : checked.status === \"invalid\" ? (\n <CircleAlert aria-hidden=\"true\" size={14} />\n ) : (\n <Braces aria-hidden=\"true\" size={14} />\n )}\n {checked.status === \"valid\"\n ? labels.valid\n : checked.status === \"invalid\"\n ? labels.errorCount(checked.errors.length)\n : labels.parseError}\n </Badge>\n </span>\n {examples.length > 0 ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\" data-slot=\"spec-playground-examples\">\n {labels.loadExample}\n <ChevronDown aria-hidden=\"true\" size={14} />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {examples.map((example) => (\n <DropdownMenuItem\n key={example.id}\n data-example-id={example.id}\n onSelect={() => setValue(example.value)}\n >\n {example.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n data-slot=\"spec-playground-reset\"\n onClick={() => setValue(resetValue)}\n >\n <RotateCcw aria-hidden=\"true\" size={14} />\n {labels.reset}\n </Button>\n </div>\n <div data-slot=\"spec-playground-editor\" className=\"min-h-80 min-w-0\">\n {editor ?? (\n <Textarea\n ref={textareaRef}\n data-slot=\"spec-playground-textarea\"\n aria-label={labels.editor}\n aria-invalid={hasErrors || undefined}\n aria-describedby={hasErrors ? errorListId : undefined}\n spellCheck={false}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n className=\"h-80 min-h-80 resize-y font-mono text-code\"\n />\n )}\n </div>\n {hasErrors ? (\n <ol\n id={errorListId}\n aria-label={labels.errors}\n data-slot=\"spec-playground-errors\"\n className=\"flex flex-col gap-1\"\n >\n {checked.errors.map((error) => {\n const line = lineOf(error);\n return (\n <li key={`${error.path}|${error.code}|${error.message}`}>\n <button\n type=\"button\"\n data-slot=\"spec-playground-error\"\n data-path={error.path}\n data-code={error.code}\n onClick={() => selectError(error)}\n className=\"focus-ring flex w-full min-w-0 flex-wrap items-baseline gap-x-2 rounded-md border-s-2 border-s-destructive px-2 py-1 text-start text-caption hover:bg-muted\"\n >\n {error.path ? <code className=\"font-mono text-code\">{error.path}</code> : null}\n <span className=\"font-mono text-code text-destructive-text\">{error.code}</span>\n <span className=\"min-w-0 break-words text-muted-foreground\">\n {error.message}\n </span>\n {line !== undefined ? (\n <span className=\"text-meta text-muted-foreground\">{labels.line(line)}</span>\n ) : null}\n </button>\n </li>\n );\n })}\n </ol>\n ) : null}\n </div>\n <section\n aria-label={labels.preview}\n data-slot=\"spec-playground-preview\"\n data-stale={stale ? \"\" : undefined}\n className=\"flex min-w-0 flex-col gap-2\"\n >\n {stale ? (\n <Badge variant=\"outline\" data-slot=\"spec-playground-stale\" className=\"self-start\">\n {labels.showingLastValid}\n </Badge>\n ) : null}\n {shown ? (\n render(shown.spec)\n ) : (\n <p className=\"text-caption text-muted-foreground\">{labels.nothingValid}</p>\n )}\n </section>\n </div>\n );\n}\n\n/**\n * A live spec editor: JSON on the left, what it renders on the right (stacked below 1024 px).\n * Edits are validated after a short pause by the host's own `validate`; its errors are listed\n * under the editor (`path · code · message`, click to jump to the line) and the render keeps\n * the last valid spec, marked as such, until the text validates again. The editor, validator\n * and renderer all come from the host — this component owns only the loop between them.\n */\nexport const SpecPlayground = forwardRef(SpecPlaygroundInner) as <TSpec>(\n props: SpecPlaygroundProps<TSpec> & { ref?: Ref<HTMLDivElement> },\n) => ReactElement;\n(SpecPlayground as { displayName?: string }).displayName = \"SpecPlayground\";\n"],"mappings":"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","names":[]}
@@ -4,13 +4,13 @@ import {
4
4
  } from "./chunk-IVEDMK5U.js";
5
5
  import {
6
6
  ATTRIBUTIONS
7
- } from "./chunk-HANBQNW3.js";
7
+ } from "./chunk-U7ADXWTI.js";
8
8
  import {
9
9
  Badge
10
10
  } from "./chunk-HNLYRHAU.js";
11
11
  import {
12
12
  useLocale
13
- } from "./chunk-EJQYE4MY.js";
13
+ } from "./chunk-OFFWEDKY.js";
14
14
  import {
15
15
  cn
16
16
  } from "./chunk-FXWWDMMP.js";
@@ -113,4 +113,4 @@ export {
113
113
  CATEGORY_LABEL,
114
114
  AttributionPanel
115
115
  };
116
- //# sourceMappingURL=chunk-AXHMQOIZ.js.map
116
+ //# sourceMappingURL=chunk-3GJLYUZ6.js.map
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-FBJ2JSRA.js";
8
8
  import {
9
9
  useLocale
10
- } from "./chunk-EJQYE4MY.js";
10
+ } from "./chunk-OFFWEDKY.js";
11
11
  import {
12
12
  cn
13
13
  } from "./chunk-FXWWDMMP.js";
@@ -65,4 +65,4 @@ export {
65
65
  COPYABLE_VALUE_TOAST_MS,
66
66
  CopyableValue
67
67
  };
68
- //# sourceMappingURL=chunk-CEDK5GM2.js.map
68
+ //# sourceMappingURL=chunk-5AJQUJ5C.js.map
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-ZI2OXD6L.js";
5
5
  import {
6
6
  Spinner
7
- } from "./chunk-W7OIVERI.js";
7
+ } from "./chunk-ONXBRQJT.js";
8
8
  import {
9
9
  Checkbox
10
10
  } from "./chunk-K4V2ELUZ.js";
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-UPGIQXUY.js";
14
14
  import {
15
15
  useLocale
16
- } from "./chunk-EJQYE4MY.js";
16
+ } from "./chunk-OFFWEDKY.js";
17
17
  import {
18
18
  cn
19
19
  } from "./chunk-FXWWDMMP.js";
@@ -90,6 +90,7 @@ function VirtualFlatRow({
90
90
  selectionMode,
91
91
  checkboxes,
92
92
  surface,
93
+ expandOn,
93
94
  onToggleExpand,
94
95
  onSelect,
95
96
  onRetry,
@@ -106,7 +107,7 @@ function VirtualFlatRow({
106
107
  if (node.disabled) return;
107
108
  setActiveId(node.id);
108
109
  onSelect(node.id);
109
- if (expandable) onToggleExpand(node.id);
110
+ if (expandable && expandOn === "row") onToggleExpand(node.id);
110
111
  };
111
112
  return /* @__PURE__ */ jsxs(
112
113
  "div",
@@ -280,6 +281,7 @@ function TreeItem({
280
281
  onSelectionChange,
281
282
  checkboxes,
282
283
  surface,
284
+ expandOn,
283
285
  activeId,
284
286
  setActiveId,
285
287
  registerNodeRef,
@@ -326,7 +328,7 @@ function TreeItem({
326
328
  const handleRowClick = () => {
327
329
  setActiveId(node.id);
328
330
  handleSelect();
329
- if (expandable) toggleExpanded();
331
+ if (expandable && expandOn === "row") toggleExpanded();
330
332
  };
331
333
  const indentStyle = { paddingLeft: `${(level - 1) * 1}rem` };
332
334
  return /* @__PURE__ */ jsxs("li", { role: "none", children: [
@@ -418,6 +420,7 @@ function TreeItem({
418
420
  onSelectionChange,
419
421
  checkboxes,
420
422
  surface,
423
+ expandOn,
421
424
  activeId,
422
425
  setActiveId,
423
426
  registerNodeRef,
@@ -495,6 +498,7 @@ var Tree = forwardRef(function Tree2({
495
498
  scrollSelectionIntoView = false,
496
499
  loadChildren,
497
500
  surface = "default",
501
+ expandOn = "row",
498
502
  className,
499
503
  ...props
500
504
  }, ref) {
@@ -712,6 +716,7 @@ var Tree = forwardRef(function Tree2({
712
716
  onSelectionChange: setSelectedIds,
713
717
  checkboxes,
714
718
  surface,
719
+ expandOn,
715
720
  activeId,
716
721
  setActiveId,
717
722
  registerNodeRef: registerAndFlush,
@@ -773,6 +778,7 @@ var Tree = forwardRef(function Tree2({
773
778
  selectionMode,
774
779
  checkboxes,
775
780
  surface,
781
+ expandOn,
776
782
  onToggleExpand: handleToggleExpand,
777
783
  onSelect: handleSelectVirtual,
778
784
  onRetry: () => handleExpandLazy(node),
@@ -793,4 +799,4 @@ var Tree = forwardRef(function Tree2({
793
799
  export {
794
800
  Tree
795
801
  };
796
- //# sourceMappingURL=chunk-MDQYRES4.js.map
802
+ //# sourceMappingURL=chunk-5KNLME6F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/tree/tree.tsx"],"sourcesContent":["// a2ui.exposed: yes\n\"use client\";\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { ChevronRight, AlertCircle, RotateCcw } from \"lucide-react\";\nimport { useVirtualizer, type Virtualizer } from \"@tanstack/react-virtual\";\nimport { cn } from \"../../lib/cn\";\nimport { Checkbox } from \"../checkbox/checkbox\";\nimport { useLocale } from \"../locale-provider\";\nimport { Skeleton } from \"../skeleton/skeleton\";\nimport { Spinner } from \"../spinner/spinner\";\nimport { useTreeKeyboard } from \"./use-tree-keyboard\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface TreeNode<T = unknown> {\n id: string;\n label: ReactNode;\n children?: TreeNode<T>[];\n /**\n * Marks a node as expandable even when `children` is not yet loaded.\n * A node with `hasChildren: true` and no `children` array will show the\n * expand affordance. Calling `loadChildren` will populate its children.\n */\n hasChildren?: boolean;\n disabled?: boolean;\n icon?: ReactNode;\n /**\n * Optional trailing content rendered after the label — e.g. a size or\n * token-count badge (#369). Rendered as a SIBLING of the label and kept out\n * of the row's accessible name: a string `label` names the row via\n * `aria-label`, a `ReactNode` label names it via `aria-labelledby` pointing\n * at the label span only, so the accessory text never joins either.\n *\n * The slot is isolated from the row: click, keydown and focus are stopped at\n * the accessory, so it never selects/expands the row, never lets the tree's\n * roving-tabindex handler swallow its keys, and never has focus yanked back\n * to the row. Interactive content (a button, a link) therefore works and is\n * independently focusable in normal tab order; the row's own keyboard\n * navigation (arrow keys, Enter/Space) is unaffected while the row is focused.\n */\n accessory?: ReactNode;\n data?: T;\n}\n\nexport interface TreeProps<T = unknown> extends Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> {\n nodes: TreeNode<T>[];\n /** Controlled expanded ids */\n expandedIds?: string[];\n /** Uncontrolled initial expanded ids */\n defaultExpandedIds?: string[];\n onExpandedChange?: (ids: string[]) => void;\n /** \"single\" | \"multiple\" | \"none\" — default \"single\" */\n selectionMode?: \"single\" | \"multiple\" | \"none\";\n /** Controlled selected ids */\n selectedIds?: string[];\n /** Uncontrolled initial selected ids */\n defaultSelectedIds?: string[];\n onSelectionChange?: (ids: string[]) => void;\n /** Show checkboxes for multi-selection affordance — default false */\n checkboxes?: boolean;\n /**\n * The surface on which the tree is rendered.\n * - `\"default\"` (default) — renders selected rows with `bg-selection` (for use\n * on background/card surfaces).\n * - `\"sidebar\"` — renders selected rows with the sidebar's own active-item\n * treatment (`bg-sidebar-accent` + `text-sidebar-accent-foreground` +\n * `font-medium`), so selection reads consistently with `SidebarMenuButton`'s\n * active state on the `--sidebar` surface. (No fill is ≥3:1 on a sidebar;\n * perceivability comes from the foreground/weight shift + `aria-selected`,\n * the same multi-cue approach the Sidebar uses.)\n */\n surface?: \"default\" | \"sidebar\";\n /**\n * What a click on a row does to an expandable node. `\"row\"` (default): the click both\n * selects the node and toggles its children. `\"chevron\"`: the click only selects; only\n * the chevron (and ArrowLeft/ArrowRight) expands or collapses — the filter-pane\n * convention, where clicking a parent value must select it without reflowing the list.\n */\n expandOn?: \"row\" | \"chevron\";\n /**\n * Enable windowed rendering for large trees (>50 visible rows).\n * When `true`, only the visible slice of the flattened tree is mounted in\n * the DOM. Requires a bounded scroll container — either via `maxHeight` or\n * by sizing the root element externally with `overflow-auto`.\n * Default: `false` (backward-compatible nested-group DOM).\n */\n virtualize?: boolean;\n /** Estimated row height in px used by the virtualizer. Default 32. */\n estimateRowHeight?: number;\n /** Number of extra rows to render beyond the visible window. Default 8. */\n overscan?: number;\n /**\n * CSS max-height for the scroll viewport when `virtualize` is true.\n * E.g. `\"400px\"` or `\"60vh\"`. When omitted the root div must be sized by\n * the caller (e.g. via `className=\"h-96 overflow-auto\"`).\n */\n maxHeight?: number | string;\n /**\n * Scroll the node with this id into view when the value CHANGES. Reveals a\n * node selected programmatically (via `selectedIds`) that is windowed out of\n * the DOM in `virtualize` mode (or below the fold), so the tree shows \"where\n * I am\", not just structure. Expands the node's (loaded) ancestors and kicks\n * their lazy `loadChildren` as needed, then centers the node. Independent of\n * keyboard focus (keyboard nav's own scroll is unchanged).\n */\n scrollToId?: string;\n /**\n * When `true`, reveal the newly-selected controlled node (the id added to\n * `selectedIds`) into view — the selection-driven equivalent of `scrollToId`.\n * `scrollToId` wins when both are set.\n */\n scrollSelectionIntoView?: boolean;\n /**\n * Async function called when a node with `hasChildren: true` (and no\n * loaded `children`) is expanded for the first time. The returned nodes\n * are merged into the internal tree state and cached so re-expanding the\n * node does not re-fetch.\n */\n loadChildren?: (node: TreeNode<T>) => Promise<TreeNode<T>[]>;\n className?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types for lazy-load state\n// ---------------------------------------------------------------------------\n\ntype LoadState = \"idle\" | \"loading\" | \"error\";\n\ninterface LazyState {\n [nodeId: string]: LoadState;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction useControllableSet(\n controlled: string[] | undefined,\n defaultValue: string[] | undefined,\n onChange: ((ids: string[]) => void) | undefined,\n): [Set<string>, (next: Set<string>) => void] {\n const isControlled = controlled !== undefined;\n const [internal, setInternal] = useState<Set<string>>(\n () => new Set(controlled ?? defaultValue ?? []),\n );\n\n // Stable controlled Set: build a new Set only when the controlled array's\n // CONTENT actually changed, not merely its reference (many callers pass a\n // freshly-computed array with the same ids on every render). Without this,\n // `selectedIds`/`expandedIds` changed identity on every render, which made\n // effects keyed on them (the scrollToId/scrollSelectionIntoView reveal\n // effect) fire on every re-render instead of on a real selection change —\n // the scroll-jump-while-scrolling bug.\n const controlledSetRef = useRef<Set<string> | null>(null);\n let value: Set<string>;\n if (isControlled) {\n const prev = controlledSetRef.current;\n const sameContent =\n !!prev && prev.size === controlled!.length && controlled!.every((id) => prev.has(id));\n value = sameContent ? prev! : new Set(controlled);\n controlledSetRef.current = value;\n } else {\n value = internal;\n }\n\n const setValue = useCallback(\n (next: Set<string>) => {\n if (!isControlled) setInternal(next);\n onChange?.(Array.from(next));\n },\n [isControlled, onChange],\n );\n\n return [value, setValue];\n}\n\n/**\n * Reconcile an incoming `nodes` prop against the previous internal tree,\n * preserving any children merged in locally via `loadChildren` that the new\n * prop doesn't (yet) carry. Without this, any parent re-render that hands\n * down a new (even structurally-identical) `nodes` array wipes out every\n * lazily-loaded subtree that isn't also present upstream.\n */\nfunction reconcileNodes<T>(propNodes: TreeNode<T>[], prevNodes: TreeNode<T>[]): TreeNode<T>[] {\n const prevById = new Map(prevNodes.map((n) => [n.id, n] as const));\n return propNodes.map((n) => {\n const prev = prevById.get(n.id);\n if (!prev) return n;\n if (!n.children?.length && prev.children?.length) {\n // The prop still marks this node as lazily-expandable but doesn't (yet)\n // carry the children we already fetched — keep what we loaded.\n return { ...n, children: prev.children, hasChildren: n.hasChildren };\n }\n if (n.children?.length && prev.children?.length) {\n return { ...n, children: reconcileNodes(n.children, prev.children) };\n }\n return n;\n });\n}\n\n/** Merge resolved children into a tree, returning a new tree. */\nfunction mergeChildren<T>(\n nodes: TreeNode<T>[],\n nodeId: string,\n children: TreeNode<T>[],\n): TreeNode<T>[] {\n return nodes.map((n) => {\n if (n.id === nodeId) {\n return { ...n, children, hasChildren: undefined };\n }\n if (n.children?.length) {\n return { ...n, children: mergeChildren(n.children, nodeId, children) };\n }\n return n;\n });\n}\n\n// ---------------------------------------------------------------------------\n// VirtualFlatRow — a single flat row for the virtualized path\n// ---------------------------------------------------------------------------\n\ninterface FlatRow<T> {\n node: TreeNode<T>;\n level: number;\n setSize: number;\n posInSet: number;\n}\n\ninterface VirtualFlatRowProps<T> {\n row: FlatRow<T>;\n isExpanded: boolean;\n isSelected: boolean;\n isActive: boolean;\n lazyState: LoadState;\n expandable: boolean; // has children OR hasChildren flag\n selectionMode: \"single\" | \"multiple\" | \"none\";\n checkboxes: boolean;\n surface: \"default\" | \"sidebar\";\n expandOn: \"row\" | \"chevron\";\n onToggleExpand: (id: string) => void;\n onSelect: (id: string) => void;\n onRetry: (id: string) => void;\n registerNodeRef: (id: string, el: HTMLElement | null) => void;\n setActiveId: (id: string | null) => void;\n}\n\nfunction VirtualFlatRow<T>({\n row,\n isExpanded,\n isSelected,\n isActive,\n lazyState,\n expandable,\n selectionMode,\n checkboxes,\n surface,\n expandOn,\n onToggleExpand,\n onSelect,\n onRetry,\n registerNodeRef,\n setActiveId,\n}: VirtualFlatRowProps<T>) {\n const { t } = useLocale();\n const { node, level, setSize, posInSet } = row;\n const isLoading = lazyState === \"loading\";\n const isError = lazyState === \"error\";\n // A ReactNode label can't name the row via `aria-label`, so without this the\n // name would fall back to the row's CONTENTS — which includes the accessory\n // (#369). Point at the label span instead, so the accessory is excluded for\n // BOTH label shapes.\n const labelId = useId();\n\n const indentStyle = { paddingLeft: `${(level - 1) * 1}rem` };\n\n const handleRowClick = () => {\n if (node.disabled) return;\n setActiveId(node.id);\n onSelect(node.id);\n if (expandable && expandOn === \"row\") onToggleExpand(node.id);\n };\n\n return (\n <div\n role=\"treeitem\"\n aria-expanded={expandable ? isExpanded : undefined}\n aria-selected={selectionMode !== \"none\" && !checkboxes ? isSelected : undefined}\n aria-checked={checkboxes ? isSelected : undefined}\n aria-label={typeof node.label === \"string\" ? node.label : undefined}\n aria-labelledby={typeof node.label === \"string\" ? undefined : labelId}\n aria-level={level}\n aria-setsize={setSize}\n aria-posinset={posInSet}\n aria-disabled={node.disabled ? true : undefined}\n aria-busy={isLoading ? true : undefined}\n tabIndex={isActive ? 0 : -1}\n data-tree-id={node.id}\n ref={(el) => registerNodeRef(node.id, el)}\n onClick={node.disabled ? undefined : handleRowClick}\n onFocus={() => setActiveId(node.id)}\n className={cn(\n \"flex min-w-0 cursor-pointer select-none items-center gap-1.5 rounded-md px-2 py-1.5 text-body outline-none\",\n \"transition-colors duration-fast ease-standard motion-reduce:transition-none\",\n \"hover:bg-accent hover:text-accent-foreground\",\n \"focus-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background\",\n isSelected &&\n selectionMode !== \"none\" &&\n (surface === \"sidebar\"\n ? \"bg-sidebar-accent text-sidebar-accent-foreground font-medium\"\n : \"bg-selection text-selection-foreground font-medium\"),\n node.disabled && \"cursor-not-allowed opacity-50 pointer-events-none\",\n )}\n style={indentStyle}\n >\n {/* expand/collapse chevron */}\n {expandable ? (\n <span\n aria-hidden=\"true\"\n onClick={(e) => {\n e.stopPropagation();\n onToggleExpand(node.id);\n }}\n className={cn(\n \"flex size-4 shrink-0 items-center justify-center rounded transition-transform duration-fast ease-standard motion-reduce:transition-none\",\n isExpanded && \"rotate-90\",\n )}\n >\n {isLoading ? (\n <Spinner className=\"size-3.5\" label=\"Loading children\" />\n ) : (\n <ChevronRight className=\"size-3.5 text-muted-foreground\" aria-hidden=\"true\" />\n )}\n </span>\n ) : (\n <span aria-hidden=\"true\" className=\"size-4 shrink-0\" />\n )}\n\n {/* optional checkbox for multi-select */}\n {checkboxes && selectionMode === \"multiple\" && (\n <Checkbox\n checked={isSelected}\n disabled={node.disabled}\n aria-hidden=\"true\"\n tabIndex={-1}\n onClick={(e) => {\n e.stopPropagation();\n onSelect(node.id);\n }}\n className=\"shrink-0\"\n />\n )}\n\n {/* optional node icon */}\n {node.icon && (\n <span aria-hidden=\"true\" className=\"flex size-4 shrink-0 items-center justify-center\">\n {node.icon}\n </span>\n )}\n\n {/* label */}\n {isError ? (\n // #124: running text (\"Failed to load…\"), not a mark — the ink rung\n // clears >=4.5:1 and the wrapped icon inherits it fine (>=3:1 trivially).\n <span id={labelId} className=\"min-w-0 flex items-center gap-1 text-destructive-text\">\n <AlertCircle className=\"size-3.5 shrink-0\" aria-hidden=\"true\" />\n <span className=\"truncate\">{t(\"ui.tree.failedToLoad\")}</span>\n <button\n type=\"button\"\n aria-label={t(\"ui.tree.retryLoadingChildren\")}\n onClick={(e) => {\n e.stopPropagation();\n onRetry(node.id);\n }}\n className={cn(\n \"ms-1 flex items-center gap-0.5 rounded px-1 py-0.5 text-caption\",\n \"text-muted-foreground hover:text-foreground\",\n \"focus-ring\",\n )}\n >\n <RotateCcw className=\"size-3\" aria-hidden=\"true\" />\n {t(\"ui.tree.retry\")}\n </button>\n </span>\n ) : (\n <span id={labelId} className=\"min-w-0 truncate\">\n {node.label}\n </span>\n )}\n\n {/* optional trailing accessory — a sibling of the label, never inside it\n and never part of the row's accessible name (#369); click/keydown/focus\n are stopped so it never selects, expands or steals the row's handling. */}\n {node.accessory ? (\n <span\n data-slot=\"tree-item-accessory\"\n className=\"ms-auto flex shrink-0 items-center gap-1\"\n onClick={(e) => e.stopPropagation()}\n // The tree's keyboard handler lives on the ROOT and preventDefaults\n // Enter/Space/arrows; without this an interactive accessory could\n // never be activated (its native click is cancelled) and the ROW\n // would be selected instead.\n onKeyDown={(e) => e.stopPropagation()}\n // React's onFocus is focusin (it bubbles), and the row's handler\n // calls setActiveId → el.focus(), which would yank focus straight\n // back out of an interactive accessory.\n onFocus={(e) => e.stopPropagation()}\n >\n {node.accessory}\n </span>\n ) : null}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Lazy-loading skeleton row (child of a loading node in non-virtual path)\n// ---------------------------------------------------------------------------\n\nfunction LoadingRow({ level }: { level: number }) {\n const { t } = useLocale();\n const indentStyle = { paddingLeft: `${(level - 1) * 1}rem` };\n return (\n <div\n role=\"treeitem\"\n aria-label={t(\"loading\")}\n aria-disabled=\"true\"\n tabIndex={-1}\n className=\"flex min-w-0 items-center gap-1.5 px-2 py-1.5\"\n style={indentStyle}\n >\n <span aria-hidden=\"true\" className=\"size-4 shrink-0\" />\n <Skeleton className=\"h-4 w-24\" />\n </div>\n );\n}\n\nfunction ErrorRow({ level, onRetry }: { level: number; onRetry: () => void }) {\n const { t } = useLocale();\n const indentStyle = { paddingLeft: `${(level - 1) * 1}rem` };\n return (\n <div\n role=\"treeitem\"\n aria-label={t(\"ui.tree.failedToLoad\")}\n aria-disabled=\"true\"\n tabIndex={-1}\n className=\"flex min-w-0 items-center gap-1.5 px-2 py-1.5 text-body text-destructive-text\"\n style={indentStyle}\n >\n <span aria-hidden=\"true\" className=\"size-4 shrink-0\" />\n <AlertCircle className=\"size-3.5 shrink-0\" aria-hidden=\"true\" />\n <span className=\"truncate\">{t(\"ui.tree.failedToLoad\")}</span>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onRetry();\n }}\n className={cn(\n \"ms-1 flex items-center gap-0.5 rounded px-1 py-0.5 text-meta\",\n \"text-muted-foreground hover:text-foreground\",\n \"focus-ring\",\n )}\n >\n <RotateCcw className=\"size-3\" aria-hidden=\"true\" />\n {t(\"ui.tree.retry\")}\n </button>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// TreeItemRow — renders a single treeitem row (recursive, non-virtual path)\n// ---------------------------------------------------------------------------\n\ninterface TreeItemProps<T> {\n node: TreeNode<T>;\n level: number;\n setSize: number;\n posInSet: number;\n expandedIds: Set<string>;\n onExpandedChange: (ids: Set<string>) => void;\n selectionMode: \"single\" | \"multiple\" | \"none\";\n selectedIds: Set<string>;\n onSelectionChange: (ids: Set<string>) => void;\n checkboxes: boolean;\n surface: \"default\" | \"sidebar\";\n expandOn: \"row\" | \"chevron\";\n activeId: string | null;\n setActiveId: (id: string | null) => void;\n registerNodeRef: (id: string, el: HTMLElement | null) => void;\n lazyState: LazyState;\n onExpandLazy: (node: TreeNode<T>) => void;\n}\n\nfunction TreeItem<T>({\n node,\n level,\n setSize,\n posInSet,\n expandedIds,\n onExpandedChange,\n selectionMode,\n selectedIds,\n onSelectionChange,\n checkboxes,\n surface,\n expandOn,\n activeId,\n setActiveId,\n registerNodeRef,\n lazyState,\n onExpandLazy,\n}: TreeItemProps<T>) {\n const hasLoadedChildren = !!node.children?.length;\n // A node is expandable if it has loaded children OR the hasChildren flag is set\n const expandable = hasLoadedChildren || !!node.hasChildren;\n const isExpanded = expandable && expandedIds.has(node.id);\n const isSelected = selectedIds.has(node.id);\n const isActive = activeId === node.id;\n const nodeLoadState: LoadState = lazyState[node.id] ?? \"idle\";\n const isLoading = nodeLoadState === \"loading\";\n const isError = nodeLoadState === \"error\";\n // See VirtualFlatRow: a ReactNode label must name the row via `aria-labelledby`\n // so the trailing accessory never joins the accessible name (#369).\n const labelId = useId();\n\n const toggleExpanded = () => {\n if (!expandable) return;\n const next = new Set(expandedIds);\n if (isExpanded) {\n next.delete(node.id);\n } else {\n next.add(node.id);\n // If no loaded children yet, trigger lazy load\n if (!hasLoadedChildren && node.hasChildren) {\n onExpandLazy(node);\n }\n }\n onExpandedChange(next);\n };\n\n const handleSelect = () => {\n if (node.disabled || selectionMode === \"none\") return;\n setActiveId(node.id);\n if (selectionMode === \"single\") {\n onSelectionChange(new Set([node.id]));\n } else {\n const next = new Set(selectedIds);\n if (next.has(node.id)) {\n next.delete(node.id);\n } else {\n next.add(node.id);\n }\n onSelectionChange(next);\n }\n };\n\n const handleRowClick = () => {\n setActiveId(node.id);\n handleSelect();\n if (expandable && expandOn === \"row\") toggleExpanded();\n };\n\n const indentStyle = { paddingLeft: `${(level - 1) * 1}rem` };\n\n return (\n <li role=\"none\">\n {/* treeitem row */}\n <div\n role=\"treeitem\"\n aria-expanded={expandable ? isExpanded : undefined}\n aria-selected={selectionMode !== \"none\" && !checkboxes ? isSelected : undefined}\n aria-checked={checkboxes ? isSelected : undefined}\n aria-label={typeof node.label === \"string\" ? node.label : undefined}\n aria-labelledby={typeof node.label === \"string\" ? undefined : labelId}\n aria-level={level}\n aria-setsize={setSize}\n aria-posinset={posInSet}\n aria-disabled={node.disabled ? true : undefined}\n aria-busy={isLoading ? true : undefined}\n tabIndex={isActive ? 0 : -1}\n data-tree-id={node.id}\n ref={(el) => registerNodeRef(node.id, el)}\n onClick={node.disabled ? undefined : handleRowClick}\n onFocus={() => setActiveId(node.id)}\n className={cn(\n \"flex min-w-0 cursor-pointer select-none items-center gap-1.5 rounded-md px-2 py-1.5 text-body outline-none\",\n \"transition-colors duration-fast ease-standard motion-reduce:transition-none\",\n \"hover:bg-accent hover:text-accent-foreground\",\n \"focus-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background\",\n isSelected &&\n selectionMode !== \"none\" &&\n (surface === \"sidebar\"\n ? \"bg-sidebar-accent text-sidebar-accent-foreground font-medium\"\n : \"bg-selection text-selection-foreground font-medium\"),\n node.disabled && \"cursor-not-allowed opacity-50 pointer-events-none\",\n )}\n style={indentStyle}\n >\n {/* expand/collapse chevron */}\n {expandable ? (\n <span\n aria-hidden=\"true\"\n onClick={(e) => {\n e.stopPropagation();\n toggleExpanded();\n }}\n className={cn(\n \"flex size-4 shrink-0 items-center justify-center rounded transition-transform duration-fast ease-standard motion-reduce:transition-none\",\n isExpanded && !isLoading && \"rotate-90\",\n )}\n >\n {isLoading ? (\n <Spinner className=\"size-3.5\" label=\"Loading children\" />\n ) : (\n <ChevronRight className=\"size-3.5 text-muted-foreground\" aria-hidden=\"true\" />\n )}\n </span>\n ) : (\n <span aria-hidden=\"true\" className=\"size-4 shrink-0\" />\n )}\n\n {/* optional checkbox for multi-select */}\n {checkboxes && selectionMode === \"multiple\" && (\n <Checkbox\n checked={isSelected}\n disabled={node.disabled}\n aria-hidden=\"true\"\n tabIndex={-1}\n onClick={(e) => {\n e.stopPropagation();\n handleSelect();\n }}\n className=\"shrink-0\"\n />\n )}\n\n {/* optional node icon */}\n {node.icon && (\n <span aria-hidden=\"true\" className=\"flex size-4 shrink-0 items-center justify-center\">\n {node.icon}\n </span>\n )}\n\n {/* label */}\n <span id={labelId} className=\"min-w-0 truncate\">\n {node.label}\n </span>\n\n {/* optional trailing accessory — a sibling of the label, never inside\n it and never part of the row's accessible name (#369);\n click/keydown/focus are stopped at the accessory. */}\n {node.accessory ? (\n <span\n data-slot=\"tree-item-accessory\"\n className=\"ms-auto flex shrink-0 items-center gap-1\"\n onClick={(e) => e.stopPropagation()}\n // See VirtualFlatRow: the tree's root keydown handler preventDefaults\n // Enter/Space/arrows, and the row's onFocus (focusin, bubbling) calls\n // setActiveId → el.focus(). Both must stop at the accessory or\n // interactive content in this slot is unusable.\n onKeyDown={(e) => e.stopPropagation()}\n onFocus={(e) => e.stopPropagation()}\n >\n {node.accessory}\n </span>\n ) : null}\n </div>\n\n {/* children group */}\n {isExpanded && (\n <ul role=\"group\" className=\"list-none m-0 p-0\">\n {isLoading ? (\n <li role=\"none\">\n <LoadingRow level={level + 1} />\n </li>\n ) : isError ? (\n <li role=\"none\">\n <ErrorRow level={level + 1} onRetry={() => onExpandLazy(node)} />\n </li>\n ) : (\n node.children?.map((child, i) => (\n <TreeItem\n key={child.id}\n node={child}\n level={level + 1}\n setSize={node.children!.length}\n posInSet={i + 1}\n expandedIds={expandedIds}\n onExpandedChange={onExpandedChange}\n selectionMode={selectionMode}\n selectedIds={selectedIds}\n onSelectionChange={onSelectionChange}\n checkboxes={checkboxes}\n surface={surface}\n expandOn={expandOn}\n activeId={activeId}\n setActiveId={setActiveId}\n registerNodeRef={registerNodeRef}\n lazyState={lazyState}\n onExpandLazy={onExpandLazy}\n />\n ))\n )}\n </ul>\n )}\n </li>\n );\n}\n\n// ---------------------------------------------------------------------------\n// flattenVisibleWithMeta — for the virtual path\n// ---------------------------------------------------------------------------\n\nfunction flattenVisibleWithMeta<T>(\n nodes: TreeNode<T>[],\n expandedIds: Set<string>,\n lazyState: LazyState,\n level = 1,\n parentSetSize?: number,\n): FlatRow<T>[] {\n const result: FlatRow<T>[] = [];\n const setSize = parentSetSize ?? nodes.length;\n nodes.forEach((node, i) => {\n result.push({\n node,\n level,\n setSize,\n posInSet: i + 1,\n });\n const hasLoadedChildren = !!node.children?.length;\n const isExpandable = hasLoadedChildren || !!node.hasChildren;\n if (isExpandable && expandedIds.has(node.id)) {\n const nodeLoad = lazyState[node.id];\n if (nodeLoad === \"loading\" || nodeLoad === \"error\") {\n // placeholder row represented by a synthetic \"loading/error\" node\n // We don't push a row here — the loading/error state is shown via\n // aria-busy on the parent treeitem row (virtual path inline indicators)\n } else if (hasLoadedChildren) {\n const childRows = flattenVisibleWithMeta(\n node.children!,\n expandedIds,\n lazyState,\n level + 1,\n node.children!.length,\n );\n result.push(...childRows);\n }\n }\n });\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Tree — root component\n// ---------------------------------------------------------------------------\n\n/**\n * A fully accessible tree view with roving tabindex keyboard navigation,\n * single/multiple selection, expand/collapse, checkboxes, and type-ahead.\n *\n * Set `virtualize` to window large trees (>50 visible rows). Set `loadChildren`\n * to lazily fetch children on demand when a node has `hasChildren: true`.\n */\n/** Ancestor ids (root → parent) of `id` within the loaded tree, or `null` if absent. */\nfunction findNodePath(nodes: TreeNode[], id: string, trail: string[] = []): string[] | null {\n for (const n of nodes) {\n if (n.id === id) return trail;\n if (n.children?.length) {\n const found = findNodePath(n.children, id, [...trail, n.id]);\n if (found) return found;\n }\n }\n return null;\n}\n\n/** The node with `id` within the loaded tree, or `null`. */\nfunction findNodeById(nodes: TreeNode[], id: string): TreeNode | null {\n for (const n of nodes) {\n if (n.id === id) return n;\n if (n.children?.length) {\n const found = findNodeById(n.children, id);\n if (found) return found;\n }\n }\n return null;\n}\n\nexport const Tree = forwardRef<HTMLDivElement, TreeProps>(function Tree(\n {\n nodes: nodesProp,\n expandedIds: expandedIdsProp,\n defaultExpandedIds,\n onExpandedChange,\n selectionMode = \"single\",\n selectedIds: selectedIdsProp,\n defaultSelectedIds,\n onSelectionChange,\n checkboxes = false,\n virtualize = false,\n estimateRowHeight = 32,\n overscan = 8,\n maxHeight,\n scrollToId,\n scrollSelectionIntoView = false,\n loadChildren,\n surface = \"default\",\n expandOn = \"row\",\n className,\n ...props\n },\n ref,\n) {\n // Internal mutable tree (supports lazy-loaded children merge)\n const [nodes, setNodes] = useState<TreeNode[]>(() => nodesProp as TreeNode[]);\n\n // Keep internal tree in sync with nodesProp if it changes externally,\n // preserving any children merged in locally via lazy `loadChildren`.\n useEffect(() => {\n setNodes((prev) => reconcileNodes(nodesProp as TreeNode[], prev));\n }, [nodesProp]);\n\n const [expandedIds, setExpandedIds] = useControllableSet(\n expandedIdsProp,\n defaultExpandedIds,\n onExpandedChange,\n );\n const [selectedIds, setSelectedIds] = useControllableSet(\n selectedIdsProp,\n defaultSelectedIds,\n onSelectionChange,\n );\n\n // Lazy-load state per node id\n const [lazyState, setLazyState] = useState<LazyState>({});\n\n // Scroll container ref for virtualizer\n const scrollRef = useRef<HTMLDivElement>(null);\n\n // Pending focus id — used when the target row isn't yet mounted (virtual path)\n const pendingFocusIdRef = useRef<string | null>(null);\n\n // ---------------------------------------------------------------------------\n // Lazy load handler\n // ---------------------------------------------------------------------------\n\n const handleExpandLazy = useCallback(\n async (node: TreeNode) => {\n if (!loadChildren) return;\n if (lazyState[node.id] === \"loading\") return;\n\n setLazyState((prev) => ({ ...prev, [node.id]: \"loading\" }));\n try {\n const children = await loadChildren(node as TreeNode<unknown>);\n setNodes((prev) => mergeChildren(prev, node.id, children as TreeNode[]));\n setLazyState((prev) => {\n const next = { ...prev };\n delete next[node.id];\n return next;\n });\n } catch {\n setLazyState((prev) => ({ ...prev, [node.id]: \"error\" }));\n }\n },\n [loadChildren, lazyState],\n );\n\n // ---------------------------------------------------------------------------\n // Flattened visible rows (for virtualized path and keyboard hook)\n // ---------------------------------------------------------------------------\n\n const flatRows = useMemo(\n () => flattenVisibleWithMeta(nodes, expandedIds, lazyState),\n [nodes, expandedIds, lazyState],\n );\n const flatNodeIds = useMemo(() => flatRows.map((r) => r.node.id), [flatRows]);\n // O(1) row lookup by id — `handleToggleExpand`/`handleSelectVirtual` run on\n // every click/keypress and previously did an O(n) `Array.find` each time.\n const flatRowIndexById = useMemo(() => {\n const map = new Map<string, number>();\n flatRows.forEach((r, i) => map.set(r.node.id, i));\n return map;\n }, [flatRows]);\n\n // ---------------------------------------------------------------------------\n // Keyboard hook\n // ---------------------------------------------------------------------------\n\n // For the virtual path: when navigating to a node whose DOM is not mounted,\n // we need to scroll to it first and then focus when it mounts.\n // We achieve this by passing a scrollToIndex callback to the keyboard hook.\n\n const virtualizerRef = useRef<Virtualizer<HTMLDivElement, Element> | null>(null);\n\n const scrollToVirtualIndex = useCallback((index: number) => {\n virtualizerRef.current?.scrollToIndex(index, { align: \"auto\" });\n }, []);\n\n const { activeId, setActiveId, registerNodeRef, onKeyDown } = useTreeKeyboard({\n nodes,\n expandedIds,\n onExpandedChange: setExpandedIds,\n selectionMode,\n selectedIds,\n onSelectionChange: setSelectedIds,\n // Virtualization-aware extras\n virtualize,\n flatNodeIds,\n pendingFocusIdRef,\n scrollToVirtualIndex,\n });\n\n // ---------------------------------------------------------------------------\n // Handle expand/collapse for virtual path (needs to call lazy loader)\n // ---------------------------------------------------------------------------\n\n const handleToggleExpand = useCallback(\n (nodeId: string) => {\n const index = flatRowIndexById.get(nodeId);\n if (index === undefined) return;\n const node = flatRows[index]?.node;\n if (!node) return;\n const hasLoadedChildren = !!node.children?.length;\n const next = new Set(expandedIds);\n if (expandedIds.has(nodeId)) {\n next.delete(nodeId);\n } else {\n next.add(nodeId);\n if (!hasLoadedChildren && node.hasChildren && loadChildren) {\n handleExpandLazy(node);\n }\n }\n setExpandedIds(next);\n },\n [expandedIds, flatRows, flatRowIndexById, setExpandedIds, loadChildren, handleExpandLazy],\n );\n\n const handleSelectVirtual = useCallback(\n (nodeId: string) => {\n const index = flatRowIndexById.get(nodeId);\n if (index === undefined) return;\n const node = flatRows[index]?.node;\n if (!node || node.disabled || selectionMode === \"none\") return;\n if (selectionMode === \"single\") {\n setSelectedIds(new Set([nodeId]));\n } else {\n const next = new Set(selectedIds);\n if (next.has(nodeId)) {\n next.delete(nodeId);\n } else {\n next.add(nodeId);\n }\n setSelectedIds(next);\n }\n },\n [flatRows, flatRowIndexById, selectionMode, selectedIds, setSelectedIds],\n );\n\n // ---------------------------------------------------------------------------\n // Layout effect to flush pending focus once a row mounts (virtual path)\n // ---------------------------------------------------------------------------\n\n // This runs after every render; if pendingFocusIdRef has an id, try to focus it.\n // The registerNodeRef callback will have stored the element if it mounted.\n // We use useLayoutEffect so the DOM is painted before we try to focus.\n const nodeRefsForFlush = useRef<Map<string, HTMLElement>>(new Map());\n\n const registerAndFlush = useCallback(\n (id: string, el: HTMLElement | null) => {\n registerNodeRef(id, el);\n if (el) {\n nodeRefsForFlush.current.set(id, el);\n if (pendingFocusIdRef.current === id) {\n pendingFocusIdRef.current = null;\n el.focus();\n }\n } else {\n nodeRefsForFlush.current.delete(id);\n }\n },\n [registerNodeRef],\n );\n\n // ---------------------------------------------------------------------------\n // Virtualizer (only created in virtual mode)\n // ---------------------------------------------------------------------------\n\n const virtualizer = useVirtualizer({\n count: flatRows.length,\n getScrollElement: () => (virtualize ? scrollRef.current : null),\n estimateSize: () => estimateRowHeight,\n overscan,\n enabled: virtualize,\n });\n\n // Keep ref so keyboard handler can call scrollToIndex\n useEffect(() => {\n if (virtualize) {\n virtualizerRef.current = virtualizer;\n }\n });\n\n // ---------------------------------------------------------------------------\n // Reveal-into-view (scrollToId / scrollSelectionIntoView)\n // ---------------------------------------------------------------------------\n\n // Set while a requested node isn't yet a visible row (its ancestors are still\n // expanding / lazy-loading); the retry effect finishes once the rows change.\n const pendingRevealIdRef = useRef<string | null>(null);\n const prevSelectedRef = useRef<Set<string>>(selectedIds);\n const prevScrollToIdRef = useRef<string | undefined>(undefined);\n\n // Scroll `id` into view if it is currently a visible row. Virtual mode drives\n // the virtualizer (the row may be unmounted); non-virtual uses the mounted DOM\n // node (registered via registerAndFlush in both paths).\n const scrollNodeIntoView = useCallback(\n (id: string): boolean => {\n const index = flatRowIndexById.get(id);\n if (index === undefined) return false;\n if (virtualize) {\n virtualizerRef.current?.scrollToIndex(index, { align: \"center\" });\n } else {\n // `?.` on scrollIntoView too — jsdom doesn't implement it (browser-only).\n nodeRefsForFlush.current.get(id)?.scrollIntoView?.({ block: \"center\" });\n }\n return true;\n },\n [flatRowIndexById, virtualize],\n );\n\n // Reveal `id`: scroll it now if visible, else expand its (loaded) ancestors and\n // kick their lazy loaders so it becomes a row — the retry effect finishes the job.\n const revealNode = useCallback(\n (id: string) => {\n if (scrollNodeIntoView(id)) {\n pendingRevealIdRef.current = null;\n return;\n }\n pendingRevealIdRef.current = id;\n const path = findNodePath(nodes, id);\n if (!path || path.length === 0) return; // unknown / not yet loaded — best effort\n const next = new Set(expandedIds);\n path.forEach((ancestorId) => next.add(ancestorId));\n setExpandedIds(next);\n if (loadChildren) {\n for (const ancestorId of path) {\n const anc = findNodeById(nodes, ancestorId);\n if (anc && anc.hasChildren && !anc.children?.length) void handleExpandLazy(anc);\n }\n }\n },\n [scrollNodeIntoView, nodes, expandedIds, setExpandedIds, loadChildren, handleExpandLazy],\n );\n\n // Latest revealNode so the trigger effect fires on target CHANGE only (without\n // re-running when flatNodeIds / expandedIds churn each render).\n const revealNodeRef = useRef(revealNode);\n revealNodeRef.current = revealNode;\n\n // Trigger: reveal when `scrollToId` changes; else (scrollSelectionIntoView) when\n // the selection gains a node. `scrollToId` wins.\n useEffect(() => {\n const scrollIdChanged = scrollToId !== prevScrollToIdRef.current;\n const selectionChanged = selectedIds !== prevSelectedRef.current;\n const prevSel = prevSelectedRef.current;\n prevScrollToIdRef.current = scrollToId;\n prevSelectedRef.current = selectedIds;\n\n if (scrollToId != null && scrollIdChanged) {\n revealNodeRef.current(scrollToId);\n } else if (scrollToId == null && scrollSelectionIntoView && selectionChanged) {\n const added = [...selectedIds].find((sid) => !prevSel.has(sid));\n const target = added ?? (selectedIds.size > 0 ? [...selectedIds][0] : undefined);\n if (target != null) revealNodeRef.current(target);\n }\n }, [scrollToId, scrollSelectionIntoView, selectedIds]);\n\n // Retry a pending reveal after the rows change (ancestors expanded / lazy data\n // arrived) — scroll once the node materialises, then clear.\n useEffect(() => {\n const id = pendingRevealIdRef.current;\n if (id != null && scrollNodeIntoView(id)) {\n pendingRevealIdRef.current = null;\n }\n }, [scrollNodeIntoView]);\n\n // ---------------------------------------------------------------------------\n // Render: NON-virtual path (backward compatible nested-group DOM)\n // ---------------------------------------------------------------------------\n\n if (!virtualize) {\n return (\n <div\n ref={ref}\n role=\"tree\"\n aria-multiselectable={selectionMode === \"multiple\" ? true : undefined}\n onKeyDown={onKeyDown}\n className={cn(\"w-full select-none\", className)}\n {...props}\n >\n <ul role=\"none\" className=\"m-0 list-none p-0\">\n {nodes.map((node, i) => (\n <TreeItem\n key={node.id}\n node={node}\n level={1}\n setSize={nodes.length}\n posInSet={i + 1}\n expandedIds={expandedIds}\n onExpandedChange={setExpandedIds}\n selectionMode={selectionMode}\n selectedIds={selectedIds}\n onSelectionChange={setSelectedIds}\n checkboxes={checkboxes}\n surface={surface}\n expandOn={expandOn}\n activeId={activeId}\n setActiveId={setActiveId}\n // registerAndFlush (not raw registerNodeRef) so nodeRefsForFlush is\n // populated in the non-virtual path too — lets scrollToId reveal a\n // below-the-fold node. pendingFocusIdRef is virtual-only, so the\n // focus-flush branch never fires here: keyboard behavior is unchanged.\n registerNodeRef={registerAndFlush}\n lazyState={lazyState}\n onExpandLazy={handleExpandLazy}\n />\n ))}\n </ul>\n </div>\n );\n }\n\n // ---------------------------------------------------------------------------\n // Render: VIRTUAL path (flat DOM, windowed rows)\n // ---------------------------------------------------------------------------\n\n const virtualItems = virtualizer.getVirtualItems();\n\n const scrollStyle: React.CSSProperties = maxHeight\n ? { maxHeight, overflowY: \"auto\" }\n : { overflowY: \"auto\" };\n\n return (\n <div\n ref={ref}\n role=\"tree\"\n aria-multiselectable={selectionMode === \"multiple\" ? true : undefined}\n onKeyDown={onKeyDown}\n className={cn(\"w-full select-none\", className)}\n {...props}\n >\n {/* Scroll viewport — role=\"presentation\" so the tree still OWNS the\n treeitems (windowing wrappers are skipped in the a11y tree, keeping\n aria-required-children valid). */}\n <div ref={scrollRef} role=\"presentation\" style={scrollStyle} className=\"outline-none\">\n {/* Total-size spacer — gives the scroll container its full height */}\n <div\n role=\"presentation\"\n style={{ height: virtualizer.getTotalSize(), position: \"relative\" }}\n >\n {virtualItems.map((virtualRow) => {\n const row = flatRows[virtualRow.index];\n if (!row) return null;\n const { node } = row;\n const hasLoadedChildren = !!node.children?.length;\n const expandable = hasLoadedChildren || !!node.hasChildren;\n const isExpanded = expandable && expandedIds.has(node.id);\n const isSelected = selectedIds.has(node.id);\n const isActive = activeId === node.id;\n const nodeLoad: LoadState = lazyState[node.id] ?? \"idle\";\n\n return (\n <div\n key={virtualRow.key}\n role=\"presentation\"\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: `${virtualRow.size}px`,\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n <VirtualFlatRow\n row={row}\n isExpanded={isExpanded}\n isSelected={isSelected}\n isActive={isActive}\n lazyState={nodeLoad}\n expandable={expandable}\n selectionMode={selectionMode}\n checkboxes={checkboxes}\n surface={surface}\n expandOn={expandOn}\n onToggleExpand={handleToggleExpand}\n onSelect={handleSelectVirtual}\n onRetry={() => handleExpandLazy(node)}\n registerNodeRef={registerAndFlush}\n setActiveId={setActiveId}\n />\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n}) as <T = unknown>(\n props: TreeProps<T> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement | null;\n"],"mappings":"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","names":["Tree"]}
@@ -57,8 +57,10 @@ var ToolbarSeparator = forwardRef(function ToolbarSeparator2({ className, ...pro
57
57
  "data-slot": "toolbar-separator",
58
58
  className: cn(
59
59
  "bg-border-strong mx-1 shrink-0",
60
- "data-[orientation=horizontal]:h-5 data-[orientation=horizontal]:w-px",
61
- "data-[orientation=vertical]:h-px data-[orientation=vertical]:w-5",
60
+ // Radix flips the separator's orientation relative to the toolbar: a HORIZONTAL toolbar
61
+ // gets `data-orientation="vertical"` separators (a vertical hairline between groups).
62
+ "data-[orientation=vertical]:h-5 data-[orientation=vertical]:w-px",
63
+ "data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-5",
62
64
  className
63
65
  ),
64
66
  ...props
@@ -98,4 +100,4 @@ export {
98
100
  ToolbarToggleItem,
99
101
  ToolbarSlot
100
102
  };
101
- //# sourceMappingURL=chunk-ERTYAID6.js.map
103
+ //# sourceMappingURL=chunk-5QQFXDUY.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/toolbar/toolbar.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Toolbar — the ONE row that genuinely claims `role=\"toolbar\"`.\n *\n * The role is a promise: a toolbar is a SINGLE tab stop, and the arrow keys move\n * between its controls (WAI-ARIA APG). Four rows in this repo claim the role\n * without implementing that, which is worse than not claiming it — a screen\n * reader tells the user to press the arrow keys and nothing happens. This\n * component delegates the roving tabindex to `@radix-ui/react-toolbar` so the\n * promise is kept, and exists so no one has to hand-roll it again.\n *\n * When NOT to use it. A row of ordinary controls above a list or table is a\n * `ViewToolbar` — that component deliberately does not claim the role, because\n * every control there is an ordinary tab stop and readers expect Tab, not\n * arrows. Reach for `Toolbar` when the row is DENSE and SECONDARY to the content\n * it acts on (a document's page/zoom controls, a formatting bar): collapsing a\n * dozen controls into one tab stop is what makes the content reachable again.\n *\n * Anatomy — a shell plus three composable parts. There is no `actions` prop and\n * no items array: a toolbar's layout is the caller's, so groups are arranged\n * with ordinary flex utilities and `ToolbarSeparator` between them.\n */\n\nimport * as ToolbarPrimitive from \"@radix-ui/react-toolbar\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { forwardRef, type ComponentPropsWithoutRef, type ElementRef } from \"react\";\n\nimport { cn } from \"../../lib/cn\";\nimport { buttonVariants } from \"../button\";\nimport { toggleVariants } from \"../toggle\";\n\n/* -------------------------------------------------------------------------- */\n/* Root */\n/* -------------------------------------------------------------------------- */\n\nexport const toolbarVariants = cva(\"flex items-center gap-1\", {\n variants: {\n orientation: {\n horizontal: \"flex-row\",\n // Radix already writes `aria-orientation`; this only lays it out.\n vertical: \"h-full flex-col\",\n },\n },\n defaultVariants: { orientation: \"horizontal\" },\n});\n\nexport interface ToolbarProps\n extends\n Omit<ComponentPropsWithoutRef<typeof ToolbarPrimitive.Root>, \"orientation\">,\n VariantProps<typeof toolbarVariants> {\n /**\n * What this toolbar acts on (\"Document\", \"Formatting\"). A toolbar is one tab\n * stop with several controls inside it, so without a name a screen-reader\n * user lands on an anonymous group — hence required, not optional.\n */\n \"aria-label\": string;\n}\n\n/**\n * The row shell. Renders no surface of its own: a toolbar sits ON something\n * (a card header, a document frame) and inherits that surface, so painting a\n * background here would double the fill wherever it is placed.\n */\nexport const Toolbar = forwardRef<ElementRef<typeof ToolbarPrimitive.Root>, ToolbarProps>(\n function Toolbar({ className, orientation, ...props }, ref) {\n return (\n <ToolbarPrimitive.Root\n ref={ref}\n data-slot=\"toolbar\"\n orientation={orientation ?? \"horizontal\"}\n className={cn(toolbarVariants({ orientation }), className)}\n {...props}\n />\n );\n },\n);\n\n/* -------------------------------------------------------------------------- */\n/* Parts */\n/* -------------------------------------------------------------------------- */\n\nexport interface ToolbarButtonProps\n extends\n ComponentPropsWithoutRef<typeof ToolbarPrimitive.Button>,\n Pick<VariantProps<typeof buttonVariants>, \"variant\" | \"size\"> {}\n\n/**\n * A control inside the toolbar. Styled with `buttonVariants` — the same ink,\n * heights and focus ring as every other button in the system, not a parallel\n * set. Icon-only controls take `size=\"icon-sm\"` and MUST carry an `aria-label`;\n * wrap in a `Tooltip` when the glyph needs a name on screen too.\n */\nexport const ToolbarButton = forwardRef<\n ElementRef<typeof ToolbarPrimitive.Button>,\n ToolbarButtonProps\n>(function ToolbarButton({ className, variant = \"ghost\", size = \"sm\", ...props }, ref) {\n return (\n <ToolbarPrimitive.Button\n ref={ref}\n data-slot=\"toolbar-button\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n );\n});\n\nexport type ToolbarSeparatorProps = ComponentPropsWithoutRef<typeof ToolbarPrimitive.Separator>;\n\n/**\n * The divider between two groups of controls. It is the ONLY cue between two\n * same-fill regions of the row, so it takes the strong rung (WCAG 1.4.11,\n * ADR 0010) — `Separator`'s subtle default would be a decorative hairline here.\n */\nexport const ToolbarSeparator = forwardRef<\n ElementRef<typeof ToolbarPrimitive.Separator>,\n ToolbarSeparatorProps\n>(function ToolbarSeparator({ className, ...props }, ref) {\n return (\n <ToolbarPrimitive.Separator\n ref={ref}\n data-slot=\"toolbar-separator\"\n className={cn(\n \"bg-border-strong mx-1 shrink-0\",\n \"data-[orientation=horizontal]:h-5 data-[orientation=horizontal]:w-px\",\n \"data-[orientation=vertical]:h-px data-[orientation=vertical]:w-5\",\n className,\n )}\n {...props}\n />\n );\n});\n\nexport type ToolbarToggleGroupProps = ComponentPropsWithoutRef<typeof ToolbarPrimitive.ToggleGroup>;\n\n/** A set of mutually-exclusive or multi-select toggles (a view switcher, bold/italic). */\nexport const ToolbarToggleGroup = forwardRef<\n ElementRef<typeof ToolbarPrimitive.ToggleGroup>,\n ToolbarToggleGroupProps\n>(function ToolbarToggleGroup({ className, ...props }, ref) {\n return (\n <ToolbarPrimitive.ToggleGroup\n ref={ref}\n data-slot=\"toolbar-toggle-group\"\n className={cn(\"flex items-center gap-1\", className)}\n {...props}\n />\n );\n});\n\nexport interface ToolbarToggleItemProps\n extends\n ComponentPropsWithoutRef<typeof ToolbarPrimitive.ToggleItem>,\n Pick<VariantProps<typeof toggleVariants>, \"size\"> {}\n\n/** One toggle. Shares `Toggle`'s pressed styling, so state reads the same everywhere. */\nexport const ToolbarToggleItem = forwardRef<\n ElementRef<typeof ToolbarPrimitive.ToggleItem>,\n ToolbarToggleItemProps\n>(function ToolbarToggleItem({ className, size = \"sm\", ...props }, ref) {\n return (\n <ToolbarPrimitive.ToggleItem\n ref={ref}\n data-slot=\"toolbar-toggle-item\"\n className={cn(toggleVariants({ size }), className)}\n {...props}\n />\n );\n});\n\n/**\n * An escape hatch for anything the parts above do not cover — a `Select`, an\n * input, a `DropdownMenu` trigger. `asChild` hands the roving-tabindex wiring to\n * whatever you render, so the control stays part of the arrow-key sequence\n * instead of becoming a second tab stop inside a single-tab-stop row.\n */\nexport const ToolbarSlot = ToolbarPrimitive.Button;\n"],"mappings":";;;;;;;;;;;;AAwBA,YAAY,sBAAsB;AAClC,SAAS,WAA8B;AACvC,SAAS,kBAAkE;AAyCrE;AA/BC,IAAM,kBAAkB,IAAI,2BAA2B;AAAA,EAC5D,UAAU;AAAA,IACR,aAAa;AAAA,MACX,YAAY;AAAA;AAAA,MAEZ,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,aAAa,aAAa;AAC/C,CAAC;AAmBM,IAAM,UAAU;AAAA,EACrB,SAASA,SAAQ,EAAE,WAAW,aAAa,GAAG,MAAM,GAAG,KAAK;AAC1D,WACE;AAAA,MAAkB;AAAA,MAAjB;AAAA,QACC;AAAA,QACA,aAAU;AAAA,QACV,aAAa,eAAe;AAAA,QAC5B,WAAW,GAAG,gBAAgB,EAAE,YAAY,CAAC,GAAG,SAAS;AAAA,QACxD,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAiBO,IAAM,gBAAgB,WAG3B,SAASC,eAAc,EAAE,WAAW,UAAU,SAAS,OAAO,MAAM,GAAG,MAAM,GAAG,KAAK;AACrF,SACE;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,EAAE,SAAS,KAAK,CAAC,GAAG,SAAS;AAAA,MACzD,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AASM,IAAM,mBAAmB,WAG9B,SAASC,kBAAiB,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AACxD,SACE;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AAKM,IAAM,qBAAqB,WAGhC,SAASC,oBAAmB,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AAC1D,SACE;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW,GAAG,2BAA2B,SAAS;AAAA,MACjD,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AAQM,IAAM,oBAAoB,WAG/B,SAASC,mBAAkB,EAAE,WAAW,OAAO,MAAM,GAAG,MAAM,GAAG,KAAK;AACtE,SACE;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,EAAE,KAAK,CAAC,GAAG,SAAS;AAAA,MAChD,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AAQM,IAAM,cAA+B;","names":["Toolbar","ToolbarButton","ToolbarSeparator","ToolbarToggleGroup","ToolbarToggleItem"]}
1
+ {"version":3,"sources":["../src/components/toolbar/toolbar.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Toolbar — the ONE row that genuinely claims `role=\"toolbar\"`.\n *\n * The role is a promise: a toolbar is a SINGLE tab stop, and the arrow keys move\n * between its controls (WAI-ARIA APG). Four rows in this repo claim the role\n * without implementing that, which is worse than not claiming it — a screen\n * reader tells the user to press the arrow keys and nothing happens. This\n * component delegates the roving tabindex to `@radix-ui/react-toolbar` so the\n * promise is kept, and exists so no one has to hand-roll it again.\n *\n * When NOT to use it. A row of ordinary controls above a list or table is a\n * `ViewToolbar` — that component deliberately does not claim the role, because\n * every control there is an ordinary tab stop and readers expect Tab, not\n * arrows. Reach for `Toolbar` when the row is DENSE and SECONDARY to the content\n * it acts on (a document's page/zoom controls, a formatting bar): collapsing a\n * dozen controls into one tab stop is what makes the content reachable again.\n *\n * Anatomy — a shell plus three composable parts. There is no `actions` prop and\n * no items array: a toolbar's layout is the caller's, so groups are arranged\n * with ordinary flex utilities and `ToolbarSeparator` between them.\n */\n\nimport * as ToolbarPrimitive from \"@radix-ui/react-toolbar\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { forwardRef, type ComponentPropsWithoutRef, type ElementRef } from \"react\";\n\nimport { cn } from \"../../lib/cn\";\nimport { buttonVariants } from \"../button\";\nimport { toggleVariants } from \"../toggle\";\n\n/* -------------------------------------------------------------------------- */\n/* Root */\n/* -------------------------------------------------------------------------- */\n\nexport const toolbarVariants = cva(\"flex items-center gap-1\", {\n variants: {\n orientation: {\n horizontal: \"flex-row\",\n // Radix already writes `aria-orientation`; this only lays it out.\n vertical: \"h-full flex-col\",\n },\n },\n defaultVariants: { orientation: \"horizontal\" },\n});\n\nexport interface ToolbarProps\n extends\n Omit<ComponentPropsWithoutRef<typeof ToolbarPrimitive.Root>, \"orientation\">,\n VariantProps<typeof toolbarVariants> {\n /**\n * What this toolbar acts on (\"Document\", \"Formatting\"). A toolbar is one tab\n * stop with several controls inside it, so without a name a screen-reader\n * user lands on an anonymous group — hence required, not optional.\n */\n \"aria-label\": string;\n}\n\n/**\n * The row shell. Renders no surface of its own: a toolbar sits ON something\n * (a card header, a document frame) and inherits that surface, so painting a\n * background here would double the fill wherever it is placed.\n */\nexport const Toolbar = forwardRef<ElementRef<typeof ToolbarPrimitive.Root>, ToolbarProps>(\n function Toolbar({ className, orientation, ...props }, ref) {\n return (\n <ToolbarPrimitive.Root\n ref={ref}\n data-slot=\"toolbar\"\n orientation={orientation ?? \"horizontal\"}\n className={cn(toolbarVariants({ orientation }), className)}\n {...props}\n />\n );\n },\n);\n\n/* -------------------------------------------------------------------------- */\n/* Parts */\n/* -------------------------------------------------------------------------- */\n\nexport interface ToolbarButtonProps\n extends\n ComponentPropsWithoutRef<typeof ToolbarPrimitive.Button>,\n Pick<VariantProps<typeof buttonVariants>, \"variant\" | \"size\"> {}\n\n/**\n * A control inside the toolbar. Styled with `buttonVariants` — the same ink,\n * heights and focus ring as every other button in the system, not a parallel\n * set. Icon-only controls take `size=\"icon-sm\"` and MUST carry an `aria-label`;\n * wrap in a `Tooltip` when the glyph needs a name on screen too.\n */\nexport const ToolbarButton = forwardRef<\n ElementRef<typeof ToolbarPrimitive.Button>,\n ToolbarButtonProps\n>(function ToolbarButton({ className, variant = \"ghost\", size = \"sm\", ...props }, ref) {\n return (\n <ToolbarPrimitive.Button\n ref={ref}\n data-slot=\"toolbar-button\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n );\n});\n\nexport type ToolbarSeparatorProps = ComponentPropsWithoutRef<typeof ToolbarPrimitive.Separator>;\n\n/**\n * The divider between two groups of controls. It is the ONLY cue between two\n * same-fill regions of the row, so it takes the strong rung (WCAG 1.4.11,\n * ADR 0010) — `Separator`'s subtle default would be a decorative hairline here.\n */\nexport const ToolbarSeparator = forwardRef<\n ElementRef<typeof ToolbarPrimitive.Separator>,\n ToolbarSeparatorProps\n>(function ToolbarSeparator({ className, ...props }, ref) {\n return (\n <ToolbarPrimitive.Separator\n ref={ref}\n data-slot=\"toolbar-separator\"\n className={cn(\n \"bg-border-strong mx-1 shrink-0\",\n // Radix flips the separator's orientation relative to the toolbar: a HORIZONTAL toolbar\n // gets `data-orientation=\"vertical\"` separators (a vertical hairline between groups).\n \"data-[orientation=vertical]:h-5 data-[orientation=vertical]:w-px\",\n \"data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-5\",\n className,\n )}\n {...props}\n />\n );\n});\n\nexport type ToolbarToggleGroupProps = ComponentPropsWithoutRef<typeof ToolbarPrimitive.ToggleGroup>;\n\n/** A set of mutually-exclusive or multi-select toggles (a view switcher, bold/italic). */\nexport const ToolbarToggleGroup = forwardRef<\n ElementRef<typeof ToolbarPrimitive.ToggleGroup>,\n ToolbarToggleGroupProps\n>(function ToolbarToggleGroup({ className, ...props }, ref) {\n return (\n <ToolbarPrimitive.ToggleGroup\n ref={ref}\n data-slot=\"toolbar-toggle-group\"\n className={cn(\"flex items-center gap-1\", className)}\n {...props}\n />\n );\n});\n\nexport interface ToolbarToggleItemProps\n extends\n ComponentPropsWithoutRef<typeof ToolbarPrimitive.ToggleItem>,\n Pick<VariantProps<typeof toggleVariants>, \"size\"> {}\n\n/** One toggle. Shares `Toggle`'s pressed styling, so state reads the same everywhere. */\nexport const ToolbarToggleItem = forwardRef<\n ElementRef<typeof ToolbarPrimitive.ToggleItem>,\n ToolbarToggleItemProps\n>(function ToolbarToggleItem({ className, size = \"sm\", ...props }, ref) {\n return (\n <ToolbarPrimitive.ToggleItem\n ref={ref}\n data-slot=\"toolbar-toggle-item\"\n className={cn(toggleVariants({ size }), className)}\n {...props}\n />\n );\n});\n\n/**\n * An escape hatch for anything the parts above do not cover — a `Select`, an\n * input, a `DropdownMenu` trigger. `asChild` hands the roving-tabindex wiring to\n * whatever you render, so the control stays part of the arrow-key sequence\n * instead of becoming a second tab stop inside a single-tab-stop row.\n */\nexport const ToolbarSlot = ToolbarPrimitive.Button;\n"],"mappings":";;;;;;;;;;;;AAwBA,YAAY,sBAAsB;AAClC,SAAS,WAA8B;AACvC,SAAS,kBAAkE;AAyCrE;AA/BC,IAAM,kBAAkB,IAAI,2BAA2B;AAAA,EAC5D,UAAU;AAAA,IACR,aAAa;AAAA,MACX,YAAY;AAAA;AAAA,MAEZ,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,aAAa,aAAa;AAC/C,CAAC;AAmBM,IAAM,UAAU;AAAA,EACrB,SAASA,SAAQ,EAAE,WAAW,aAAa,GAAG,MAAM,GAAG,KAAK;AAC1D,WACE;AAAA,MAAkB;AAAA,MAAjB;AAAA,QACC;AAAA,QACA,aAAU;AAAA,QACV,aAAa,eAAe;AAAA,QAC5B,WAAW,GAAG,gBAAgB,EAAE,YAAY,CAAC,GAAG,SAAS;AAAA,QACxD,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAiBO,IAAM,gBAAgB,WAG3B,SAASC,eAAc,EAAE,WAAW,UAAU,SAAS,OAAO,MAAM,GAAG,MAAM,GAAG,KAAK;AACrF,SACE;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,EAAE,SAAS,KAAK,CAAC,GAAG,SAAS;AAAA,MACzD,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AASM,IAAM,mBAAmB,WAG9B,SAASC,kBAAiB,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AACxD,SACE;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA;AAAA;AAAA,QAGA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AAKM,IAAM,qBAAqB,WAGhC,SAASC,oBAAmB,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AAC1D,SACE;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW,GAAG,2BAA2B,SAAS;AAAA,MACjD,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AAQM,IAAM,oBAAoB,WAG/B,SAASC,mBAAkB,EAAE,WAAW,OAAO,MAAM,GAAG,MAAM,GAAG,KAAK;AACtE,SACE;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,EAAE,KAAK,CAAC,GAAG,SAAS;AAAA,MAChD,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AAQM,IAAM,cAA+B;","names":["Toolbar","ToolbarButton","ToolbarSeparator","ToolbarToggleGroup","ToolbarToggleItem"]}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  StatePanel
4
- } from "./chunk-Y33ZFTMR.js";
4
+ } from "./chunk-FWAFP76U.js";
5
5
 
6
6
  // src/components/empty-state/empty-state.tsx
7
7
  import "react";
@@ -23,4 +23,4 @@ function EmptyState({ title, description, icon, actions, className }) {
23
23
  export {
24
24
  EmptyState
25
25
  };
26
- //# sourceMappingURL=chunk-E3GNYOLS.js.map
26
+ //# sourceMappingURL=chunk-64BKIIJC.js.map
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-HNLYRHAU.js";
14
14
  import {
15
15
  useLocale
16
- } from "./chunk-EJQYE4MY.js";
16
+ } from "./chunk-OFFWEDKY.js";
17
17
  import {
18
18
  Button
19
19
  } from "./chunk-C5QBV5RE.js";
@@ -198,4 +198,4 @@ export {
198
198
  FilterChip,
199
199
  ResultCount
200
200
  };
201
- //# sourceMappingURL=chunk-RHVYRQN4.js.map
201
+ //# sourceMappingURL=chunk-7ZJLR6RP.js.map
@@ -5,7 +5,7 @@ import {
5
5
  SheetDescription,
6
6
  SheetHeader,
7
7
  SheetTitle
8
- } from "./chunk-FXC64HLD.js";
8
+ } from "./chunk-S7YR3FYZ.js";
9
9
  import {
10
10
  Skeleton
11
11
  } from "./chunk-UPGIQXUY.js";
@@ -29,7 +29,7 @@ import {
29
29
  } from "./chunk-I3U52BDH.js";
30
30
  import {
31
31
  useLocale
32
- } from "./chunk-EJQYE4MY.js";
32
+ } from "./chunk-OFFWEDKY.js";
33
33
  import {
34
34
  Button
35
35
  } from "./chunk-C5QBV5RE.js";
@@ -784,4 +784,4 @@ export {
784
784
  SidebarMenuSubItem,
785
785
  SidebarMenuSubButton
786
786
  };
787
- //# sourceMappingURL=chunk-HWVU636Q.js.map
787
+ //# sourceMappingURL=chunk-A3JF66ZC.js.map
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-I3U52BDH.js";
5
5
  import {
6
6
  useLocale
7
- } from "./chunk-EJQYE4MY.js";
7
+ } from "./chunk-OFFWEDKY.js";
8
8
  import {
9
9
  Button
10
10
  } from "./chunk-C5QBV5RE.js";
@@ -198,4 +198,4 @@ var KeyValueEditor = forwardRef(
198
198
  export {
199
199
  KeyValueEditor
200
200
  };
201
- //# sourceMappingURL=chunk-NZUKZRT7.js.map
201
+ //# sourceMappingURL=chunk-A3TT32GE.js.map
@@ -19,7 +19,7 @@ import {
19
19
  } from "./chunk-HNLYRHAU.js";
20
20
  import {
21
21
  useLocale
22
- } from "./chunk-EJQYE4MY.js";
22
+ } from "./chunk-OFFWEDKY.js";
23
23
  import {
24
24
  Button
25
25
  } from "./chunk-C5QBV5RE.js";
@@ -397,4 +397,4 @@ var Transfer = forwardRef(function Transfer2({
397
397
  export {
398
398
  Transfer
399
399
  };
400
- //# sourceMappingURL=chunk-C2ICCCP5.js.map
400
+ //# sourceMappingURL=chunk-A4ZSNEZD.js.map
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  Spinner
4
- } from "./chunk-W7OIVERI.js";
4
+ } from "./chunk-ONXBRQJT.js";
5
5
  import {
6
6
  useLocale
7
- } from "./chunk-EJQYE4MY.js";
7
+ } from "./chunk-OFFWEDKY.js";
8
8
  import {
9
9
  AlertDialog,
10
10
  AlertDialogAction,
@@ -73,4 +73,4 @@ function ConfirmDialog({
73
73
  export {
74
74
  ConfirmDialog
75
75
  };
76
- //# sourceMappingURL=chunk-JTY3REOB.js.map
76
+ //# sourceMappingURL=chunk-BGXBANS2.js.map
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-SGBCLZQF.js";
7
7
  import {
8
8
  useLocale
9
- } from "./chunk-EJQYE4MY.js";
9
+ } from "./chunk-OFFWEDKY.js";
10
10
  import {
11
11
  cn
12
12
  } from "./chunk-FXWWDMMP.js";
@@ -242,4 +242,4 @@ export {
242
242
  COLOR_TOKENS,
243
243
  ColorPicker
244
244
  };
245
- //# sourceMappingURL=chunk-MY5H6D5Y.js.map
245
+ //# sourceMappingURL=chunk-C4FNDXBM.js.map
@@ -122,4 +122,4 @@ export {
122
122
  locateJsonPath,
123
123
  lineOfParseError
124
124
  };
125
- //# sourceMappingURL=chunk-QF6UWWDY.js.map
125
+ //# sourceMappingURL=chunk-C4FZWPI4.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/spec-playground/locate-json-path.ts"],"sourcesContent":["/**\n * Map a validator's error `path` onto a line of the JSON text it came from, so clicking an\n * error can put the caret there. Paths are JSON-path-like and tolerant of both house styles:\n * `root.children[2].props.variant` (A2UI) and `$.tiles[3].layout.w` (DashboardSpec).\n *\n * The scanner is deliberately small: it walks well-formed JSON, recording where each key or\n * array element starts, and returns the DEEPEST prefix of the path that exists — a\n * `missing` prop's path points at a key that is not there, so its owning object is the best\n * place to land. Malformed text returns `undefined` (the caller shows the error without a line).\n */\n\ntype Segment = string | number;\n\n/** Split `$.a.b[2].c` / `root.children[0]` / `a/b/0` into segments. */\nexport function parseJsonPath(path: string): Segment[] {\n const segments: Segment[] = [];\n const re = /\\[(\\d+)\\]|([^.[\\]/]+)/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(path)) !== null) {\n if (match[1] !== undefined) segments.push(Number(match[1]));\n else if (match[2] !== undefined && match[2] !== \"$\") {\n const key = match[2];\n segments.push(/^\\d+$/.test(key) ? Number(key) : key);\n }\n }\n return segments;\n}\n\nclass Scanner {\n i = 0;\n constructor(\n readonly text: string,\n readonly target: Segment[],\n ) {}\n /** Offset of the deepest matched prefix, and how many segments it matched. */\n best = { offset: 0, depth: 0 };\n\n ws() {\n while (this.i < this.text.length && /\\s/.test(this.text[this.i]!)) this.i++;\n }\n\n string(): string {\n const start = this.i;\n this.i++; // opening quote\n while (this.i < this.text.length && this.text[this.i] !== '\"') {\n if (this.text[this.i] === \"\\\\\") this.i++;\n this.i++;\n }\n this.i++; // closing quote\n return JSON.parse(this.text.slice(start, this.i)) as string;\n }\n\n value(depth: number, onPath: boolean) {\n this.ws();\n const ch = this.text[this.i];\n if (ch === \"{\") return this.object(depth, onPath);\n if (ch === \"[\") return this.array(depth, onPath);\n if (ch === '\"') return void this.string();\n while (this.i < this.text.length && !/[,\\]}\\s]/.test(this.text[this.i]!)) this.i++;\n }\n\n private mark(depth: number, offset: number) {\n if (depth > this.best.depth) this.best = { offset, depth };\n }\n\n object(depth: number, onPath: boolean) {\n this.i++; // {\n for (;;) {\n this.ws();\n if (this.text[this.i] === \"}\") return void this.i++;\n const keyStart = this.i;\n const key = this.string();\n const hit = onPath && this.target[depth] === key;\n if (hit) this.mark(depth + 1, keyStart);\n this.ws();\n this.i++; // :\n this.value(depth + 1, hit);\n this.ws();\n if (this.text[this.i] === \",\") this.i++;\n else if (this.text[this.i] === \"}\") return void this.i++;\n else throw new Error(\"malformed\");\n }\n }\n\n array(depth: number, onPath: boolean) {\n this.i++; // [\n let index = 0;\n for (;;) {\n this.ws();\n if (this.text[this.i] === \"]\") return void this.i++;\n const hit = onPath && this.target[depth] === index;\n if (hit) this.mark(depth + 1, this.i);\n this.value(depth + 1, hit);\n this.ws();\n index++;\n if (this.text[this.i] === \",\") this.i++;\n else if (this.text[this.i] === \"]\") return void this.i++;\n else throw new Error(\"malformed\");\n }\n }\n}\n\n/** 1-based line of `offset` in `text`. */\nexport function lineOfOffset(text: string, offset: number): number {\n let line = 1;\n for (let i = 0; i < offset && i < text.length; i++) if (text[i] === \"\\n\") line++;\n return line;\n}\n\n/** 0-based offset where 1-based `line` starts in `text`. */\nexport function offsetOfLine(text: string, line: number): number {\n let current = 1;\n for (let i = 0; i < text.length; i++) {\n if (current === line) return i;\n if (text[i] === \"\\n\") current++;\n }\n return current === line ? text.length : 0;\n}\n\n/**\n * The 1-based line in `text` that best matches `path` — the deepest existing prefix, the\n * document root's line when nothing below it matches — or `undefined` for text that is not\n * well-formed JSON.\n */\nexport function locateJsonPath(text: string, path: string): number | undefined {\n const scanner = new Scanner(text, parseJsonPath(path));\n try {\n scanner.ws();\n const rootOffset = scanner.i;\n scanner.value(0, true);\n return lineOfOffset(text, scanner.best.depth > 0 ? scanner.best.offset : rootOffset);\n } catch {\n return undefined;\n }\n}\n\n/** The line a `JSON.parse` error message points at (`position 42`, `line 3 column 5`), if any. */\nexport function lineOfParseError(text: string, message: string): number | undefined {\n const lineCol = /line (\\d+) column \\d+/.exec(message);\n if (lineCol) return Number(lineCol[1]);\n const position = /position (\\d+)/.exec(message);\n if (position) return lineOfOffset(text, Number(position[1]));\n return undefined;\n}\n"],"mappings":";;;AAcO,SAAS,cAAc,MAAyB;AACrD,QAAM,WAAsB,CAAC;AAC7B,QAAM,KAAK;AACX,MAAI;AACJ,UAAQ,QAAQ,GAAG,KAAK,IAAI,OAAO,MAAM;AACvC,QAAI,MAAM,CAAC,MAAM,OAAW,UAAS,KAAK,OAAO,MAAM,CAAC,CAAC,CAAC;AAAA,aACjD,MAAM,CAAC,MAAM,UAAa,MAAM,CAAC,MAAM,KAAK;AACnD,YAAM,MAAM,MAAM,CAAC;AACnB,eAAS,KAAK,QAAQ,KAAK,GAAG,IAAI,OAAO,GAAG,IAAI,GAAG;AAAA,IACrD;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,UAAN,MAAc;AAAA,EAEZ,YACW,MACA,QACT;AAFS;AACA;AAAA,EACR;AAAA,EAFQ;AAAA,EACA;AAAA,EAHX,IAAI;AAAA;AAAA,EAMJ,OAAO,EAAE,QAAQ,GAAG,OAAO,EAAE;AAAA,EAE7B,KAAK;AACH,WAAO,KAAK,IAAI,KAAK,KAAK,UAAU,KAAK,KAAK,KAAK,KAAK,KAAK,CAAC,CAAE,EAAG,MAAK;AAAA,EAC1E;AAAA,EAEA,SAAiB;AACf,UAAM,QAAQ,KAAK;AACnB,SAAK;AACL,WAAO,KAAK,IAAI,KAAK,KAAK,UAAU,KAAK,KAAK,KAAK,CAAC,MAAM,KAAK;AAC7D,UAAI,KAAK,KAAK,KAAK,CAAC,MAAM,KAAM,MAAK;AACrC,WAAK;AAAA,IACP;AACA,SAAK;AACL,WAAO,KAAK,MAAM,KAAK,KAAK,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,EAClD;AAAA,EAEA,MAAM,OAAe,QAAiB;AACpC,SAAK,GAAG;AACR,UAAM,KAAK,KAAK,KAAK,KAAK,CAAC;AAC3B,QAAI,OAAO,IAAK,QAAO,KAAK,OAAO,OAAO,MAAM;AAChD,QAAI,OAAO,IAAK,QAAO,KAAK,MAAM,OAAO,MAAM;AAC/C,QAAI,OAAO,IAAK,QAAO,KAAK,KAAK,OAAO;AACxC,WAAO,KAAK,IAAI,KAAK,KAAK,UAAU,CAAC,WAAW,KAAK,KAAK,KAAK,KAAK,CAAC,CAAE,EAAG,MAAK;AAAA,EACjF;AAAA,EAEQ,KAAK,OAAe,QAAgB;AAC1C,QAAI,QAAQ,KAAK,KAAK,MAAO,MAAK,OAAO,EAAE,QAAQ,MAAM;AAAA,EAC3D;AAAA,EAEA,OAAO,OAAe,QAAiB;AACrC,SAAK;AACL,eAAS;AACP,WAAK,GAAG;AACR,UAAI,KAAK,KAAK,KAAK,CAAC,MAAM,IAAK,QAAO,KAAK,KAAK;AAChD,YAAM,WAAW,KAAK;AACtB,YAAM,MAAM,KAAK,OAAO;AACxB,YAAM,MAAM,UAAU,KAAK,OAAO,KAAK,MAAM;AAC7C,UAAI,IAAK,MAAK,KAAK,QAAQ,GAAG,QAAQ;AACtC,WAAK,GAAG;AACR,WAAK;AACL,WAAK,MAAM,QAAQ,GAAG,GAAG;AACzB,WAAK,GAAG;AACR,UAAI,KAAK,KAAK,KAAK,CAAC,MAAM,IAAK,MAAK;AAAA,eAC3B,KAAK,KAAK,KAAK,CAAC,MAAM,IAAK,QAAO,KAAK,KAAK;AAAA,UAChD,OAAM,IAAI,MAAM,WAAW;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,MAAM,OAAe,QAAiB;AACpC,SAAK;AACL,QAAI,QAAQ;AACZ,eAAS;AACP,WAAK,GAAG;AACR,UAAI,KAAK,KAAK,KAAK,CAAC,MAAM,IAAK,QAAO,KAAK,KAAK;AAChD,YAAM,MAAM,UAAU,KAAK,OAAO,KAAK,MAAM;AAC7C,UAAI,IAAK,MAAK,KAAK,QAAQ,GAAG,KAAK,CAAC;AACpC,WAAK,MAAM,QAAQ,GAAG,GAAG;AACzB,WAAK,GAAG;AACR;AACA,UAAI,KAAK,KAAK,KAAK,CAAC,MAAM,IAAK,MAAK;AAAA,eAC3B,KAAK,KAAK,KAAK,CAAC,MAAM,IAAK,QAAO,KAAK,KAAK;AAAA,UAChD,OAAM,IAAI,MAAM,WAAW;AAAA,IAClC;AAAA,EACF;AACF;AAGO,SAAS,aAAa,MAAc,QAAwB;AACjE,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,UAAU,IAAI,KAAK,QAAQ,IAAK,KAAI,KAAK,CAAC,MAAM,KAAM;AAC1E,SAAO;AACT;AAGO,SAAS,aAAa,MAAc,MAAsB;AAC/D,MAAI,UAAU;AACd,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,YAAY,KAAM,QAAO;AAC7B,QAAI,KAAK,CAAC,MAAM,KAAM;AAAA,EACxB;AACA,SAAO,YAAY,OAAO,KAAK,SAAS;AAC1C;AAOO,SAAS,eAAe,MAAc,MAAkC;AAC7E,QAAM,UAAU,IAAI,QAAQ,MAAM,cAAc,IAAI,CAAC;AACrD,MAAI;AACF,YAAQ,GAAG;AACX,UAAM,aAAa,QAAQ;AAC3B,YAAQ,MAAM,GAAG,IAAI;AACrB,WAAO,aAAa,MAAM,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,SAAS,UAAU;AAAA,EACrF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,iBAAiB,MAAc,SAAqC;AAClF,QAAM,UAAU,wBAAwB,KAAK,OAAO;AACpD,MAAI,QAAS,QAAO,OAAO,QAAQ,CAAC,CAAC;AACrC,QAAM,WAAW,iBAAiB,KAAK,OAAO;AAC9C,MAAI,SAAU,QAAO,aAAa,MAAM,OAAO,SAAS,CAAC,CAAC,CAAC;AAC3D,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/components/spec-playground/locate-json-path.ts"],"sourcesContent":["/**\n * Map a validator's error `path` onto a line of the JSON text it came from, so clicking an\n * error can put the caret there. Paths are JSON-path-like and tolerant of both house styles:\n * `root.children[2].props.variant` (A2UI) and `$.tiles[3].layout.w` (any tile spec).\n *\n * The scanner is deliberately small: it walks well-formed JSON, recording where each key or\n * array element starts, and returns the DEEPEST prefix of the path that exists — a\n * `missing` prop's path points at a key that is not there, so its owning object is the best\n * place to land. Malformed text returns `undefined` (the caller shows the error without a line).\n */\n\ntype Segment = string | number;\n\n/** Split `$.a.b[2].c` / `root.children[0]` / `a/b/0` into segments. */\nexport function parseJsonPath(path: string): Segment[] {\n const segments: Segment[] = [];\n const re = /\\[(\\d+)\\]|([^.[\\]/]+)/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(path)) !== null) {\n if (match[1] !== undefined) segments.push(Number(match[1]));\n else if (match[2] !== undefined && match[2] !== \"$\") {\n const key = match[2];\n segments.push(/^\\d+$/.test(key) ? Number(key) : key);\n }\n }\n return segments;\n}\n\nclass Scanner {\n i = 0;\n constructor(\n readonly text: string,\n readonly target: Segment[],\n ) {}\n /** Offset of the deepest matched prefix, and how many segments it matched. */\n best = { offset: 0, depth: 0 };\n\n ws() {\n while (this.i < this.text.length && /\\s/.test(this.text[this.i]!)) this.i++;\n }\n\n string(): string {\n const start = this.i;\n this.i++; // opening quote\n while (this.i < this.text.length && this.text[this.i] !== '\"') {\n if (this.text[this.i] === \"\\\\\") this.i++;\n this.i++;\n }\n this.i++; // closing quote\n return JSON.parse(this.text.slice(start, this.i)) as string;\n }\n\n value(depth: number, onPath: boolean) {\n this.ws();\n const ch = this.text[this.i];\n if (ch === \"{\") return this.object(depth, onPath);\n if (ch === \"[\") return this.array(depth, onPath);\n if (ch === '\"') return void this.string();\n while (this.i < this.text.length && !/[,\\]}\\s]/.test(this.text[this.i]!)) this.i++;\n }\n\n private mark(depth: number, offset: number) {\n if (depth > this.best.depth) this.best = { offset, depth };\n }\n\n object(depth: number, onPath: boolean) {\n this.i++; // {\n for (;;) {\n this.ws();\n if (this.text[this.i] === \"}\") return void this.i++;\n const keyStart = this.i;\n const key = this.string();\n const hit = onPath && this.target[depth] === key;\n if (hit) this.mark(depth + 1, keyStart);\n this.ws();\n this.i++; // :\n this.value(depth + 1, hit);\n this.ws();\n if (this.text[this.i] === \",\") this.i++;\n else if (this.text[this.i] === \"}\") return void this.i++;\n else throw new Error(\"malformed\");\n }\n }\n\n array(depth: number, onPath: boolean) {\n this.i++; // [\n let index = 0;\n for (;;) {\n this.ws();\n if (this.text[this.i] === \"]\") return void this.i++;\n const hit = onPath && this.target[depth] === index;\n if (hit) this.mark(depth + 1, this.i);\n this.value(depth + 1, hit);\n this.ws();\n index++;\n if (this.text[this.i] === \",\") this.i++;\n else if (this.text[this.i] === \"]\") return void this.i++;\n else throw new Error(\"malformed\");\n }\n }\n}\n\n/** 1-based line of `offset` in `text`. */\nexport function lineOfOffset(text: string, offset: number): number {\n let line = 1;\n for (let i = 0; i < offset && i < text.length; i++) if (text[i] === \"\\n\") line++;\n return line;\n}\n\n/** 0-based offset where 1-based `line` starts in `text`. */\nexport function offsetOfLine(text: string, line: number): number {\n let current = 1;\n for (let i = 0; i < text.length; i++) {\n if (current === line) return i;\n if (text[i] === \"\\n\") current++;\n }\n return current === line ? text.length : 0;\n}\n\n/**\n * The 1-based line in `text` that best matches `path` — the deepest existing prefix, the\n * document root's line when nothing below it matches — or `undefined` for text that is not\n * well-formed JSON.\n */\nexport function locateJsonPath(text: string, path: string): number | undefined {\n const scanner = new Scanner(text, parseJsonPath(path));\n try {\n scanner.ws();\n const rootOffset = scanner.i;\n scanner.value(0, true);\n return lineOfOffset(text, scanner.best.depth > 0 ? scanner.best.offset : rootOffset);\n } catch {\n return undefined;\n }\n}\n\n/** The line a `JSON.parse` error message points at (`position 42`, `line 3 column 5`), if any. */\nexport function lineOfParseError(text: string, message: string): number | undefined {\n const lineCol = /line (\\d+) column \\d+/.exec(message);\n if (lineCol) return Number(lineCol[1]);\n const position = /position (\\d+)/.exec(message);\n if (position) return lineOfOffset(text, Number(position[1]));\n return undefined;\n}\n"],"mappings":"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","names":[]}
@@ -13,10 +13,10 @@ import {
13
13
  SidebarMenuButton,
14
14
  SidebarMenuItem,
15
15
  useSidebar
16
- } from "./chunk-HWVU636Q.js";
16
+ } from "./chunk-A3JF66ZC.js";
17
17
  import {
18
18
  useLocale
19
- } from "./chunk-EJQYE4MY.js";
19
+ } from "./chunk-OFFWEDKY.js";
20
20
  import {
21
21
  cn
22
22
  } from "./chunk-FXWWDMMP.js";
@@ -97,4 +97,4 @@ function TeamSwitcher({ teams, logoClassName, className }) {
97
97
  export {
98
98
  TeamSwitcher
99
99
  };
100
- //# sourceMappingURL=chunk-QLM3KTAQ.js.map
100
+ //# sourceMappingURL=chunk-C6I5I5LA.js.map