@flanksource/clicky-ui 0.3.40 → 0.3.41

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 (342) hide show
  1. package/README.md +24 -0
  2. package/dist/ai.cjs +10 -0
  3. package/dist/ai.cjs.map +1 -1
  4. package/dist/ai.js +10 -0
  5. package/dist/ai.js.map +1 -1
  6. package/dist/components/AccordionList.cjs +5 -1
  7. package/dist/components/AccordionList.cjs.map +1 -1
  8. package/dist/components/AccordionList.d.ts +3 -1
  9. package/dist/components/AccordionList.d.ts.map +1 -1
  10. package/dist/components/AccordionList.js +5 -1
  11. package/dist/components/AccordionList.js.map +1 -1
  12. package/dist/components/JsonSchemaForm.cjs +9 -4
  13. package/dist/components/JsonSchemaForm.cjs.map +1 -1
  14. package/dist/components/JsonSchemaForm.d.ts +1 -1
  15. package/dist/components/JsonSchemaForm.d.ts.map +1 -1
  16. package/dist/components/JsonSchemaForm.js +8 -3
  17. package/dist/components/JsonSchemaForm.js.map +1 -1
  18. package/dist/components/json-schema-form-accordion-array.cjs +3 -1
  19. package/dist/components/json-schema-form-accordion-array.cjs.map +1 -1
  20. package/dist/components/json-schema-form-accordion-array.d.ts +4 -1
  21. package/dist/components/json-schema-form-accordion-array.d.ts.map +1 -1
  22. package/dist/components/json-schema-form-accordion-array.js +3 -1
  23. package/dist/components/json-schema-form-accordion-array.js.map +1 -1
  24. package/dist/components/json-schema-form-array-view.cjs +63 -0
  25. package/dist/components/json-schema-form-array-view.cjs.map +1 -0
  26. package/dist/components/json-schema-form-array-view.d.ts +21 -0
  27. package/dist/components/json-schema-form-array-view.d.ts.map +1 -0
  28. package/dist/components/json-schema-form-array-view.js +63 -0
  29. package/dist/components/json-schema-form-array-view.js.map +1 -0
  30. package/dist/components/json-schema-form-array.cjs +3 -7
  31. package/dist/components/json-schema-form-array.cjs.map +1 -1
  32. package/dist/components/json-schema-form-array.d.ts.map +1 -1
  33. package/dist/components/json-schema-form-array.js +3 -7
  34. package/dist/components/json-schema-form-array.js.map +1 -1
  35. package/dist/components/json-schema-form-conditionals.cjs +67 -0
  36. package/dist/components/json-schema-form-conditionals.cjs.map +1 -0
  37. package/dist/components/json-schema-form-conditionals.d.ts +9 -0
  38. package/dist/components/json-schema-form-conditionals.d.ts.map +1 -0
  39. package/dist/components/json-schema-form-conditionals.js +67 -0
  40. package/dist/components/json-schema-form-conditionals.js.map +1 -0
  41. package/dist/components/json-schema-form-defaults.cjs +68 -0
  42. package/dist/components/json-schema-form-defaults.cjs.map +1 -0
  43. package/dist/components/json-schema-form-defaults.d.ts +4 -0
  44. package/dist/components/json-schema-form-defaults.d.ts.map +1 -0
  45. package/dist/components/json-schema-form-defaults.js +68 -0
  46. package/dist/components/json-schema-form-defaults.js.map +1 -0
  47. package/dist/components/json-schema-form-errors.cjs +49 -31
  48. package/dist/components/json-schema-form-errors.cjs.map +1 -1
  49. package/dist/components/json-schema-form-errors.d.ts +4 -2
  50. package/dist/components/json-schema-form-errors.d.ts.map +1 -1
  51. package/dist/components/json-schema-form-errors.js +51 -33
  52. package/dist/components/json-schema-form-errors.js.map +1 -1
  53. package/dist/components/json-schema-form-filter.cjs +2 -1
  54. package/dist/components/json-schema-form-filter.cjs.map +1 -1
  55. package/dist/components/json-schema-form-filter.js +2 -1
  56. package/dist/components/json-schema-form-filter.js.map +1 -1
  57. package/dist/components/json-schema-form-item-summary.cjs +6 -2
  58. package/dist/components/json-schema-form-item-summary.cjs.map +1 -1
  59. package/dist/components/json-schema-form-item-summary.d.ts.map +1 -1
  60. package/dist/components/json-schema-form-item-summary.js +6 -2
  61. package/dist/components/json-schema-form-item-summary.js.map +1 -1
  62. package/dist/components/json-schema-form-layout.cjs +28 -19
  63. package/dist/components/json-schema-form-layout.cjs.map +1 -1
  64. package/dist/components/json-schema-form-layout.d.ts +8 -6
  65. package/dist/components/json-schema-form-layout.d.ts.map +1 -1
  66. package/dist/components/json-schema-form-layout.js +29 -20
  67. package/dist/components/json-schema-form-layout.js.map +1 -1
  68. package/dist/components/json-schema-form-listener-paths.cjs +52 -0
  69. package/dist/components/json-schema-form-listener-paths.cjs.map +1 -0
  70. package/dist/components/json-schema-form-listener-paths.d.ts +10 -0
  71. package/dist/components/json-schema-form-listener-paths.d.ts.map +1 -0
  72. package/dist/components/json-schema-form-listener-paths.js +52 -0
  73. package/dist/components/json-schema-form-listener-paths.js.map +1 -0
  74. package/dist/components/json-schema-form-listener-types.d.ts +22 -0
  75. package/dist/components/json-schema-form-listener-types.d.ts.map +1 -0
  76. package/dist/components/json-schema-form-listeners.cjs +250 -0
  77. package/dist/components/json-schema-form-listeners.cjs.map +1 -0
  78. package/dist/components/json-schema-form-listeners.d.ts +13 -0
  79. package/dist/components/json-schema-form-listeners.d.ts.map +1 -0
  80. package/dist/components/json-schema-form-listeners.js +250 -0
  81. package/dist/components/json-schema-form-listeners.js.map +1 -0
  82. package/dist/components/json-schema-form-object-array-view.cjs +62 -0
  83. package/dist/components/json-schema-form-object-array-view.cjs.map +1 -0
  84. package/dist/components/json-schema-form-object-array-view.d.ts +14 -0
  85. package/dist/components/json-schema-form-object-array-view.d.ts.map +1 -0
  86. package/dist/components/json-schema-form-object-array-view.js +62 -0
  87. package/dist/components/json-schema-form-object-array-view.js.map +1 -0
  88. package/dist/components/json-schema-form-object.cjs +3 -0
  89. package/dist/components/json-schema-form-object.cjs.map +1 -1
  90. package/dist/components/json-schema-form-object.d.ts.map +1 -1
  91. package/dist/components/json-schema-form-object.js +3 -0
  92. package/dist/components/json-schema-form-object.js.map +1 -1
  93. package/dist/components/json-schema-form-render.cjs +17 -9
  94. package/dist/components/json-schema-form-render.cjs.map +1 -1
  95. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  96. package/dist/components/json-schema-form-render.js +19 -11
  97. package/dist/components/json-schema-form-render.js.map +1 -1
  98. package/dist/components/json-schema-form-resolve.cjs +6 -99
  99. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  100. package/dist/components/json-schema-form-resolve.d.ts +1 -8
  101. package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
  102. package/dist/components/json-schema-form-resolve.js +5 -98
  103. package/dist/components/json-schema-form-resolve.js.map +1 -1
  104. package/dist/components/json-schema-form-runtime-types.d.ts +15 -0
  105. package/dist/components/json-schema-form-runtime-types.d.ts.map +1 -1
  106. package/dist/components/json-schema-form-table-array.cjs +67 -16
  107. package/dist/components/json-schema-form-table-array.cjs.map +1 -1
  108. package/dist/components/json-schema-form-table-array.d.ts +4 -1
  109. package/dist/components/json-schema-form-table-array.d.ts.map +1 -1
  110. package/dist/components/json-schema-form-table-array.js +70 -19
  111. package/dist/components/json-schema-form-table-array.js.map +1 -1
  112. package/dist/components/json-schema-form-types.d.ts +16 -0
  113. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  114. package/dist/components/json-schema-form-utils.cjs +7 -1
  115. package/dist/components/json-schema-form-utils.cjs.map +1 -1
  116. package/dist/components/json-schema-form-utils.d.ts +2 -1
  117. package/dist/components/json-schema-form-utils.d.ts.map +1 -1
  118. package/dist/components/json-schema-form-utils.js +7 -1
  119. package/dist/components/json-schema-form-utils.js.map +1 -1
  120. package/dist/components.cjs +3 -2
  121. package/dist/components.cjs.map +1 -1
  122. package/dist/components.d.ts +3 -2
  123. package/dist/components.d.ts.map +1 -1
  124. package/dist/components.js +2 -1
  125. package/dist/components.js.map +1 -1
  126. package/dist/data/DataTable.cjs +9 -3
  127. package/dist/data/DataTable.cjs.map +1 -1
  128. package/dist/data/DataTable.d.ts +6 -0
  129. package/dist/data/DataTable.d.ts.map +1 -1
  130. package/dist/data/DataTable.js +9 -3
  131. package/dist/data/DataTable.js.map +1 -1
  132. package/dist/data/FixtureEditor/FixtureEditor.cjs +43 -24
  133. package/dist/data/FixtureEditor/FixtureEditor.cjs.map +1 -1
  134. package/dist/data/FixtureEditor/FixtureEditor.d.ts.map +1 -1
  135. package/dist/data/FixtureEditor/FixtureEditor.js +43 -24
  136. package/dist/data/FixtureEditor/FixtureEditor.js.map +1 -1
  137. package/dist/data/Tree.cjs +10 -2
  138. package/dist/data/Tree.cjs.map +1 -1
  139. package/dist/data/Tree.d.ts +6 -1
  140. package/dist/data/Tree.d.ts.map +1 -1
  141. package/dist/data/Tree.js +10 -2
  142. package/dist/data/Tree.js.map +1 -1
  143. package/dist/data/ai/SessionInspector.cjs +143 -167
  144. package/dist/data/ai/SessionInspector.cjs.map +1 -1
  145. package/dist/data/ai/SessionInspector.collection-types.d.ts +5 -0
  146. package/dist/data/ai/SessionInspector.collection-types.d.ts.map +1 -1
  147. package/dist/data/ai/SessionInspector.collection.cjs +18 -5
  148. package/dist/data/ai/SessionInspector.collection.cjs.map +1 -1
  149. package/dist/data/ai/SessionInspector.collection.d.ts +2 -0
  150. package/dist/data/ai/SessionInspector.collection.d.ts.map +1 -1
  151. package/dist/data/ai/SessionInspector.collection.fixtures.d.ts +6 -0
  152. package/dist/data/ai/SessionInspector.collection.fixtures.d.ts.map +1 -0
  153. package/dist/data/ai/SessionInspector.collection.js +18 -5
  154. package/dist/data/ai/SessionInspector.collection.js.map +1 -1
  155. package/dist/data/ai/SessionInspector.d.ts +24 -2
  156. package/dist/data/ai/SessionInspector.d.ts.map +1 -1
  157. package/dist/data/ai/SessionInspector.hierarchy-state.cjs +105 -7
  158. package/dist/data/ai/SessionInspector.hierarchy-state.cjs.map +1 -1
  159. package/dist/data/ai/SessionInspector.hierarchy-state.d.ts +12 -1
  160. package/dist/data/ai/SessionInspector.hierarchy-state.d.ts.map +1 -1
  161. package/dist/data/ai/SessionInspector.hierarchy-state.js +107 -9
  162. package/dist/data/ai/SessionInspector.hierarchy-state.js.map +1 -1
  163. package/dist/data/ai/SessionInspector.hierarchy.cjs +1 -1
  164. package/dist/data/ai/SessionInspector.hierarchy.cjs.map +1 -1
  165. package/dist/data/ai/SessionInspector.hierarchy.js +1 -1
  166. package/dist/data/ai/SessionInspector.hierarchy.js.map +1 -1
  167. package/dist/data/ai/SessionInspector.js +144 -168
  168. package/dist/data/ai/SessionInspector.js.map +1 -1
  169. package/dist/data/ai/SessionInspector.legacy.cjs +116 -0
  170. package/dist/data/ai/SessionInspector.legacy.cjs.map +1 -0
  171. package/dist/data/ai/SessionInspector.legacy.d.ts +19 -0
  172. package/dist/data/ai/SessionInspector.legacy.d.ts.map +1 -0
  173. package/dist/data/ai/SessionInspector.legacy.js +116 -0
  174. package/dist/data/ai/SessionInspector.legacy.js.map +1 -0
  175. package/dist/data/ai/SessionInspector.panels.cjs +3 -0
  176. package/dist/data/ai/SessionInspector.panels.cjs.map +1 -1
  177. package/dist/data/ai/SessionInspector.panels.d.ts.map +1 -1
  178. package/dist/data/ai/SessionInspector.panels.js +3 -0
  179. package/dist/data/ai/SessionInspector.panels.js.map +1 -1
  180. package/dist/data/ai/SessionInspector.plan.cjs +29 -12
  181. package/dist/data/ai/SessionInspector.plan.cjs.map +1 -1
  182. package/dist/data/ai/SessionInspector.plan.d.ts.map +1 -1
  183. package/dist/data/ai/SessionInspector.plan.js +30 -13
  184. package/dist/data/ai/SessionInspector.plan.js.map +1 -1
  185. package/dist/data/ai/SessionInspector.remote-view.cjs +44 -0
  186. package/dist/data/ai/SessionInspector.remote-view.cjs.map +1 -0
  187. package/dist/data/ai/SessionInspector.remote-view.d.ts +11 -0
  188. package/dist/data/ai/SessionInspector.remote-view.d.ts.map +1 -0
  189. package/dist/data/ai/SessionInspector.remote-view.js +44 -0
  190. package/dist/data/ai/SessionInspector.remote-view.js.map +1 -0
  191. package/dist/data/ai/SessionInspector.remote.cjs +275 -0
  192. package/dist/data/ai/SessionInspector.remote.cjs.map +1 -0
  193. package/dist/data/ai/SessionInspector.remote.d.ts +57 -0
  194. package/dist/data/ai/SessionInspector.remote.d.ts.map +1 -0
  195. package/dist/data/ai/SessionInspector.remote.js +275 -0
  196. package/dist/data/ai/SessionInspector.remote.js.map +1 -0
  197. package/dist/data/ai/SessionInspector.summary.cjs +0 -156
  198. package/dist/data/ai/SessionInspector.summary.cjs.map +1 -1
  199. package/dist/data/ai/SessionInspector.summary.d.ts +0 -3
  200. package/dist/data/ai/SessionInspector.summary.d.ts.map +1 -1
  201. package/dist/data/ai/SessionInspector.summary.js +2 -158
  202. package/dist/data/ai/SessionInspector.summary.js.map +1 -1
  203. package/dist/data/ai/SessionInspector.tab-state.cjs +15 -0
  204. package/dist/data/ai/SessionInspector.tab-state.cjs.map +1 -0
  205. package/dist/data/ai/SessionInspector.tab-state.d.ts +3 -0
  206. package/dist/data/ai/SessionInspector.tab-state.d.ts.map +1 -0
  207. package/dist/data/ai/SessionInspector.tab-state.js +15 -0
  208. package/dist/data/ai/SessionInspector.tab-state.js.map +1 -0
  209. package/dist/data/ai/SessionInspector.tabs.model.cjs +31 -18
  210. package/dist/data/ai/SessionInspector.tabs.model.cjs.map +1 -1
  211. package/dist/data/ai/SessionInspector.tabs.model.d.ts +3 -1
  212. package/dist/data/ai/SessionInspector.tabs.model.d.ts.map +1 -1
  213. package/dist/data/ai/SessionInspector.tabs.model.js +32 -19
  214. package/dist/data/ai/SessionInspector.tabs.model.js.map +1 -1
  215. package/dist/data/ai/SessionInspector.verification.cjs +53 -0
  216. package/dist/data/ai/SessionInspector.verification.cjs.map +1 -0
  217. package/dist/data/ai/SessionInspector.verification.d.ts +7 -0
  218. package/dist/data/ai/SessionInspector.verification.d.ts.map +1 -0
  219. package/dist/data/ai/SessionInspector.verification.js +53 -0
  220. package/dist/data/ai/SessionInspector.verification.js.map +1 -0
  221. package/dist/data/ai/SessionViewer.model.cjs +7 -1
  222. package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
  223. package/dist/data/ai/SessionViewer.model.d.ts +21 -3
  224. package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
  225. package/dist/data/ai/SessionViewer.model.js +7 -1
  226. package/dist/data/ai/SessionViewer.model.js.map +1 -1
  227. package/dist/data/ai/SessionViewer.unified.d.ts +13 -0
  228. package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
  229. package/dist/data/ai/index.d.ts +3 -1
  230. package/dist/data/ai/index.d.ts.map +1 -1
  231. package/dist/data/version-info.cjs +3 -3
  232. package/dist/data/version-info.js +3 -3
  233. package/dist/devtools/useDebugStream.cjs +5 -1
  234. package/dist/devtools/useDebugStream.cjs.map +1 -1
  235. package/dist/devtools/useDebugStream.d.ts.map +1 -1
  236. package/dist/devtools/useDebugStream.js +6 -2
  237. package/dist/devtools/useDebugStream.js.map +1 -1
  238. package/dist/hooks/event-source-provider.cjs +9 -0
  239. package/dist/hooks/event-source-provider.cjs.map +1 -0
  240. package/dist/hooks/event-source-provider.d.ts +15 -0
  241. package/dist/hooks/event-source-provider.d.ts.map +1 -0
  242. package/dist/hooks/event-source-provider.js +9 -0
  243. package/dist/hooks/event-source-provider.js.map +1 -0
  244. package/dist/hooks/event-source.cjs +11 -0
  245. package/dist/hooks/event-source.cjs.map +1 -0
  246. package/dist/hooks/event-source.d.ts +22 -0
  247. package/dist/hooks/event-source.d.ts.map +1 -0
  248. package/dist/hooks/event-source.js +11 -0
  249. package/dist/hooks/event-source.js.map +1 -0
  250. package/dist/hooks/use-log-tail.cjs +5 -1
  251. package/dist/hooks/use-log-tail.cjs.map +1 -1
  252. package/dist/hooks/use-log-tail.d.ts.map +1 -1
  253. package/dist/hooks/use-log-tail.js +5 -1
  254. package/dist/hooks/use-log-tail.js.map +1 -1
  255. package/dist/hooks/use-prompts.cjs +5 -1
  256. package/dist/hooks/use-prompts.cjs.map +1 -1
  257. package/dist/hooks/use-prompts.d.ts.map +1 -1
  258. package/dist/hooks/use-prompts.js +6 -2
  259. package/dist/hooks/use-prompts.js.map +1 -1
  260. package/dist/hooks/use-task-run.cjs +9 -2
  261. package/dist/hooks/use-task-run.cjs.map +1 -1
  262. package/dist/hooks/use-task-run.d.ts.map +1 -1
  263. package/dist/hooks/use-task-run.js +10 -3
  264. package/dist/hooks/use-task-run.js.map +1 -1
  265. package/dist/hooks.cjs +4 -0
  266. package/dist/hooks.cjs.map +1 -1
  267. package/dist/hooks.d.ts +2 -0
  268. package/dist/hooks.d.ts.map +1 -1
  269. package/dist/hooks.js +4 -0
  270. package/dist/hooks.js.map +1 -1
  271. package/dist/icons/programmingCatalog.cjs +34 -34
  272. package/dist/icons/programmingCatalog.cjs.map +1 -1
  273. package/dist/icons/programmingCatalog.js +34 -34
  274. package/dist/icons/programmingCatalog.js.map +1 -1
  275. package/dist/index.cjs +9 -2
  276. package/dist/index.cjs.map +1 -1
  277. package/dist/index.js +8 -1
  278. package/dist/index.js.map +1 -1
  279. package/dist/monaco/MonacoEditor.cjs +4 -1
  280. package/dist/monaco/MonacoEditor.cjs.map +1 -1
  281. package/dist/monaco/MonacoEditor.d.ts +1 -1
  282. package/dist/monaco/MonacoEditor.d.ts.map +1 -1
  283. package/dist/monaco/MonacoEditor.js +4 -1
  284. package/dist/monaco/MonacoEditor.js.map +1 -1
  285. package/dist/monaco/types.d.ts +2 -1
  286. package/dist/monaco/types.d.ts.map +1 -1
  287. package/dist/overlay/CommandPalette.cjs +14 -4
  288. package/dist/overlay/CommandPalette.cjs.map +1 -1
  289. package/dist/overlay/CommandPalette.d.ts +5 -1
  290. package/dist/overlay/CommandPalette.d.ts.map +1 -1
  291. package/dist/overlay/CommandPalette.js +14 -4
  292. package/dist/overlay/CommandPalette.js.map +1 -1
  293. package/dist/overlay/CommandPaletteList.cjs +5 -0
  294. package/dist/overlay/CommandPaletteList.cjs.map +1 -1
  295. package/dist/overlay/CommandPaletteList.d.ts +4 -2
  296. package/dist/overlay/CommandPaletteList.d.ts.map +1 -1
  297. package/dist/overlay/CommandPaletteList.js +5 -0
  298. package/dist/overlay/CommandPaletteList.js.map +1 -1
  299. package/dist/overlay/DropdownMenu.cjs +1 -0
  300. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  301. package/dist/overlay/DropdownMenu.js +1 -0
  302. package/dist/overlay/DropdownMenu.js.map +1 -1
  303. package/dist/rpc/OperationCatalog.cjs +29 -26
  304. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  305. package/dist/rpc/OperationCatalog.d.ts +9 -1
  306. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  307. package/dist/rpc/OperationCatalog.js +29 -26
  308. package/dist/rpc/OperationCatalog.js.map +1 -1
  309. package/dist/rpc/OperationEntityContextPicker.cjs +62 -256
  310. package/dist/rpc/OperationEntityContextPicker.cjs.map +1 -1
  311. package/dist/rpc/OperationEntityContextPicker.d.ts.map +1 -1
  312. package/dist/rpc/OperationEntityContextPicker.js +64 -258
  313. package/dist/rpc/OperationEntityContextPicker.js.map +1 -1
  314. package/dist/rpc/OperationEntityPicker.cjs +185 -0
  315. package/dist/rpc/OperationEntityPicker.cjs.map +1 -0
  316. package/dist/rpc/OperationEntityPicker.d.ts +51 -0
  317. package/dist/rpc/OperationEntityPicker.d.ts.map +1 -0
  318. package/dist/rpc/OperationEntityPicker.js +185 -0
  319. package/dist/rpc/OperationEntityPicker.js.map +1 -0
  320. package/dist/rpc/OperationEntityPicker.model.cjs +39 -0
  321. package/dist/rpc/OperationEntityPicker.model.cjs.map +1 -0
  322. package/dist/rpc/OperationEntityPicker.model.d.ts +27 -0
  323. package/dist/rpc/OperationEntityPicker.model.d.ts.map +1 -0
  324. package/dist/rpc/OperationEntityPicker.model.js +39 -0
  325. package/dist/rpc/OperationEntityPicker.model.js.map +1 -0
  326. package/dist/rpc/operationCatalogRowSelection.cjs +85 -0
  327. package/dist/rpc/operationCatalogRowSelection.cjs.map +1 -0
  328. package/dist/rpc/operationCatalogRowSelection.d.ts +57 -0
  329. package/dist/rpc/operationCatalogRowSelection.d.ts.map +1 -0
  330. package/dist/rpc/operationCatalogRowSelection.js +85 -0
  331. package/dist/rpc/operationCatalogRowSelection.js.map +1 -0
  332. package/dist/rpc/operationEntityPicker.fixtures.d.ts +13 -0
  333. package/dist/rpc/operationEntityPicker.fixtures.d.ts.map +1 -0
  334. package/dist/rpc.cjs +2 -0
  335. package/dist/rpc.cjs.map +1 -1
  336. package/dist/rpc.d.ts +2 -0
  337. package/dist/rpc.d.ts.map +1 -1
  338. package/dist/rpc.js +2 -0
  339. package/dist/rpc.js.map +1 -1
  340. package/dist/styles.css +1 -1
  341. package/package.json +4 -1
  342. package/schemas/json-schema-form.schema.json +566 -0
package/dist/index.cjs CHANGED
@@ -21,6 +21,8 @@ const useDensity = require("./hooks/use-density.cjs");
21
21
  const densityProvider = require("./hooks/density-provider.cjs");
22
22
  const useSort = require("./hooks/use-sort.cjs");
23
23
  const useHistoryRoute = require("./hooks/use-history-route.cjs");
24
+ const eventSource = require("./hooks/event-source.cjs");
25
+ const eventSourceProvider = require("./hooks/event-source-provider.cjs");
24
26
  const useTaskRun = require("./hooks/use-task-run.cjs");
25
27
  const usePrompts = require("./hooks/use-prompts.cjs");
26
28
  const useHotkey = require("./hooks/use-hotkey.cjs");
@@ -91,6 +93,7 @@ const formLookupContext = require("./components/form-lookup-context.cjs");
91
93
  const jsonSchemaFormSize = require("./components/json-schema-form-size.cjs");
92
94
  const jsonSchemaFormPreferences = require("./components/json-schema-form-preferences.cjs");
93
95
  const jsonSchemaFormResolve = require("./components/json-schema-form-resolve.cjs");
96
+ const jsonSchemaFormConditionals = require("./components/json-schema-form-conditionals.cjs");
94
97
  const jsonSchemaFormRefs = require("./components/json-schema-form-refs.cjs");
95
98
  const jsonSchemaFormTemplate = require("./components/json-schema-form-template.cjs");
96
99
  const jsonSchemaFormExtensions = require("./components/json-schema-form-extensions.cjs");
@@ -245,6 +248,7 @@ const CommentFilterBar = require("./comments/CommentFilterBar.cjs");
245
248
  const CommentProgress = require("./comments/CommentProgress.cjs");
246
249
  const Clicky = require("./data/Clicky.cjs");
247
250
  const OperationCatalog = require("./rpc/OperationCatalog.cjs");
251
+ const OperationEntityPicker = require("./rpc/OperationEntityPicker.cjs");
248
252
  const SessionsCatalog = require("./rpc/SessionsCatalog.cjs");
249
253
  const SessionHeader = require("./rpc/SessionHeader.cjs");
250
254
  const useSession = require("./rpc/useSession.cjs");
@@ -978,6 +982,8 @@ exports.DensityProvider = densityProvider.DensityProvider;
978
982
  exports.DensityValueProvider = densityProvider.DensityValueProvider;
979
983
  exports.useSort = useSort.useSort;
980
984
  exports.useHistoryRoute = useHistoryRoute.useHistoryRoute;
985
+ exports.useEventSourceFactory = eventSource.useEventSourceFactory;
986
+ exports.EventSourceProvider = eventSourceProvider.EventSourceProvider;
981
987
  exports.useTaskRun = useTaskRun.useTaskRun;
982
988
  exports.useTaskRuns = useTaskRun.useTaskRuns;
983
989
  exports.answerPrompt = usePrompts.answerPrompt;
@@ -1083,10 +1089,10 @@ exports.DEFAULT_FORM_SIZE = jsonSchemaFormSize.DEFAULT_FORM_SIZE;
1083
1089
  exports.DEFAULT_PREFERENCES_STORAGE_KEY = jsonSchemaFormPreferences.DEFAULT_PREFERENCES_STORAGE_KEY;
1084
1090
  exports.readPreferences = jsonSchemaFormPreferences.readPreferences;
1085
1091
  exports.writePreferences = jsonSchemaFormPreferences.writePreferences;
1086
- exports.effectiveProperties = jsonSchemaFormResolve.effectiveProperties;
1087
1092
  exports.isOpenStringMap = jsonSchemaFormResolve.isOpenStringMap;
1088
- exports.matchesIf = jsonSchemaFormResolve.matchesIf;
1089
1093
  exports.resolveControl = jsonSchemaFormResolve.resolveControl;
1094
+ exports.effectiveProperties = jsonSchemaFormConditionals.effectiveProperties;
1095
+ exports.matchesIf = jsonSchemaFormConditionals.matchesIf;
1090
1096
  exports.rehydrateRefs = jsonSchemaFormRefs.rehydrateRefs;
1091
1097
  exports.templateValuePre = jsonSchemaFormTemplate.templateValuePre;
1092
1098
  exports.applyPostExtensions = jsonSchemaFormExtensions.applyPostExtensions;
@@ -1381,6 +1387,7 @@ exports.Clicky = Clicky.Clicky;
1381
1387
  exports.ClickyNodeView = Clicky.ClickyNodeView;
1382
1388
  exports.ClickyTable = Clicky.ClickyTable;
1383
1389
  exports.OperationCatalog = OperationCatalog.OperationCatalog;
1390
+ exports.OperationEntityPicker = OperationEntityPicker.OperationEntityPicker;
1384
1391
  exports.SESSIONS_SURFACE_KEY = SessionsCatalog.SESSIONS_SURFACE_KEY;
1385
1392
  exports.SessionsCatalog = SessionsCatalog.SessionsCatalog;
1386
1393
  exports.SessionHeader = SessionHeader.SessionHeader;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.js CHANGED
@@ -19,6 +19,8 @@ import { useDensity, useDensityValue } from "./hooks/use-density.js";
19
19
  import { DensityProvider, DensityValueProvider } from "./hooks/density-provider.js";
20
20
  import { useSort } from "./hooks/use-sort.js";
21
21
  import { useHistoryRoute } from "./hooks/use-history-route.js";
22
+ import { useEventSourceFactory } from "./hooks/event-source.js";
23
+ import { EventSourceProvider } from "./hooks/event-source-provider.js";
22
24
  import { useTaskRun, useTaskRuns } from "./hooks/use-task-run.js";
23
25
  import { answerPrompt, usePrompts } from "./hooks/use-prompts.js";
24
26
  import { formatHotkey, parseHotkey, useHotkey } from "./hooks/use-hotkey.js";
@@ -88,7 +90,8 @@ import { FormLookupProvider } from "./components/FormLookupProvider.js";
88
90
  import { resolveLookupScope, useLookupFetcher } from "./components/form-lookup-context.js";
89
91
  import { DEFAULT_FORM_SIZE } from "./components/json-schema-form-size.js";
90
92
  import { DEFAULT_PREFERENCES_STORAGE_KEY, readPreferences, writePreferences } from "./components/json-schema-form-preferences.js";
91
- import { effectiveProperties, isOpenStringMap, matchesIf, resolveControl } from "./components/json-schema-form-resolve.js";
93
+ import { isOpenStringMap, resolveControl } from "./components/json-schema-form-resolve.js";
94
+ import { effectiveProperties, matchesIf } from "./components/json-schema-form-conditionals.js";
92
95
  import { rehydrateRefs } from "./components/json-schema-form-refs.js";
93
96
  import { templateValuePre } from "./components/json-schema-form-template.js";
94
97
  import { applyPostExtensions } from "./components/json-schema-form-extensions.js";
@@ -243,6 +246,7 @@ import { CommentFilterBar } from "./comments/CommentFilterBar.js";
243
246
  import { CommentProgress } from "./comments/CommentProgress.js";
244
247
  import { Clicky, ClickyNodeView, ClickyTable } from "./data/Clicky.js";
245
248
  import { OperationCatalog } from "./rpc/OperationCatalog.js";
249
+ import { OperationEntityPicker } from "./rpc/OperationEntityPicker.js";
246
250
  import { SESSIONS_SURFACE_KEY, SessionsCatalog } from "./rpc/SessionsCatalog.js";
247
251
  import { SessionHeader } from "./rpc/SessionHeader.js";
248
252
  import { SESSION_POLL_MS, useSession } from "./rpc/useSession.js";
@@ -980,6 +984,7 @@ export {
980
984
  EntityExplorerApp,
981
985
  ErrorDetails,
982
986
  ErrorWrapper,
987
+ EventSourceProvider,
983
988
  ExecutionTree,
984
989
  Field,
985
990
  FieldErrorText,
@@ -1052,6 +1057,7 @@ export {
1052
1057
  OperationCommandPage,
1053
1058
  OperationEntityContextPicker,
1054
1059
  OperationEntityPage,
1060
+ OperationEntityPicker,
1055
1061
  OperationPicker,
1056
1062
  OperationResultView,
1057
1063
  OperationScheduleDialog,
@@ -2549,6 +2555,7 @@ export {
2549
2555
  useDensity,
2550
2556
  useDensityValue,
2551
2557
  useEscapeLayer,
2558
+ useEventSourceFactory,
2552
2559
  useFloatingZIndex,
2553
2560
  useForm,
2554
2561
  useHistoryRoute,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -27,6 +27,7 @@ Editor.loader.config({ monaco: monacoEditor__namespace });
27
27
  function MonacoEditor({
28
28
  value,
29
29
  onChange,
30
+ readOnly = false,
30
31
  language,
31
32
  path,
32
33
  height = "20rem",
@@ -34,6 +35,7 @@ function MonacoEditor({
34
35
  onMount,
35
36
  onValidate
36
37
  }) {
38
+ if (!readOnly && !onChange) throw new Error("MonacoEditor requires onChange when editing");
37
39
  const workers = useMonacoWorker.useMonacoWorkerFactory();
38
40
  const theme = useTheme.useResolvedTheme() === "dark" ? "vs-dark" : "light";
39
41
  const latestValue = react.useRef(value);
@@ -45,7 +47,7 @@ function MonacoEditor({
45
47
  Editor,
46
48
  {
47
49
  value,
48
- onChange: (next) => onChange(next ?? ""),
50
+ onChange: (next) => onChange == null ? void 0 : onChange(next ?? ""),
49
51
  language,
50
52
  path,
51
53
  height,
@@ -58,6 +60,7 @@ function MonacoEditor({
58
60
  },
59
61
  ...onValidate ? { onValidate } : {},
60
62
  options: {
63
+ readOnly,
61
64
  automaticLayout: true,
62
65
  fontFamily: "var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)",
63
66
  fontSize: 13,
@@ -1 +1 @@
1
- {"version":3,"file":"MonacoEditor.cjs","sources":["../../src/monaco/MonacoEditor.tsx"],"sourcesContent":["import Editor, { loader, type Monaco } from \"@monaco-editor/react\";\nimport * as monaco from \"monaco-editor\";\nimport { useRef } from \"react\";\nimport { useResolvedTheme } from \"../hooks/use-theme\";\nimport { useMonacoWorkerFactory } from \"./use-monaco-worker\";\nimport type { MonacoEditorProps } from \"./types\";\n\nloader.config({ monaco });\n\nexport function MonacoEditor({\n value,\n onChange,\n language,\n path,\n height = \"20rem\",\n beforeMount,\n onMount,\n onValidate,\n}: MonacoEditorProps) {\n const workers = useMonacoWorkerFactory();\n const theme = useResolvedTheme() === \"dark\" ? \"vs-dark\" : \"light\";\n // @monaco-editor/react keeps the first onMount it sees, so read the value at\n // mount time through a ref rather than that render's closure.\n const latestValue = useRef(value);\n latestValue.current = value;\n\n if (!workers) {\n return <div role=\"alert\" className=\"rounded-md border border-destructive/40 p-3 text-sm text-destructive\">Monaco workers are not configured.</div>;\n }\n\n return (\n <div className=\"overflow-hidden rounded-md border border-input\" data-slot=\"monaco-editor\">\n <Editor\n value={value}\n onChange={(next) => onChange(next ?? \"\")}\n language={language}\n path={path}\n height={height}\n theme={theme}\n keepCurrentModel\n {...(beforeMount ? { beforeMount } : {})}\n onMount={(instance, monacoInstance) => {\n // keepCurrentModel remounts onto the model already at `path`, which\n // still holds the text from when the previous editor unmounted.\n if (instance.getValue() !== latestValue.current) instance.setValue(latestValue.current);\n onMount?.(instance, monacoInstance);\n }}\n {...(onValidate ? { onValidate } : {})}\n options={{\n automaticLayout: true,\n fontFamily: \"var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)\",\n fontSize: 13,\n lineHeight: 20,\n minimap: { enabled: false },\n scrollBeyondLastLine: false,\n tabSize: 2,\n wordWrap: \"on\",\n quickSuggestions: { other: true, comments: true, strings: true },\n }}\n />\n </div>\n );\n}\n\nexport type { Monaco };\n"],"names":["loader","monaco","useMonacoWorkerFactory","useResolvedTheme","useRef","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAOAA,OAAAA,OAAO,OAAO,EAAA,QAAEC,yBAAQ;AAEjB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,UAAUC,gBAAAA,uBAAA;AAChB,QAAM,QAAQC,SAAAA,iBAAA,MAAuB,SAAS,YAAY;AAG1D,QAAM,cAAcC,MAAAA,OAAO,KAAK;AAChC,cAAY,UAAU;AAEtB,MAAI,CAAC,SAAS;AACZ,0CAAQ,OAAA,EAAI,MAAK,SAAQ,WAAU,wEAAuE,UAAA,sCAAkC;AAAA,EAC9I;AAEA,SACEC,2BAAAA,IAAC,OAAA,EAAI,WAAU,kDAAiD,aAAU,iBACxE,UAAAA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,UAAU,CAAC,SAAS,SAAS,QAAQ,EAAE;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAgB;AAAA,MACf,GAAI,cAAc,EAAE,YAAA,IAAgB,CAAA;AAAA,MACrC,SAAS,CAAC,UAAU,mBAAmB;AAGrC,YAAI,SAAS,eAAe,YAAY,QAAS,UAAS,SAAS,YAAY,OAAO;AACtF,2CAAU,UAAU;AAAA,MACtB;AAAA,MACC,GAAI,aAAa,EAAE,WAAA,IAAe,CAAA;AAAA,MACnC,SAAS;AAAA,QACP,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,SAAS,EAAE,SAAS,MAAA;AAAA,QACpB,sBAAsB;AAAA,QACtB,SAAS;AAAA,QACT,UAAU;AAAA,QACV,kBAAkB,EAAE,OAAO,MAAM,UAAU,MAAM,SAAS,KAAA;AAAA,MAAK;AAAA,IACjE;AAAA,EAAA,GAEJ;AAEJ;;"}
1
+ {"version":3,"file":"MonacoEditor.cjs","sources":["../../src/monaco/MonacoEditor.tsx"],"sourcesContent":["import Editor, { loader, type Monaco } from \"@monaco-editor/react\";\nimport * as monaco from \"monaco-editor\";\nimport { useRef } from \"react\";\nimport { useResolvedTheme } from \"../hooks/use-theme\";\nimport { useMonacoWorkerFactory } from \"./use-monaco-worker\";\nimport type { MonacoEditorProps } from \"./types\";\n\nloader.config({ monaco });\n\nexport function MonacoEditor({\n value,\n onChange,\n readOnly = false,\n language,\n path,\n height = \"20rem\",\n beforeMount,\n onMount,\n onValidate,\n}: MonacoEditorProps) {\n if (!readOnly && !onChange) throw new Error(\"MonacoEditor requires onChange when editing\");\n const workers = useMonacoWorkerFactory();\n const theme = useResolvedTheme() === \"dark\" ? \"vs-dark\" : \"light\";\n // @monaco-editor/react keeps the first onMount it sees, so read the value at\n // mount time through a ref rather than that render's closure.\n const latestValue = useRef(value);\n latestValue.current = value;\n\n if (!workers) {\n return <div role=\"alert\" className=\"rounded-md border border-destructive/40 p-3 text-sm text-destructive\">Monaco workers are not configured.</div>;\n }\n\n return (\n <div className=\"overflow-hidden rounded-md border border-input\" data-slot=\"monaco-editor\">\n <Editor\n value={value}\n onChange={(next) => onChange?.(next ?? \"\")}\n language={language}\n path={path}\n height={height}\n theme={theme}\n keepCurrentModel\n {...(beforeMount ? { beforeMount } : {})}\n onMount={(instance, monacoInstance) => {\n // keepCurrentModel remounts onto the model already at `path`, which\n // still holds the text from when the previous editor unmounted.\n if (instance.getValue() !== latestValue.current) instance.setValue(latestValue.current);\n onMount?.(instance, monacoInstance);\n }}\n {...(onValidate ? { onValidate } : {})}\n options={{\n readOnly,\n automaticLayout: true,\n fontFamily: \"var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)\",\n fontSize: 13,\n lineHeight: 20,\n minimap: { enabled: false },\n scrollBeyondLastLine: false,\n tabSize: 2,\n wordWrap: \"on\",\n quickSuggestions: { other: true, comments: true, strings: true },\n }}\n />\n </div>\n );\n}\n\nexport type { Monaco };\n"],"names":["loader","monaco","useMonacoWorkerFactory","useResolvedTheme","useRef","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAOAA,OAAAA,OAAO,OAAO,EAAA,QAAEC,yBAAQ;AAEjB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,MAAI,CAAC,YAAY,CAAC,SAAU,OAAM,IAAI,MAAM,6CAA6C;AACzF,QAAM,UAAUC,gBAAAA,uBAAA;AAChB,QAAM,QAAQC,SAAAA,iBAAA,MAAuB,SAAS,YAAY;AAG1D,QAAM,cAAcC,MAAAA,OAAO,KAAK;AAChC,cAAY,UAAU;AAEtB,MAAI,CAAC,SAAS;AACZ,0CAAQ,OAAA,EAAI,MAAK,SAAQ,WAAU,wEAAuE,UAAA,sCAAkC;AAAA,EAC9I;AAEA,SACEC,2BAAAA,IAAC,OAAA,EAAI,WAAU,kDAAiD,aAAU,iBACxE,UAAAA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,UAAU,CAAC,SAAS,qCAAW,QAAQ;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAgB;AAAA,MACf,GAAI,cAAc,EAAE,YAAA,IAAgB,CAAA;AAAA,MACrC,SAAS,CAAC,UAAU,mBAAmB;AAGrC,YAAI,SAAS,eAAe,YAAY,QAAS,UAAS,SAAS,YAAY,OAAO;AACtF,2CAAU,UAAU;AAAA,MACtB;AAAA,MACC,GAAI,aAAa,EAAE,WAAA,IAAe,CAAA;AAAA,MACnC,SAAS;AAAA,QACP;AAAA,QACA,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,SAAS,EAAE,SAAS,MAAA;AAAA,QACpB,sBAAsB;AAAA,QACtB,SAAS;AAAA,QACT,UAAU;AAAA,QACV,kBAAkB,EAAE,OAAO,MAAM,UAAU,MAAM,SAAS,KAAA;AAAA,MAAK;AAAA,IACjE;AAAA,EAAA,GAEJ;AAEJ;;"}
@@ -1,5 +1,5 @@
1
1
  import { Monaco } from '@monaco-editor/react';
2
2
  import { MonacoEditorProps } from './types.js';
3
- export declare function MonacoEditor({ value, onChange, language, path, height, beforeMount, onMount, onValidate, }: MonacoEditorProps): import("react").JSX.Element;
3
+ export declare function MonacoEditor({ value, onChange, readOnly, language, path, height, beforeMount, onMount, onValidate, }: MonacoEditorProps): import("react").JSX.Element;
4
4
  export type { Monaco };
5
5
  //# sourceMappingURL=MonacoEditor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MonacoEditor.d.ts","sourceRoot":"","sources":["../../src/monaco/MonacoEditor.tsx"],"names":[],"mappings":"AAAA,OAAe,EAAU,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAKnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAIjD,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,MAAgB,EAChB,WAAW,EACX,OAAO,EACP,UAAU,GACX,EAAE,iBAAiB,+BA4CnB;AAED,YAAY,EAAE,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"MonacoEditor.d.ts","sourceRoot":"","sources":["../../src/monaco/MonacoEditor.tsx"],"names":[],"mappings":"AAAA,OAAe,EAAU,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAKnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAIjD,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,QAAgB,EAChB,QAAQ,EACR,IAAI,EACJ,MAAgB,EAChB,WAAW,EACX,OAAO,EACP,UAAU,GACX,EAAE,iBAAiB,+BA8CnB;AAED,YAAY,EAAE,MAAM,EAAE,CAAC"}
@@ -8,6 +8,7 @@ loader.config({ monaco: monacoEditor });
8
8
  function MonacoEditor({
9
9
  value,
10
10
  onChange,
11
+ readOnly = false,
11
12
  language,
12
13
  path,
13
14
  height = "20rem",
@@ -15,6 +16,7 @@ function MonacoEditor({
15
16
  onMount,
16
17
  onValidate
17
18
  }) {
19
+ if (!readOnly && !onChange) throw new Error("MonacoEditor requires onChange when editing");
18
20
  const workers = useMonacoWorkerFactory();
19
21
  const theme = useResolvedTheme() === "dark" ? "vs-dark" : "light";
20
22
  const latestValue = useRef(value);
@@ -26,7 +28,7 @@ function MonacoEditor({
26
28
  Editor,
27
29
  {
28
30
  value,
29
- onChange: (next) => onChange(next ?? ""),
31
+ onChange: (next) => onChange == null ? void 0 : onChange(next ?? ""),
30
32
  language,
31
33
  path,
32
34
  height,
@@ -39,6 +41,7 @@ function MonacoEditor({
39
41
  },
40
42
  ...onValidate ? { onValidate } : {},
41
43
  options: {
44
+ readOnly,
42
45
  automaticLayout: true,
43
46
  fontFamily: "var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)",
44
47
  fontSize: 13,
@@ -1 +1 @@
1
- {"version":3,"file":"MonacoEditor.js","sources":["../../src/monaco/MonacoEditor.tsx"],"sourcesContent":["import Editor, { loader, type Monaco } from \"@monaco-editor/react\";\nimport * as monaco from \"monaco-editor\";\nimport { useRef } from \"react\";\nimport { useResolvedTheme } from \"../hooks/use-theme\";\nimport { useMonacoWorkerFactory } from \"./use-monaco-worker\";\nimport type { MonacoEditorProps } from \"./types\";\n\nloader.config({ monaco });\n\nexport function MonacoEditor({\n value,\n onChange,\n language,\n path,\n height = \"20rem\",\n beforeMount,\n onMount,\n onValidate,\n}: MonacoEditorProps) {\n const workers = useMonacoWorkerFactory();\n const theme = useResolvedTheme() === \"dark\" ? \"vs-dark\" : \"light\";\n // @monaco-editor/react keeps the first onMount it sees, so read the value at\n // mount time through a ref rather than that render's closure.\n const latestValue = useRef(value);\n latestValue.current = value;\n\n if (!workers) {\n return <div role=\"alert\" className=\"rounded-md border border-destructive/40 p-3 text-sm text-destructive\">Monaco workers are not configured.</div>;\n }\n\n return (\n <div className=\"overflow-hidden rounded-md border border-input\" data-slot=\"monaco-editor\">\n <Editor\n value={value}\n onChange={(next) => onChange(next ?? \"\")}\n language={language}\n path={path}\n height={height}\n theme={theme}\n keepCurrentModel\n {...(beforeMount ? { beforeMount } : {})}\n onMount={(instance, monacoInstance) => {\n // keepCurrentModel remounts onto the model already at `path`, which\n // still holds the text from when the previous editor unmounted.\n if (instance.getValue() !== latestValue.current) instance.setValue(latestValue.current);\n onMount?.(instance, monacoInstance);\n }}\n {...(onValidate ? { onValidate } : {})}\n options={{\n automaticLayout: true,\n fontFamily: \"var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)\",\n fontSize: 13,\n lineHeight: 20,\n minimap: { enabled: false },\n scrollBeyondLastLine: false,\n tabSize: 2,\n wordWrap: \"on\",\n quickSuggestions: { other: true, comments: true, strings: true },\n }}\n />\n </div>\n );\n}\n\nexport type { Monaco };\n"],"names":["monaco"],"mappings":";;;;;;AAOA,OAAO,OAAO,EAAA,QAAEA,cAAQ;AAEjB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,UAAU,uBAAA;AAChB,QAAM,QAAQ,iBAAA,MAAuB,SAAS,YAAY;AAG1D,QAAM,cAAc,OAAO,KAAK;AAChC,cAAY,UAAU;AAEtB,MAAI,CAAC,SAAS;AACZ,+BAAQ,OAAA,EAAI,MAAK,SAAQ,WAAU,wEAAuE,UAAA,sCAAkC;AAAA,EAC9I;AAEA,SACE,oBAAC,OAAA,EAAI,WAAU,kDAAiD,aAAU,iBACxE,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,UAAU,CAAC,SAAS,SAAS,QAAQ,EAAE;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAgB;AAAA,MACf,GAAI,cAAc,EAAE,YAAA,IAAgB,CAAA;AAAA,MACrC,SAAS,CAAC,UAAU,mBAAmB;AAGrC,YAAI,SAAS,eAAe,YAAY,QAAS,UAAS,SAAS,YAAY,OAAO;AACtF,2CAAU,UAAU;AAAA,MACtB;AAAA,MACC,GAAI,aAAa,EAAE,WAAA,IAAe,CAAA;AAAA,MACnC,SAAS;AAAA,QACP,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,SAAS,EAAE,SAAS,MAAA;AAAA,QACpB,sBAAsB;AAAA,QACtB,SAAS;AAAA,QACT,UAAU;AAAA,QACV,kBAAkB,EAAE,OAAO,MAAM,UAAU,MAAM,SAAS,KAAA;AAAA,MAAK;AAAA,IACjE;AAAA,EAAA,GAEJ;AAEJ;"}
1
+ {"version":3,"file":"MonacoEditor.js","sources":["../../src/monaco/MonacoEditor.tsx"],"sourcesContent":["import Editor, { loader, type Monaco } from \"@monaco-editor/react\";\nimport * as monaco from \"monaco-editor\";\nimport { useRef } from \"react\";\nimport { useResolvedTheme } from \"../hooks/use-theme\";\nimport { useMonacoWorkerFactory } from \"./use-monaco-worker\";\nimport type { MonacoEditorProps } from \"./types\";\n\nloader.config({ monaco });\n\nexport function MonacoEditor({\n value,\n onChange,\n readOnly = false,\n language,\n path,\n height = \"20rem\",\n beforeMount,\n onMount,\n onValidate,\n}: MonacoEditorProps) {\n if (!readOnly && !onChange) throw new Error(\"MonacoEditor requires onChange when editing\");\n const workers = useMonacoWorkerFactory();\n const theme = useResolvedTheme() === \"dark\" ? \"vs-dark\" : \"light\";\n // @monaco-editor/react keeps the first onMount it sees, so read the value at\n // mount time through a ref rather than that render's closure.\n const latestValue = useRef(value);\n latestValue.current = value;\n\n if (!workers) {\n return <div role=\"alert\" className=\"rounded-md border border-destructive/40 p-3 text-sm text-destructive\">Monaco workers are not configured.</div>;\n }\n\n return (\n <div className=\"overflow-hidden rounded-md border border-input\" data-slot=\"monaco-editor\">\n <Editor\n value={value}\n onChange={(next) => onChange?.(next ?? \"\")}\n language={language}\n path={path}\n height={height}\n theme={theme}\n keepCurrentModel\n {...(beforeMount ? { beforeMount } : {})}\n onMount={(instance, monacoInstance) => {\n // keepCurrentModel remounts onto the model already at `path`, which\n // still holds the text from when the previous editor unmounted.\n if (instance.getValue() !== latestValue.current) instance.setValue(latestValue.current);\n onMount?.(instance, monacoInstance);\n }}\n {...(onValidate ? { onValidate } : {})}\n options={{\n readOnly,\n automaticLayout: true,\n fontFamily: \"var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace)\",\n fontSize: 13,\n lineHeight: 20,\n minimap: { enabled: false },\n scrollBeyondLastLine: false,\n tabSize: 2,\n wordWrap: \"on\",\n quickSuggestions: { other: true, comments: true, strings: true },\n }}\n />\n </div>\n );\n}\n\nexport type { Monaco };\n"],"names":["monaco"],"mappings":";;;;;;AAOA,OAAO,OAAO,EAAA,QAAEA,cAAQ;AAEjB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,MAAI,CAAC,YAAY,CAAC,SAAU,OAAM,IAAI,MAAM,6CAA6C;AACzF,QAAM,UAAU,uBAAA;AAChB,QAAM,QAAQ,iBAAA,MAAuB,SAAS,YAAY;AAG1D,QAAM,cAAc,OAAO,KAAK;AAChC,cAAY,UAAU;AAEtB,MAAI,CAAC,SAAS;AACZ,+BAAQ,OAAA,EAAI,MAAK,SAAQ,WAAU,wEAAuE,UAAA,sCAAkC;AAAA,EAC9I;AAEA,SACE,oBAAC,OAAA,EAAI,WAAU,kDAAiD,aAAU,iBACxE,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,UAAU,CAAC,SAAS,qCAAW,QAAQ;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAgB;AAAA,MACf,GAAI,cAAc,EAAE,YAAA,IAAgB,CAAA;AAAA,MACrC,SAAS,CAAC,UAAU,mBAAmB;AAGrC,YAAI,SAAS,eAAe,YAAY,QAAS,UAAS,SAAS,YAAY,OAAO;AACtF,2CAAU,UAAU;AAAA,MACtB;AAAA,MACC,GAAI,aAAa,EAAE,WAAA,IAAe,CAAA;AAAA,MACnC,SAAS;AAAA,QACP;AAAA,QACA,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,SAAS,EAAE,SAAS,MAAA;AAAA,QACpB,sBAAsB;AAAA,QACtB,SAAS;AAAA,QACT,UAAU;AAAA,QACV,kBAAkB,EAAE,OAAO,MAAM,UAAU,MAAM,SAAS,KAAA;AAAA,MAAK;AAAA,IACjE;AAAA,EAAA,GAEJ;AAEJ;"}
@@ -14,7 +14,8 @@ export type MonacoProviderProps = {
14
14
  };
15
15
  export type MonacoEditorProps = {
16
16
  value: string;
17
- onChange: (value: string) => void;
17
+ onChange?: (value: string) => void;
18
+ readOnly?: boolean;
18
19
  language: string;
19
20
  path: string;
20
21
  height?: string | number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/monaco/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,aAAa,CAAC;AAErF,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;AAE5D,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,IAAI,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC,GAAG;IACrH,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC5D,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/monaco/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,aAAa,CAAC;AAErF,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;AAE5D,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,mBAAmB,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,IAAI,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC,GAAG;IACrH,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC5D,CAAC"}
@@ -21,6 +21,8 @@ function CommandPalette({
21
21
  groups,
22
22
  query,
23
23
  onQueryChange,
24
+ customInput,
25
+ focusListKey,
24
26
  hotkey = "mod+k",
25
27
  placeholder = "Type a command or search…",
26
28
  loading,
@@ -45,6 +47,7 @@ function CommandPalette({
45
47
  const restoreFocusRef = react.useRef(null);
46
48
  const isOpen = open ?? selfOpen;
47
49
  const currentQuery = query ?? selfQuery;
50
+ const usesCustomInput = customInput !== void 0;
48
51
  const setOpen = react.useCallback(
49
52
  (next) => {
50
53
  if (open === void 0) setSelfOpen(next);
@@ -80,7 +83,11 @@ function CommandPalette({
80
83
  }
81
84
  restoreFocusRef.current = document.activeElement;
82
85
  (_c = inputRef.current) == null ? void 0 : _c.focus();
83
- }, [isOpen, resetQueryOnClose, query]);
86
+ }, [isOpen, resetQueryOnClose, query, usesCustomInput]);
87
+ react.useEffect(() => {
88
+ var _a;
89
+ if (isOpen && focusListKey !== void 0) (_a = listRef.current) == null ? void 0 : _a.focus();
90
+ }, [isOpen, focusListKey]);
84
91
  react.useEffect(() => {
85
92
  var _a;
86
93
  if (activeIndex < 0) return;
@@ -151,14 +158,15 @@ function CommandPalette({
151
158
  "aria-modal": "true",
152
159
  "aria-label": ariaLabel,
153
160
  className: utils.cn(
154
- "flex h-fit w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl",
161
+ "flex h-fit w-full flex-col rounded-lg border border-border bg-background shadow-xl",
162
+ usesCustomInput ? "overflow-visible" : "overflow-hidden",
155
163
  SIZE_CLASS[size],
156
164
  className
157
165
  ),
158
166
  style: { marginTop: topOffset },
159
167
  onClick: (event) => event.stopPropagation(),
160
168
  children: [
161
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-density-2 border-b border-border px-density-3", children: [
169
+ !usesCustomInput ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-density-2 border-b border-border px-density-3", children: [
162
170
  /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiSearch.UiSearch, className: "shrink-0 text-muted-foreground" }),
163
171
  /* @__PURE__ */ jsxRuntime.jsx(
164
172
  "input",
@@ -178,7 +186,7 @@ function CommandPalette({
178
186
  className: "h-12 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-placeholder"
179
187
  }
180
188
  )
181
- ] }),
189
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-border p-density-3", children: customInput }),
182
190
  /* @__PURE__ */ jsxRuntime.jsx(
183
191
  CommandPaletteList.CommandPaletteList,
184
192
  {
@@ -189,6 +197,8 @@ function CommandPalette({
189
197
  optionId,
190
198
  onActivate: activate,
191
199
  onHover: setActiveIndex,
200
+ onKeyDown,
201
+ activeItemId: activeItem ? optionId(activeItem) : void 0,
192
202
  listRef,
193
203
  loading,
194
204
  emptyState,
@@ -1 +1 @@
1
- {"version":3,"file":"CommandPalette.cjs","sources":["../../src/overlay/CommandPalette.tsx"],"sourcesContent":["import { useCallback, useEffect, useId, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiSearch } from \"../icons\";\nimport { useHotkey } from \"../hooks/use-hotkey\";\nimport { useEscapeLayer, useModalStack } from \"./modalStack\";\nimport { zIndex } from \"./zIndex\";\nimport { CommandPaletteList } from \"./CommandPaletteList\";\nimport {\n defaultCommandFilter,\n filterCommandGroups,\n firstEnabledIndex,\n flattenCommands,\n lastEnabledIndex,\n nextEnabledIndex,\n type CommandFilter,\n type CommandGroup,\n type CommandItem,\n} from \"./CommandPalette.model\";\n\nexport type {\n CommandFilter,\n CommandGroup,\n CommandItem,\n CommandSelectContext,\n} from \"./CommandPalette.model\";\n\nconst SIZE_CLASS = {\n md: \"max-w-[40rem]\",\n lg: \"max-w-[48rem]\",\n} as const;\n\nexport type CommandPaletteProps = {\n /**\n * Controls visibility. Omit to run uncontrolled — the palette then owns its\n * open state and the built-in hotkey works with no wiring beyond mounting it.\n */\n open?: boolean;\n /** Called with the next open state on hotkey, Escape, backdrop click, and selection. */\n onOpenChange?: (open: boolean) => void;\n /** Command groups, rendered top to bottom in array order. */\n groups: CommandGroup[];\n /** Controlled query. Omit to let the palette own the input. */\n query?: string;\n /** Called with the next query on every keystroke. Required for server-side search. */\n onQueryChange?: (query: string) => void;\n /**\n * Global shortcut that opens (and, while open, closes) the palette, in\n * `useHotkey` syntax — `\"mod+k\"` by default, where `mod` is ⌘ on macOS and\n * Ctrl elsewhere. Pass `null` when an ancestor owns the binding.\n */\n hotkey?: string | null;\n /** Ghost text in the search input. Defaults to \"Type a command or search…\". */\n placeholder?: string;\n /** Shows a loading row instead of the empty state while results are in flight. */\n loading?: boolean;\n /** Replaces the default \"No results\" body. */\n emptyState?: ReactNode;\n /** Non-interactive hint strip pinned below the list. */\n footer?: ReactNode;\n /**\n * How rows are matched. Defaults to a case-insensitive substring match over\n * label, description and keywords, ranked by hit position. Pass `false` when\n * the caller already filtered `groups` server-side.\n */\n filter?: CommandFilter | false;\n /** Fallback handler for items with no own `onSelect`. */\n onSelect?: (context: { item: CommandItem; query: string; close: () => void }) => void;\n /** Close after a successful activation. Defaults to true. */\n closeOnSelect?: boolean;\n /** Clear the query when the palette closes. Defaults to true. */\n resetQueryOnClose?: boolean;\n /** Panel width preset. Defaults to \"md\". */\n size?: \"md\" | \"lg\";\n /** Distance from the viewport top. Defaults to \"12vh\". Applied as an inline style. */\n topOffset?: string | number;\n /** Max height of the scrolling list. Defaults to \"min(24rem, 50dvh)\". Inline style. */\n listMaxHeight?: string | number;\n /** Accessible name for the dialog. Defaults to \"Command palette\". */\n ariaLabel?: string;\n /** Classes applied to the palette panel. */\n className?: string;\n};\n\n/**\n * A ⌘K command palette: a top-anchored overlay with a search field over a\n * grouped, keyboard-navigable command list.\n *\n * It renders its own portal rather than building on `Modal`, which centres its\n * panel, focuses the dialog element instead of an input, forces body padding,\n * and pins an inline max-height — none of which a palette can override. The\n * stacking primitives are shared though (`useModalStack`, `useEscapeLayer`, the\n * `zIndex` scale), so a palette opened over a modal sits above it and Escape\n * still dismisses exactly one layer.\n */\nexport function CommandPalette({\n open,\n onOpenChange,\n groups,\n query,\n onQueryChange,\n hotkey = \"mod+k\",\n placeholder = \"Type a command or search…\",\n loading,\n emptyState,\n footer,\n filter = defaultCommandFilter,\n onSelect,\n closeOnSelect = true,\n resetQueryOnClose = true,\n size = \"md\",\n topOffset = \"12vh\",\n listMaxHeight = \"min(24rem, 50dvh)\",\n ariaLabel = \"Command palette\",\n className,\n}: CommandPaletteProps) {\n const baseId = useId();\n const [selfOpen, setSelfOpen] = useState(false);\n const [selfQuery, setSelfQuery] = useState(\"\");\n const [activeIndex, setActiveIndex] = useState(0);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const restoreFocusRef = useRef<HTMLElement | null>(null);\n\n const isOpen = open ?? selfOpen;\n const currentQuery = query ?? selfQuery;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (open === undefined) setSelfOpen(next);\n onOpenChange?.(next);\n },\n [open, onOpenChange],\n );\n\n const setQuery = useCallback(\n (next: string) => {\n if (query === undefined) setSelfQuery(next);\n onQueryChange?.(next);\n },\n [query, onQueryChange],\n );\n\n const visibleGroups = useMemo(\n () => filterCommandGroups(groups, currentQuery, filter),\n [groups, currentQuery, filter],\n );\n const items = useMemo(() => flattenCommands(visibleGroups), [visibleGroups]);\n\n // Priority keeps the palette ahead of any page-level ⌘K search field, whose\n // binding would otherwise win purely by mounting later.\n useHotkey(hotkey, () => setOpen(!isOpen), { priority: 10 });\n useEscapeLayer(isOpen, () => setOpen(false));\n\n const { depth } = useModalStack(isOpen);\n\n // Enter-runs-the-top-result is the point of a palette, so the active row\n // resets to the first selectable one whenever the result set changes.\n useEffect(() => {\n setActiveIndex(firstEnabledIndex(items));\n }, [items]);\n\n useEffect(() => {\n if (!isOpen) {\n if (resetQueryOnClose && query === undefined) setSelfQuery(\"\");\n restoreFocusRef.current?.focus?.();\n restoreFocusRef.current = null;\n return;\n }\n restoreFocusRef.current = document.activeElement as HTMLElement | null;\n inputRef.current?.focus();\n }, [isOpen, resetQueryOnClose, query]);\n\n // Keep the active row in view without stealing focus from the input.\n useEffect(() => {\n if (activeIndex < 0) return;\n const option = listRef.current?.querySelectorAll('[role=\"option\"]')[activeIndex];\n // jsdom does not implement scrollIntoView; scrolling is a progressive\n // enhancement, so skip it rather than crash a consumer's test run.\n if (option instanceof HTMLElement && typeof option.scrollIntoView === \"function\") {\n option.scrollIntoView({ block: \"nearest\" });\n }\n }, [activeIndex]);\n\n const optionId = useCallback((item: CommandItem) => `${baseId}-option-${item.id}`, [baseId]);\n\n const activate = useCallback(\n (item: CommandItem) => {\n if (item.disabled) return;\n const close = () => setOpen(false);\n const context = { item, query: currentQuery.trim(), close };\n if (item.onSelect) item.onSelect(context);\n else onSelect?.(context);\n if (closeOnSelect) close();\n },\n [currentQuery, onSelect, closeOnSelect, setOpen],\n );\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n setActiveIndex((current) => nextEnabledIndex(items, current, 1));\n break;\n case \"ArrowUp\":\n event.preventDefault();\n setActiveIndex((current) => nextEnabledIndex(items, current, -1));\n break;\n case \"Home\":\n event.preventDefault();\n setActiveIndex(firstEnabledIndex(items));\n break;\n case \"End\":\n event.preventDefault();\n setActiveIndex(lastEnabledIndex(items));\n break;\n case \"Enter\": {\n event.preventDefault();\n const index = activeIndex >= 0 ? activeIndex : firstEnabledIndex(items);\n const item = index >= 0 ? items[index] : undefined;\n if (item) activate(item);\n break;\n }\n case \"Tab\":\n // Nothing else in the panel is focusable, and letting Tab escape an\n // aria-modal dialog would strand focus behind the backdrop.\n if (!footer) event.preventDefault();\n break;\n default:\n break;\n }\n };\n\n if (!isOpen || typeof document === \"undefined\") return null;\n\n const activeItem = activeIndex >= 0 ? items[activeIndex] : undefined;\n const listId = `${baseId}-list`;\n\n const overlay = (\n <div\n className={cn(\n \"fixed inset-0 flex justify-center p-density-4\",\n depth === 0 ? \"bg-black/40\" : \"bg-black/20\",\n )}\n style={{ zIndex: zIndex.modal + depth * zIndex.modalStep }}\n role=\"presentation\"\n onClick={() => setOpen(false)}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={ariaLabel}\n className={cn(\n \"flex h-fit w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl\",\n SIZE_CLASS[size],\n className,\n )}\n style={{ marginTop: topOffset }}\n onClick={(event) => event.stopPropagation()}\n >\n <div className=\"flex items-center gap-density-2 border-b border-border px-density-3\">\n <Icon icon={UiSearch} className=\"shrink-0 text-muted-foreground\" />\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={activeItem ? optionId(activeItem) : undefined}\n aria-label={ariaLabel}\n value={currentQuery}\n placeholder={placeholder}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={onKeyDown}\n className=\"h-12 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-placeholder\"\n />\n </div>\n\n <CommandPaletteList\n groups={visibleGroups}\n items={items}\n activeIndex={activeIndex}\n listId={listId}\n optionId={optionId}\n onActivate={activate}\n onHover={setActiveIndex}\n listRef={listRef}\n loading={loading}\n emptyState={emptyState}\n listMaxHeight={listMaxHeight}\n />\n\n {footer && (\n <div className=\"border-t border-border px-density-3 py-density-2 text-xs text-muted-foreground\">\n {footer}\n </div>\n )}\n </div>\n </div>\n );\n\n return createPortal(overlay, document.body);\n}\n"],"names":["defaultCommandFilter","useId","useState","useRef","useCallback","useMemo","filterCommandGroups","flattenCommands","useHotkey","useEscapeLayer","useModalStack","useEffect","firstEnabledIndex","nextEnabledIndex","lastEnabledIndex","jsx","cn","zIndex","jsxs","Icon","UiSearch","CommandPaletteList","createPortal"],"mappings":"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"}
1
+ {"version":3,"file":"CommandPalette.cjs","sources":["../../src/overlay/CommandPalette.tsx"],"sourcesContent":["import { useCallback, useEffect, useId, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiSearch } from \"../icons\";\nimport { useHotkey } from \"../hooks/use-hotkey\";\nimport { useEscapeLayer, useModalStack } from \"./modalStack\";\nimport { zIndex } from \"./zIndex\";\nimport { CommandPaletteList } from \"./CommandPaletteList\";\nimport {\n defaultCommandFilter,\n filterCommandGroups,\n firstEnabledIndex,\n flattenCommands,\n lastEnabledIndex,\n nextEnabledIndex,\n type CommandFilter,\n type CommandGroup,\n type CommandItem,\n} from \"./CommandPalette.model\";\n\nexport type {\n CommandFilter,\n CommandGroup,\n CommandItem,\n CommandSelectContext,\n} from \"./CommandPalette.model\";\n\nconst SIZE_CLASS = {\n md: \"max-w-[40rem]\",\n lg: \"max-w-[48rem]\",\n} as const;\n\nexport type CommandPaletteProps = {\n /**\n * Controls visibility. Omit to run uncontrolled — the palette then owns its\n * open state and the built-in hotkey works with no wiring beyond mounting it.\n */\n open?: boolean;\n /** Called with the next open state on hotkey, Escape, backdrop click, and selection. */\n onOpenChange?: (open: boolean) => void;\n /** Command groups, rendered top to bottom in array order. */\n groups: CommandGroup[];\n /** Controlled query. Omit to let the palette own the input. */\n query?: string;\n /** Called with the next query on every keystroke. Required for server-side search. */\n onQueryChange?: (query: string) => void;\n /** Replaces the built-in search field while preserving the palette and result list. */\n customInput?: ReactNode;\n /** Changing this value focuses the result list for keyboard selection. */\n focusListKey?: number;\n /**\n * Global shortcut that opens (and, while open, closes) the palette, in\n * `useHotkey` syntax — `\"mod+k\"` by default, where `mod` is ⌘ on macOS and\n * Ctrl elsewhere. Pass `null` when an ancestor owns the binding.\n */\n hotkey?: string | null;\n /** Ghost text in the search input. Defaults to \"Type a command or search…\". */\n placeholder?: string;\n /** Shows a loading row instead of the empty state while results are in flight. */\n loading?: boolean;\n /** Replaces the default \"No results\" body. */\n emptyState?: ReactNode;\n /** Non-interactive hint strip pinned below the list. */\n footer?: ReactNode;\n /**\n * How rows are matched. Defaults to a case-insensitive substring match over\n * label, description and keywords, ranked by hit position. Pass `false` when\n * the caller already filtered `groups` server-side.\n */\n filter?: CommandFilter | false;\n /** Fallback handler for items with no own `onSelect`. */\n onSelect?: (context: { item: CommandItem; query: string; close: () => void }) => void;\n /** Close after a successful activation. Defaults to true. */\n closeOnSelect?: boolean;\n /** Clear the query when the palette closes. Defaults to true. */\n resetQueryOnClose?: boolean;\n /** Panel width preset. Defaults to \"md\". */\n size?: \"md\" | \"lg\";\n /** Distance from the viewport top. Defaults to \"12vh\". Applied as an inline style. */\n topOffset?: string | number;\n /** Max height of the scrolling list. Defaults to \"min(24rem, 50dvh)\". Inline style. */\n listMaxHeight?: string | number;\n /** Accessible name for the dialog. Defaults to \"Command palette\". */\n ariaLabel?: string;\n /** Classes applied to the palette panel. */\n className?: string;\n};\n\n/**\n * A ⌘K command palette: a top-anchored overlay with a search field over a\n * grouped, keyboard-navigable command list.\n *\n * It renders its own portal rather than building on `Modal`, which centres its\n * panel, focuses the dialog element instead of an input, forces body padding,\n * and pins an inline max-height — none of which a palette can override. The\n * stacking primitives are shared though (`useModalStack`, `useEscapeLayer`, the\n * `zIndex` scale), so a palette opened over a modal sits above it and Escape\n * still dismisses exactly one layer.\n */\nexport function CommandPalette({\n open,\n onOpenChange,\n groups,\n query,\n onQueryChange,\n customInput,\n focusListKey,\n hotkey = \"mod+k\",\n placeholder = \"Type a command or search…\",\n loading,\n emptyState,\n footer,\n filter = defaultCommandFilter,\n onSelect,\n closeOnSelect = true,\n resetQueryOnClose = true,\n size = \"md\",\n topOffset = \"12vh\",\n listMaxHeight = \"min(24rem, 50dvh)\",\n ariaLabel = \"Command palette\",\n className,\n}: CommandPaletteProps) {\n const baseId = useId();\n const [selfOpen, setSelfOpen] = useState(false);\n const [selfQuery, setSelfQuery] = useState(\"\");\n const [activeIndex, setActiveIndex] = useState(0);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const restoreFocusRef = useRef<HTMLElement | null>(null);\n\n const isOpen = open ?? selfOpen;\n const currentQuery = query ?? selfQuery;\n const usesCustomInput = customInput !== undefined;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (open === undefined) setSelfOpen(next);\n onOpenChange?.(next);\n },\n [open, onOpenChange],\n );\n\n const setQuery = useCallback(\n (next: string) => {\n if (query === undefined) setSelfQuery(next);\n onQueryChange?.(next);\n },\n [query, onQueryChange],\n );\n\n const visibleGroups = useMemo(\n () => filterCommandGroups(groups, currentQuery, filter),\n [groups, currentQuery, filter],\n );\n const items = useMemo(() => flattenCommands(visibleGroups), [visibleGroups]);\n\n // Priority keeps the palette ahead of any page-level ⌘K search field, whose\n // binding would otherwise win purely by mounting later.\n useHotkey(hotkey, () => setOpen(!isOpen), { priority: 10 });\n useEscapeLayer(isOpen, () => setOpen(false));\n\n const { depth } = useModalStack(isOpen);\n\n // Enter-runs-the-top-result is the point of a palette, so the active row\n // resets to the first selectable one whenever the result set changes.\n useEffect(() => {\n setActiveIndex(firstEnabledIndex(items));\n }, [items]);\n\n useEffect(() => {\n if (!isOpen) {\n if (resetQueryOnClose && query === undefined) setSelfQuery(\"\");\n restoreFocusRef.current?.focus?.();\n restoreFocusRef.current = null;\n return;\n }\n restoreFocusRef.current = document.activeElement as HTMLElement | null;\n inputRef.current?.focus();\n }, [isOpen, resetQueryOnClose, query, usesCustomInput]);\n\n useEffect(() => {\n if (isOpen && focusListKey !== undefined) listRef.current?.focus();\n }, [isOpen, focusListKey]);\n\n // Keep the active row in view without stealing focus from the input.\n useEffect(() => {\n if (activeIndex < 0) return;\n const option = listRef.current?.querySelectorAll('[role=\"option\"]')[activeIndex];\n // jsdom does not implement scrollIntoView; scrolling is a progressive\n // enhancement, so skip it rather than crash a consumer's test run.\n if (option instanceof HTMLElement && typeof option.scrollIntoView === \"function\") {\n option.scrollIntoView({ block: \"nearest\" });\n }\n }, [activeIndex]);\n\n const optionId = useCallback((item: CommandItem) => `${baseId}-option-${item.id}`, [baseId]);\n\n const activate = useCallback(\n (item: CommandItem) => {\n if (item.disabled) return;\n const close = () => setOpen(false);\n const context = { item, query: currentQuery.trim(), close };\n if (item.onSelect) item.onSelect(context);\n else onSelect?.(context);\n if (closeOnSelect) close();\n },\n [currentQuery, onSelect, closeOnSelect, setOpen],\n );\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n setActiveIndex((current) => nextEnabledIndex(items, current, 1));\n break;\n case \"ArrowUp\":\n event.preventDefault();\n setActiveIndex((current) => nextEnabledIndex(items, current, -1));\n break;\n case \"Home\":\n event.preventDefault();\n setActiveIndex(firstEnabledIndex(items));\n break;\n case \"End\":\n event.preventDefault();\n setActiveIndex(lastEnabledIndex(items));\n break;\n case \"Enter\": {\n event.preventDefault();\n const index = activeIndex >= 0 ? activeIndex : firstEnabledIndex(items);\n const item = index >= 0 ? items[index] : undefined;\n if (item) activate(item);\n break;\n }\n case \"Tab\":\n // Nothing else in the panel is focusable, and letting Tab escape an\n // aria-modal dialog would strand focus behind the backdrop.\n if (!footer) event.preventDefault();\n break;\n default:\n break;\n }\n };\n\n if (!isOpen || typeof document === \"undefined\") return null;\n\n const activeItem = activeIndex >= 0 ? items[activeIndex] : undefined;\n const listId = `${baseId}-list`;\n\n const overlay = (\n <div\n className={cn(\n \"fixed inset-0 flex justify-center p-density-4\",\n depth === 0 ? \"bg-black/40\" : \"bg-black/20\",\n )}\n style={{ zIndex: zIndex.modal + depth * zIndex.modalStep }}\n role=\"presentation\"\n onClick={() => setOpen(false)}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={ariaLabel}\n className={cn(\n \"flex h-fit w-full flex-col rounded-lg border border-border bg-background shadow-xl\",\n usesCustomInput ? \"overflow-visible\" : \"overflow-hidden\",\n SIZE_CLASS[size],\n className,\n )}\n style={{ marginTop: topOffset }}\n onClick={(event) => event.stopPropagation()}\n >\n {!usesCustomInput ? <div className=\"flex items-center gap-density-2 border-b border-border px-density-3\">\n <Icon icon={UiSearch} className=\"shrink-0 text-muted-foreground\" />\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={activeItem ? optionId(activeItem) : undefined}\n aria-label={ariaLabel}\n value={currentQuery}\n placeholder={placeholder}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={onKeyDown}\n className=\"h-12 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-placeholder\"\n />\n </div> : <div className=\"border-b border-border p-density-3\">{customInput}</div>}\n\n <CommandPaletteList\n groups={visibleGroups}\n items={items}\n activeIndex={activeIndex}\n listId={listId}\n optionId={optionId}\n onActivate={activate}\n onHover={setActiveIndex}\n onKeyDown={onKeyDown}\n activeItemId={activeItem ? optionId(activeItem) : undefined}\n listRef={listRef}\n loading={loading}\n emptyState={emptyState}\n listMaxHeight={listMaxHeight}\n />\n\n {footer && (\n <div className=\"border-t border-border px-density-3 py-density-2 text-xs text-muted-foreground\">\n {footer}\n </div>\n )}\n </div>\n </div>\n );\n\n return createPortal(overlay, document.body);\n}\n"],"names":["defaultCommandFilter","useId","useState","useRef","useCallback","useMemo","filterCommandGroups","flattenCommands","useHotkey","useEscapeLayer","useModalStack","useEffect","firstEnabledIndex","nextEnabledIndex","lastEnabledIndex","jsx","cn","zIndex","jsxs","Icon","UiSearch","CommandPaletteList","createPortal"],"mappings":"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"}
@@ -15,6 +15,10 @@ export type CommandPaletteProps = {
15
15
  query?: string;
16
16
  /** Called with the next query on every keystroke. Required for server-side search. */
17
17
  onQueryChange?: (query: string) => void;
18
+ /** Replaces the built-in search field while preserving the palette and result list. */
19
+ customInput?: ReactNode;
20
+ /** Changing this value focuses the result list for keyboard selection. */
21
+ focusListKey?: number;
18
22
  /**
19
23
  * Global shortcut that opens (and, while open, closes) the palette, in
20
24
  * `useHotkey` syntax — `"mod+k"` by default, where `mod` is ⌘ on macOS and
@@ -67,5 +71,5 @@ export type CommandPaletteProps = {
67
71
  * `zIndex` scale), so a palette opened over a modal sits above it and Escape
68
72
  * still dismisses exactly one layer.
69
73
  */
70
- export declare function CommandPalette({ open, onOpenChange, groups, query, onQueryChange, hotkey, placeholder, loading, emptyState, footer, filter, onSelect, closeOnSelect, resetQueryOnClose, size, topOffset, listMaxHeight, ariaLabel, className, }: CommandPaletteProps): import('react').ReactPortal | null;
74
+ export declare function CommandPalette({ open, onOpenChange, groups, query, onQueryChange, customInput, focusListKey, hotkey, placeholder, loading, emptyState, footer, filter, onSelect, closeOnSelect, resetQueryOnClose, size, topOffset, listMaxHeight, ariaLabel, className, }: CommandPaletteProps): import('react').ReactPortal | null;
71
75
  //# sourceMappingURL=CommandPalette.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CommandPalette.d.ts","sourceRoot":"","sources":["../../src/overlay/CommandPalette.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AASjG,OAAO,EAOL,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAOhC,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wFAAwF;IACxF,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,6DAA6D;IAC7D,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,wDAAwD;IACxD,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,GAAG,KAAK,CAAC;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IACtF,6DAA6D;IAC7D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iEAAiE;IACjE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4CAA4C;IAC5C,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,KAAK,EACL,aAAa,EACb,MAAgB,EAChB,WAAyC,EACzC,OAAO,EACP,UAAU,EACV,MAAM,EACN,MAA6B,EAC7B,QAAQ,EACR,aAAoB,EACpB,iBAAwB,EACxB,IAAW,EACX,SAAkB,EAClB,aAAmC,EACnC,SAA6B,EAC7B,SAAS,GACV,EAAE,mBAAmB,sCA6LrB"}
1
+ {"version":3,"file":"CommandPalette.d.ts","sourceRoot":"","sources":["../../src/overlay/CommandPalette.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AASjG,OAAO,EAOL,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAOhC,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wFAAwF;IACxF,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,6DAA6D;IAC7D,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uFAAuF;IACvF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,wDAAwD;IACxD,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,GAAG,KAAK,CAAC;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IACtF,6DAA6D;IAC7D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iEAAiE;IACjE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4CAA4C;IAC5C,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,KAAK,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,MAAgB,EAChB,WAAyC,EACzC,OAAO,EACP,UAAU,EACV,MAAM,EACN,MAA6B,EAC7B,QAAQ,EACR,aAAoB,EACpB,iBAAwB,EACxB,IAAW,EACX,SAAkB,EAClB,aAAmC,EACnC,SAA6B,EAC7B,SAAS,GACV,EAAE,mBAAmB,sCAqMrB"}
@@ -19,6 +19,8 @@ function CommandPalette({
19
19
  groups,
20
20
  query,
21
21
  onQueryChange,
22
+ customInput,
23
+ focusListKey,
22
24
  hotkey = "mod+k",
23
25
  placeholder = "Type a command or search…",
24
26
  loading,
@@ -43,6 +45,7 @@ function CommandPalette({
43
45
  const restoreFocusRef = useRef(null);
44
46
  const isOpen = open ?? selfOpen;
45
47
  const currentQuery = query ?? selfQuery;
48
+ const usesCustomInput = customInput !== void 0;
46
49
  const setOpen = useCallback(
47
50
  (next) => {
48
51
  if (open === void 0) setSelfOpen(next);
@@ -78,7 +81,11 @@ function CommandPalette({
78
81
  }
79
82
  restoreFocusRef.current = document.activeElement;
80
83
  (_c = inputRef.current) == null ? void 0 : _c.focus();
81
- }, [isOpen, resetQueryOnClose, query]);
84
+ }, [isOpen, resetQueryOnClose, query, usesCustomInput]);
85
+ useEffect(() => {
86
+ var _a;
87
+ if (isOpen && focusListKey !== void 0) (_a = listRef.current) == null ? void 0 : _a.focus();
88
+ }, [isOpen, focusListKey]);
82
89
  useEffect(() => {
83
90
  var _a;
84
91
  if (activeIndex < 0) return;
@@ -149,14 +156,15 @@ function CommandPalette({
149
156
  "aria-modal": "true",
150
157
  "aria-label": ariaLabel,
151
158
  className: cn(
152
- "flex h-fit w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl",
159
+ "flex h-fit w-full flex-col rounded-lg border border-border bg-background shadow-xl",
160
+ usesCustomInput ? "overflow-visible" : "overflow-hidden",
153
161
  SIZE_CLASS[size],
154
162
  className
155
163
  ),
156
164
  style: { marginTop: topOffset },
157
165
  onClick: (event) => event.stopPropagation(),
158
166
  children: [
159
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-density-2 border-b border-border px-density-3", children: [
167
+ !usesCustomInput ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-density-2 border-b border-border px-density-3", children: [
160
168
  /* @__PURE__ */ jsx(Icon, { icon: UiSearch, className: "shrink-0 text-muted-foreground" }),
161
169
  /* @__PURE__ */ jsx(
162
170
  "input",
@@ -176,7 +184,7 @@ function CommandPalette({
176
184
  className: "h-12 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-placeholder"
177
185
  }
178
186
  )
179
- ] }),
187
+ ] }) : /* @__PURE__ */ jsx("div", { className: "border-b border-border p-density-3", children: customInput }),
180
188
  /* @__PURE__ */ jsx(
181
189
  CommandPaletteList,
182
190
  {
@@ -187,6 +195,8 @@ function CommandPalette({
187
195
  optionId,
188
196
  onActivate: activate,
189
197
  onHover: setActiveIndex,
198
+ onKeyDown,
199
+ activeItemId: activeItem ? optionId(activeItem) : void 0,
190
200
  listRef,
191
201
  loading,
192
202
  emptyState,
@@ -1 +1 @@
1
- {"version":3,"file":"CommandPalette.js","sources":["../../src/overlay/CommandPalette.tsx"],"sourcesContent":["import { useCallback, useEffect, useId, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiSearch } from \"../icons\";\nimport { useHotkey } from \"../hooks/use-hotkey\";\nimport { useEscapeLayer, useModalStack } from \"./modalStack\";\nimport { zIndex } from \"./zIndex\";\nimport { CommandPaletteList } from \"./CommandPaletteList\";\nimport {\n defaultCommandFilter,\n filterCommandGroups,\n firstEnabledIndex,\n flattenCommands,\n lastEnabledIndex,\n nextEnabledIndex,\n type CommandFilter,\n type CommandGroup,\n type CommandItem,\n} from \"./CommandPalette.model\";\n\nexport type {\n CommandFilter,\n CommandGroup,\n CommandItem,\n CommandSelectContext,\n} from \"./CommandPalette.model\";\n\nconst SIZE_CLASS = {\n md: \"max-w-[40rem]\",\n lg: \"max-w-[48rem]\",\n} as const;\n\nexport type CommandPaletteProps = {\n /**\n * Controls visibility. Omit to run uncontrolled — the palette then owns its\n * open state and the built-in hotkey works with no wiring beyond mounting it.\n */\n open?: boolean;\n /** Called with the next open state on hotkey, Escape, backdrop click, and selection. */\n onOpenChange?: (open: boolean) => void;\n /** Command groups, rendered top to bottom in array order. */\n groups: CommandGroup[];\n /** Controlled query. Omit to let the palette own the input. */\n query?: string;\n /** Called with the next query on every keystroke. Required for server-side search. */\n onQueryChange?: (query: string) => void;\n /**\n * Global shortcut that opens (and, while open, closes) the palette, in\n * `useHotkey` syntax — `\"mod+k\"` by default, where `mod` is ⌘ on macOS and\n * Ctrl elsewhere. Pass `null` when an ancestor owns the binding.\n */\n hotkey?: string | null;\n /** Ghost text in the search input. Defaults to \"Type a command or search…\". */\n placeholder?: string;\n /** Shows a loading row instead of the empty state while results are in flight. */\n loading?: boolean;\n /** Replaces the default \"No results\" body. */\n emptyState?: ReactNode;\n /** Non-interactive hint strip pinned below the list. */\n footer?: ReactNode;\n /**\n * How rows are matched. Defaults to a case-insensitive substring match over\n * label, description and keywords, ranked by hit position. Pass `false` when\n * the caller already filtered `groups` server-side.\n */\n filter?: CommandFilter | false;\n /** Fallback handler for items with no own `onSelect`. */\n onSelect?: (context: { item: CommandItem; query: string; close: () => void }) => void;\n /** Close after a successful activation. Defaults to true. */\n closeOnSelect?: boolean;\n /** Clear the query when the palette closes. Defaults to true. */\n resetQueryOnClose?: boolean;\n /** Panel width preset. Defaults to \"md\". */\n size?: \"md\" | \"lg\";\n /** Distance from the viewport top. Defaults to \"12vh\". Applied as an inline style. */\n topOffset?: string | number;\n /** Max height of the scrolling list. Defaults to \"min(24rem, 50dvh)\". Inline style. */\n listMaxHeight?: string | number;\n /** Accessible name for the dialog. Defaults to \"Command palette\". */\n ariaLabel?: string;\n /** Classes applied to the palette panel. */\n className?: string;\n};\n\n/**\n * A ⌘K command palette: a top-anchored overlay with a search field over a\n * grouped, keyboard-navigable command list.\n *\n * It renders its own portal rather than building on `Modal`, which centres its\n * panel, focuses the dialog element instead of an input, forces body padding,\n * and pins an inline max-height — none of which a palette can override. The\n * stacking primitives are shared though (`useModalStack`, `useEscapeLayer`, the\n * `zIndex` scale), so a palette opened over a modal sits above it and Escape\n * still dismisses exactly one layer.\n */\nexport function CommandPalette({\n open,\n onOpenChange,\n groups,\n query,\n onQueryChange,\n hotkey = \"mod+k\",\n placeholder = \"Type a command or search…\",\n loading,\n emptyState,\n footer,\n filter = defaultCommandFilter,\n onSelect,\n closeOnSelect = true,\n resetQueryOnClose = true,\n size = \"md\",\n topOffset = \"12vh\",\n listMaxHeight = \"min(24rem, 50dvh)\",\n ariaLabel = \"Command palette\",\n className,\n}: CommandPaletteProps) {\n const baseId = useId();\n const [selfOpen, setSelfOpen] = useState(false);\n const [selfQuery, setSelfQuery] = useState(\"\");\n const [activeIndex, setActiveIndex] = useState(0);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const restoreFocusRef = useRef<HTMLElement | null>(null);\n\n const isOpen = open ?? selfOpen;\n const currentQuery = query ?? selfQuery;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (open === undefined) setSelfOpen(next);\n onOpenChange?.(next);\n },\n [open, onOpenChange],\n );\n\n const setQuery = useCallback(\n (next: string) => {\n if (query === undefined) setSelfQuery(next);\n onQueryChange?.(next);\n },\n [query, onQueryChange],\n );\n\n const visibleGroups = useMemo(\n () => filterCommandGroups(groups, currentQuery, filter),\n [groups, currentQuery, filter],\n );\n const items = useMemo(() => flattenCommands(visibleGroups), [visibleGroups]);\n\n // Priority keeps the palette ahead of any page-level ⌘K search field, whose\n // binding would otherwise win purely by mounting later.\n useHotkey(hotkey, () => setOpen(!isOpen), { priority: 10 });\n useEscapeLayer(isOpen, () => setOpen(false));\n\n const { depth } = useModalStack(isOpen);\n\n // Enter-runs-the-top-result is the point of a palette, so the active row\n // resets to the first selectable one whenever the result set changes.\n useEffect(() => {\n setActiveIndex(firstEnabledIndex(items));\n }, [items]);\n\n useEffect(() => {\n if (!isOpen) {\n if (resetQueryOnClose && query === undefined) setSelfQuery(\"\");\n restoreFocusRef.current?.focus?.();\n restoreFocusRef.current = null;\n return;\n }\n restoreFocusRef.current = document.activeElement as HTMLElement | null;\n inputRef.current?.focus();\n }, [isOpen, resetQueryOnClose, query]);\n\n // Keep the active row in view without stealing focus from the input.\n useEffect(() => {\n if (activeIndex < 0) return;\n const option = listRef.current?.querySelectorAll('[role=\"option\"]')[activeIndex];\n // jsdom does not implement scrollIntoView; scrolling is a progressive\n // enhancement, so skip it rather than crash a consumer's test run.\n if (option instanceof HTMLElement && typeof option.scrollIntoView === \"function\") {\n option.scrollIntoView({ block: \"nearest\" });\n }\n }, [activeIndex]);\n\n const optionId = useCallback((item: CommandItem) => `${baseId}-option-${item.id}`, [baseId]);\n\n const activate = useCallback(\n (item: CommandItem) => {\n if (item.disabled) return;\n const close = () => setOpen(false);\n const context = { item, query: currentQuery.trim(), close };\n if (item.onSelect) item.onSelect(context);\n else onSelect?.(context);\n if (closeOnSelect) close();\n },\n [currentQuery, onSelect, closeOnSelect, setOpen],\n );\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n setActiveIndex((current) => nextEnabledIndex(items, current, 1));\n break;\n case \"ArrowUp\":\n event.preventDefault();\n setActiveIndex((current) => nextEnabledIndex(items, current, -1));\n break;\n case \"Home\":\n event.preventDefault();\n setActiveIndex(firstEnabledIndex(items));\n break;\n case \"End\":\n event.preventDefault();\n setActiveIndex(lastEnabledIndex(items));\n break;\n case \"Enter\": {\n event.preventDefault();\n const index = activeIndex >= 0 ? activeIndex : firstEnabledIndex(items);\n const item = index >= 0 ? items[index] : undefined;\n if (item) activate(item);\n break;\n }\n case \"Tab\":\n // Nothing else in the panel is focusable, and letting Tab escape an\n // aria-modal dialog would strand focus behind the backdrop.\n if (!footer) event.preventDefault();\n break;\n default:\n break;\n }\n };\n\n if (!isOpen || typeof document === \"undefined\") return null;\n\n const activeItem = activeIndex >= 0 ? items[activeIndex] : undefined;\n const listId = `${baseId}-list`;\n\n const overlay = (\n <div\n className={cn(\n \"fixed inset-0 flex justify-center p-density-4\",\n depth === 0 ? \"bg-black/40\" : \"bg-black/20\",\n )}\n style={{ zIndex: zIndex.modal + depth * zIndex.modalStep }}\n role=\"presentation\"\n onClick={() => setOpen(false)}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={ariaLabel}\n className={cn(\n \"flex h-fit w-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl\",\n SIZE_CLASS[size],\n className,\n )}\n style={{ marginTop: topOffset }}\n onClick={(event) => event.stopPropagation()}\n >\n <div className=\"flex items-center gap-density-2 border-b border-border px-density-3\">\n <Icon icon={UiSearch} className=\"shrink-0 text-muted-foreground\" />\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={activeItem ? optionId(activeItem) : undefined}\n aria-label={ariaLabel}\n value={currentQuery}\n placeholder={placeholder}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={onKeyDown}\n className=\"h-12 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-placeholder\"\n />\n </div>\n\n <CommandPaletteList\n groups={visibleGroups}\n items={items}\n activeIndex={activeIndex}\n listId={listId}\n optionId={optionId}\n onActivate={activate}\n onHover={setActiveIndex}\n listRef={listRef}\n loading={loading}\n emptyState={emptyState}\n listMaxHeight={listMaxHeight}\n />\n\n {footer && (\n <div className=\"border-t border-border px-density-3 py-density-2 text-xs text-muted-foreground\">\n {footer}\n </div>\n )}\n </div>\n </div>\n );\n\n return createPortal(overlay, document.body);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CommandPalette.js","sources":["../../src/overlay/CommandPalette.tsx"],"sourcesContent":["import { useCallback, useEffect, useId, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiSearch } from \"../icons\";\nimport { useHotkey } from \"../hooks/use-hotkey\";\nimport { useEscapeLayer, useModalStack } from \"./modalStack\";\nimport { zIndex } from \"./zIndex\";\nimport { CommandPaletteList } from \"./CommandPaletteList\";\nimport {\n defaultCommandFilter,\n filterCommandGroups,\n firstEnabledIndex,\n flattenCommands,\n lastEnabledIndex,\n nextEnabledIndex,\n type CommandFilter,\n type CommandGroup,\n type CommandItem,\n} from \"./CommandPalette.model\";\n\nexport type {\n CommandFilter,\n CommandGroup,\n CommandItem,\n CommandSelectContext,\n} from \"./CommandPalette.model\";\n\nconst SIZE_CLASS = {\n md: \"max-w-[40rem]\",\n lg: \"max-w-[48rem]\",\n} as const;\n\nexport type CommandPaletteProps = {\n /**\n * Controls visibility. Omit to run uncontrolled — the palette then owns its\n * open state and the built-in hotkey works with no wiring beyond mounting it.\n */\n open?: boolean;\n /** Called with the next open state on hotkey, Escape, backdrop click, and selection. */\n onOpenChange?: (open: boolean) => void;\n /** Command groups, rendered top to bottom in array order. */\n groups: CommandGroup[];\n /** Controlled query. Omit to let the palette own the input. */\n query?: string;\n /** Called with the next query on every keystroke. Required for server-side search. */\n onQueryChange?: (query: string) => void;\n /** Replaces the built-in search field while preserving the palette and result list. */\n customInput?: ReactNode;\n /** Changing this value focuses the result list for keyboard selection. */\n focusListKey?: number;\n /**\n * Global shortcut that opens (and, while open, closes) the palette, in\n * `useHotkey` syntax — `\"mod+k\"` by default, where `mod` is ⌘ on macOS and\n * Ctrl elsewhere. Pass `null` when an ancestor owns the binding.\n */\n hotkey?: string | null;\n /** Ghost text in the search input. Defaults to \"Type a command or search…\". */\n placeholder?: string;\n /** Shows a loading row instead of the empty state while results are in flight. */\n loading?: boolean;\n /** Replaces the default \"No results\" body. */\n emptyState?: ReactNode;\n /** Non-interactive hint strip pinned below the list. */\n footer?: ReactNode;\n /**\n * How rows are matched. Defaults to a case-insensitive substring match over\n * label, description and keywords, ranked by hit position. Pass `false` when\n * the caller already filtered `groups` server-side.\n */\n filter?: CommandFilter | false;\n /** Fallback handler for items with no own `onSelect`. */\n onSelect?: (context: { item: CommandItem; query: string; close: () => void }) => void;\n /** Close after a successful activation. Defaults to true. */\n closeOnSelect?: boolean;\n /** Clear the query when the palette closes. Defaults to true. */\n resetQueryOnClose?: boolean;\n /** Panel width preset. Defaults to \"md\". */\n size?: \"md\" | \"lg\";\n /** Distance from the viewport top. Defaults to \"12vh\". Applied as an inline style. */\n topOffset?: string | number;\n /** Max height of the scrolling list. Defaults to \"min(24rem, 50dvh)\". Inline style. */\n listMaxHeight?: string | number;\n /** Accessible name for the dialog. Defaults to \"Command palette\". */\n ariaLabel?: string;\n /** Classes applied to the palette panel. */\n className?: string;\n};\n\n/**\n * A ⌘K command palette: a top-anchored overlay with a search field over a\n * grouped, keyboard-navigable command list.\n *\n * It renders its own portal rather than building on `Modal`, which centres its\n * panel, focuses the dialog element instead of an input, forces body padding,\n * and pins an inline max-height — none of which a palette can override. The\n * stacking primitives are shared though (`useModalStack`, `useEscapeLayer`, the\n * `zIndex` scale), so a palette opened over a modal sits above it and Escape\n * still dismisses exactly one layer.\n */\nexport function CommandPalette({\n open,\n onOpenChange,\n groups,\n query,\n onQueryChange,\n customInput,\n focusListKey,\n hotkey = \"mod+k\",\n placeholder = \"Type a command or search…\",\n loading,\n emptyState,\n footer,\n filter = defaultCommandFilter,\n onSelect,\n closeOnSelect = true,\n resetQueryOnClose = true,\n size = \"md\",\n topOffset = \"12vh\",\n listMaxHeight = \"min(24rem, 50dvh)\",\n ariaLabel = \"Command palette\",\n className,\n}: CommandPaletteProps) {\n const baseId = useId();\n const [selfOpen, setSelfOpen] = useState(false);\n const [selfQuery, setSelfQuery] = useState(\"\");\n const [activeIndex, setActiveIndex] = useState(0);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const restoreFocusRef = useRef<HTMLElement | null>(null);\n\n const isOpen = open ?? selfOpen;\n const currentQuery = query ?? selfQuery;\n const usesCustomInput = customInput !== undefined;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (open === undefined) setSelfOpen(next);\n onOpenChange?.(next);\n },\n [open, onOpenChange],\n );\n\n const setQuery = useCallback(\n (next: string) => {\n if (query === undefined) setSelfQuery(next);\n onQueryChange?.(next);\n },\n [query, onQueryChange],\n );\n\n const visibleGroups = useMemo(\n () => filterCommandGroups(groups, currentQuery, filter),\n [groups, currentQuery, filter],\n );\n const items = useMemo(() => flattenCommands(visibleGroups), [visibleGroups]);\n\n // Priority keeps the palette ahead of any page-level ⌘K search field, whose\n // binding would otherwise win purely by mounting later.\n useHotkey(hotkey, () => setOpen(!isOpen), { priority: 10 });\n useEscapeLayer(isOpen, () => setOpen(false));\n\n const { depth } = useModalStack(isOpen);\n\n // Enter-runs-the-top-result is the point of a palette, so the active row\n // resets to the first selectable one whenever the result set changes.\n useEffect(() => {\n setActiveIndex(firstEnabledIndex(items));\n }, [items]);\n\n useEffect(() => {\n if (!isOpen) {\n if (resetQueryOnClose && query === undefined) setSelfQuery(\"\");\n restoreFocusRef.current?.focus?.();\n restoreFocusRef.current = null;\n return;\n }\n restoreFocusRef.current = document.activeElement as HTMLElement | null;\n inputRef.current?.focus();\n }, [isOpen, resetQueryOnClose, query, usesCustomInput]);\n\n useEffect(() => {\n if (isOpen && focusListKey !== undefined) listRef.current?.focus();\n }, [isOpen, focusListKey]);\n\n // Keep the active row in view without stealing focus from the input.\n useEffect(() => {\n if (activeIndex < 0) return;\n const option = listRef.current?.querySelectorAll('[role=\"option\"]')[activeIndex];\n // jsdom does not implement scrollIntoView; scrolling is a progressive\n // enhancement, so skip it rather than crash a consumer's test run.\n if (option instanceof HTMLElement && typeof option.scrollIntoView === \"function\") {\n option.scrollIntoView({ block: \"nearest\" });\n }\n }, [activeIndex]);\n\n const optionId = useCallback((item: CommandItem) => `${baseId}-option-${item.id}`, [baseId]);\n\n const activate = useCallback(\n (item: CommandItem) => {\n if (item.disabled) return;\n const close = () => setOpen(false);\n const context = { item, query: currentQuery.trim(), close };\n if (item.onSelect) item.onSelect(context);\n else onSelect?.(context);\n if (closeOnSelect) close();\n },\n [currentQuery, onSelect, closeOnSelect, setOpen],\n );\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n setActiveIndex((current) => nextEnabledIndex(items, current, 1));\n break;\n case \"ArrowUp\":\n event.preventDefault();\n setActiveIndex((current) => nextEnabledIndex(items, current, -1));\n break;\n case \"Home\":\n event.preventDefault();\n setActiveIndex(firstEnabledIndex(items));\n break;\n case \"End\":\n event.preventDefault();\n setActiveIndex(lastEnabledIndex(items));\n break;\n case \"Enter\": {\n event.preventDefault();\n const index = activeIndex >= 0 ? activeIndex : firstEnabledIndex(items);\n const item = index >= 0 ? items[index] : undefined;\n if (item) activate(item);\n break;\n }\n case \"Tab\":\n // Nothing else in the panel is focusable, and letting Tab escape an\n // aria-modal dialog would strand focus behind the backdrop.\n if (!footer) event.preventDefault();\n break;\n default:\n break;\n }\n };\n\n if (!isOpen || typeof document === \"undefined\") return null;\n\n const activeItem = activeIndex >= 0 ? items[activeIndex] : undefined;\n const listId = `${baseId}-list`;\n\n const overlay = (\n <div\n className={cn(\n \"fixed inset-0 flex justify-center p-density-4\",\n depth === 0 ? \"bg-black/40\" : \"bg-black/20\",\n )}\n style={{ zIndex: zIndex.modal + depth * zIndex.modalStep }}\n role=\"presentation\"\n onClick={() => setOpen(false)}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={ariaLabel}\n className={cn(\n \"flex h-fit w-full flex-col rounded-lg border border-border bg-background shadow-xl\",\n usesCustomInput ? \"overflow-visible\" : \"overflow-hidden\",\n SIZE_CLASS[size],\n className,\n )}\n style={{ marginTop: topOffset }}\n onClick={(event) => event.stopPropagation()}\n >\n {!usesCustomInput ? <div className=\"flex items-center gap-density-2 border-b border-border px-density-3\">\n <Icon icon={UiSearch} className=\"shrink-0 text-muted-foreground\" />\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={activeItem ? optionId(activeItem) : undefined}\n aria-label={ariaLabel}\n value={currentQuery}\n placeholder={placeholder}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={onKeyDown}\n className=\"h-12 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-placeholder\"\n />\n </div> : <div className=\"border-b border-border p-density-3\">{customInput}</div>}\n\n <CommandPaletteList\n groups={visibleGroups}\n items={items}\n activeIndex={activeIndex}\n listId={listId}\n optionId={optionId}\n onActivate={activate}\n onHover={setActiveIndex}\n onKeyDown={onKeyDown}\n activeItemId={activeItem ? optionId(activeItem) : undefined}\n listRef={listRef}\n loading={loading}\n emptyState={emptyState}\n listMaxHeight={listMaxHeight}\n />\n\n {footer && (\n <div className=\"border-t border-border px-density-3 py-density-2 text-xs text-muted-foreground\">\n {footer}\n </div>\n )}\n </div>\n </div>\n );\n\n return createPortal(overlay, document.body);\n}\n"],"names":[],"mappings":"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"}
@@ -12,6 +12,8 @@ function CommandPaletteList({
12
12
  optionId,
13
13
  onActivate,
14
14
  onHover,
15
+ onKeyDown,
16
+ activeItemId,
15
17
  listRef,
16
18
  loading,
17
19
  emptyState,
@@ -25,6 +27,9 @@ function CommandPaletteList({
25
27
  id: listId,
26
28
  role: "listbox",
27
29
  "aria-label": "Commands",
30
+ "aria-activedescendant": activeItemId,
31
+ tabIndex: -1,
32
+ onKeyDown,
28
33
  className: "overflow-y-auto overscroll-contain py-density-1",
29
34
  style: { maxHeight: listMaxHeight },
30
35
  children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-density-3 py-density-3 text-sm text-muted-foreground", children: "Searching…" }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-density-3 py-density-4 text-center text-sm text-muted-foreground", children: emptyState ?? "No results" }) : groups.map((group) => {