@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
@@ -0,0 +1,63 @@
1
+ import { isPlainObject } from "../lib/collections.js";
2
+ import { applyListenerState } from "./json-schema-form-listeners.js";
3
+ import { resolveControl } from "./json-schema-form-resolve.js";
4
+ import { orderByXOrder, orderByClickyOrder, hasObjectItemProperties } from "./json-schema-form-utils.js";
5
+ const DEFAULT_TABLE_MAX_COLUMNS = 4;
6
+ function arrayViewOptions(field, ctx) {
7
+ return { ...tableColumnOptions(field, ctx), layoutMode: ctx.layout.mode };
8
+ }
9
+ function tableColumnOptions(field, ctx) {
10
+ return {
11
+ hideReadOnlyFields: ctx.hideReadOnlyFields,
12
+ valueCells: ctx.viewOnly || field.readOnly === true,
13
+ ...ctx.rootValue ? { rootValue: ctx.rootValue } : {},
14
+ ...ctx.expressionEvaluator ? { evaluate: ctx.expressionEvaluator } : {}
15
+ };
16
+ }
17
+ function tableLayout(itemSchema, items, options) {
18
+ const schema = itemSchema;
19
+ const states = (items.length > 0 ? items : [{}]).map((item) => {
20
+ const row = isPlainObject(item) ? item : {};
21
+ return applyListenerState(schema, row, {
22
+ root: options.rootValue ?? row,
23
+ ...options.evaluate ? { evaluate: options.evaluate } : {}
24
+ }).properties;
25
+ });
26
+ const keys = new Set(states.flatMap((state) => Object.keys(state)));
27
+ const shown = [...keys].flatMap((key) => {
28
+ const prop = states.map((state) => state[key]).find((p) => p !== void 0 && cellShows(p, options));
29
+ return prop ? [[key, prop]] : [];
30
+ });
31
+ return {
32
+ columns: orderByXOrder(orderByClickyOrder(shown), schema["x-order"]),
33
+ rows: items.length > 0 ? states : []
34
+ };
35
+ }
36
+ function cellShows(prop, options) {
37
+ return prop["x-hidden"] !== true && !(options.hideReadOnlyFields && prop.readOnly === true) && !(prop.writeOnly === true && (options.valueCells || prop.readOnly === true));
38
+ }
39
+ function defaultArrayView(field, options) {
40
+ if (field.arrayDisplay === "accordion") return options.layoutMode === "inline" ? "inline" : "stack";
41
+ if (field.layout === "table") return "grid";
42
+ const max = field.schema["x-table-max-columns"] ?? DEFAULT_TABLE_MAX_COLUMNS;
43
+ if (!Number.isInteger(max) || max < 1) {
44
+ throw new Error(`${field.key}: x-table-max-columns must be a positive integer, got ${JSON.stringify(max)}`);
45
+ }
46
+ const items = Array.isArray(field.value) ? field.value : [];
47
+ const { columns } = tableLayout(field.itemSchema ?? {}, items, options);
48
+ if (columns.some(([key, prop]) => nestsForm(key, prop))) return "inline";
49
+ return columns.length <= max ? "grid" : "inline";
50
+ }
51
+ function nestsForm(key, prop) {
52
+ const control = resolveControl({ key, prop, required: false, value: void 0, onChange: () => {
53
+ } });
54
+ return control.kind === "object" || control.kind === "string-map" || control.kind === "array" && hasObjectItemProperties(control.itemSchema);
55
+ }
56
+ export {
57
+ DEFAULT_TABLE_MAX_COLUMNS,
58
+ arrayViewOptions,
59
+ defaultArrayView,
60
+ tableColumnOptions,
61
+ tableLayout
62
+ };
63
+ //# sourceMappingURL=json-schema-form-array-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema-form-array-view.js","sources":["../../src/components/json-schema-form-array-view.ts"],"sourcesContent":["import { isPlainObject } from \"../lib/collections\";\nimport { applyListenerState } from \"./json-schema-form-listeners\";\nimport { resolveControl } from \"./json-schema-form-resolve\";\nimport { hasObjectItemProperties, orderByClickyOrder, orderByXOrder } from \"./json-schema-form-utils\";\nimport type {\n ExpressionEvaluator,\n FieldControl,\n FormLayout,\n JsonSchemaObject,\n JsonSchemaProperty,\n RenderContext,\n} from \"./json-schema-form-types\";\n\n// How an object array renders: the row grid (TableArray), or the item list\n// (AccordionArray) with each item's fields stacked or labelled inline.\nexport type ArrayView = \"grid\" | \"stack\" | \"inline\";\n\nexport const DEFAULT_TABLE_MAX_COLUMNS = 4;\n\nexport interface TableColumnOptions {\n hideReadOnlyFields: boolean;\n // The whole table is a view, so every cell renders as its value; see TableArray.\n valueCells: boolean;\n rootValue?: Record<string, unknown>;\n evaluate?: ExpressionEvaluator;\n}\n\nexport interface TableLayout {\n // Every column at least one row shows, in x-clicky-order / x-order order,\n // carrying the first showing row's property for the header.\n columns: [string, JsonSchemaProperty][];\n // Per row, that row's effective item properties under its own listener state.\n rows: Record<string, JsonSchemaProperty>[];\n}\n\nexport interface ArrayViewOptions extends TableColumnOptions {\n // The layout the array inherits, which an explicit accordion keeps.\n layoutMode: FormLayout[\"mode\"];\n}\n\nexport function arrayViewOptions(field: FieldControl, ctx: RenderContext): ArrayViewOptions {\n return { ...tableColumnOptions(field, ctx), layoutMode: ctx.layout.mode };\n}\n\nexport function tableColumnOptions(field: FieldControl, ctx: RenderContext): TableColumnOptions {\n return {\n hideReadOnlyFields: ctx.hideReadOnlyFields,\n valueCells: ctx.viewOnly || field.readOnly === true,\n ...(ctx.rootValue ? { rootValue: ctx.rootValue } : {}),\n ...(ctx.expressionEvaluator ? { evaluate: ctx.expressionEvaluator } : {}),\n };\n}\n\n// tableLayout evaluates the item schema's listeners per row, as the object\n// renderer does for each item of the list views, so a cell a row's own\n// `x-on-change` reveals gets a column. With no rows the columns come from the\n// load state of an empty item.\nexport function tableLayout(\n itemSchema: JsonSchemaProperty,\n items: unknown[],\n options: TableColumnOptions,\n): TableLayout {\n const schema = itemSchema as JsonSchemaObject;\n const states = (items.length > 0 ? items : [{}]).map((item) => {\n const row = isPlainObject(item) ? item : {};\n return applyListenerState(schema, row, {\n root: options.rootValue ?? row,\n ...(options.evaluate ? { evaluate: options.evaluate } : {}),\n }).properties;\n });\n const keys = new Set(states.flatMap((state) => Object.keys(state)));\n const shown = [...keys].flatMap((key): [string, JsonSchemaProperty][] => {\n const prop = states.map((state) => state[key]).find((p) => p !== undefined && cellShows(p, options));\n return prop ? [[key, prop]] : [];\n });\n return {\n columns: orderByXOrder(orderByClickyOrder(shown), schema[\"x-order\"]),\n rows: items.length > 0 ? states : [],\n };\n}\n\n// cellShows mirrors the renderer's drop rules for one cell: `x-hidden`, a\n// readOnly cell under hideReadOnlyFields, and a writeOnly cell in a view.\nfunction cellShows(prop: JsonSchemaProperty, options: TableColumnOptions): boolean {\n return (\n prop[\"x-hidden\"] !== true &&\n !(options.hideReadOnlyFields && prop.readOnly === true) &&\n !(prop.writeOnly === true && (options.valueCells || prop.readOnly === true))\n );\n}\n\n// defaultArrayView picks the view an object array opens in. An explicit\n// accordion names its renderer and outranks an explicit table, keeping the\n// label placement of the form around it (inline in an inline form, stacked\n// otherwise); without either hint a grid of up to `x-table-max-columns`\n// visible columns stays a grid and a wider one — or one with a nested\n// sub-form column — opens as the inline item form.\nexport function defaultArrayView(field: FieldControl, options: ArrayViewOptions): ArrayView {\n if (field.arrayDisplay === \"accordion\") return options.layoutMode === \"inline\" ? \"inline\" : \"stack\";\n if (field.layout === \"table\") return \"grid\";\n const max = field.schema[\"x-table-max-columns\"] ?? DEFAULT_TABLE_MAX_COLUMNS;\n if (!Number.isInteger(max) || max < 1) {\n throw new Error(`${field.key}: x-table-max-columns must be a positive integer, got ${JSON.stringify(max)}`);\n }\n const items = Array.isArray(field.value) ? field.value : [];\n const { columns } = tableLayout(field.itemSchema ?? { type: \"object\" }, items, options);\n // A cell holding a whole sub-form (an object, a map, a list of objects)\n // needs the item form's width, however few columns there are.\n if (columns.some(([key, prop]) => nestsForm(key, prop))) return \"inline\";\n return columns.length <= max ? \"grid\" : \"inline\";\n}\n\nfunction nestsForm(key: string, prop: JsonSchemaProperty): boolean {\n const control = resolveControl({ key, prop, required: false, value: undefined, onChange: () => {} });\n return (\n control.kind === \"object\" ||\n control.kind === \"string-map\" ||\n (control.kind === \"array\" && hasObjectItemProperties(control.itemSchema))\n );\n}\n"],"names":[],"mappings":";;;;AAiBO,MAAM,4BAA4B;AAuBlC,SAAS,iBAAiB,OAAqB,KAAsC;AAC1F,SAAO,EAAE,GAAG,mBAAmB,OAAO,GAAG,GAAG,YAAY,IAAI,OAAO,KAAA;AACrE;AAEO,SAAS,mBAAmB,OAAqB,KAAwC;AAC9F,SAAO;AAAA,IACL,oBAAoB,IAAI;AAAA,IACxB,YAAY,IAAI,YAAY,MAAM,aAAa;AAAA,IAC/C,GAAI,IAAI,YAAY,EAAE,WAAW,IAAI,UAAA,IAAc,CAAA;AAAA,IACnD,GAAI,IAAI,sBAAsB,EAAE,UAAU,IAAI,oBAAA,IAAwB,CAAA;AAAA,EAAC;AAE3E;AAMO,SAAS,YACd,YACA,OACA,SACa;AACb,QAAM,SAAS;AACf,QAAM,UAAU,MAAM,SAAS,IAAI,QAAQ,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS;AAC7D,UAAM,MAAM,cAAc,IAAI,IAAI,OAAO,CAAA;AACzC,WAAO,mBAAmB,QAAQ,KAAK;AAAA,MACrC,MAAM,QAAQ,aAAa;AAAA,MAC3B,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAA,IAAa,CAAA;AAAA,IAAC,CAC1D,EAAE;AAAA,EACL,CAAC;AACD,QAAM,OAAO,IAAI,IAAI,OAAO,QAAQ,CAAC,UAAU,OAAO,KAAK,KAAK,CAAC,CAAC;AAClE,QAAM,QAAQ,CAAC,GAAG,IAAI,EAAE,QAAQ,CAAC,QAAwC;AACvE,UAAM,OAAO,OAAO,IAAI,CAAC,UAAU,MAAM,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,MAAM,UAAa,UAAU,GAAG,OAAO,CAAC;AACnG,WAAO,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,CAAA;AAAA,EAChC,CAAC;AACD,SAAO;AAAA,IACL,SAAS,cAAc,mBAAmB,KAAK,GAAG,OAAO,SAAS,CAAC;AAAA,IACnE,MAAM,MAAM,SAAS,IAAI,SAAS,CAAA;AAAA,EAAC;AAEvC;AAIA,SAAS,UAAU,MAA0B,SAAsC;AACjF,SACE,KAAK,UAAU,MAAM,QACrB,EAAE,QAAQ,sBAAsB,KAAK,aAAa,SAClD,EAAE,KAAK,cAAc,SAAS,QAAQ,cAAc,KAAK,aAAa;AAE1E;AAQO,SAAS,iBAAiB,OAAqB,SAAsC;AAC1F,MAAI,MAAM,iBAAiB,oBAAoB,QAAQ,eAAe,WAAW,WAAW;AAC5F,MAAI,MAAM,WAAW,QAAS,QAAO;AACrC,QAAM,MAAM,MAAM,OAAO,qBAAqB,KAAK;AACnD,MAAI,CAAC,OAAO,UAAU,GAAG,KAAK,MAAM,GAAG;AACrC,UAAM,IAAI,MAAM,GAAG,MAAM,GAAG,yDAAyD,KAAK,UAAU,GAAG,CAAC,EAAE;AAAA,EAC5G;AACA,QAAM,QAAQ,MAAM,QAAQ,MAAM,KAAK,IAAI,MAAM,QAAQ,CAAA;AACzD,QAAM,EAAE,QAAA,IAAY,YAAY,MAAM,cAAc,CAAiB,GAAG,OAAO,OAAO;AAGtF,MAAI,QAAQ,KAAK,CAAC,CAAC,KAAK,IAAI,MAAM,UAAU,KAAK,IAAI,CAAC,EAAG,QAAO;AAChE,SAAO,QAAQ,UAAU,MAAM,SAAS;AAC1C;AAEA,SAAS,UAAU,KAAa,MAAmC;AACjE,QAAM,UAAU,eAAe,EAAE,KAAK,MAAM,UAAU,OAAO,OAAO,QAAW,UAAU,MAAM;AAAA,EAAC,GAAG;AACnG,SACE,QAAQ,SAAS,YACjB,QAAQ,SAAS,gBAChB,QAAQ,SAAS,WAAW,wBAAwB,QAAQ,UAAU;AAE3E;"}
@@ -8,12 +8,11 @@ const FilterPill = require("../data/FilterPill.cjs");
8
8
  const button = require("./button.cjs");
9
9
  const ItemActions = require("./ItemActions.cjs");
10
10
  const jsonSchemaFormSize = require("./json-schema-form-size.cjs");
11
- const jsonSchemaFormAccordionArray = require("./json-schema-form-accordion-array.cjs");
12
11
  const jsonSchemaFormCardsArray = require("./json-schema-form-cards-array.cjs");
13
12
  const jsonSchemaFormLayout = require("./json-schema-form-layout.cjs");
14
13
  const jsonSchemaFormResolve = require("./json-schema-form-resolve.cjs");
15
14
  const jsonSchemaFormErrors = require("./json-schema-form-errors.cjs");
16
- const jsonSchemaFormTableArray = require("./json-schema-form-table-array.cjs");
15
+ const jsonSchemaFormObjectArrayView = require("./json-schema-form-object-array-view.cjs");
17
16
  const jsonSchemaFormTagsCombobox = require("./json-schema-form-tags-combobox.cjs");
18
17
  const jsonSchemaFormListArray = require("./json-schema-form-list-array.cjs");
19
18
  const jsonSchemaFormUtils = require("./json-schema-form-utils.cjs");
@@ -84,11 +83,8 @@ function ArrayControl({
84
83
  if (field.arrayDisplay === "cards") {
85
84
  return /* @__PURE__ */ jsxRuntime.jsx(jsonSchemaFormCardsArray.CardsArray, { field, ctx, readOnly });
86
85
  }
87
- if (field.arrayDisplay === "accordion" || field.arrayDisplay !== "stacked" && field.layout !== "table") {
88
- return /* @__PURE__ */ jsxRuntime.jsx(jsonSchemaFormAccordionArray.AccordionArray, { field, ctx, readOnly });
89
- }
90
- if (field.layout === "table") {
91
- return /* @__PURE__ */ jsxRuntime.jsx(jsonSchemaFormTableArray.TableArray, { field, ctx, readOnly });
86
+ if (field.arrayDisplay !== "stacked") {
87
+ return /* @__PURE__ */ jsxRuntime.jsx(jsonSchemaFormObjectArrayView.ObjectArrayView, { field, ctx, readOnly });
92
88
  }
93
89
  }
94
90
  const items = Array.isArray(field.value) ? field.value : [];
@@ -1 +1 @@
1
- {"version":3,"file":"json-schema-form-array.cjs","sources":["../../src/components/json-schema-form-array.tsx"],"sourcesContent":["import { moveItem, removeIndex, setIndex } from \"../lib/collections\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { FilterPill } from \"../data/FilterPill\";\nimport { UiAdd } from \"../icons\";\nimport { Button } from \"./button\";\nimport { ItemActions } from \"./ItemActions\";\nimport {\n controlMinHeightClass,\n fieldInnerGapClass,\n inputSizeClass,\n type FormSize,\n} from \"./json-schema-form-size\";\nimport { AccordionArray } from \"./json-schema-form-accordion-array\";\nimport { CardsArray } from \"./json-schema-form-cards-array\";\nimport { FieldsGrid } from \"./json-schema-form-layout\";\nimport { scalarItemsType } from \"./json-schema-form-resolve\";\nimport { appendInstancePath } from \"./json-schema-form-errors\";\nimport { TableArray } from \"./json-schema-form-table-array\";\nimport { TagsComboboxControl } from \"./json-schema-form-tags-combobox\";\nimport { CompactListArray } from \"./json-schema-form-list-array\";\nimport {\n canAddItem,\n canRemoveItem,\n hasObjectItemProperties,\n seedFromSchema,\n toStringArray,\n} from \"./json-schema-form-utils\";\nimport type {\n FieldControl,\n FieldOption,\n RenderContext,\n} from \"./json-schema-form-types\";\n\n// A comma is the second commit key in every tag list, and what a pasted list is\n// split on. Newlines split too — see splitOnComboboxSeparators.\nconst TAG_SEPARATORS = [\",\"];\n\n// ArrayControl routes an array to the control its items call for: a flat list of\n// values (choices, scalars) is ONE tag combobox; object items are summary rows,\n// cards or a table; anything else renders a control per item with add / remove /\n// reorder. Recursion goes through ctx.render so this module never imports the\n// renderer (no import cycle).\nexport function ArrayControl({\n field,\n fieldId,\n ctx,\n}: {\n field: FieldControl;\n fieldId: string;\n ctx: RenderContext;\n}) {\n // A read-only array marks its whole subtree non-editable: no add/remove/reorder\n // and item inputs disabled (a child the schema marks readOnly still renders as\n // a value span).\n const readOnly = ctx.readOnly || field.readOnly === true;\n const choices = enumItemOptions(field);\n const scalarType = scalarItemsType(field.itemSchema);\n if (field.arrayDisplay === \"list\") {\n if (scalarType !== \"string\") {\n throw new Error(\n `${field.key} uses x-array-display list without string items`,\n );\n }\n return (\n <CompactListArray\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n presentation={ctx.presentation === true}\n />\n );\n }\n if (field.arrayDisplay === \"filter-pills\" && choices.length > 0) {\n return (\n <FilterPillArray\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n />\n );\n }\n // A list of choices is ONE control, not a stack of them: the enum item schema\n // makes the whole array a multi-select whose committed values are pills, so\n // the option set is discoverable in one dropdown instead of repeated per item.\n // `x-array-display: \"stacked\"` opts back into a combobox per item.\n if (field.arrayDisplay !== \"stacked\" && choices.length > 0) {\n return (\n <TagsComboboxControl\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n options={choices}\n />\n );\n }\n // A flat list of scalars is the same gesture as the enum list above — type a\n // value, get a pill — so it takes the same control, with no options to pick\n // from and a comma as a second commit key. Numeric items commit numbers.\n if (field.arrayDisplay !== \"stacked\" && scalarType) {\n return (\n <TagsComboboxControl\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n options={[]}\n itemType={scalarType}\n separators={TAG_SEPARATORS}\n />\n );\n }\n if (hasObjectItemProperties(field.itemSchema)) {\n if (field.arrayDisplay === \"cards\") {\n return <CardsArray field={field} ctx={ctx} readOnly={readOnly} />;\n }\n // The accordion is the DEFAULT for object items: stacked in full, a\n // ten-property item costs ~700px of screen each and a list of them says\n // nothing about which item is which. `x-array-display: \"stacked\"` opts back\n // into the per-item sub-form below; `x-layout: \"table\"` into the row grid.\n // An explicit accordion outranks the table, since it names the renderer.\n if (\n field.arrayDisplay === \"accordion\" ||\n (field.arrayDisplay !== \"stacked\" && field.layout !== \"table\")\n ) {\n return <AccordionArray field={field} ctx={ctx} readOnly={readOnly} />;\n }\n // `x-layout: table` renders object-item arrays as compact rows with one\n // column per item property — denser still than the summary rows.\n if (field.layout === \"table\") {\n return <TableArray field={field} ctx={ctx} readOnly={readOnly} />;\n }\n }\n const items = Array.isArray(field.value) ? field.value : [];\n const itemSchema = field.itemSchema ?? { type: \"string\" };\n const childCtx: RenderContext = { ...ctx, readOnly, depth: ctx.depth + 1 };\n\n return (\n <div\n className={cn(\n \"flex flex-col\",\n !ctx.presentation && \"rounded-md border border-input p-2\",\n fieldInnerGapClass[ctx.size],\n )}\n >\n {items.map((item, i) => (\n <div\n key={i}\n className={cn(\n \"grid items-start gap-2\",\n readOnly ? \"grid-cols-1\" : \"grid-cols-[1fr_auto]\",\n )}\n >\n {/* The item's row is a FieldWrapper (or a full-width ObjectSection),\n both of which are grid children of a FieldsGrid — inline mode's\n `grid-cols-subgrid` resolves to `none` without one, collapsing\n every item into a stacked column while the rest of the form stays\n aligned. Fixed at one column: an item is a single row, and any\n multi-column layout belongs to the item's own object body. */}\n <FieldsGrid\n layout={ctx.layout}\n size={ctx.size}\n columns={1}\n className=\"min-w-0\"\n >\n {ctx.render.renderFieldRow(\n {\n key: `${field.key}[${i}]`,\n prop: itemSchema,\n required: false,\n value: item,\n onChange: (next) => field.onChange(setIndex(items, i, next)),\n instancePath: appendInstancePath(ctx.instancePath, i),\n },\n childCtx,\n { labelOverride: `Item ${i + 1}` },\n )}\n </FieldsGrid>\n {!readOnly && (\n <ItemActions\n label={`item ${i + 1}`}\n index={i}\n count={items.length}\n size={ctx.size}\n reveal={false}\n onMove={(to) => field.onChange(moveItem(items, i, to))}\n {...(canRemoveItem(field, items.length)\n ? { onRemove: () => field.onChange(removeIndex(items, i)) }\n : {})}\n />\n )}\n </div>\n ))}\n {!readOnly && canAddItem(field, items.length) && (\n <Button\n type=\"button\"\n variant=\"outline\"\n className={cn(\"gap-1.5\", inputSizeClass[ctx.size])}\n onClick={() => field.onChange([...items, seedFromSchema(itemSchema)])}\n >\n <Icon icon={UiAdd} className=\"text-sm\" />\n Add item\n </Button>\n )}\n </div>\n );\n}\n\n// The choices an array of enum items offers, deduped by value. Prefers the\n// resolved `options` (they carry the schema's labels, icons and tones) and falls\n// back to the raw item `enum` for a field a pre-extension built by hand.\nfunction enumItemOptions(field: FieldControl): FieldOption[] {\n const rawOptions =\n field.options ??\n (Array.isArray(field.itemSchema?.enum)\n ? field.itemSchema.enum.map((value) => ({\n value: String(value),\n label: String(value),\n }))\n : []);\n const seen = new Set<string>();\n return rawOptions.filter((option) => {\n if (seen.has(option.value)) return false;\n seen.add(option.value);\n return true;\n });\n}\n\nfunction FilterPillArray({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n const options = enumItemOptions(field);\n const validValues = new Set(options.map((option) => option.value));\n const explicitValues = toStringArray(field.value).filter((value) =>\n validValues.has(value),\n );\n const implicitAll = explicitValues.length === 0;\n const selected = new Set(\n implicitAll ? options.map((option) => option.value) : explicitValues,\n );\n\n function commit(nextSelected: Set<string>) {\n const next = options\n .map((option) => option.value)\n .filter((value) => nextSelected.has(value));\n field.onChange(next.length === options.length ? [] : next);\n }\n\n function toggle(value: string) {\n if (readOnly) return;\n const next = new Set(selected);\n if (next.has(value)) {\n next.delete(value);\n } else {\n next.add(value);\n }\n commit(next);\n }\n\n return (\n <div\n id={fieldId}\n data-jsf-input\n role=\"group\"\n aria-label={field.label}\n className={cn(\n \"flex flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1 shadow-sm\",\n controlMinHeightClass[size],\n )}\n >\n {options.map((option) => (\n <FilterPill\n key={option.value}\n label={option.label}\n mode={selected.has(option.value) ? \"active\" : \"neutral\"}\n title={\n implicitAll ? `${option.label} enabled by default` : option.label\n }\n {...(!readOnly ? { onClick: () => toggle(option.value) } : {})}\n className=\"max-w-full\"\n />\n ))}\n </div>\n );\n}\n"],"names":["scalarItemsType","jsx","CompactListArray","TagsComboboxControl","hasObjectItemProperties","CardsArray","AccordionArray","TableArray","jsxs","cn","fieldInnerGapClass","FieldsGrid","setIndex","appendInstancePath","ItemActions","moveItem","canRemoveItem","removeIndex","canAddItem","Button","inputSizeClass","seedFromSchema","Icon","UiAdd","toStringArray","controlMinHeightClass","FilterPill"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoCA,MAAM,iBAAiB,CAAC,GAAG;AAOpB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AAID,QAAM,WAAW,IAAI,YAAY,MAAM,aAAa;AACpD,QAAM,UAAU,gBAAgB,KAAK;AACrC,QAAM,aAAaA,sBAAAA,gBAAgB,MAAM,UAAU;AACnD,MAAI,MAAM,iBAAiB,QAAQ;AACjC,QAAI,eAAe,UAAU;AAC3B,YAAM,IAAI;AAAA,QACR,GAAG,MAAM,GAAG;AAAA,MAAA;AAAA,IAEhB;AACA,WACEC,2BAAAA;AAAAA,MAACC,wBAAAA;AAAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,IAAI,iBAAiB;AAAA,MAAA;AAAA,IAAA;AAAA,EAGzC;AACA,MAAI,MAAM,iBAAiB,kBAAkB,QAAQ,SAAS,GAAG;AAC/D,WACED,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,EAGhB;AAKA,MAAI,MAAM,iBAAiB,aAAa,QAAQ,SAAS,GAAG;AAC1D,WACEA,2BAAAA;AAAAA,MAACE,2BAAAA;AAAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,IAAI;AAAA,QACV,SAAS;AAAA,MAAA;AAAA,IAAA;AAAA,EAGf;AAIA,MAAI,MAAM,iBAAiB,aAAa,YAAY;AAClD,WACEF,2BAAAA;AAAAA,MAACE,2BAAAA;AAAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,IAAI;AAAA,QACV,SAAS,CAAA;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,MAAA;AAAA,IAAA;AAAA,EAGlB;AACA,MAAIC,oBAAAA,wBAAwB,MAAM,UAAU,GAAG;AAC7C,QAAI,MAAM,iBAAiB,SAAS;AAClC,aAAOH,2BAAAA,IAACI,yBAAAA,YAAA,EAAW,OAAc,KAAU,SAAA,CAAoB;AAAA,IACjE;AAMA,QACE,MAAM,iBAAiB,eACtB,MAAM,iBAAiB,aAAa,MAAM,WAAW,SACtD;AACA,aAAOJ,2BAAAA,IAACK,6BAAAA,gBAAA,EAAe,OAAc,KAAU,SAAA,CAAoB;AAAA,IACrE;AAGA,QAAI,MAAM,WAAW,SAAS;AAC5B,aAAOL,2BAAAA,IAACM,yBAAAA,YAAA,EAAW,OAAc,KAAU,SAAA,CAAoB;AAAA,IACjE;AAAA,EACF;AACA,QAAM,QAAQ,MAAM,QAAQ,MAAM,KAAK,IAAI,MAAM,QAAQ,CAAA;AACzD,QAAM,aAAa,MAAM,cAAc,EAAE,MAAM,SAAA;AAC/C,QAAM,WAA0B,EAAE,GAAG,KAAK,UAAU,OAAO,IAAI,QAAQ,EAAA;AAEvE,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,MAAAA;AAAAA,QACT;AAAA,QACA,CAAC,IAAI,gBAAgB;AAAA,QACrBC,mBAAAA,mBAAmB,IAAI,IAAI;AAAA,MAAA;AAAA,MAG5B,UAAA;AAAA,QAAA,MAAM,IAAI,CAAC,MAAM,MAChBF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAWC,MAAAA;AAAAA,cACT;AAAA,cACE,WAAW,gBAAgB;AAAA,YAAA;AAAA,YAS/B,UAAA;AAAA,cAAAR,2BAAAA;AAAAA,gBAACU,qBAAAA;AAAAA,gBAAA;AAAA,kBACC,QAAQ,IAAI;AAAA,kBACZ,MAAM,IAAI;AAAA,kBACV,SAAS;AAAA,kBACT,WAAU;AAAA,kBAET,cAAI,OAAO;AAAA,oBACV;AAAA,sBACE,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;AAAA,sBACtB,MAAM;AAAA,sBACN,UAAU;AAAA,sBACV,OAAO;AAAA,sBACP,UAAU,CAAC,SAAS,MAAM,SAASC,YAAAA,SAAS,OAAO,GAAG,IAAI,CAAC;AAAA,sBAC3D,cAAcC,qBAAAA,mBAAmB,IAAI,cAAc,CAAC;AAAA,oBAAA;AAAA,oBAEtD;AAAA,oBACA,EAAE,eAAe,QAAQ,IAAI,CAAC,GAAA;AAAA,kBAAG;AAAA,gBACnC;AAAA,cAAA;AAAA,cAED,CAAC,YACAZ,2BAAAA;AAAAA,gBAACa,YAAAA;AAAAA,gBAAA;AAAA,kBACC,OAAO,QAAQ,IAAI,CAAC;AAAA,kBACpB,OAAO;AAAA,kBACP,OAAO,MAAM;AAAA,kBACb,MAAM,IAAI;AAAA,kBACV,QAAQ;AAAA,kBACR,QAAQ,CAAC,OAAO,MAAM,SAASC,YAAAA,SAAS,OAAO,GAAG,EAAE,CAAC;AAAA,kBACpD,GAAIC,oBAAAA,cAAc,OAAO,MAAM,MAAM,IAClC,EAAE,UAAU,MAAM,MAAM,SAASC,YAAAA,YAAY,OAAO,CAAC,CAAC,EAAA,IACtD,CAAA;AAAA,gBAAC;AAAA,cAAA;AAAA,YACP;AAAA,UAAA;AAAA,UA1CG;AAAA,QAAA,CA6CR;AAAA,QACA,CAAC,YAAYC,oBAAAA,WAAW,OAAO,MAAM,MAAM,KAC1CV,2BAAAA;AAAAA,UAACW,OAAAA;AAAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,WAAWV,MAAAA,GAAG,WAAWW,mBAAAA,eAAe,IAAI,IAAI,CAAC;AAAA,YACjD,SAAS,MAAM,MAAM,SAAS,CAAC,GAAG,OAAOC,oBAAAA,eAAe,UAAU,CAAC,CAAC;AAAA,YAEpE,UAAA;AAAA,cAAApB,2BAAAA,IAACqB,KAAAA,MAAA,EAAK,MAAMC,MAAAA,OAAO,WAAU,WAAU;AAAA,cAAE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAE3C;AAAA,IAAA;AAAA,EAAA;AAIR;AAKA,SAAS,gBAAgB,OAAoC;;AAC3D,QAAM,aACJ,MAAM,YACL,MAAM,SAAQ,WAAM,eAAN,mBAAkB,IAAI,IACjC,MAAM,WAAW,KAAK,IAAI,CAAC,WAAW;AAAA,IACpC,OAAO,OAAO,KAAK;AAAA,IACnB,OAAO,OAAO,KAAK;AAAA,EAAA,EACnB,IACF,CAAA;AACN,QAAM,2BAAW,IAAA;AACjB,SAAO,WAAW,OAAO,CAAC,WAAW;AACnC,QAAI,KAAK,IAAI,OAAO,KAAK,EAAG,QAAO;AACnC,SAAK,IAAI,OAAO,KAAK;AACrB,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,UAAU,gBAAgB,KAAK;AACrC,QAAM,cAAc,IAAI,IAAI,QAAQ,IAAI,CAAC,WAAW,OAAO,KAAK,CAAC;AACjE,QAAM,iBAAiBC,oBAAAA,cAAc,MAAM,KAAK,EAAE;AAAA,IAAO,CAAC,UACxD,YAAY,IAAI,KAAK;AAAA,EAAA;AAEvB,QAAM,cAAc,eAAe,WAAW;AAC9C,QAAM,WAAW,IAAI;AAAA,IACnB,cAAc,QAAQ,IAAI,CAAC,WAAW,OAAO,KAAK,IAAI;AAAA,EAAA;AAGxD,WAAS,OAAO,cAA2B;AACzC,UAAM,OAAO,QACV,IAAI,CAAC,WAAW,OAAO,KAAK,EAC5B,OAAO,CAAC,UAAU,aAAa,IAAI,KAAK,CAAC;AAC5C,UAAM,SAAS,KAAK,WAAW,QAAQ,SAAS,CAAA,IAAK,IAAI;AAAA,EAC3D;AAEA,WAAS,OAAO,OAAe;AAC7B,QAAI,SAAU;AACd,UAAM,OAAO,IAAI,IAAI,QAAQ;AAC7B,QAAI,KAAK,IAAI,KAAK,GAAG;AACnB,WAAK,OAAO,KAAK;AAAA,IACnB,OAAO;AACL,WAAK,IAAI,KAAK;AAAA,IAChB;AACA,WAAO,IAAI;AAAA,EACb;AAEA,SACEvB,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,IAAI;AAAA,MACJ,kBAAc;AAAA,MACd,MAAK;AAAA,MACL,cAAY,MAAM;AAAA,MAClB,WAAWQ,MAAAA;AAAAA,QACT;AAAA,QACAgB,mBAAAA,sBAAsB,IAAI;AAAA,MAAA;AAAA,MAG3B,UAAA,QAAQ,IAAI,CAAC,WACZxB,2BAAAA;AAAAA,QAACyB,WAAAA;AAAAA,QAAA;AAAA,UAEC,OAAO,OAAO;AAAA,UACd,MAAM,SAAS,IAAI,OAAO,KAAK,IAAI,WAAW;AAAA,UAC9C,OACE,cAAc,GAAG,OAAO,KAAK,wBAAwB,OAAO;AAAA,UAE7D,GAAI,CAAC,WAAW,EAAE,SAAS,MAAM,OAAO,OAAO,KAAK,EAAA,IAAM,CAAA;AAAA,UAC3D,WAAU;AAAA,QAAA;AAAA,QAPL,OAAO;AAAA,MAAA,CASf;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
1
+ {"version":3,"file":"json-schema-form-array.cjs","sources":["../../src/components/json-schema-form-array.tsx"],"sourcesContent":["import { moveItem, removeIndex, setIndex } from \"../lib/collections\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { FilterPill } from \"../data/FilterPill\";\nimport { UiAdd } from \"../icons\";\nimport { Button } from \"./button\";\nimport { ItemActions } from \"./ItemActions\";\nimport {\n controlMinHeightClass,\n fieldInnerGapClass,\n inputSizeClass,\n type FormSize,\n} from \"./json-schema-form-size\";\nimport { CardsArray } from \"./json-schema-form-cards-array\";\nimport { FieldsGrid } from \"./json-schema-form-layout\";\nimport { scalarItemsType } from \"./json-schema-form-resolve\";\nimport { appendInstancePath } from \"./json-schema-form-errors\";\nimport { ObjectArrayView } from \"./json-schema-form-object-array-view\";\nimport { TagsComboboxControl } from \"./json-schema-form-tags-combobox\";\nimport { CompactListArray } from \"./json-schema-form-list-array\";\nimport {\n canAddItem,\n canRemoveItem,\n hasObjectItemProperties,\n seedFromSchema,\n toStringArray,\n} from \"./json-schema-form-utils\";\nimport type {\n FieldControl,\n FieldOption,\n RenderContext,\n} from \"./json-schema-form-types\";\n\n// A comma is the second commit key in every tag list, and what a pasted list is\n// split on. Newlines split too — see splitOnComboboxSeparators.\nconst TAG_SEPARATORS = [\",\"];\n\n// ArrayControl routes an array to the control its items call for: a flat list of\n// values (choices, scalars) is ONE tag combobox; object items are cards or a\n// switchable grid / item-form view (ObjectArrayView); anything else — and the\n// `x-array-display: stacked` opt-out — renders a control per item with add / remove /\n// reorder. Recursion goes through ctx.render so this module never imports the\n// renderer (no import cycle).\nexport function ArrayControl({\n field,\n fieldId,\n ctx,\n}: {\n field: FieldControl;\n fieldId: string;\n ctx: RenderContext;\n}) {\n // A read-only array marks its whole subtree non-editable: no add/remove/reorder\n // and item inputs disabled (a child the schema marks readOnly still renders as\n // a value span). A table shows every read-only cell as a value span instead;\n // see TableArray.\n const readOnly = ctx.readOnly || field.readOnly === true;\n const choices = enumItemOptions(field);\n const scalarType = scalarItemsType(field.itemSchema);\n if (field.arrayDisplay === \"list\") {\n if (scalarType !== \"string\") {\n throw new Error(\n `${field.key} uses x-array-display list without string items`,\n );\n }\n return (\n <CompactListArray\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n presentation={ctx.presentation === true}\n />\n );\n }\n if (field.arrayDisplay === \"filter-pills\" && choices.length > 0) {\n return (\n <FilterPillArray\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n />\n );\n }\n // A list of choices is ONE control, not a stack of them: the enum item schema\n // makes the whole array a multi-select whose committed values are pills, so\n // the option set is discoverable in one dropdown instead of repeated per item.\n // `x-array-display: \"stacked\"` opts back into a combobox per item.\n if (field.arrayDisplay !== \"stacked\" && choices.length > 0) {\n return (\n <TagsComboboxControl\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n options={choices}\n />\n );\n }\n // A flat list of scalars is the same gesture as the enum list above — type a\n // value, get a pill — so it takes the same control, with no options to pick\n // from and a comma as a second commit key. Numeric items commit numbers.\n if (field.arrayDisplay !== \"stacked\" && scalarType) {\n return (\n <TagsComboboxControl\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n options={[]}\n itemType={scalarType}\n separators={TAG_SEPARATORS}\n />\n );\n }\n if (hasObjectItemProperties(field.itemSchema)) {\n if (field.arrayDisplay === \"cards\") {\n return <CardsArray field={field} ctx={ctx} readOnly={readOnly} />;\n }\n // Object items render as a switchable view: the row grid while the item's\n // visible columns fit, the item list (one summary row per item, opening\n // into its form) once they do not — stacked in full, a ten-property item\n // costs ~700px of screen each. `x-layout: \"table\"` and\n // `x-array-display: \"accordion\"` pick the view it opens in; see\n // defaultArrayView. `x-array-display: \"stacked\"` opts back into the\n // per-item sub-form below.\n if (field.arrayDisplay !== \"stacked\") {\n return <ObjectArrayView field={field} ctx={ctx} readOnly={readOnly} />;\n }\n }\n const items = Array.isArray(field.value) ? field.value : [];\n const itemSchema = field.itemSchema ?? { type: \"string\" };\n const childCtx: RenderContext = { ...ctx, readOnly, depth: ctx.depth + 1 };\n\n return (\n <div\n className={cn(\n \"flex flex-col\",\n !ctx.presentation && \"rounded-md border border-input p-2\",\n fieldInnerGapClass[ctx.size],\n )}\n >\n {items.map((item, i) => (\n <div\n key={i}\n className={cn(\n \"grid items-start gap-2\",\n readOnly ? \"grid-cols-1\" : \"grid-cols-[1fr_auto]\",\n )}\n >\n {/* The item's row is a FieldWrapper (or a full-width ObjectSection),\n both of which are grid children of a FieldsGrid — inline mode's\n `grid-cols-subgrid` resolves to `none` without one, collapsing\n every item into a stacked column while the rest of the form stays\n aligned. Fixed at one column: an item is a single row, and any\n multi-column layout belongs to the item's own object body. */}\n <FieldsGrid\n layout={ctx.layout}\n size={ctx.size}\n columns={1}\n className=\"min-w-0\"\n >\n {ctx.render.renderFieldRow(\n {\n key: `${field.key}[${i}]`,\n prop: itemSchema,\n required: false,\n value: item,\n onChange: (next) => field.onChange(setIndex(items, i, next)),\n instancePath: appendInstancePath(ctx.instancePath, i),\n },\n childCtx,\n { labelOverride: `Item ${i + 1}` },\n )}\n </FieldsGrid>\n {!readOnly && (\n <ItemActions\n label={`item ${i + 1}`}\n index={i}\n count={items.length}\n size={ctx.size}\n reveal={false}\n onMove={(to) => field.onChange(moveItem(items, i, to))}\n {...(canRemoveItem(field, items.length)\n ? { onRemove: () => field.onChange(removeIndex(items, i)) }\n : {})}\n />\n )}\n </div>\n ))}\n {!readOnly && canAddItem(field, items.length) && (\n <Button\n type=\"button\"\n variant=\"outline\"\n className={cn(\"gap-1.5\", inputSizeClass[ctx.size])}\n onClick={() => field.onChange([...items, seedFromSchema(itemSchema)])}\n >\n <Icon icon={UiAdd} className=\"text-sm\" />\n Add item\n </Button>\n )}\n </div>\n );\n}\n\n// The choices an array of enum items offers, deduped by value. Prefers the\n// resolved `options` (they carry the schema's labels, icons and tones) and falls\n// back to the raw item `enum` for a field a pre-extension built by hand.\nfunction enumItemOptions(field: FieldControl): FieldOption[] {\n const rawOptions =\n field.options ??\n (Array.isArray(field.itemSchema?.enum)\n ? field.itemSchema.enum.map((value) => ({\n value: String(value),\n label: String(value),\n }))\n : []);\n const seen = new Set<string>();\n return rawOptions.filter((option) => {\n if (seen.has(option.value)) return false;\n seen.add(option.value);\n return true;\n });\n}\n\nfunction FilterPillArray({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n const options = enumItemOptions(field);\n const validValues = new Set(options.map((option) => option.value));\n const explicitValues = toStringArray(field.value).filter((value) =>\n validValues.has(value),\n );\n const implicitAll = explicitValues.length === 0;\n const selected = new Set(\n implicitAll ? options.map((option) => option.value) : explicitValues,\n );\n\n function commit(nextSelected: Set<string>) {\n const next = options\n .map((option) => option.value)\n .filter((value) => nextSelected.has(value));\n field.onChange(next.length === options.length ? [] : next);\n }\n\n function toggle(value: string) {\n if (readOnly) return;\n const next = new Set(selected);\n if (next.has(value)) {\n next.delete(value);\n } else {\n next.add(value);\n }\n commit(next);\n }\n\n return (\n <div\n id={fieldId}\n data-jsf-input\n role=\"group\"\n aria-label={field.label}\n className={cn(\n \"flex flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1 shadow-sm\",\n controlMinHeightClass[size],\n )}\n >\n {options.map((option) => (\n <FilterPill\n key={option.value}\n label={option.label}\n mode={selected.has(option.value) ? \"active\" : \"neutral\"}\n title={\n implicitAll ? `${option.label} enabled by default` : option.label\n }\n {...(!readOnly ? { onClick: () => toggle(option.value) } : {})}\n className=\"max-w-full\"\n />\n ))}\n </div>\n );\n}\n"],"names":["scalarItemsType","jsx","CompactListArray","TagsComboboxControl","hasObjectItemProperties","CardsArray","ObjectArrayView","jsxs","cn","fieldInnerGapClass","FieldsGrid","setIndex","appendInstancePath","ItemActions","moveItem","canRemoveItem","removeIndex","canAddItem","Button","inputSizeClass","seedFromSchema","Icon","UiAdd","toStringArray","controlMinHeightClass","FilterPill"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"json-schema-form-array.d.ts","sourceRoot":"","sources":["../../src/components/json-schema-form-array.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EACV,YAAY,EAEZ,aAAa,EACd,MAAM,0BAA0B,CAAC;AAWlC,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,aAAa,CAAC;CACpB,+BA6JA"}
1
+ {"version":3,"file":"json-schema-form-array.d.ts","sourceRoot":"","sources":["../../src/components/json-schema-form-array.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,YAAY,EAEZ,aAAa,EACd,MAAM,0BAA0B,CAAC;AAYlC,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,aAAa,CAAC;CACpB,+BAwJA"}
@@ -6,12 +6,11 @@ import { FilterPill } from "../data/FilterPill.js";
6
6
  import { Button } from "./button.js";
7
7
  import { ItemActions } from "./ItemActions.js";
8
8
  import { inputSizeClass, fieldInnerGapClass, controlMinHeightClass } from "./json-schema-form-size.js";
9
- import { AccordionArray } from "./json-schema-form-accordion-array.js";
10
9
  import { CardsArray } from "./json-schema-form-cards-array.js";
11
10
  import { FieldsGrid } from "./json-schema-form-layout.js";
12
11
  import { scalarItemsType } from "./json-schema-form-resolve.js";
13
12
  import { appendInstancePath } from "./json-schema-form-errors.js";
14
- import { TableArray } from "./json-schema-form-table-array.js";
13
+ import { ObjectArrayView } from "./json-schema-form-object-array-view.js";
15
14
  import { TagsComboboxControl } from "./json-schema-form-tags-combobox.js";
16
15
  import { CompactListArray } from "./json-schema-form-list-array.js";
17
16
  import { hasObjectItemProperties, canRemoveItem, canAddItem, seedFromSchema, toStringArray } from "./json-schema-form-utils.js";
@@ -82,11 +81,8 @@ function ArrayControl({
82
81
  if (field.arrayDisplay === "cards") {
83
82
  return /* @__PURE__ */ jsx(CardsArray, { field, ctx, readOnly });
84
83
  }
85
- if (field.arrayDisplay === "accordion" || field.arrayDisplay !== "stacked" && field.layout !== "table") {
86
- return /* @__PURE__ */ jsx(AccordionArray, { field, ctx, readOnly });
87
- }
88
- if (field.layout === "table") {
89
- return /* @__PURE__ */ jsx(TableArray, { field, ctx, readOnly });
84
+ if (field.arrayDisplay !== "stacked") {
85
+ return /* @__PURE__ */ jsx(ObjectArrayView, { field, ctx, readOnly });
90
86
  }
91
87
  }
92
88
  const items = Array.isArray(field.value) ? field.value : [];
@@ -1 +1 @@
1
- {"version":3,"file":"json-schema-form-array.js","sources":["../../src/components/json-schema-form-array.tsx"],"sourcesContent":["import { moveItem, removeIndex, setIndex } from \"../lib/collections\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { FilterPill } from \"../data/FilterPill\";\nimport { UiAdd } from \"../icons\";\nimport { Button } from \"./button\";\nimport { ItemActions } from \"./ItemActions\";\nimport {\n controlMinHeightClass,\n fieldInnerGapClass,\n inputSizeClass,\n type FormSize,\n} from \"./json-schema-form-size\";\nimport { AccordionArray } from \"./json-schema-form-accordion-array\";\nimport { CardsArray } from \"./json-schema-form-cards-array\";\nimport { FieldsGrid } from \"./json-schema-form-layout\";\nimport { scalarItemsType } from \"./json-schema-form-resolve\";\nimport { appendInstancePath } from \"./json-schema-form-errors\";\nimport { TableArray } from \"./json-schema-form-table-array\";\nimport { TagsComboboxControl } from \"./json-schema-form-tags-combobox\";\nimport { CompactListArray } from \"./json-schema-form-list-array\";\nimport {\n canAddItem,\n canRemoveItem,\n hasObjectItemProperties,\n seedFromSchema,\n toStringArray,\n} from \"./json-schema-form-utils\";\nimport type {\n FieldControl,\n FieldOption,\n RenderContext,\n} from \"./json-schema-form-types\";\n\n// A comma is the second commit key in every tag list, and what a pasted list is\n// split on. Newlines split too — see splitOnComboboxSeparators.\nconst TAG_SEPARATORS = [\",\"];\n\n// ArrayControl routes an array to the control its items call for: a flat list of\n// values (choices, scalars) is ONE tag combobox; object items are summary rows,\n// cards or a table; anything else renders a control per item with add / remove /\n// reorder. Recursion goes through ctx.render so this module never imports the\n// renderer (no import cycle).\nexport function ArrayControl({\n field,\n fieldId,\n ctx,\n}: {\n field: FieldControl;\n fieldId: string;\n ctx: RenderContext;\n}) {\n // A read-only array marks its whole subtree non-editable: no add/remove/reorder\n // and item inputs disabled (a child the schema marks readOnly still renders as\n // a value span).\n const readOnly = ctx.readOnly || field.readOnly === true;\n const choices = enumItemOptions(field);\n const scalarType = scalarItemsType(field.itemSchema);\n if (field.arrayDisplay === \"list\") {\n if (scalarType !== \"string\") {\n throw new Error(\n `${field.key} uses x-array-display list without string items`,\n );\n }\n return (\n <CompactListArray\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n presentation={ctx.presentation === true}\n />\n );\n }\n if (field.arrayDisplay === \"filter-pills\" && choices.length > 0) {\n return (\n <FilterPillArray\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n />\n );\n }\n // A list of choices is ONE control, not a stack of them: the enum item schema\n // makes the whole array a multi-select whose committed values are pills, so\n // the option set is discoverable in one dropdown instead of repeated per item.\n // `x-array-display: \"stacked\"` opts back into a combobox per item.\n if (field.arrayDisplay !== \"stacked\" && choices.length > 0) {\n return (\n <TagsComboboxControl\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n options={choices}\n />\n );\n }\n // A flat list of scalars is the same gesture as the enum list above — type a\n // value, get a pill — so it takes the same control, with no options to pick\n // from and a comma as a second commit key. Numeric items commit numbers.\n if (field.arrayDisplay !== \"stacked\" && scalarType) {\n return (\n <TagsComboboxControl\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n options={[]}\n itemType={scalarType}\n separators={TAG_SEPARATORS}\n />\n );\n }\n if (hasObjectItemProperties(field.itemSchema)) {\n if (field.arrayDisplay === \"cards\") {\n return <CardsArray field={field} ctx={ctx} readOnly={readOnly} />;\n }\n // The accordion is the DEFAULT for object items: stacked in full, a\n // ten-property item costs ~700px of screen each and a list of them says\n // nothing about which item is which. `x-array-display: \"stacked\"` opts back\n // into the per-item sub-form below; `x-layout: \"table\"` into the row grid.\n // An explicit accordion outranks the table, since it names the renderer.\n if (\n field.arrayDisplay === \"accordion\" ||\n (field.arrayDisplay !== \"stacked\" && field.layout !== \"table\")\n ) {\n return <AccordionArray field={field} ctx={ctx} readOnly={readOnly} />;\n }\n // `x-layout: table` renders object-item arrays as compact rows with one\n // column per item property — denser still than the summary rows.\n if (field.layout === \"table\") {\n return <TableArray field={field} ctx={ctx} readOnly={readOnly} />;\n }\n }\n const items = Array.isArray(field.value) ? field.value : [];\n const itemSchema = field.itemSchema ?? { type: \"string\" };\n const childCtx: RenderContext = { ...ctx, readOnly, depth: ctx.depth + 1 };\n\n return (\n <div\n className={cn(\n \"flex flex-col\",\n !ctx.presentation && \"rounded-md border border-input p-2\",\n fieldInnerGapClass[ctx.size],\n )}\n >\n {items.map((item, i) => (\n <div\n key={i}\n className={cn(\n \"grid items-start gap-2\",\n readOnly ? \"grid-cols-1\" : \"grid-cols-[1fr_auto]\",\n )}\n >\n {/* The item's row is a FieldWrapper (or a full-width ObjectSection),\n both of which are grid children of a FieldsGrid — inline mode's\n `grid-cols-subgrid` resolves to `none` without one, collapsing\n every item into a stacked column while the rest of the form stays\n aligned. Fixed at one column: an item is a single row, and any\n multi-column layout belongs to the item's own object body. */}\n <FieldsGrid\n layout={ctx.layout}\n size={ctx.size}\n columns={1}\n className=\"min-w-0\"\n >\n {ctx.render.renderFieldRow(\n {\n key: `${field.key}[${i}]`,\n prop: itemSchema,\n required: false,\n value: item,\n onChange: (next) => field.onChange(setIndex(items, i, next)),\n instancePath: appendInstancePath(ctx.instancePath, i),\n },\n childCtx,\n { labelOverride: `Item ${i + 1}` },\n )}\n </FieldsGrid>\n {!readOnly && (\n <ItemActions\n label={`item ${i + 1}`}\n index={i}\n count={items.length}\n size={ctx.size}\n reveal={false}\n onMove={(to) => field.onChange(moveItem(items, i, to))}\n {...(canRemoveItem(field, items.length)\n ? { onRemove: () => field.onChange(removeIndex(items, i)) }\n : {})}\n />\n )}\n </div>\n ))}\n {!readOnly && canAddItem(field, items.length) && (\n <Button\n type=\"button\"\n variant=\"outline\"\n className={cn(\"gap-1.5\", inputSizeClass[ctx.size])}\n onClick={() => field.onChange([...items, seedFromSchema(itemSchema)])}\n >\n <Icon icon={UiAdd} className=\"text-sm\" />\n Add item\n </Button>\n )}\n </div>\n );\n}\n\n// The choices an array of enum items offers, deduped by value. Prefers the\n// resolved `options` (they carry the schema's labels, icons and tones) and falls\n// back to the raw item `enum` for a field a pre-extension built by hand.\nfunction enumItemOptions(field: FieldControl): FieldOption[] {\n const rawOptions =\n field.options ??\n (Array.isArray(field.itemSchema?.enum)\n ? field.itemSchema.enum.map((value) => ({\n value: String(value),\n label: String(value),\n }))\n : []);\n const seen = new Set<string>();\n return rawOptions.filter((option) => {\n if (seen.has(option.value)) return false;\n seen.add(option.value);\n return true;\n });\n}\n\nfunction FilterPillArray({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n const options = enumItemOptions(field);\n const validValues = new Set(options.map((option) => option.value));\n const explicitValues = toStringArray(field.value).filter((value) =>\n validValues.has(value),\n );\n const implicitAll = explicitValues.length === 0;\n const selected = new Set(\n implicitAll ? options.map((option) => option.value) : explicitValues,\n );\n\n function commit(nextSelected: Set<string>) {\n const next = options\n .map((option) => option.value)\n .filter((value) => nextSelected.has(value));\n field.onChange(next.length === options.length ? [] : next);\n }\n\n function toggle(value: string) {\n if (readOnly) return;\n const next = new Set(selected);\n if (next.has(value)) {\n next.delete(value);\n } else {\n next.add(value);\n }\n commit(next);\n }\n\n return (\n <div\n id={fieldId}\n data-jsf-input\n role=\"group\"\n aria-label={field.label}\n className={cn(\n \"flex flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1 shadow-sm\",\n controlMinHeightClass[size],\n )}\n >\n {options.map((option) => (\n <FilterPill\n key={option.value}\n label={option.label}\n mode={selected.has(option.value) ? \"active\" : \"neutral\"}\n title={\n implicitAll ? `${option.label} enabled by default` : option.label\n }\n {...(!readOnly ? { onClick: () => toggle(option.value) } : {})}\n className=\"max-w-full\"\n />\n ))}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"json-schema-form-array.js","sources":["../../src/components/json-schema-form-array.tsx"],"sourcesContent":["import { moveItem, removeIndex, setIndex } from \"../lib/collections\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { FilterPill } from \"../data/FilterPill\";\nimport { UiAdd } from \"../icons\";\nimport { Button } from \"./button\";\nimport { ItemActions } from \"./ItemActions\";\nimport {\n controlMinHeightClass,\n fieldInnerGapClass,\n inputSizeClass,\n type FormSize,\n} from \"./json-schema-form-size\";\nimport { CardsArray } from \"./json-schema-form-cards-array\";\nimport { FieldsGrid } from \"./json-schema-form-layout\";\nimport { scalarItemsType } from \"./json-schema-form-resolve\";\nimport { appendInstancePath } from \"./json-schema-form-errors\";\nimport { ObjectArrayView } from \"./json-schema-form-object-array-view\";\nimport { TagsComboboxControl } from \"./json-schema-form-tags-combobox\";\nimport { CompactListArray } from \"./json-schema-form-list-array\";\nimport {\n canAddItem,\n canRemoveItem,\n hasObjectItemProperties,\n seedFromSchema,\n toStringArray,\n} from \"./json-schema-form-utils\";\nimport type {\n FieldControl,\n FieldOption,\n RenderContext,\n} from \"./json-schema-form-types\";\n\n// A comma is the second commit key in every tag list, and what a pasted list is\n// split on. Newlines split too — see splitOnComboboxSeparators.\nconst TAG_SEPARATORS = [\",\"];\n\n// ArrayControl routes an array to the control its items call for: a flat list of\n// values (choices, scalars) is ONE tag combobox; object items are cards or a\n// switchable grid / item-form view (ObjectArrayView); anything else — and the\n// `x-array-display: stacked` opt-out — renders a control per item with add / remove /\n// reorder. Recursion goes through ctx.render so this module never imports the\n// renderer (no import cycle).\nexport function ArrayControl({\n field,\n fieldId,\n ctx,\n}: {\n field: FieldControl;\n fieldId: string;\n ctx: RenderContext;\n}) {\n // A read-only array marks its whole subtree non-editable: no add/remove/reorder\n // and item inputs disabled (a child the schema marks readOnly still renders as\n // a value span). A table shows every read-only cell as a value span instead;\n // see TableArray.\n const readOnly = ctx.readOnly || field.readOnly === true;\n const choices = enumItemOptions(field);\n const scalarType = scalarItemsType(field.itemSchema);\n if (field.arrayDisplay === \"list\") {\n if (scalarType !== \"string\") {\n throw new Error(\n `${field.key} uses x-array-display list without string items`,\n );\n }\n return (\n <CompactListArray\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n presentation={ctx.presentation === true}\n />\n );\n }\n if (field.arrayDisplay === \"filter-pills\" && choices.length > 0) {\n return (\n <FilterPillArray\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n />\n );\n }\n // A list of choices is ONE control, not a stack of them: the enum item schema\n // makes the whole array a multi-select whose committed values are pills, so\n // the option set is discoverable in one dropdown instead of repeated per item.\n // `x-array-display: \"stacked\"` opts back into a combobox per item.\n if (field.arrayDisplay !== \"stacked\" && choices.length > 0) {\n return (\n <TagsComboboxControl\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n options={choices}\n />\n );\n }\n // A flat list of scalars is the same gesture as the enum list above — type a\n // value, get a pill — so it takes the same control, with no options to pick\n // from and a comma as a second commit key. Numeric items commit numbers.\n if (field.arrayDisplay !== \"stacked\" && scalarType) {\n return (\n <TagsComboboxControl\n field={field}\n fieldId={fieldId}\n readOnly={readOnly}\n size={ctx.size}\n options={[]}\n itemType={scalarType}\n separators={TAG_SEPARATORS}\n />\n );\n }\n if (hasObjectItemProperties(field.itemSchema)) {\n if (field.arrayDisplay === \"cards\") {\n return <CardsArray field={field} ctx={ctx} readOnly={readOnly} />;\n }\n // Object items render as a switchable view: the row grid while the item's\n // visible columns fit, the item list (one summary row per item, opening\n // into its form) once they do not — stacked in full, a ten-property item\n // costs ~700px of screen each. `x-layout: \"table\"` and\n // `x-array-display: \"accordion\"` pick the view it opens in; see\n // defaultArrayView. `x-array-display: \"stacked\"` opts back into the\n // per-item sub-form below.\n if (field.arrayDisplay !== \"stacked\") {\n return <ObjectArrayView field={field} ctx={ctx} readOnly={readOnly} />;\n }\n }\n const items = Array.isArray(field.value) ? field.value : [];\n const itemSchema = field.itemSchema ?? { type: \"string\" };\n const childCtx: RenderContext = { ...ctx, readOnly, depth: ctx.depth + 1 };\n\n return (\n <div\n className={cn(\n \"flex flex-col\",\n !ctx.presentation && \"rounded-md border border-input p-2\",\n fieldInnerGapClass[ctx.size],\n )}\n >\n {items.map((item, i) => (\n <div\n key={i}\n className={cn(\n \"grid items-start gap-2\",\n readOnly ? \"grid-cols-1\" : \"grid-cols-[1fr_auto]\",\n )}\n >\n {/* The item's row is a FieldWrapper (or a full-width ObjectSection),\n both of which are grid children of a FieldsGrid — inline mode's\n `grid-cols-subgrid` resolves to `none` without one, collapsing\n every item into a stacked column while the rest of the form stays\n aligned. Fixed at one column: an item is a single row, and any\n multi-column layout belongs to the item's own object body. */}\n <FieldsGrid\n layout={ctx.layout}\n size={ctx.size}\n columns={1}\n className=\"min-w-0\"\n >\n {ctx.render.renderFieldRow(\n {\n key: `${field.key}[${i}]`,\n prop: itemSchema,\n required: false,\n value: item,\n onChange: (next) => field.onChange(setIndex(items, i, next)),\n instancePath: appendInstancePath(ctx.instancePath, i),\n },\n childCtx,\n { labelOverride: `Item ${i + 1}` },\n )}\n </FieldsGrid>\n {!readOnly && (\n <ItemActions\n label={`item ${i + 1}`}\n index={i}\n count={items.length}\n size={ctx.size}\n reveal={false}\n onMove={(to) => field.onChange(moveItem(items, i, to))}\n {...(canRemoveItem(field, items.length)\n ? { onRemove: () => field.onChange(removeIndex(items, i)) }\n : {})}\n />\n )}\n </div>\n ))}\n {!readOnly && canAddItem(field, items.length) && (\n <Button\n type=\"button\"\n variant=\"outline\"\n className={cn(\"gap-1.5\", inputSizeClass[ctx.size])}\n onClick={() => field.onChange([...items, seedFromSchema(itemSchema)])}\n >\n <Icon icon={UiAdd} className=\"text-sm\" />\n Add item\n </Button>\n )}\n </div>\n );\n}\n\n// The choices an array of enum items offers, deduped by value. Prefers the\n// resolved `options` (they carry the schema's labels, icons and tones) and falls\n// back to the raw item `enum` for a field a pre-extension built by hand.\nfunction enumItemOptions(field: FieldControl): FieldOption[] {\n const rawOptions =\n field.options ??\n (Array.isArray(field.itemSchema?.enum)\n ? field.itemSchema.enum.map((value) => ({\n value: String(value),\n label: String(value),\n }))\n : []);\n const seen = new Set<string>();\n return rawOptions.filter((option) => {\n if (seen.has(option.value)) return false;\n seen.add(option.value);\n return true;\n });\n}\n\nfunction FilterPillArray({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n const options = enumItemOptions(field);\n const validValues = new Set(options.map((option) => option.value));\n const explicitValues = toStringArray(field.value).filter((value) =>\n validValues.has(value),\n );\n const implicitAll = explicitValues.length === 0;\n const selected = new Set(\n implicitAll ? options.map((option) => option.value) : explicitValues,\n );\n\n function commit(nextSelected: Set<string>) {\n const next = options\n .map((option) => option.value)\n .filter((value) => nextSelected.has(value));\n field.onChange(next.length === options.length ? [] : next);\n }\n\n function toggle(value: string) {\n if (readOnly) return;\n const next = new Set(selected);\n if (next.has(value)) {\n next.delete(value);\n } else {\n next.add(value);\n }\n commit(next);\n }\n\n return (\n <div\n id={fieldId}\n data-jsf-input\n role=\"group\"\n aria-label={field.label}\n className={cn(\n \"flex flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1 shadow-sm\",\n controlMinHeightClass[size],\n )}\n >\n {options.map((option) => (\n <FilterPill\n key={option.value}\n label={option.label}\n mode={selected.has(option.value) ? \"active\" : \"neutral\"}\n title={\n implicitAll ? `${option.label} enabled by default` : option.label\n }\n {...(!readOnly ? { onClick: () => toggle(option.value) } : {})}\n className=\"max-w-full\"\n />\n ))}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const collections = require("../lib/collections.cjs");
4
+ function evaluatePredicate(sub, value) {
5
+ let decided = false;
6
+ let holds = true;
7
+ if ("const" in sub) {
8
+ decided = true;
9
+ if (value !== sub.const) holds = false;
10
+ }
11
+ if (sub.enum !== void 0) {
12
+ decided = true;
13
+ if (!sub.enum.some((option) => option === value)) holds = false;
14
+ }
15
+ if (sub.not !== void 0) {
16
+ const inner = evaluatePredicate(sub.not, value);
17
+ if (inner === void 0) return void 0;
18
+ decided = true;
19
+ if (inner) holds = false;
20
+ }
21
+ if (sub.properties !== void 0 || sub.required !== void 0) {
22
+ decided = true;
23
+ if (!collections.isPlainObject(value) || !matchesIf(sub, value)) {
24
+ holds = false;
25
+ }
26
+ }
27
+ return decided ? holds : void 0;
28
+ }
29
+ function matchesIf(ifSchema, value) {
30
+ if (!ifSchema) return false;
31
+ for (const k of ifSchema.required ?? []) {
32
+ if (!(k in value)) return false;
33
+ }
34
+ for (const [k, sub] of Object.entries(ifSchema.properties ?? {})) {
35
+ if (evaluatePredicate(sub, value[k]) !== true) return false;
36
+ }
37
+ return true;
38
+ }
39
+ function mergeBranch(branch, properties, required) {
40
+ if (!branch) return;
41
+ for (const [k, sub] of Object.entries(branch.properties ?? {})) {
42
+ properties[k] = sub;
43
+ }
44
+ for (const k of branch.required ?? []) required.add(k);
45
+ }
46
+ function effectiveProperties(schema, value) {
47
+ const properties = {
48
+ ...schema.properties
49
+ };
50
+ const required = new Set(schema.required ?? []);
51
+ for (const clause of schema.allOf ?? []) {
52
+ if (clause.if === void 0 && clause.then === void 0) {
53
+ mergeBranch(clause, properties, required);
54
+ continue;
55
+ }
56
+ mergeBranch(
57
+ matchesIf(clause.if, value) ? clause.then : clause.else,
58
+ properties,
59
+ required
60
+ );
61
+ }
62
+ return { properties, required: [...required] };
63
+ }
64
+ exports.effectiveProperties = effectiveProperties;
65
+ exports.evaluatePredicate = evaluatePredicate;
66
+ exports.matchesIf = matchesIf;
67
+ //# sourceMappingURL=json-schema-form-conditionals.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema-form-conditionals.cjs","sources":["../../src/components/json-schema-form-conditionals.ts"],"sourcesContent":["import { isPlainObject } from \"../lib/collections\";\nimport type { JsonSchemaObject, JsonSchemaProperty } from \"./json-schema-form-types\";\n\n// evaluatePredicate answers whether one `if.properties[k]` sub-schema holds for\n// the value at that key, or `undefined` when the sub-schema states nothing this\n// form knows how to check. The tri-state is what lets the caller fail closed:\n// \"cannot tell\" is never silently promoted to \"matches\".\n//\n// Recognised: `const`, `enum`, `not` (negating any of these), and a nested\n// `properties`/`required` object sub-schema, evaluated recursively against the\n// value at that key. Every recognised keyword present must hold.\n//\n// The value is read positionally — an absent key evaluates as `undefined`, so\n// `const` rejects it. State presence requirements in `if.required` rather than\n// relying on a predicate to imply them.\nexport function evaluatePredicate(\n sub: JsonSchemaProperty,\n value: unknown,\n): boolean | undefined {\n let decided = false;\n let holds = true;\n\n if (\"const\" in sub) {\n decided = true;\n if (value !== sub.const) holds = false;\n }\n if (sub.enum !== undefined) {\n decided = true;\n if (!sub.enum.some((option) => option === value)) holds = false;\n }\n if (sub.not !== undefined) {\n // A negation of something unevaluatable is itself unevaluatable.\n const inner = evaluatePredicate(sub.not, value);\n if (inner === undefined) return undefined;\n decided = true;\n if (inner) holds = false;\n }\n if (sub.properties !== undefined || sub.required !== undefined) {\n decided = true;\n if (!isPlainObject(value) || !matchesIf(sub, value as Record<string, unknown>)) {\n holds = false;\n }\n }\n\n return decided ? holds : undefined;\n}\n\n// matchesIf reports whether the `if` sub-schema holds for the current value:\n// every `if.required` key is present AND every `if.properties[k]` predicate\n// holds for `value[k]`.\n//\n// A predicate this form cannot evaluate (a bare `type`, a `pattern`, a numeric\n// bound) makes the whole `if` false, never true. Merging a `then` branch the\n// form could not verify would put fields in front of the user that the schema\n// never asked for, so an unreadable condition fails closed.\nexport function matchesIf(\n ifSchema: JsonSchemaProperty | undefined,\n value: Record<string, unknown>,\n): boolean {\n if (!ifSchema) return false;\n for (const k of ifSchema.required ?? []) {\n if (!(k in value)) return false;\n }\n for (const [k, sub] of Object.entries(ifSchema.properties ?? {})) {\n if (evaluatePredicate(sub, value[k]) !== true) return false;\n }\n return true;\n}\n\nexport interface EffectiveProperties {\n properties: Record<string, JsonSchemaProperty>;\n required: string[];\n}\n\nfunction mergeBranch(\n branch: Pick<JsonSchemaProperty, \"properties\" | \"required\"> | undefined,\n properties: Record<string, JsonSchemaProperty>,\n required: Set<string>,\n): void {\n if (!branch) return;\n for (const [k, sub] of Object.entries(branch.properties ?? {})) {\n properties[k] = sub;\n }\n for (const k of branch.required ?? []) required.add(k);\n}\n\n// effectiveProperties merges the schema's base `properties` with each `allOf`\n// member's contribution. An `if`/`then` member contributes `then.properties`\n// when its `if` matches the current value and `else.properties` when it does\n// not; an unconditional member (e.g. an inlined `$ref` composition, which\n// carries its own `properties` and no `if`) always contributes. Later members\n// win on key collision; required is the union. A branch REPLACES a property\n// wholesale rather than deep-merging it, so a branch that re-declares a field\n// also re-declares its keywords (`readOnly`, `x-hidden`, …). Pure and\n// idempotent.\nexport function effectiveProperties(\n schema: JsonSchemaObject,\n value: Record<string, unknown>,\n): EffectiveProperties {\n const properties: Record<string, JsonSchemaProperty> = {\n ...schema.properties,\n };\n const required = new Set(schema.required ?? []);\n for (const clause of schema.allOf ?? []) {\n // Unconditional composition member: merge its own properties/required.\n if (clause.if === undefined && clause.then === undefined) {\n mergeBranch(clause, properties, required);\n continue;\n }\n mergeBranch(\n matchesIf(clause.if, value) ? clause.then : clause.else,\n properties,\n required,\n );\n }\n return { properties, required: [...required] };\n}\n"],"names":["isPlainObject"],"mappings":";;;AAeO,SAAS,kBACd,KACA,OACqB;AACrB,MAAI,UAAU;AACd,MAAI,QAAQ;AAEZ,MAAI,WAAW,KAAK;AAClB,cAAU;AACV,QAAI,UAAU,IAAI,MAAO,SAAQ;AAAA,EACnC;AACA,MAAI,IAAI,SAAS,QAAW;AAC1B,cAAU;AACV,QAAI,CAAC,IAAI,KAAK,KAAK,CAAC,WAAW,WAAW,KAAK,EAAG,SAAQ;AAAA,EAC5D;AACA,MAAI,IAAI,QAAQ,QAAW;AAEzB,UAAM,QAAQ,kBAAkB,IAAI,KAAK,KAAK;AAC9C,QAAI,UAAU,OAAW,QAAO;AAChC,cAAU;AACV,QAAI,MAAO,SAAQ;AAAA,EACrB;AACA,MAAI,IAAI,eAAe,UAAa,IAAI,aAAa,QAAW;AAC9D,cAAU;AACV,QAAI,CAACA,YAAAA,cAAc,KAAK,KAAK,CAAC,UAAU,KAAK,KAAgC,GAAG;AAC9E,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO,UAAU,QAAQ;AAC3B;AAUO,SAAS,UACd,UACA,OACS;AACT,MAAI,CAAC,SAAU,QAAO;AACtB,aAAW,KAAK,SAAS,YAAY,CAAA,GAAI;AACvC,QAAI,EAAE,KAAK,OAAQ,QAAO;AAAA,EAC5B;AACA,aAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,SAAS,cAAc,CAAA,CAAE,GAAG;AAChE,QAAI,kBAAkB,KAAK,MAAM,CAAC,CAAC,MAAM,KAAM,QAAO;AAAA,EACxD;AACA,SAAO;AACT;AAOA,SAAS,YACP,QACA,YACA,UACM;AACN,MAAI,CAAC,OAAQ;AACb,aAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,OAAO,cAAc,CAAA,CAAE,GAAG;AAC9D,eAAW,CAAC,IAAI;AAAA,EAClB;AACA,aAAW,KAAK,OAAO,YAAY,CAAA,EAAI,UAAS,IAAI,CAAC;AACvD;AAWO,SAAS,oBACd,QACA,OACqB;AACrB,QAAM,aAAiD;AAAA,IACrD,GAAG,OAAO;AAAA,EAAA;AAEZ,QAAM,WAAW,IAAI,IAAI,OAAO,YAAY,CAAA,CAAE;AAC9C,aAAW,UAAU,OAAO,SAAS,CAAA,GAAI;AAEvC,QAAI,OAAO,OAAO,UAAa,OAAO,SAAS,QAAW;AACxD,kBAAY,QAAQ,YAAY,QAAQ;AACxC;AAAA,IACF;AACA;AAAA,MACE,UAAU,OAAO,IAAI,KAAK,IAAI,OAAO,OAAO,OAAO;AAAA,MACnD;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AACA,SAAO,EAAE,YAAY,UAAU,CAAC,GAAG,QAAQ,EAAA;AAC7C;;;;"}
@@ -0,0 +1,9 @@
1
+ import { JsonSchemaObject, JsonSchemaProperty } from './json-schema-form-types.js';
2
+ export declare function evaluatePredicate(sub: JsonSchemaProperty, value: unknown): boolean | undefined;
3
+ export declare function matchesIf(ifSchema: JsonSchemaProperty | undefined, value: Record<string, unknown>): boolean;
4
+ export interface EffectiveProperties {
5
+ properties: Record<string, JsonSchemaProperty>;
6
+ required: string[];
7
+ }
8
+ export declare function effectiveProperties(schema: JsonSchemaObject, value: Record<string, unknown>): EffectiveProperties;
9
+ //# sourceMappingURL=json-schema-form-conditionals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema-form-conditionals.d.ts","sourceRoot":"","sources":["../../src/components/json-schema-form-conditionals.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAcrF,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,kBAAkB,EACvB,KAAK,EAAE,OAAO,GACb,OAAO,GAAG,SAAS,CA2BrB;AAUD,wBAAgB,SAAS,CACvB,QAAQ,EAAE,kBAAkB,GAAG,SAAS,EACxC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAST;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC/C,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAuBD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,mBAAmB,CAkBrB"}
@@ -0,0 +1,67 @@
1
+ import { isPlainObject } from "../lib/collections.js";
2
+ function evaluatePredicate(sub, value) {
3
+ let decided = false;
4
+ let holds = true;
5
+ if ("const" in sub) {
6
+ decided = true;
7
+ if (value !== sub.const) holds = false;
8
+ }
9
+ if (sub.enum !== void 0) {
10
+ decided = true;
11
+ if (!sub.enum.some((option) => option === value)) holds = false;
12
+ }
13
+ if (sub.not !== void 0) {
14
+ const inner = evaluatePredicate(sub.not, value);
15
+ if (inner === void 0) return void 0;
16
+ decided = true;
17
+ if (inner) holds = false;
18
+ }
19
+ if (sub.properties !== void 0 || sub.required !== void 0) {
20
+ decided = true;
21
+ if (!isPlainObject(value) || !matchesIf(sub, value)) {
22
+ holds = false;
23
+ }
24
+ }
25
+ return decided ? holds : void 0;
26
+ }
27
+ function matchesIf(ifSchema, value) {
28
+ if (!ifSchema) return false;
29
+ for (const k of ifSchema.required ?? []) {
30
+ if (!(k in value)) return false;
31
+ }
32
+ for (const [k, sub] of Object.entries(ifSchema.properties ?? {})) {
33
+ if (evaluatePredicate(sub, value[k]) !== true) return false;
34
+ }
35
+ return true;
36
+ }
37
+ function mergeBranch(branch, properties, required) {
38
+ if (!branch) return;
39
+ for (const [k, sub] of Object.entries(branch.properties ?? {})) {
40
+ properties[k] = sub;
41
+ }
42
+ for (const k of branch.required ?? []) required.add(k);
43
+ }
44
+ function effectiveProperties(schema, value) {
45
+ const properties = {
46
+ ...schema.properties
47
+ };
48
+ const required = new Set(schema.required ?? []);
49
+ for (const clause of schema.allOf ?? []) {
50
+ if (clause.if === void 0 && clause.then === void 0) {
51
+ mergeBranch(clause, properties, required);
52
+ continue;
53
+ }
54
+ mergeBranch(
55
+ matchesIf(clause.if, value) ? clause.then : clause.else,
56
+ properties,
57
+ required
58
+ );
59
+ }
60
+ return { properties, required: [...required] };
61
+ }
62
+ export {
63
+ effectiveProperties,
64
+ evaluatePredicate,
65
+ matchesIf
66
+ };
67
+ //# sourceMappingURL=json-schema-form-conditionals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema-form-conditionals.js","sources":["../../src/components/json-schema-form-conditionals.ts"],"sourcesContent":["import { isPlainObject } from \"../lib/collections\";\nimport type { JsonSchemaObject, JsonSchemaProperty } from \"./json-schema-form-types\";\n\n// evaluatePredicate answers whether one `if.properties[k]` sub-schema holds for\n// the value at that key, or `undefined` when the sub-schema states nothing this\n// form knows how to check. The tri-state is what lets the caller fail closed:\n// \"cannot tell\" is never silently promoted to \"matches\".\n//\n// Recognised: `const`, `enum`, `not` (negating any of these), and a nested\n// `properties`/`required` object sub-schema, evaluated recursively against the\n// value at that key. Every recognised keyword present must hold.\n//\n// The value is read positionally — an absent key evaluates as `undefined`, so\n// `const` rejects it. State presence requirements in `if.required` rather than\n// relying on a predicate to imply them.\nexport function evaluatePredicate(\n sub: JsonSchemaProperty,\n value: unknown,\n): boolean | undefined {\n let decided = false;\n let holds = true;\n\n if (\"const\" in sub) {\n decided = true;\n if (value !== sub.const) holds = false;\n }\n if (sub.enum !== undefined) {\n decided = true;\n if (!sub.enum.some((option) => option === value)) holds = false;\n }\n if (sub.not !== undefined) {\n // A negation of something unevaluatable is itself unevaluatable.\n const inner = evaluatePredicate(sub.not, value);\n if (inner === undefined) return undefined;\n decided = true;\n if (inner) holds = false;\n }\n if (sub.properties !== undefined || sub.required !== undefined) {\n decided = true;\n if (!isPlainObject(value) || !matchesIf(sub, value as Record<string, unknown>)) {\n holds = false;\n }\n }\n\n return decided ? holds : undefined;\n}\n\n// matchesIf reports whether the `if` sub-schema holds for the current value:\n// every `if.required` key is present AND every `if.properties[k]` predicate\n// holds for `value[k]`.\n//\n// A predicate this form cannot evaluate (a bare `type`, a `pattern`, a numeric\n// bound) makes the whole `if` false, never true. Merging a `then` branch the\n// form could not verify would put fields in front of the user that the schema\n// never asked for, so an unreadable condition fails closed.\nexport function matchesIf(\n ifSchema: JsonSchemaProperty | undefined,\n value: Record<string, unknown>,\n): boolean {\n if (!ifSchema) return false;\n for (const k of ifSchema.required ?? []) {\n if (!(k in value)) return false;\n }\n for (const [k, sub] of Object.entries(ifSchema.properties ?? {})) {\n if (evaluatePredicate(sub, value[k]) !== true) return false;\n }\n return true;\n}\n\nexport interface EffectiveProperties {\n properties: Record<string, JsonSchemaProperty>;\n required: string[];\n}\n\nfunction mergeBranch(\n branch: Pick<JsonSchemaProperty, \"properties\" | \"required\"> | undefined,\n properties: Record<string, JsonSchemaProperty>,\n required: Set<string>,\n): void {\n if (!branch) return;\n for (const [k, sub] of Object.entries(branch.properties ?? {})) {\n properties[k] = sub;\n }\n for (const k of branch.required ?? []) required.add(k);\n}\n\n// effectiveProperties merges the schema's base `properties` with each `allOf`\n// member's contribution. An `if`/`then` member contributes `then.properties`\n// when its `if` matches the current value and `else.properties` when it does\n// not; an unconditional member (e.g. an inlined `$ref` composition, which\n// carries its own `properties` and no `if`) always contributes. Later members\n// win on key collision; required is the union. A branch REPLACES a property\n// wholesale rather than deep-merging it, so a branch that re-declares a field\n// also re-declares its keywords (`readOnly`, `x-hidden`, …). Pure and\n// idempotent.\nexport function effectiveProperties(\n schema: JsonSchemaObject,\n value: Record<string, unknown>,\n): EffectiveProperties {\n const properties: Record<string, JsonSchemaProperty> = {\n ...schema.properties,\n };\n const required = new Set(schema.required ?? []);\n for (const clause of schema.allOf ?? []) {\n // Unconditional composition member: merge its own properties/required.\n if (clause.if === undefined && clause.then === undefined) {\n mergeBranch(clause, properties, required);\n continue;\n }\n mergeBranch(\n matchesIf(clause.if, value) ? clause.then : clause.else,\n properties,\n required,\n );\n }\n return { properties, required: [...required] };\n}\n"],"names":[],"mappings":";AAeO,SAAS,kBACd,KACA,OACqB;AACrB,MAAI,UAAU;AACd,MAAI,QAAQ;AAEZ,MAAI,WAAW,KAAK;AAClB,cAAU;AACV,QAAI,UAAU,IAAI,MAAO,SAAQ;AAAA,EACnC;AACA,MAAI,IAAI,SAAS,QAAW;AAC1B,cAAU;AACV,QAAI,CAAC,IAAI,KAAK,KAAK,CAAC,WAAW,WAAW,KAAK,EAAG,SAAQ;AAAA,EAC5D;AACA,MAAI,IAAI,QAAQ,QAAW;AAEzB,UAAM,QAAQ,kBAAkB,IAAI,KAAK,KAAK;AAC9C,QAAI,UAAU,OAAW,QAAO;AAChC,cAAU;AACV,QAAI,MAAO,SAAQ;AAAA,EACrB;AACA,MAAI,IAAI,eAAe,UAAa,IAAI,aAAa,QAAW;AAC9D,cAAU;AACV,QAAI,CAAC,cAAc,KAAK,KAAK,CAAC,UAAU,KAAK,KAAgC,GAAG;AAC9E,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO,UAAU,QAAQ;AAC3B;AAUO,SAAS,UACd,UACA,OACS;AACT,MAAI,CAAC,SAAU,QAAO;AACtB,aAAW,KAAK,SAAS,YAAY,CAAA,GAAI;AACvC,QAAI,EAAE,KAAK,OAAQ,QAAO;AAAA,EAC5B;AACA,aAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,SAAS,cAAc,CAAA,CAAE,GAAG;AAChE,QAAI,kBAAkB,KAAK,MAAM,CAAC,CAAC,MAAM,KAAM,QAAO;AAAA,EACxD;AACA,SAAO;AACT;AAOA,SAAS,YACP,QACA,YACA,UACM;AACN,MAAI,CAAC,OAAQ;AACb,aAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,OAAO,cAAc,CAAA,CAAE,GAAG;AAC9D,eAAW,CAAC,IAAI;AAAA,EAClB;AACA,aAAW,KAAK,OAAO,YAAY,CAAA,EAAI,UAAS,IAAI,CAAC;AACvD;AAWO,SAAS,oBACd,QACA,OACqB;AACrB,QAAM,aAAiD;AAAA,IACrD,GAAG,OAAO;AAAA,EAAA;AAEZ,QAAM,WAAW,IAAI,IAAI,OAAO,YAAY,CAAA,CAAE;AAC9C,aAAW,UAAU,OAAO,SAAS,CAAA,GAAI;AAEvC,QAAI,OAAO,OAAO,UAAa,OAAO,SAAS,QAAW;AACxD,kBAAY,QAAQ,YAAY,QAAQ;AACxC;AAAA,IACF;AACA;AAAA,MACE,UAAU,OAAO,IAAI,KAAK,IAAI,OAAO,OAAO,OAAO;AAAA,MACnD;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AACA,SAAO,EAAE,YAAY,UAAU,CAAC,GAAG,QAAQ,EAAA;AAC7C;"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const collections = require("../lib/collections.cjs");
4
+ const jsonSchemaFormConditionals = require("./json-schema-form-conditionals.cjs");
5
+ const jsonSchemaFormResolve = require("./json-schema-form-resolve.cjs");
6
+ function applySchemaDefaults(schema, value) {
7
+ return applyObjectDefaults(schema, value, /* @__PURE__ */ new Set());
8
+ }
9
+ function applyObjectDefaults(schema, value, ancestors) {
10
+ var _a;
11
+ if (ancestors.has(schema)) return value;
12
+ const nextAncestors = new Set(ancestors).add(schema);
13
+ let next = value;
14
+ const maxPasses = Math.min(
15
+ 100,
16
+ Object.keys(schema.properties ?? {}).length + (((_a = schema.allOf) == null ? void 0 : _a.length) ?? 0) + 2
17
+ );
18
+ for (let pass = 0; pass < maxPasses; pass += 1) {
19
+ const { properties } = jsonSchemaFormConditionals.effectiveProperties(schema, next);
20
+ let passChanged = false;
21
+ let passValue = next;
22
+ for (const [key, propertySchema] of Object.entries(properties)) {
23
+ const existing = passValue[key];
24
+ let fieldValue = existing;
25
+ let fieldChanged = false;
26
+ if (existing === void 0 && propertySchema.default !== void 0) {
27
+ fieldValue = cloneSchemaDefault(propertySchema.default);
28
+ fieldChanged = true;
29
+ }
30
+ const structuredObject = jsonSchemaFormResolve.schemaRendersAsObject(propertySchema);
31
+ if (structuredObject && !jsonSchemaFormResolve.isOpenStringMap(propertySchema)) {
32
+ const objectValue = collections.isPlainObject(fieldValue) ? fieldValue : {};
33
+ const defaultedObject = applyObjectDefaults(
34
+ propertySchema,
35
+ objectValue,
36
+ nextAncestors
37
+ );
38
+ if (defaultedObject !== objectValue) {
39
+ fieldValue = defaultedObject;
40
+ fieldChanged = true;
41
+ }
42
+ }
43
+ if (fieldChanged) {
44
+ if (!passChanged) passValue = { ...next };
45
+ passValue[key] = fieldValue;
46
+ passChanged = true;
47
+ }
48
+ }
49
+ if (!passChanged) break;
50
+ next = passValue;
51
+ }
52
+ return next;
53
+ }
54
+ function cloneSchemaDefault(value) {
55
+ if (Array.isArray(value)) return value.map(cloneSchemaDefault);
56
+ if (collections.isPlainObject(value)) {
57
+ return Object.fromEntries(
58
+ Object.entries(value).map(([key, entry]) => [
59
+ key,
60
+ cloneSchemaDefault(entry)
61
+ ])
62
+ );
63
+ }
64
+ return value;
65
+ }
66
+ exports.applySchemaDefaults = applySchemaDefaults;
67
+ exports.cloneSchemaDefault = cloneSchemaDefault;
68
+ //# sourceMappingURL=json-schema-form-defaults.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema-form-defaults.cjs","sources":["../../src/components/json-schema-form-defaults.ts"],"sourcesContent":["import { isPlainObject } from \"../lib/collections\";\nimport type { JsonSchemaObject } from \"./json-schema-form-types\";\nimport { effectiveProperties } from \"./json-schema-form-conditionals\";\nimport { isOpenStringMap, schemaRendersAsObject } from \"./json-schema-form-resolve\";\n\n// applySchemaDefaults fills missing values from JSON Schema `default` keywords.\n// It walks fixed object properties recursively and re-evaluates `if`/`then`\n// branches after each pass, so a defaulted discriminator can activate defaults\n// in its selected branch. Existing values, including null and empty strings, are\n// never replaced. The original value is returned when no defaults apply.\nexport function applySchemaDefaults(\n schema: JsonSchemaObject,\n value: Record<string, unknown>,\n): Record<string, unknown> {\n return applyObjectDefaults(schema, value, new Set());\n}\n\nfunction applyObjectDefaults(\n schema: JsonSchemaObject,\n value: Record<string, unknown>,\n ancestors: Set<JsonSchemaObject>,\n): Record<string, unknown> {\n // Recursive schemas may point back to an ancestor after refs are hydrated.\n if (ancestors.has(schema)) return value;\n const nextAncestors = new Set(ancestors).add(schema);\n let next = value;\n\n // A default can select another conditional branch, so allow enough passes for\n // a chain of discriminator defaults while keeping malformed schemas bounded.\n const maxPasses = Math.min(\n 100,\n Object.keys(schema.properties ?? {}).length +\n (schema.allOf?.length ?? 0) +\n 2,\n );\n for (let pass = 0; pass < maxPasses; pass += 1) {\n const { properties } = effectiveProperties(schema, next);\n let passChanged = false;\n let passValue = next;\n\n for (const [key, propertySchema] of Object.entries(properties)) {\n const existing = passValue[key];\n let fieldValue = existing;\n let fieldChanged = false;\n\n if (existing === undefined && propertySchema.default !== undefined) {\n fieldValue = cloneSchemaDefault(propertySchema.default);\n fieldChanged = true;\n }\n\n const structuredObject = schemaRendersAsObject(propertySchema);\n if (structuredObject && !isOpenStringMap(propertySchema)) {\n const objectValue = isPlainObject(fieldValue)\n ? (fieldValue as Record<string, unknown>)\n : {};\n const defaultedObject = applyObjectDefaults(\n propertySchema as JsonSchemaObject,\n objectValue,\n nextAncestors,\n );\n if (defaultedObject !== objectValue) {\n fieldValue = defaultedObject;\n fieldChanged = true;\n }\n }\n\n if (fieldChanged) {\n if (!passChanged) passValue = { ...next };\n passValue[key] = fieldValue;\n passChanged = true;\n }\n }\n\n if (!passChanged) break;\n next = passValue;\n }\n return next;\n}\n\nexport function cloneSchemaDefault(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(cloneSchemaDefault);\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, entry]) => [\n key,\n cloneSchemaDefault(entry),\n ]),\n );\n }\n return value;\n}\n"],"names":["effectiveProperties","schemaRendersAsObject","isOpenStringMap","isPlainObject"],"mappings":";;;;;AAUO,SAAS,oBACd,QACA,OACyB;AACzB,SAAO,oBAAoB,QAAQ,OAAO,oBAAI,KAAK;AACrD;AAEA,SAAS,oBACP,QACA,OACA,WACyB;;AAEzB,MAAI,UAAU,IAAI,MAAM,EAAG,QAAO;AAClC,QAAM,gBAAgB,IAAI,IAAI,SAAS,EAAE,IAAI,MAAM;AACnD,MAAI,OAAO;AAIX,QAAM,YAAY,KAAK;AAAA,IACrB;AAAA,IACA,OAAO,KAAK,OAAO,cAAc,CAAA,CAAE,EAAE,YAClC,YAAO,UAAP,mBAAc,WAAU,KACzB;AAAA,EAAA;AAEJ,WAAS,OAAO,GAAG,OAAO,WAAW,QAAQ,GAAG;AAC9C,UAAM,EAAE,WAAA,IAAeA,+CAAoB,QAAQ,IAAI;AACvD,QAAI,cAAc;AAClB,QAAI,YAAY;AAEhB,eAAW,CAAC,KAAK,cAAc,KAAK,OAAO,QAAQ,UAAU,GAAG;AAC9D,YAAM,WAAW,UAAU,GAAG;AAC9B,UAAI,aAAa;AACjB,UAAI,eAAe;AAEnB,UAAI,aAAa,UAAa,eAAe,YAAY,QAAW;AAClE,qBAAa,mBAAmB,eAAe,OAAO;AACtD,uBAAe;AAAA,MACjB;AAEA,YAAM,mBAAmBC,sBAAAA,sBAAsB,cAAc;AAC7D,UAAI,oBAAoB,CAACC,sCAAgB,cAAc,GAAG;AACxD,cAAM,cAAcC,YAAAA,cAAc,UAAU,IACvC,aACD,CAAA;AACJ,cAAM,kBAAkB;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAEF,YAAI,oBAAoB,aAAa;AACnC,uBAAa;AACb,yBAAe;AAAA,QACjB;AAAA,MACF;AAEA,UAAI,cAAc;AAChB,YAAI,CAAC,YAAa,aAAY,EAAE,GAAG,KAAA;AACnC,kBAAU,GAAG,IAAI;AACjB,sBAAc;AAAA,MAChB;AAAA,IACF;AAEA,QAAI,CAAC,YAAa;AAClB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,mBAAmB,OAAyB;AAC1D,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,kBAAkB;AAC7D,MAAIA,YAAAA,cAAc,KAAK,GAAG;AACxB,WAAO,OAAO;AAAA,MACZ,OAAO,QAAQ,KAAgC,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AAAA,QACrE;AAAA,QACA,mBAAmB,KAAK;AAAA,MAAA,CACzB;AAAA,IAAA;AAAA,EAEL;AACA,SAAO;AACT;;;"}
@@ -0,0 +1,4 @@
1
+ import { JsonSchemaObject } from './json-schema-form-types.js';
2
+ export declare function applySchemaDefaults(schema: JsonSchemaObject, value: Record<string, unknown>): Record<string, unknown>;
3
+ export declare function cloneSchemaDefault(value: unknown): unknown;
4
+ //# sourceMappingURL=json-schema-form-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema-form-defaults.d.ts","sourceRoot":"","sources":["../../src/components/json-schema-form-defaults.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AASjE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAgED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAW1D"}