@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
@@ -1 +1 @@
1
- {"version":3,"file":"CommandPaletteList.cjs","sources":["../../src/overlay/CommandPaletteList.tsx"],"sourcesContent":["import { Fragment, type RefObject } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport type { CommandGroup, CommandItem } from \"./CommandPalette.model\";\n\nexport type CommandPaletteListProps = {\n groups: CommandGroup[];\n /** Flattened rows, in render order — index space for `activeIndex`. */\n items: CommandItem[];\n activeIndex: number;\n listId: string;\n optionId: (item: CommandItem) => string;\n onActivate: (item: CommandItem) => void;\n onHover: (index: number) => void;\n listRef: RefObject<HTMLDivElement | null>;\n loading?: boolean | undefined;\n emptyState?: React.ReactNode;\n listMaxHeight: string | number;\n};\n\n/**\n * The palette's grouped listbox. Headings are `role=\"presentation\"` so the\n * option index space stays contiguous — the same trick Combobox uses to scroll\n * by `[role=\"option\"]` index.\n */\nexport function CommandPaletteList({\n groups,\n items,\n activeIndex,\n listId,\n optionId,\n onActivate,\n onHover,\n listRef,\n loading,\n emptyState,\n listMaxHeight,\n}: CommandPaletteListProps) {\n // A flat cursor walked alongside the nested render so each row knows its index\n // in the flattened list without a lookup.\n let flatIndex = -1;\n\n return (\n <div\n ref={listRef}\n id={listId}\n role=\"listbox\"\n aria-label=\"Commands\"\n className=\"overflow-y-auto overscroll-contain py-density-1\"\n style={{ maxHeight: listMaxHeight }}\n >\n {loading ? (\n <div className=\"px-density-3 py-density-3 text-sm text-muted-foreground\">Searching…</div>\n ) : items.length === 0 ? (\n <div className=\"px-density-3 py-density-4 text-center text-sm text-muted-foreground\">\n {emptyState ?? \"No results\"}\n </div>\n ) : (\n groups.map((group) => {\n const headingId = `${listId}-group-${group.id}`;\n return (\n <Fragment key={group.id}>\n <div role=\"group\" aria-labelledby={group.heading ? headingId : undefined}>\n {group.heading && (\n <div\n id={headingId}\n role=\"presentation\"\n className=\"px-density-3 pb-1 pt-density-2 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground\"\n >\n {group.heading}\n </div>\n )}\n {group.items.map((item) => {\n flatIndex += 1;\n const index = flatIndex;\n const active = index === activeIndex;\n return (\n <div\n key={item.id}\n id={optionId(item)}\n role=\"option\"\n aria-selected={active}\n aria-disabled={item.disabled || undefined}\n // onMouseMove, not onMouseEnter: keyboard navigation\n // scrolls rows under a stationary cursor, and mouseenter\n // would yank the highlight back to wherever it sits.\n onMouseMove={() => {\n if (!item.disabled) onHover(index);\n }}\n onClick={() => {\n if (!item.disabled) onActivate(item);\n }}\n className={cn(\n \"mx-density-1 flex cursor-pointer items-center gap-density-2 rounded-md px-density-2 py-1.5 text-sm\",\n active && \"bg-accent text-accent-foreground\",\n item.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n {item.icon !== undefined && (\n <span className=\"flex h-4 w-4 shrink-0 items-center justify-center text-muted-foreground\">\n <Icon\n {...(typeof item.icon === \"string\"\n ? { name: item.icon }\n : { icon: item.icon })}\n />\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n {item.label}\n {item.description && (\n <span className=\"ml-density-2 text-xs text-muted-foreground\">\n {item.description}\n </span>\n )}\n </span>\n {item.trailing}\n {item.shortcut && (\n <kbd className=\"shrink-0 rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground\">\n {item.shortcut}\n </kbd>\n )}\n </div>\n );\n })}\n </div>\n </Fragment>\n );\n })\n )}\n </div>\n );\n}\n"],"names":["jsx","Fragment","jsxs","cn","Icon"],"mappings":";;;;;;AAyBO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAG1B,MAAI,YAAY;AAEhB,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,MAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,cAAA;AAAA,MAEnB,UAAA,yCACE,OAAA,EAAI,WAAU,2DAA0D,UAAA,aAAA,CAAU,IACjF,MAAM,WAAW,mCAClB,OAAA,EAAI,WAAU,uEACZ,UAAA,cAAc,aAAA,CACjB,IAEA,OAAO,IAAI,CAAC,UAAU;AACpB,cAAM,YAAY,GAAG,MAAM,UAAU,MAAM,EAAE;AAC7C,eACEA,2BAAAA,IAACC,MAAAA,UAAA,EACC,UAAAC,2BAAAA,KAAC,OAAA,EAAI,MAAK,SAAQ,mBAAiB,MAAM,UAAU,YAAY,QAC5D,UAAA;AAAA,UAAA,MAAM,WACLF,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAI;AAAA,cACJ,MAAK;AAAA,cACL,WAAU;AAAA,cAET,UAAA,MAAM;AAAA,YAAA;AAAA,UAAA;AAAA,UAGV,MAAM,MAAM,IAAI,CAAC,SAAS;AACzB,yBAAa;AACb,kBAAM,QAAQ;AACd,kBAAM,SAAS,UAAU;AACzB,mBACEE,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,IAAI,SAAS,IAAI;AAAA,gBACjB,MAAK;AAAA,gBACL,iBAAe;AAAA,gBACf,iBAAe,KAAK,YAAY;AAAA,gBAIhC,aAAa,MAAM;AACjB,sBAAI,CAAC,KAAK,SAAU,SAAQ,KAAK;AAAA,gBACnC;AAAA,gBACA,SAAS,MAAM;AACb,sBAAI,CAAC,KAAK,SAAU,YAAW,IAAI;AAAA,gBACrC;AAAA,gBACA,WAAWC,MAAAA;AAAAA,kBACT;AAAA,kBACA,UAAU;AAAA,kBACV,KAAK,YAAY;AAAA,gBAAA;AAAA,gBAGlB,UAAA;AAAA,kBAAA,KAAK,SAAS,UACbH,2BAAAA,IAAC,QAAA,EAAK,WAAU,2EACd,UAAAA,2BAAAA;AAAAA,oBAACI,KAAAA;AAAAA,oBAAA;AAAA,sBACE,GAAI,OAAO,KAAK,SAAS,WACtB,EAAE,MAAM,KAAK,KAAA,IACb,EAAE,MAAM,KAAK,KAAA;AAAA,oBAAK;AAAA,kBAAA,GAE1B;AAAA,kBAEFF,2BAAAA,KAAC,QAAA,EAAK,WAAU,2BACb,UAAA;AAAA,oBAAA,KAAK;AAAA,oBACL,KAAK,eACJF,2BAAAA,IAAC,UAAK,WAAU,8CACb,eAAK,YAAA,CACR;AAAA,kBAAA,GAEJ;AAAA,kBACC,KAAK;AAAA,kBACL,KAAK,YACJA,2BAAAA,IAAC,SAAI,WAAU,4GACZ,eAAK,SAAA,CACR;AAAA,gBAAA;AAAA,cAAA;AAAA,cAzCG,KAAK;AAAA,YAAA;AAAA,UA6ChB,CAAC;AAAA,QAAA,GACH,EAAA,GA/Da,MAAM,EAgErB;AAAA,MAEJ,CAAC;AAAA,IAAA;AAAA,EAAA;AAIT;;"}
1
+ {"version":3,"file":"CommandPaletteList.cjs","sources":["../../src/overlay/CommandPaletteList.tsx"],"sourcesContent":["import { Fragment, type KeyboardEventHandler, type RefObject } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport type { CommandGroup, CommandItem } from \"./CommandPalette.model\";\n\nexport type CommandPaletteListProps = {\n groups: CommandGroup[];\n /** Flattened rows, in render order — index space for `activeIndex`. */\n items: CommandItem[];\n activeIndex: number;\n listId: string;\n optionId: (item: CommandItem) => string;\n onActivate: (item: CommandItem) => void;\n onHover: (index: number) => void;\n onKeyDown: KeyboardEventHandler<HTMLDivElement>;\n activeItemId?: string | undefined;\n listRef: RefObject<HTMLDivElement | null>;\n loading?: boolean | undefined;\n emptyState?: React.ReactNode;\n listMaxHeight: string | number;\n};\n\n/**\n * The palette's grouped listbox. Headings are `role=\"presentation\"` so the\n * option index space stays contiguous — the same trick Combobox uses to scroll\n * by `[role=\"option\"]` index.\n */\nexport function CommandPaletteList({\n groups,\n items,\n activeIndex,\n listId,\n optionId,\n onActivate,\n onHover,\n onKeyDown,\n activeItemId,\n listRef,\n loading,\n emptyState,\n listMaxHeight,\n}: CommandPaletteListProps) {\n // A flat cursor walked alongside the nested render so each row knows its index\n // in the flattened list without a lookup.\n let flatIndex = -1;\n\n return (\n <div\n ref={listRef}\n id={listId}\n role=\"listbox\"\n aria-label=\"Commands\"\n aria-activedescendant={activeItemId}\n tabIndex={-1}\n onKeyDown={onKeyDown}\n className=\"overflow-y-auto overscroll-contain py-density-1\"\n style={{ maxHeight: listMaxHeight }}\n >\n {loading ? (\n <div className=\"px-density-3 py-density-3 text-sm text-muted-foreground\">Searching…</div>\n ) : items.length === 0 ? (\n <div className=\"px-density-3 py-density-4 text-center text-sm text-muted-foreground\">\n {emptyState ?? \"No results\"}\n </div>\n ) : (\n groups.map((group) => {\n const headingId = `${listId}-group-${group.id}`;\n return (\n <Fragment key={group.id}>\n <div role=\"group\" aria-labelledby={group.heading ? headingId : undefined}>\n {group.heading && (\n <div\n id={headingId}\n role=\"presentation\"\n className=\"px-density-3 pb-1 pt-density-2 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground\"\n >\n {group.heading}\n </div>\n )}\n {group.items.map((item) => {\n flatIndex += 1;\n const index = flatIndex;\n const active = index === activeIndex;\n return (\n <div\n key={item.id}\n id={optionId(item)}\n role=\"option\"\n aria-selected={active}\n aria-disabled={item.disabled || undefined}\n // onMouseMove, not onMouseEnter: keyboard navigation\n // scrolls rows under a stationary cursor, and mouseenter\n // would yank the highlight back to wherever it sits.\n onMouseMove={() => {\n if (!item.disabled) onHover(index);\n }}\n onClick={() => {\n if (!item.disabled) onActivate(item);\n }}\n className={cn(\n \"mx-density-1 flex cursor-pointer items-center gap-density-2 rounded-md px-density-2 py-1.5 text-sm\",\n active && \"bg-accent text-accent-foreground\",\n item.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n {item.icon !== undefined && (\n <span className=\"flex h-4 w-4 shrink-0 items-center justify-center text-muted-foreground\">\n <Icon\n {...(typeof item.icon === \"string\"\n ? { name: item.icon }\n : { icon: item.icon })}\n />\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n {item.label}\n {item.description && (\n <span className=\"ml-density-2 text-xs text-muted-foreground\">\n {item.description}\n </span>\n )}\n </span>\n {item.trailing}\n {item.shortcut && (\n <kbd className=\"shrink-0 rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground\">\n {item.shortcut}\n </kbd>\n )}\n </div>\n );\n })}\n </div>\n </Fragment>\n );\n })\n )}\n </div>\n );\n}\n"],"names":["jsx","Fragment","jsxs","cn","Icon"],"mappings":";;;;;;AA2BO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAG1B,MAAI,YAAY;AAEhB,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,MAAK;AAAA,MACL,cAAW;AAAA,MACX,yBAAuB;AAAA,MACvB,UAAU;AAAA,MACV;AAAA,MACA,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,cAAA;AAAA,MAEnB,UAAA,yCACE,OAAA,EAAI,WAAU,2DAA0D,UAAA,aAAA,CAAU,IACjF,MAAM,WAAW,mCAClB,OAAA,EAAI,WAAU,uEACZ,UAAA,cAAc,aAAA,CACjB,IAEA,OAAO,IAAI,CAAC,UAAU;AACpB,cAAM,YAAY,GAAG,MAAM,UAAU,MAAM,EAAE;AAC7C,eACEA,2BAAAA,IAACC,MAAAA,UAAA,EACC,UAAAC,2BAAAA,KAAC,OAAA,EAAI,MAAK,SAAQ,mBAAiB,MAAM,UAAU,YAAY,QAC5D,UAAA;AAAA,UAAA,MAAM,WACLF,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAI;AAAA,cACJ,MAAK;AAAA,cACL,WAAU;AAAA,cAET,UAAA,MAAM;AAAA,YAAA;AAAA,UAAA;AAAA,UAGV,MAAM,MAAM,IAAI,CAAC,SAAS;AACzB,yBAAa;AACb,kBAAM,QAAQ;AACd,kBAAM,SAAS,UAAU;AACzB,mBACEE,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,IAAI,SAAS,IAAI;AAAA,gBACjB,MAAK;AAAA,gBACL,iBAAe;AAAA,gBACf,iBAAe,KAAK,YAAY;AAAA,gBAIhC,aAAa,MAAM;AACjB,sBAAI,CAAC,KAAK,SAAU,SAAQ,KAAK;AAAA,gBACnC;AAAA,gBACA,SAAS,MAAM;AACb,sBAAI,CAAC,KAAK,SAAU,YAAW,IAAI;AAAA,gBACrC;AAAA,gBACA,WAAWC,MAAAA;AAAAA,kBACT;AAAA,kBACA,UAAU;AAAA,kBACV,KAAK,YAAY;AAAA,gBAAA;AAAA,gBAGlB,UAAA;AAAA,kBAAA,KAAK,SAAS,UACbH,2BAAAA,IAAC,QAAA,EAAK,WAAU,2EACd,UAAAA,2BAAAA;AAAAA,oBAACI,KAAAA;AAAAA,oBAAA;AAAA,sBACE,GAAI,OAAO,KAAK,SAAS,WACtB,EAAE,MAAM,KAAK,KAAA,IACb,EAAE,MAAM,KAAK,KAAA;AAAA,oBAAK;AAAA,kBAAA,GAE1B;AAAA,kBAEFF,2BAAAA,KAAC,QAAA,EAAK,WAAU,2BACb,UAAA;AAAA,oBAAA,KAAK;AAAA,oBACL,KAAK,eACJF,2BAAAA,IAAC,UAAK,WAAU,8CACb,eAAK,YAAA,CACR;AAAA,kBAAA,GAEJ;AAAA,kBACC,KAAK;AAAA,kBACL,KAAK,YACJA,2BAAAA,IAAC,SAAI,WAAU,4GACZ,eAAK,SAAA,CACR;AAAA,gBAAA;AAAA,cAAA;AAAA,cAzCG,KAAK;AAAA,YAAA;AAAA,UA6ChB,CAAC;AAAA,QAAA,GACH,EAAA,GA/Da,MAAM,EAgErB;AAAA,MAEJ,CAAC;AAAA,IAAA;AAAA,EAAA;AAIT;;"}
@@ -1,4 +1,4 @@
1
- import { RefObject } from 'react';
1
+ import { KeyboardEventHandler, RefObject } from 'react';
2
2
  import { CommandGroup, CommandItem } from './CommandPalette.model.js';
3
3
  export type CommandPaletteListProps = {
4
4
  groups: CommandGroup[];
@@ -9,6 +9,8 @@ export type CommandPaletteListProps = {
9
9
  optionId: (item: CommandItem) => string;
10
10
  onActivate: (item: CommandItem) => void;
11
11
  onHover: (index: number) => void;
12
+ onKeyDown: KeyboardEventHandler<HTMLDivElement>;
13
+ activeItemId?: string | undefined;
12
14
  listRef: RefObject<HTMLDivElement | null>;
13
15
  loading?: boolean | undefined;
14
16
  emptyState?: React.ReactNode;
@@ -19,5 +21,5 @@ export type CommandPaletteListProps = {
19
21
  * option index space stays contiguous — the same trick Combobox uses to scroll
20
22
  * by `[role="option"]` index.
21
23
  */
22
- export declare function CommandPaletteList({ groups, items, activeIndex, listId, optionId, onActivate, onHover, listRef, loading, emptyState, listMaxHeight, }: CommandPaletteListProps): import("react").JSX.Element;
24
+ export declare function CommandPaletteList({ groups, items, activeIndex, listId, optionId, onActivate, onHover, onKeyDown, activeItemId, listRef, loading, emptyState, listMaxHeight, }: CommandPaletteListProps): import("react").JSX.Element;
23
25
  //# sourceMappingURL=CommandPaletteList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CommandPaletteList.d.ts","sourceRoot":"","sources":["../../src/overlay/CommandPaletteList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGjD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAExE,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,uEAAuE;IACvE,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,MAAM,CAAC;IACxC,UAAU,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,OAAO,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,UAAU,EACV,OAAO,EACP,OAAO,EACP,OAAO,EACP,UAAU,EACV,aAAa,GACd,EAAE,uBAAuB,+BA8FzB"}
1
+ {"version":3,"file":"CommandPaletteList.d.ts","sourceRoot":"","sources":["../../src/overlay/CommandPaletteList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,oBAAoB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG5E,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAExE,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,uEAAuE;IACvE,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,MAAM,CAAC;IACxC,UAAU,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;IAChD,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,OAAO,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,UAAU,EACV,OAAO,EACP,SAAS,EACT,YAAY,EACZ,OAAO,EACP,OAAO,EACP,UAAU,EACV,aAAa,GACd,EAAE,uBAAuB,+BAiGzB"}
@@ -10,6 +10,8 @@ function CommandPaletteList({
10
10
  optionId,
11
11
  onActivate,
12
12
  onHover,
13
+ onKeyDown,
14
+ activeItemId,
13
15
  listRef,
14
16
  loading,
15
17
  emptyState,
@@ -23,6 +25,9 @@ function CommandPaletteList({
23
25
  id: listId,
24
26
  role: "listbox",
25
27
  "aria-label": "Commands",
28
+ "aria-activedescendant": activeItemId,
29
+ tabIndex: -1,
30
+ onKeyDown,
26
31
  className: "overflow-y-auto overscroll-contain py-density-1",
27
32
  style: { maxHeight: listMaxHeight },
28
33
  children: loading ? /* @__PURE__ */ jsx("div", { className: "px-density-3 py-density-3 text-sm text-muted-foreground", children: "Searching…" }) : items.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-density-3 py-density-4 text-center text-sm text-muted-foreground", children: emptyState ?? "No results" }) : groups.map((group) => {
@@ -1 +1 @@
1
- {"version":3,"file":"CommandPaletteList.js","sources":["../../src/overlay/CommandPaletteList.tsx"],"sourcesContent":["import { Fragment, type RefObject } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport type { CommandGroup, CommandItem } from \"./CommandPalette.model\";\n\nexport type CommandPaletteListProps = {\n groups: CommandGroup[];\n /** Flattened rows, in render order — index space for `activeIndex`. */\n items: CommandItem[];\n activeIndex: number;\n listId: string;\n optionId: (item: CommandItem) => string;\n onActivate: (item: CommandItem) => void;\n onHover: (index: number) => void;\n listRef: RefObject<HTMLDivElement | null>;\n loading?: boolean | undefined;\n emptyState?: React.ReactNode;\n listMaxHeight: string | number;\n};\n\n/**\n * The palette's grouped listbox. Headings are `role=\"presentation\"` so the\n * option index space stays contiguous — the same trick Combobox uses to scroll\n * by `[role=\"option\"]` index.\n */\nexport function CommandPaletteList({\n groups,\n items,\n activeIndex,\n listId,\n optionId,\n onActivate,\n onHover,\n listRef,\n loading,\n emptyState,\n listMaxHeight,\n}: CommandPaletteListProps) {\n // A flat cursor walked alongside the nested render so each row knows its index\n // in the flattened list without a lookup.\n let flatIndex = -1;\n\n return (\n <div\n ref={listRef}\n id={listId}\n role=\"listbox\"\n aria-label=\"Commands\"\n className=\"overflow-y-auto overscroll-contain py-density-1\"\n style={{ maxHeight: listMaxHeight }}\n >\n {loading ? (\n <div className=\"px-density-3 py-density-3 text-sm text-muted-foreground\">Searching…</div>\n ) : items.length === 0 ? (\n <div className=\"px-density-3 py-density-4 text-center text-sm text-muted-foreground\">\n {emptyState ?? \"No results\"}\n </div>\n ) : (\n groups.map((group) => {\n const headingId = `${listId}-group-${group.id}`;\n return (\n <Fragment key={group.id}>\n <div role=\"group\" aria-labelledby={group.heading ? headingId : undefined}>\n {group.heading && (\n <div\n id={headingId}\n role=\"presentation\"\n className=\"px-density-3 pb-1 pt-density-2 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground\"\n >\n {group.heading}\n </div>\n )}\n {group.items.map((item) => {\n flatIndex += 1;\n const index = flatIndex;\n const active = index === activeIndex;\n return (\n <div\n key={item.id}\n id={optionId(item)}\n role=\"option\"\n aria-selected={active}\n aria-disabled={item.disabled || undefined}\n // onMouseMove, not onMouseEnter: keyboard navigation\n // scrolls rows under a stationary cursor, and mouseenter\n // would yank the highlight back to wherever it sits.\n onMouseMove={() => {\n if (!item.disabled) onHover(index);\n }}\n onClick={() => {\n if (!item.disabled) onActivate(item);\n }}\n className={cn(\n \"mx-density-1 flex cursor-pointer items-center gap-density-2 rounded-md px-density-2 py-1.5 text-sm\",\n active && \"bg-accent text-accent-foreground\",\n item.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n {item.icon !== undefined && (\n <span className=\"flex h-4 w-4 shrink-0 items-center justify-center text-muted-foreground\">\n <Icon\n {...(typeof item.icon === \"string\"\n ? { name: item.icon }\n : { icon: item.icon })}\n />\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n {item.label}\n {item.description && (\n <span className=\"ml-density-2 text-xs text-muted-foreground\">\n {item.description}\n </span>\n )}\n </span>\n {item.trailing}\n {item.shortcut && (\n <kbd className=\"shrink-0 rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground\">\n {item.shortcut}\n </kbd>\n )}\n </div>\n );\n })}\n </div>\n </Fragment>\n );\n })\n )}\n </div>\n );\n}\n"],"names":[],"mappings":";;;;AAyBO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAG1B,MAAI,YAAY;AAEhB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,MAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,cAAA;AAAA,MAEnB,UAAA,8BACE,OAAA,EAAI,WAAU,2DAA0D,UAAA,aAAA,CAAU,IACjF,MAAM,WAAW,wBAClB,OAAA,EAAI,WAAU,uEACZ,UAAA,cAAc,aAAA,CACjB,IAEA,OAAO,IAAI,CAAC,UAAU;AACpB,cAAM,YAAY,GAAG,MAAM,UAAU,MAAM,EAAE;AAC7C,eACE,oBAAC,UAAA,EACC,UAAA,qBAAC,OAAA,EAAI,MAAK,SAAQ,mBAAiB,MAAM,UAAU,YAAY,QAC5D,UAAA;AAAA,UAAA,MAAM,WACL;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAI;AAAA,cACJ,MAAK;AAAA,cACL,WAAU;AAAA,cAET,UAAA,MAAM;AAAA,YAAA;AAAA,UAAA;AAAA,UAGV,MAAM,MAAM,IAAI,CAAC,SAAS;AACzB,yBAAa;AACb,kBAAM,QAAQ;AACd,kBAAM,SAAS,UAAU;AACzB,mBACE;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,IAAI,SAAS,IAAI;AAAA,gBACjB,MAAK;AAAA,gBACL,iBAAe;AAAA,gBACf,iBAAe,KAAK,YAAY;AAAA,gBAIhC,aAAa,MAAM;AACjB,sBAAI,CAAC,KAAK,SAAU,SAAQ,KAAK;AAAA,gBACnC;AAAA,gBACA,SAAS,MAAM;AACb,sBAAI,CAAC,KAAK,SAAU,YAAW,IAAI;AAAA,gBACrC;AAAA,gBACA,WAAW;AAAA,kBACT;AAAA,kBACA,UAAU;AAAA,kBACV,KAAK,YAAY;AAAA,gBAAA;AAAA,gBAGlB,UAAA;AAAA,kBAAA,KAAK,SAAS,UACb,oBAAC,QAAA,EAAK,WAAU,2EACd,UAAA;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACE,GAAI,OAAO,KAAK,SAAS,WACtB,EAAE,MAAM,KAAK,KAAA,IACb,EAAE,MAAM,KAAK,KAAA;AAAA,oBAAK;AAAA,kBAAA,GAE1B;AAAA,kBAEF,qBAAC,QAAA,EAAK,WAAU,2BACb,UAAA;AAAA,oBAAA,KAAK;AAAA,oBACL,KAAK,eACJ,oBAAC,UAAK,WAAU,8CACb,eAAK,YAAA,CACR;AAAA,kBAAA,GAEJ;AAAA,kBACC,KAAK;AAAA,kBACL,KAAK,YACJ,oBAAC,SAAI,WAAU,4GACZ,eAAK,SAAA,CACR;AAAA,gBAAA;AAAA,cAAA;AAAA,cAzCG,KAAK;AAAA,YAAA;AAAA,UA6ChB,CAAC;AAAA,QAAA,GACH,EAAA,GA/Da,MAAM,EAgErB;AAAA,MAEJ,CAAC;AAAA,IAAA;AAAA,EAAA;AAIT;"}
1
+ {"version":3,"file":"CommandPaletteList.js","sources":["../../src/overlay/CommandPaletteList.tsx"],"sourcesContent":["import { Fragment, type KeyboardEventHandler, type RefObject } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport type { CommandGroup, CommandItem } from \"./CommandPalette.model\";\n\nexport type CommandPaletteListProps = {\n groups: CommandGroup[];\n /** Flattened rows, in render order — index space for `activeIndex`. */\n items: CommandItem[];\n activeIndex: number;\n listId: string;\n optionId: (item: CommandItem) => string;\n onActivate: (item: CommandItem) => void;\n onHover: (index: number) => void;\n onKeyDown: KeyboardEventHandler<HTMLDivElement>;\n activeItemId?: string | undefined;\n listRef: RefObject<HTMLDivElement | null>;\n loading?: boolean | undefined;\n emptyState?: React.ReactNode;\n listMaxHeight: string | number;\n};\n\n/**\n * The palette's grouped listbox. Headings are `role=\"presentation\"` so the\n * option index space stays contiguous — the same trick Combobox uses to scroll\n * by `[role=\"option\"]` index.\n */\nexport function CommandPaletteList({\n groups,\n items,\n activeIndex,\n listId,\n optionId,\n onActivate,\n onHover,\n onKeyDown,\n activeItemId,\n listRef,\n loading,\n emptyState,\n listMaxHeight,\n}: CommandPaletteListProps) {\n // A flat cursor walked alongside the nested render so each row knows its index\n // in the flattened list without a lookup.\n let flatIndex = -1;\n\n return (\n <div\n ref={listRef}\n id={listId}\n role=\"listbox\"\n aria-label=\"Commands\"\n aria-activedescendant={activeItemId}\n tabIndex={-1}\n onKeyDown={onKeyDown}\n className=\"overflow-y-auto overscroll-contain py-density-1\"\n style={{ maxHeight: listMaxHeight }}\n >\n {loading ? (\n <div className=\"px-density-3 py-density-3 text-sm text-muted-foreground\">Searching…</div>\n ) : items.length === 0 ? (\n <div className=\"px-density-3 py-density-4 text-center text-sm text-muted-foreground\">\n {emptyState ?? \"No results\"}\n </div>\n ) : (\n groups.map((group) => {\n const headingId = `${listId}-group-${group.id}`;\n return (\n <Fragment key={group.id}>\n <div role=\"group\" aria-labelledby={group.heading ? headingId : undefined}>\n {group.heading && (\n <div\n id={headingId}\n role=\"presentation\"\n className=\"px-density-3 pb-1 pt-density-2 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground\"\n >\n {group.heading}\n </div>\n )}\n {group.items.map((item) => {\n flatIndex += 1;\n const index = flatIndex;\n const active = index === activeIndex;\n return (\n <div\n key={item.id}\n id={optionId(item)}\n role=\"option\"\n aria-selected={active}\n aria-disabled={item.disabled || undefined}\n // onMouseMove, not onMouseEnter: keyboard navigation\n // scrolls rows under a stationary cursor, and mouseenter\n // would yank the highlight back to wherever it sits.\n onMouseMove={() => {\n if (!item.disabled) onHover(index);\n }}\n onClick={() => {\n if (!item.disabled) onActivate(item);\n }}\n className={cn(\n \"mx-density-1 flex cursor-pointer items-center gap-density-2 rounded-md px-density-2 py-1.5 text-sm\",\n active && \"bg-accent text-accent-foreground\",\n item.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n {item.icon !== undefined && (\n <span className=\"flex h-4 w-4 shrink-0 items-center justify-center text-muted-foreground\">\n <Icon\n {...(typeof item.icon === \"string\"\n ? { name: item.icon }\n : { icon: item.icon })}\n />\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate\">\n {item.label}\n {item.description && (\n <span className=\"ml-density-2 text-xs text-muted-foreground\">\n {item.description}\n </span>\n )}\n </span>\n {item.trailing}\n {item.shortcut && (\n <kbd className=\"shrink-0 rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground\">\n {item.shortcut}\n </kbd>\n )}\n </div>\n );\n })}\n </div>\n </Fragment>\n );\n })\n )}\n </div>\n );\n}\n"],"names":[],"mappings":";;;;AA2BO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAG1B,MAAI,YAAY;AAEhB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,MAAK;AAAA,MACL,cAAW;AAAA,MACX,yBAAuB;AAAA,MACvB,UAAU;AAAA,MACV;AAAA,MACA,WAAU;AAAA,MACV,OAAO,EAAE,WAAW,cAAA;AAAA,MAEnB,UAAA,8BACE,OAAA,EAAI,WAAU,2DAA0D,UAAA,aAAA,CAAU,IACjF,MAAM,WAAW,wBAClB,OAAA,EAAI,WAAU,uEACZ,UAAA,cAAc,aAAA,CACjB,IAEA,OAAO,IAAI,CAAC,UAAU;AACpB,cAAM,YAAY,GAAG,MAAM,UAAU,MAAM,EAAE;AAC7C,eACE,oBAAC,UAAA,EACC,UAAA,qBAAC,OAAA,EAAI,MAAK,SAAQ,mBAAiB,MAAM,UAAU,YAAY,QAC5D,UAAA;AAAA,UAAA,MAAM,WACL;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAI;AAAA,cACJ,MAAK;AAAA,cACL,WAAU;AAAA,cAET,UAAA,MAAM;AAAA,YAAA;AAAA,UAAA;AAAA,UAGV,MAAM,MAAM,IAAI,CAAC,SAAS;AACzB,yBAAa;AACb,kBAAM,QAAQ;AACd,kBAAM,SAAS,UAAU;AACzB,mBACE;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,IAAI,SAAS,IAAI;AAAA,gBACjB,MAAK;AAAA,gBACL,iBAAe;AAAA,gBACf,iBAAe,KAAK,YAAY;AAAA,gBAIhC,aAAa,MAAM;AACjB,sBAAI,CAAC,KAAK,SAAU,SAAQ,KAAK;AAAA,gBACnC;AAAA,gBACA,SAAS,MAAM;AACb,sBAAI,CAAC,KAAK,SAAU,YAAW,IAAI;AAAA,gBACrC;AAAA,gBACA,WAAW;AAAA,kBACT;AAAA,kBACA,UAAU;AAAA,kBACV,KAAK,YAAY;AAAA,gBAAA;AAAA,gBAGlB,UAAA;AAAA,kBAAA,KAAK,SAAS,UACb,oBAAC,QAAA,EAAK,WAAU,2EACd,UAAA;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACE,GAAI,OAAO,KAAK,SAAS,WACtB,EAAE,MAAM,KAAK,KAAA,IACb,EAAE,MAAM,KAAK,KAAA;AAAA,oBAAK;AAAA,kBAAA,GAE1B;AAAA,kBAEF,qBAAC,QAAA,EAAK,WAAU,2BACb,UAAA;AAAA,oBAAA,KAAK;AAAA,oBACL,KAAK,eACJ,oBAAC,UAAK,WAAU,8CACb,eAAK,YAAA,CACR;AAAA,kBAAA,GAEJ;AAAA,kBACC,KAAK;AAAA,kBACL,KAAK,YACJ,oBAAC,SAAI,WAAU,4GACZ,eAAK,SAAA,CACR;AAAA,gBAAA;AAAA,cAAA;AAAA,cAzCG,KAAK;AAAA,YAAA;AAAA,UA6ChB,CAAC;AAAA,QAAA,GACH,EAAA,GA/Da,MAAM,EAgErB;AAAA,MAEJ,CAAC;AAAA,IAAA;AAAA,EAAA;AAIT;"}
@@ -96,6 +96,7 @@ function DropdownMenuRoot({
96
96
  button.Button,
97
97
  {
98
98
  ref: refs.setReference,
99
+ type: "button",
99
100
  variant,
100
101
  size,
101
102
  title,
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.cjs","sources":["../../src/overlay/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingList,\n FloatingNode,\n FloatingPortal,\n FloatingTree,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingTree,\n useInteractions,\n useListNavigation,\n useRole,\n} from \"@floating-ui/react\";\nimport { cn } from \"../lib/utils\";\nimport { Button, type ButtonProps } from \"../components/button\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\nimport { MENU_POPOVER_CLASS, MenuContext } from \"./dropdownMenuContext\";\nimport { MenuItemList } from \"./DropdownMenuSubmenu\";\nimport { useEscapeLayer, useFloatingZIndex } from \"./modalStack\";\n\nexport type DropdownMenuItem = {\n /** Visible label. */\n label: ReactNode;\n /** Called when the item is chosen. Ignored when the item has `children`. */\n onSelect: () => void;\n /** Iconify name or imported icon component rendered before the label. */\n icon?: string | StaticIconComponent;\n /** CSS colour applied to this item's icon (the glyph fills `currentColor`). */\n iconColor?: string;\n /**\n * Section header. A non-interactive header renders above the first item of\n * each contiguous group — provide items pre-sorted by `group`. Items without\n * a `group` render no header.\n */\n group?: string;\n /** Browser tooltip for the item. */\n title?: string;\n /** Disable selection. */\n disabled?: boolean;\n /**\n * Nested submenu items. When present the item becomes a submenu trigger: it\n * opens a flyout of `children` (recursively) on hover / click / ArrowRight\n * instead of firing `onSelect`.\n */\n children?: DropdownMenuItem[];\n};\n\nexport type DropdownMenuProps = {\n /** Trigger label. Ignored when `trigger` is provided. */\n label?: ReactNode;\n /** Icon shown before the trigger label. Ignored when `trigger` is provided. */\n icon?: string | StaticIconComponent;\n /** Hide the trailing chevron on the default trigger. */\n hideChevron?: boolean;\n /** Variant forwarded to the default Button trigger. */\n variant?: ButtonProps[\"variant\"];\n /** Size forwarded to the default Button trigger. */\n size?: ButtonProps[\"size\"];\n /** Fully custom trigger. Receives no props; the menu wraps it with open state. */\n trigger?: ReactNode;\n /** Declarative menu items. Provide this or `children`, not both. */\n items?: DropdownMenuItem[];\n /** Custom menu content. Use `closeMenu` to dismiss after a selection. */\n children?: (closeMenu: () => void) => ReactNode;\n /** Rendered at the top of the menu, above the items/children. */\n header?: ReactNode;\n /** Rendered at the bottom of the menu, below the items/children (e.g. a \"Show more…\" link). */\n footer?: ReactNode;\n /** Horizontal alignment of the menu relative to the trigger. */\n align?: \"left\" | \"right\";\n /** Notified whenever the menu opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Browser tooltip / accessible label for the default trigger. */\n title?: string;\n /** Accessible label (`aria-label`) for the floating menu element itself. */\n menuLabel?: string;\n /** Classes applied to the wrapper. */\n className?: string;\n /** Classes applied to the floating menu. */\n menuClassName?: string;\n};\n\n/**\n * A trigger + floating menu. Flat `items` render as a single list; an item with\n * `children` opens a flyout submenu. The FloatingTree lets every level cooperate\n * on focus and dismissal, so selecting any leaf closes the whole menu.\n */\nexport function DropdownMenu(props: DropdownMenuProps) {\n return (\n <FloatingTree>\n <DropdownMenuRoot {...props} />\n </FloatingTree>\n );\n}\n\nfunction DropdownMenuRoot({\n label,\n icon,\n hideChevron = false,\n variant = \"outline\",\n size = \"sm\",\n trigger,\n items,\n children,\n header,\n footer,\n align = \"right\",\n onOpenChange,\n title,\n menuLabel,\n className,\n menuClassName,\n}: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const floatingZ = useFloatingZIndex();\n const tree = useFloatingTree();\n const nodeId = useFloatingNodeId();\n const elementsRef = useRef<Array<HTMLElement | null>>([]);\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n useEffect(() => {\n onOpenChangeRef.current?.(open);\n }, [open]);\n\n const { refs, floatingStyles, context } = useFloating<HTMLDivElement>({\n // nodeId is always defined inside the FloatingTree; guard for the type only.\n ...(nodeId ? { nodeId } : {}),\n open,\n onOpenChange: setOpen,\n // bottom-end / bottom-start reproduce the previous right/left alignment.\n placement: align === \"right\" ? \"bottom-end\" : \"bottom-start\",\n whileElementsMounted: autoUpdate,\n // offset(4) ≈ the previous mt-1; flip opens upward at the bottom edge and\n // shift slides the menu back on-screen at the horizontal edges.\n middleware: [offset(4), flip({ padding: 8 }), shift({ padding: 8 })],\n });\n\n const click = useClick(context);\n // useDismiss is React-tree aware: a press inside anything rendered through the\n // menu's `children` render-prop — including a Modal that portals to\n // document.body — propagates via React's synthetic events to the floating\n // element and counts as \"inside\", so it won't dismiss the menu (which would\n // unmount that child Modal). A Modal owned by a sibling/parent instead of this\n // menu correctly does dismiss the menu, which is harmless since closing the\n // menu does not unmount a Modal it doesn't own.\n const dismiss = useDismiss(context, { escapeKey: false });\n const role = useRole(context, { role: \"menu\" });\n const listNav = useListNavigation(context, {\n listRef: elementsRef,\n activeIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(\n [click, dismiss, role, listNav],\n );\n\n const closeMenu = () => {\n setOpen(false);\n if (refs.domReference.current instanceof HTMLElement)\n refs.domReference.current.focus();\n };\n useEscapeLayer(open, closeMenu);\n\n // Selecting any leaf (at any depth) emits a tree-wide \"click\"; the root closes\n // and restores focus to the trigger.\n const closeMenuRef = useRef(closeMenu);\n closeMenuRef.current = closeMenu;\n useEffect(() => {\n if (!tree) return;\n const onTreeClick = () => closeMenuRef.current();\n tree.events.on(\"click\", onTreeClick);\n return () => tree.events.off(\"click\", onTreeClick);\n }, [tree]);\n\n return (\n <FloatingNode id={nodeId}>\n <div className={cn(\"relative inline-flex\", className)}>\n {trigger ? (\n <span\n ref={refs.setReference}\n className=\"inline-flex\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {trigger}\n </span>\n ) : (\n <Button\n ref={refs.setReference as React.Ref<HTMLButtonElement>}\n variant={variant}\n size={size}\n title={title}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {icon && (\n <Icon\n {...(typeof icon === \"string\" ? { name: icon } : { icon })}\n />\n )}\n {label}\n {!hideChevron && <Icon icon={UiChevronDown} />}\n </Button>\n )}\n {open && (\n <FloatingPortal>\n <FloatingFocusManager\n context={context}\n modal={false}\n closeOnFocusOut={false}\n >\n <div\n ref={refs.setFloating}\n {...getFloatingProps()}\n role=\"menu\"\n aria-label={menuLabel}\n style={{ ...floatingStyles, zIndex: floatingZ }}\n className={cn(MENU_POPOVER_CLASS, menuClassName)}\n >\n {header != null && (\n <div className=\"border-b border-border px-3 py-1.5\">\n {header}\n </div>\n )}\n {children ? (\n children(closeMenu)\n ) : (\n <MenuContext.Provider\n value={{\n getItemProps,\n activeIndex,\n setActiveIndex,\n setHasFocusInside: () => {},\n isOpen: open,\n }}\n >\n <FloatingList elementsRef={elementsRef}>\n <MenuItemList items={items ?? []} />\n </FloatingList>\n </MenuContext.Provider>\n )}\n {footer != null && (\n <div className=\"border-t border-border px-3 py-1.5\">\n {footer}\n </div>\n )}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n </FloatingNode>\n );\n}\n"],"names":["FloatingTree","jsx","useState","useFloatingZIndex","useFloatingTree","useFloatingNodeId","useRef","useEffect","useFloating","autoUpdate","offset","flip","shift","useClick","useDismiss","useRole","useListNavigation","useInteractions","useEscapeLayer","FloatingNode","jsxs","cn","Button","Icon","UiChevronDown","FloatingPortal","FloatingFocusManager","MENU_POPOVER_CLASS","MenuContext","FloatingList","MenuItemList"],"mappings":"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"}
1
+ {"version":3,"file":"DropdownMenu.cjs","sources":["../../src/overlay/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingList,\n FloatingNode,\n FloatingPortal,\n FloatingTree,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingTree,\n useInteractions,\n useListNavigation,\n useRole,\n} from \"@floating-ui/react\";\nimport { cn } from \"../lib/utils\";\nimport { Button, type ButtonProps } from \"../components/button\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\nimport { MENU_POPOVER_CLASS, MenuContext } from \"./dropdownMenuContext\";\nimport { MenuItemList } from \"./DropdownMenuSubmenu\";\nimport { useEscapeLayer, useFloatingZIndex } from \"./modalStack\";\n\nexport type DropdownMenuItem = {\n /** Visible label. */\n label: ReactNode;\n /** Called when the item is chosen. Ignored when the item has `children`. */\n onSelect: () => void;\n /** Iconify name or imported icon component rendered before the label. */\n icon?: string | StaticIconComponent;\n /** CSS colour applied to this item's icon (the glyph fills `currentColor`). */\n iconColor?: string;\n /**\n * Section header. A non-interactive header renders above the first item of\n * each contiguous group — provide items pre-sorted by `group`. Items without\n * a `group` render no header.\n */\n group?: string;\n /** Browser tooltip for the item. */\n title?: string;\n /** Disable selection. */\n disabled?: boolean;\n /**\n * Nested submenu items. When present the item becomes a submenu trigger: it\n * opens a flyout of `children` (recursively) on hover / click / ArrowRight\n * instead of firing `onSelect`.\n */\n children?: DropdownMenuItem[];\n};\n\nexport type DropdownMenuProps = {\n /** Trigger label. Ignored when `trigger` is provided. */\n label?: ReactNode;\n /** Icon shown before the trigger label. Ignored when `trigger` is provided. */\n icon?: string | StaticIconComponent;\n /** Hide the trailing chevron on the default trigger. */\n hideChevron?: boolean;\n /** Variant forwarded to the default Button trigger. */\n variant?: ButtonProps[\"variant\"];\n /** Size forwarded to the default Button trigger. */\n size?: ButtonProps[\"size\"];\n /** Fully custom trigger. Receives no props; the menu wraps it with open state. */\n trigger?: ReactNode;\n /** Declarative menu items. Provide this or `children`, not both. */\n items?: DropdownMenuItem[];\n /** Custom menu content. Use `closeMenu` to dismiss after a selection. */\n children?: (closeMenu: () => void) => ReactNode;\n /** Rendered at the top of the menu, above the items/children. */\n header?: ReactNode;\n /** Rendered at the bottom of the menu, below the items/children (e.g. a \"Show more…\" link). */\n footer?: ReactNode;\n /** Horizontal alignment of the menu relative to the trigger. */\n align?: \"left\" | \"right\";\n /** Notified whenever the menu opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Browser tooltip / accessible label for the default trigger. */\n title?: string;\n /** Accessible label (`aria-label`) for the floating menu element itself. */\n menuLabel?: string;\n /** Classes applied to the wrapper. */\n className?: string;\n /** Classes applied to the floating menu. */\n menuClassName?: string;\n};\n\n/**\n * A trigger + floating menu. Flat `items` render as a single list; an item with\n * `children` opens a flyout submenu. The FloatingTree lets every level cooperate\n * on focus and dismissal, so selecting any leaf closes the whole menu.\n */\nexport function DropdownMenu(props: DropdownMenuProps) {\n return (\n <FloatingTree>\n <DropdownMenuRoot {...props} />\n </FloatingTree>\n );\n}\n\nfunction DropdownMenuRoot({\n label,\n icon,\n hideChevron = false,\n variant = \"outline\",\n size = \"sm\",\n trigger,\n items,\n children,\n header,\n footer,\n align = \"right\",\n onOpenChange,\n title,\n menuLabel,\n className,\n menuClassName,\n}: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const floatingZ = useFloatingZIndex();\n const tree = useFloatingTree();\n const nodeId = useFloatingNodeId();\n const elementsRef = useRef<Array<HTMLElement | null>>([]);\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n useEffect(() => {\n onOpenChangeRef.current?.(open);\n }, [open]);\n\n const { refs, floatingStyles, context } = useFloating<HTMLDivElement>({\n // nodeId is always defined inside the FloatingTree; guard for the type only.\n ...(nodeId ? { nodeId } : {}),\n open,\n onOpenChange: setOpen,\n // bottom-end / bottom-start reproduce the previous right/left alignment.\n placement: align === \"right\" ? \"bottom-end\" : \"bottom-start\",\n whileElementsMounted: autoUpdate,\n // offset(4) ≈ the previous mt-1; flip opens upward at the bottom edge and\n // shift slides the menu back on-screen at the horizontal edges.\n middleware: [offset(4), flip({ padding: 8 }), shift({ padding: 8 })],\n });\n\n const click = useClick(context);\n // useDismiss is React-tree aware: a press inside anything rendered through the\n // menu's `children` render-prop — including a Modal that portals to\n // document.body — propagates via React's synthetic events to the floating\n // element and counts as \"inside\", so it won't dismiss the menu (which would\n // unmount that child Modal). A Modal owned by a sibling/parent instead of this\n // menu correctly does dismiss the menu, which is harmless since closing the\n // menu does not unmount a Modal it doesn't own.\n const dismiss = useDismiss(context, { escapeKey: false });\n const role = useRole(context, { role: \"menu\" });\n const listNav = useListNavigation(context, {\n listRef: elementsRef,\n activeIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(\n [click, dismiss, role, listNav],\n );\n\n const closeMenu = () => {\n setOpen(false);\n if (refs.domReference.current instanceof HTMLElement)\n refs.domReference.current.focus();\n };\n useEscapeLayer(open, closeMenu);\n\n // Selecting any leaf (at any depth) emits a tree-wide \"click\"; the root closes\n // and restores focus to the trigger.\n const closeMenuRef = useRef(closeMenu);\n closeMenuRef.current = closeMenu;\n useEffect(() => {\n if (!tree) return;\n const onTreeClick = () => closeMenuRef.current();\n tree.events.on(\"click\", onTreeClick);\n return () => tree.events.off(\"click\", onTreeClick);\n }, [tree]);\n\n return (\n <FloatingNode id={nodeId}>\n <div className={cn(\"relative inline-flex\", className)}>\n {trigger ? (\n <span\n ref={refs.setReference}\n className=\"inline-flex\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {trigger}\n </span>\n ) : (\n <Button\n ref={refs.setReference as React.Ref<HTMLButtonElement>}\n // Opening a menu never submits the form the trigger sits in.\n type=\"button\"\n variant={variant}\n size={size}\n title={title}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {icon && (\n <Icon\n {...(typeof icon === \"string\" ? { name: icon } : { icon })}\n />\n )}\n {label}\n {!hideChevron && <Icon icon={UiChevronDown} />}\n </Button>\n )}\n {open && (\n <FloatingPortal>\n <FloatingFocusManager\n context={context}\n modal={false}\n closeOnFocusOut={false}\n >\n <div\n ref={refs.setFloating}\n {...getFloatingProps()}\n role=\"menu\"\n aria-label={menuLabel}\n style={{ ...floatingStyles, zIndex: floatingZ }}\n className={cn(MENU_POPOVER_CLASS, menuClassName)}\n >\n {header != null && (\n <div className=\"border-b border-border px-3 py-1.5\">\n {header}\n </div>\n )}\n {children ? (\n children(closeMenu)\n ) : (\n <MenuContext.Provider\n value={{\n getItemProps,\n activeIndex,\n setActiveIndex,\n setHasFocusInside: () => {},\n isOpen: open,\n }}\n >\n <FloatingList elementsRef={elementsRef}>\n <MenuItemList items={items ?? []} />\n </FloatingList>\n </MenuContext.Provider>\n )}\n {footer != null && (\n <div className=\"border-t border-border px-3 py-1.5\">\n {footer}\n </div>\n )}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n </FloatingNode>\n );\n}\n"],"names":["FloatingTree","jsx","useState","useFloatingZIndex","useFloatingTree","useFloatingNodeId","useRef","useEffect","useFloating","autoUpdate","offset","flip","shift","useClick","useDismiss","useRole","useListNavigation","useInteractions","useEscapeLayer","FloatingNode","jsxs","cn","Button","Icon","UiChevronDown","FloatingPortal","FloatingFocusManager","MENU_POPOVER_CLASS","MenuContext","FloatingList","MenuItemList"],"mappings":"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"}
@@ -94,6 +94,7 @@ function DropdownMenuRoot({
94
94
  Button,
95
95
  {
96
96
  ref: refs.setReference,
97
+ type: "button",
97
98
  variant,
98
99
  size,
99
100
  title,
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.js","sources":["../../src/overlay/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingList,\n FloatingNode,\n FloatingPortal,\n FloatingTree,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingTree,\n useInteractions,\n useListNavigation,\n useRole,\n} from \"@floating-ui/react\";\nimport { cn } from \"../lib/utils\";\nimport { Button, type ButtonProps } from \"../components/button\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\nimport { MENU_POPOVER_CLASS, MenuContext } from \"./dropdownMenuContext\";\nimport { MenuItemList } from \"./DropdownMenuSubmenu\";\nimport { useEscapeLayer, useFloatingZIndex } from \"./modalStack\";\n\nexport type DropdownMenuItem = {\n /** Visible label. */\n label: ReactNode;\n /** Called when the item is chosen. Ignored when the item has `children`. */\n onSelect: () => void;\n /** Iconify name or imported icon component rendered before the label. */\n icon?: string | StaticIconComponent;\n /** CSS colour applied to this item's icon (the glyph fills `currentColor`). */\n iconColor?: string;\n /**\n * Section header. A non-interactive header renders above the first item of\n * each contiguous group — provide items pre-sorted by `group`. Items without\n * a `group` render no header.\n */\n group?: string;\n /** Browser tooltip for the item. */\n title?: string;\n /** Disable selection. */\n disabled?: boolean;\n /**\n * Nested submenu items. When present the item becomes a submenu trigger: it\n * opens a flyout of `children` (recursively) on hover / click / ArrowRight\n * instead of firing `onSelect`.\n */\n children?: DropdownMenuItem[];\n};\n\nexport type DropdownMenuProps = {\n /** Trigger label. Ignored when `trigger` is provided. */\n label?: ReactNode;\n /** Icon shown before the trigger label. Ignored when `trigger` is provided. */\n icon?: string | StaticIconComponent;\n /** Hide the trailing chevron on the default trigger. */\n hideChevron?: boolean;\n /** Variant forwarded to the default Button trigger. */\n variant?: ButtonProps[\"variant\"];\n /** Size forwarded to the default Button trigger. */\n size?: ButtonProps[\"size\"];\n /** Fully custom trigger. Receives no props; the menu wraps it with open state. */\n trigger?: ReactNode;\n /** Declarative menu items. Provide this or `children`, not both. */\n items?: DropdownMenuItem[];\n /** Custom menu content. Use `closeMenu` to dismiss after a selection. */\n children?: (closeMenu: () => void) => ReactNode;\n /** Rendered at the top of the menu, above the items/children. */\n header?: ReactNode;\n /** Rendered at the bottom of the menu, below the items/children (e.g. a \"Show more…\" link). */\n footer?: ReactNode;\n /** Horizontal alignment of the menu relative to the trigger. */\n align?: \"left\" | \"right\";\n /** Notified whenever the menu opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Browser tooltip / accessible label for the default trigger. */\n title?: string;\n /** Accessible label (`aria-label`) for the floating menu element itself. */\n menuLabel?: string;\n /** Classes applied to the wrapper. */\n className?: string;\n /** Classes applied to the floating menu. */\n menuClassName?: string;\n};\n\n/**\n * A trigger + floating menu. Flat `items` render as a single list; an item with\n * `children` opens a flyout submenu. The FloatingTree lets every level cooperate\n * on focus and dismissal, so selecting any leaf closes the whole menu.\n */\nexport function DropdownMenu(props: DropdownMenuProps) {\n return (\n <FloatingTree>\n <DropdownMenuRoot {...props} />\n </FloatingTree>\n );\n}\n\nfunction DropdownMenuRoot({\n label,\n icon,\n hideChevron = false,\n variant = \"outline\",\n size = \"sm\",\n trigger,\n items,\n children,\n header,\n footer,\n align = \"right\",\n onOpenChange,\n title,\n menuLabel,\n className,\n menuClassName,\n}: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const floatingZ = useFloatingZIndex();\n const tree = useFloatingTree();\n const nodeId = useFloatingNodeId();\n const elementsRef = useRef<Array<HTMLElement | null>>([]);\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n useEffect(() => {\n onOpenChangeRef.current?.(open);\n }, [open]);\n\n const { refs, floatingStyles, context } = useFloating<HTMLDivElement>({\n // nodeId is always defined inside the FloatingTree; guard for the type only.\n ...(nodeId ? { nodeId } : {}),\n open,\n onOpenChange: setOpen,\n // bottom-end / bottom-start reproduce the previous right/left alignment.\n placement: align === \"right\" ? \"bottom-end\" : \"bottom-start\",\n whileElementsMounted: autoUpdate,\n // offset(4) ≈ the previous mt-1; flip opens upward at the bottom edge and\n // shift slides the menu back on-screen at the horizontal edges.\n middleware: [offset(4), flip({ padding: 8 }), shift({ padding: 8 })],\n });\n\n const click = useClick(context);\n // useDismiss is React-tree aware: a press inside anything rendered through the\n // menu's `children` render-prop — including a Modal that portals to\n // document.body — propagates via React's synthetic events to the floating\n // element and counts as \"inside\", so it won't dismiss the menu (which would\n // unmount that child Modal). A Modal owned by a sibling/parent instead of this\n // menu correctly does dismiss the menu, which is harmless since closing the\n // menu does not unmount a Modal it doesn't own.\n const dismiss = useDismiss(context, { escapeKey: false });\n const role = useRole(context, { role: \"menu\" });\n const listNav = useListNavigation(context, {\n listRef: elementsRef,\n activeIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(\n [click, dismiss, role, listNav],\n );\n\n const closeMenu = () => {\n setOpen(false);\n if (refs.domReference.current instanceof HTMLElement)\n refs.domReference.current.focus();\n };\n useEscapeLayer(open, closeMenu);\n\n // Selecting any leaf (at any depth) emits a tree-wide \"click\"; the root closes\n // and restores focus to the trigger.\n const closeMenuRef = useRef(closeMenu);\n closeMenuRef.current = closeMenu;\n useEffect(() => {\n if (!tree) return;\n const onTreeClick = () => closeMenuRef.current();\n tree.events.on(\"click\", onTreeClick);\n return () => tree.events.off(\"click\", onTreeClick);\n }, [tree]);\n\n return (\n <FloatingNode id={nodeId}>\n <div className={cn(\"relative inline-flex\", className)}>\n {trigger ? (\n <span\n ref={refs.setReference}\n className=\"inline-flex\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {trigger}\n </span>\n ) : (\n <Button\n ref={refs.setReference as React.Ref<HTMLButtonElement>}\n variant={variant}\n size={size}\n title={title}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {icon && (\n <Icon\n {...(typeof icon === \"string\" ? { name: icon } : { icon })}\n />\n )}\n {label}\n {!hideChevron && <Icon icon={UiChevronDown} />}\n </Button>\n )}\n {open && (\n <FloatingPortal>\n <FloatingFocusManager\n context={context}\n modal={false}\n closeOnFocusOut={false}\n >\n <div\n ref={refs.setFloating}\n {...getFloatingProps()}\n role=\"menu\"\n aria-label={menuLabel}\n style={{ ...floatingStyles, zIndex: floatingZ }}\n className={cn(MENU_POPOVER_CLASS, menuClassName)}\n >\n {header != null && (\n <div className=\"border-b border-border px-3 py-1.5\">\n {header}\n </div>\n )}\n {children ? (\n children(closeMenu)\n ) : (\n <MenuContext.Provider\n value={{\n getItemProps,\n activeIndex,\n setActiveIndex,\n setHasFocusInside: () => {},\n isOpen: open,\n }}\n >\n <FloatingList elementsRef={elementsRef}>\n <MenuItemList items={items ?? []} />\n </FloatingList>\n </MenuContext.Provider>\n )}\n {footer != null && (\n <div className=\"border-t border-border px-3 py-1.5\">\n {footer}\n </div>\n )}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n </FloatingNode>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DropdownMenu.js","sources":["../../src/overlay/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingList,\n FloatingNode,\n FloatingPortal,\n FloatingTree,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingTree,\n useInteractions,\n useListNavigation,\n useRole,\n} from \"@floating-ui/react\";\nimport { cn } from \"../lib/utils\";\nimport { Button, type ButtonProps } from \"../components/button\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\nimport { MENU_POPOVER_CLASS, MenuContext } from \"./dropdownMenuContext\";\nimport { MenuItemList } from \"./DropdownMenuSubmenu\";\nimport { useEscapeLayer, useFloatingZIndex } from \"./modalStack\";\n\nexport type DropdownMenuItem = {\n /** Visible label. */\n label: ReactNode;\n /** Called when the item is chosen. Ignored when the item has `children`. */\n onSelect: () => void;\n /** Iconify name or imported icon component rendered before the label. */\n icon?: string | StaticIconComponent;\n /** CSS colour applied to this item's icon (the glyph fills `currentColor`). */\n iconColor?: string;\n /**\n * Section header. A non-interactive header renders above the first item of\n * each contiguous group — provide items pre-sorted by `group`. Items without\n * a `group` render no header.\n */\n group?: string;\n /** Browser tooltip for the item. */\n title?: string;\n /** Disable selection. */\n disabled?: boolean;\n /**\n * Nested submenu items. When present the item becomes a submenu trigger: it\n * opens a flyout of `children` (recursively) on hover / click / ArrowRight\n * instead of firing `onSelect`.\n */\n children?: DropdownMenuItem[];\n};\n\nexport type DropdownMenuProps = {\n /** Trigger label. Ignored when `trigger` is provided. */\n label?: ReactNode;\n /** Icon shown before the trigger label. Ignored when `trigger` is provided. */\n icon?: string | StaticIconComponent;\n /** Hide the trailing chevron on the default trigger. */\n hideChevron?: boolean;\n /** Variant forwarded to the default Button trigger. */\n variant?: ButtonProps[\"variant\"];\n /** Size forwarded to the default Button trigger. */\n size?: ButtonProps[\"size\"];\n /** Fully custom trigger. Receives no props; the menu wraps it with open state. */\n trigger?: ReactNode;\n /** Declarative menu items. Provide this or `children`, not both. */\n items?: DropdownMenuItem[];\n /** Custom menu content. Use `closeMenu` to dismiss after a selection. */\n children?: (closeMenu: () => void) => ReactNode;\n /** Rendered at the top of the menu, above the items/children. */\n header?: ReactNode;\n /** Rendered at the bottom of the menu, below the items/children (e.g. a \"Show more…\" link). */\n footer?: ReactNode;\n /** Horizontal alignment of the menu relative to the trigger. */\n align?: \"left\" | \"right\";\n /** Notified whenever the menu opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Browser tooltip / accessible label for the default trigger. */\n title?: string;\n /** Accessible label (`aria-label`) for the floating menu element itself. */\n menuLabel?: string;\n /** Classes applied to the wrapper. */\n className?: string;\n /** Classes applied to the floating menu. */\n menuClassName?: string;\n};\n\n/**\n * A trigger + floating menu. Flat `items` render as a single list; an item with\n * `children` opens a flyout submenu. The FloatingTree lets every level cooperate\n * on focus and dismissal, so selecting any leaf closes the whole menu.\n */\nexport function DropdownMenu(props: DropdownMenuProps) {\n return (\n <FloatingTree>\n <DropdownMenuRoot {...props} />\n </FloatingTree>\n );\n}\n\nfunction DropdownMenuRoot({\n label,\n icon,\n hideChevron = false,\n variant = \"outline\",\n size = \"sm\",\n trigger,\n items,\n children,\n header,\n footer,\n align = \"right\",\n onOpenChange,\n title,\n menuLabel,\n className,\n menuClassName,\n}: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const floatingZ = useFloatingZIndex();\n const tree = useFloatingTree();\n const nodeId = useFloatingNodeId();\n const elementsRef = useRef<Array<HTMLElement | null>>([]);\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n useEffect(() => {\n onOpenChangeRef.current?.(open);\n }, [open]);\n\n const { refs, floatingStyles, context } = useFloating<HTMLDivElement>({\n // nodeId is always defined inside the FloatingTree; guard for the type only.\n ...(nodeId ? { nodeId } : {}),\n open,\n onOpenChange: setOpen,\n // bottom-end / bottom-start reproduce the previous right/left alignment.\n placement: align === \"right\" ? \"bottom-end\" : \"bottom-start\",\n whileElementsMounted: autoUpdate,\n // offset(4) ≈ the previous mt-1; flip opens upward at the bottom edge and\n // shift slides the menu back on-screen at the horizontal edges.\n middleware: [offset(4), flip({ padding: 8 }), shift({ padding: 8 })],\n });\n\n const click = useClick(context);\n // useDismiss is React-tree aware: a press inside anything rendered through the\n // menu's `children` render-prop — including a Modal that portals to\n // document.body — propagates via React's synthetic events to the floating\n // element and counts as \"inside\", so it won't dismiss the menu (which would\n // unmount that child Modal). A Modal owned by a sibling/parent instead of this\n // menu correctly does dismiss the menu, which is harmless since closing the\n // menu does not unmount a Modal it doesn't own.\n const dismiss = useDismiss(context, { escapeKey: false });\n const role = useRole(context, { role: \"menu\" });\n const listNav = useListNavigation(context, {\n listRef: elementsRef,\n activeIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(\n [click, dismiss, role, listNav],\n );\n\n const closeMenu = () => {\n setOpen(false);\n if (refs.domReference.current instanceof HTMLElement)\n refs.domReference.current.focus();\n };\n useEscapeLayer(open, closeMenu);\n\n // Selecting any leaf (at any depth) emits a tree-wide \"click\"; the root closes\n // and restores focus to the trigger.\n const closeMenuRef = useRef(closeMenu);\n closeMenuRef.current = closeMenu;\n useEffect(() => {\n if (!tree) return;\n const onTreeClick = () => closeMenuRef.current();\n tree.events.on(\"click\", onTreeClick);\n return () => tree.events.off(\"click\", onTreeClick);\n }, [tree]);\n\n return (\n <FloatingNode id={nodeId}>\n <div className={cn(\"relative inline-flex\", className)}>\n {trigger ? (\n <span\n ref={refs.setReference}\n className=\"inline-flex\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {trigger}\n </span>\n ) : (\n <Button\n ref={refs.setReference as React.Ref<HTMLButtonElement>}\n // Opening a menu never submits the form the trigger sits in.\n type=\"button\"\n variant={variant}\n size={size}\n title={title}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {icon && (\n <Icon\n {...(typeof icon === \"string\" ? { name: icon } : { icon })}\n />\n )}\n {label}\n {!hideChevron && <Icon icon={UiChevronDown} />}\n </Button>\n )}\n {open && (\n <FloatingPortal>\n <FloatingFocusManager\n context={context}\n modal={false}\n closeOnFocusOut={false}\n >\n <div\n ref={refs.setFloating}\n {...getFloatingProps()}\n role=\"menu\"\n aria-label={menuLabel}\n style={{ ...floatingStyles, zIndex: floatingZ }}\n className={cn(MENU_POPOVER_CLASS, menuClassName)}\n >\n {header != null && (\n <div className=\"border-b border-border px-3 py-1.5\">\n {header}\n </div>\n )}\n {children ? (\n children(closeMenu)\n ) : (\n <MenuContext.Provider\n value={{\n getItemProps,\n activeIndex,\n setActiveIndex,\n setHasFocusInside: () => {},\n isOpen: open,\n }}\n >\n <FloatingList elementsRef={elementsRef}>\n <MenuItemList items={items ?? []} />\n </FloatingList>\n </MenuContext.Provider>\n )}\n {footer != null && (\n <div className=\"border-t border-border px-3 py-1.5\">\n {footer}\n </div>\n )}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n </FloatingNode>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -23,6 +23,7 @@ const operationCatalogFilterState = require("./operationCatalogFilterState.cjs")
23
23
  const operationCatalogFollow = require("./operationCatalogFollow.cjs");
24
24
  const OperationCatalogFollowStatus = require("./OperationCatalogFollowStatus.cjs");
25
25
  const useOperationCatalogFollow = require("./useOperationCatalogFollow.cjs");
26
+ const operationCatalogRowSelection = require("./operationCatalogRowSelection.cjs");
26
27
  const defaultCommandHref = (operationId) => `/commands/${operationId}`;
27
28
  const EMPTY_LOCKED_VALUES = {};
28
29
  const EMPTY_INITIAL_VALUES = {};
@@ -54,7 +55,8 @@ function OperationCatalog({
54
55
  rowDetail,
55
56
  cellRenderers,
56
57
  rowCard,
57
- follow
58
+ follow,
59
+ rowSelection
58
60
  }) {
59
61
  var _a, _b, _c, _d, _e;
60
62
  const renderRowDetail = rowDetail == null ? void 0 : rowDetail.render;
@@ -174,22 +176,7 @@ function OperationCatalog({
174
176
  setValues: setFilters
175
177
  });
176
178
  const lookupQuery = reactQuery.useQuery({
177
- queryKey: [
178
- "operation-lookup",
179
- listEndpoint == null ? void 0 : listEndpoint.method,
180
- listEndpoint == null ? void 0 : listEndpoint.path,
181
- lookupParameters
182
- ],
183
- queryFn: async () => {
184
- var _a2;
185
- return await ((_a2 = client.lookupFilters) == null ? void 0 : _a2.call(
186
- client,
187
- listEndpoint.path,
188
- listEndpoint.method,
189
- lookupParameters,
190
- { Accept: "application/json+clicky" }
191
- )) ?? { filters: {} };
192
- },
179
+ ...operationCatalogRowSelection.operationLookupQuery(client, listEndpoint, lookupParameters),
193
180
  enabled: !!listEndpoint && !!client.lookupFilters,
194
181
  placeholderData: reactQuery.keepPreviousData,
195
182
  staleTime: 3e4,
@@ -338,7 +325,16 @@ function OperationCatalog({
338
325
  onCellFilterChange
339
326
  ]
340
327
  );
328
+ const pickerSelection = react.useMemo(
329
+ () => rowSelection ? operationCatalogRowSelection.pickerTableRowSelection(rowSelection, effectiveFilters) : void 0,
330
+ [effectiveFilters, rowSelection]
331
+ );
341
332
  const showTable = !!listEndpoint;
333
+ if (rowSelection && !isLoading && !showTable) {
334
+ throw new Error(
335
+ `OperationCatalog rowSelection needs a list operation, but surface "${surfaceKey ?? definition.title}" has none`
336
+ );
337
+ }
342
338
  let listError;
343
339
  if (!list.isFetching) {
344
340
  if (list.isError) {
@@ -368,23 +364,30 @@ function OperationCatalog({
368
364
  followPartition.rows,
369
365
  followOrder
370
366
  ) : void 0;
371
- const mergedTableResponse = followMerge ? followMerge.response : tableResponse;
367
+ const unavailableRows = rowSelection == null ? void 0 : rowSelection.unavailableRows;
368
+ const markRows = (response) => response && unavailableRows ? operationCatalogRowSelection.markUnavailableRows(response, unavailableRows) : response;
369
+ const mergedTableResponse = markRows(
370
+ followMerge ? followMerge.response : tableResponse
371
+ );
372
372
  const resultsPagination = followMerge && followMerge.addedCount > 0 && dataTablePagination ? {
373
373
  ...dataTablePagination,
374
374
  total: (dataTablePagination.total ?? 0) + followMerge.addedCount,
375
375
  totalRelation: "gte"
376
376
  } : dataTablePagination;
377
- const walkProps = list.infinite ? { pages: list.pages, infinite: list.infinite } : {};
377
+ const walkProps = list.infinite ? {
378
+ pages: unavailableRows ? list.pages.map((page) => operationCatalogRowSelection.markUnavailableRows(page, unavailableRows)) : list.pages,
379
+ infinite: list.infinite
380
+ } : {};
378
381
  if (isLoading || showTable && list.isPending && list.response == null) {
379
382
  return /* @__PURE__ */ jsxRuntime.jsx(loading.Loading, { variant: "centered", label: `Loading ${definition.title}…` });
380
383
  }
381
384
  return /* @__PURE__ */ jsxRuntime.jsxs(
382
385
  "div",
383
386
  {
384
- className: "flex h-full min-h-0 flex-col gap-2",
387
+ className: "flex h-full min-h-0 flex-1 flex-col gap-2",
385
388
  "data-slot": "operation-catalog",
386
389
  children: [
387
- /* @__PURE__ */ jsxRuntime.jsx(
390
+ !rowSelection && /* @__PURE__ */ jsxRuntime.jsx(
388
391
  OperationCatalogActions.OperationCatalogActions,
389
392
  {
390
393
  actions: collectionActionOps,
@@ -416,7 +419,7 @@ function OperationCatalog({
416
419
  client
417
420
  }
418
421
  ),
419
- showTable ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", "data-slot": "operation-catalog-results", children: followMissing ? renderError(
422
+ showTable ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-0 flex-1 flex-col", "data-slot": "operation-catalog-results", children: followMissing ? renderError(
420
423
  new Error(
421
424
  `Surface "${surfaceKey ?? definition.title}" set follow, but ${listEndpoint == null ? void 0 : listEndpoint.path} advertises no session to follow (expected POST ${listEndpoint == null ? void 0 : listEndpoint.path}/sessions)`
422
425
  ),
@@ -441,11 +444,11 @@ function OperationCatalog({
441
444
  loadingMessage: `Loading ${definition.title} results…`,
442
445
  emptyMessage: "No records returned",
443
446
  ariaLabel: `${definition.title} results`,
444
- className: "mt-0 h-full min-h-0",
445
- detailOperation,
447
+ className: "mt-0 h-full min-h-0 flex-1",
448
+ detailOperation: pickerSelection ? void 0 : detailOperation,
446
449
  ...hiddenColumns ? { hiddenColumns } : {},
447
- ...getRowDetailHref ? { getRowDetailHref } : {},
448
- ...selectionActionOps.length > 0 ? {
450
+ ...getRowDetailHref && !pickerSelection ? { getRowDetailHref } : {},
451
+ ...pickerSelection ? { rowSelection: pickerSelection } : selectionActionOps.length > 0 ? {
449
452
  rowSelection: {
450
453
  selectedRowIds,
451
454
  onSelectionChange: (ids, rows) => {