@rjsf/core 6.0.0-alpha.0 → 6.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/dist/core.umd.js +1664 -799
  2. package/dist/index.esm.js +2158 -1203
  3. package/dist/index.esm.js.map +4 -4
  4. package/dist/index.js +2208 -1296
  5. package/dist/index.js.map +4 -4
  6. package/lib/components/Form.d.ts +22 -9
  7. package/lib/components/Form.d.ts.map +1 -0
  8. package/lib/components/Form.js +368 -312
  9. package/lib/components/fields/ArrayField.d.ts +20 -9
  10. package/lib/components/fields/ArrayField.d.ts.map +1 -0
  11. package/lib/components/fields/ArrayField.js +212 -206
  12. package/lib/components/fields/BooleanField.d.ts +1 -0
  13. package/lib/components/fields/BooleanField.d.ts.map +1 -0
  14. package/lib/components/fields/BooleanField.js +6 -14
  15. package/lib/components/fields/LayoutGridField.d.ts +480 -0
  16. package/lib/components/fields/LayoutGridField.d.ts.map +1 -0
  17. package/lib/components/fields/LayoutGridField.js +711 -0
  18. package/lib/components/fields/LayoutHeaderField.d.ts +12 -0
  19. package/lib/components/fields/LayoutHeaderField.d.ts.map +1 -0
  20. package/lib/components/fields/LayoutHeaderField.js +23 -0
  21. package/lib/components/fields/LayoutMultiSchemaField.d.ts +28 -0
  22. package/lib/components/fields/LayoutMultiSchemaField.d.ts.map +1 -0
  23. package/lib/components/fields/LayoutMultiSchemaField.js +114 -0
  24. package/lib/components/fields/MultiSchemaField.d.ts +1 -0
  25. package/lib/components/fields/MultiSchemaField.d.ts.map +1 -0
  26. package/lib/components/fields/MultiSchemaField.js +31 -31
  27. package/lib/components/fields/NullField.d.ts +1 -0
  28. package/lib/components/fields/NullField.d.ts.map +1 -0
  29. package/lib/components/fields/NullField.js +0 -1
  30. package/lib/components/fields/NumberField.d.ts +1 -0
  31. package/lib/components/fields/NumberField.d.ts.map +1 -0
  32. package/lib/components/fields/NumberField.js +2 -3
  33. package/lib/components/fields/ObjectField.d.ts +1 -0
  34. package/lib/components/fields/ObjectField.d.ts.map +1 -0
  35. package/lib/components/fields/ObjectField.js +146 -141
  36. package/lib/components/fields/SchemaField.d.ts +1 -0
  37. package/lib/components/fields/SchemaField.d.ts.map +1 -0
  38. package/lib/components/fields/SchemaField.js +9 -17
  39. package/lib/components/fields/StringField.d.ts +1 -0
  40. package/lib/components/fields/StringField.d.ts.map +1 -0
  41. package/lib/components/fields/StringField.js +1 -3
  42. package/lib/components/fields/index.d.ts +1 -0
  43. package/lib/components/fields/index.d.ts.map +1 -0
  44. package/lib/components/fields/index.js +14 -9
  45. package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts +1 -0
  46. package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts.map +1 -0
  47. package/lib/components/templates/ArrayFieldDescriptionTemplate.js +0 -1
  48. package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts +8 -0
  49. package/lib/components/templates/ArrayFieldItemButtonsTemplate.d.ts.map +1 -0
  50. package/lib/components/templates/ArrayFieldItemButtonsTemplate.js +17 -0
  51. package/lib/components/templates/ArrayFieldItemTemplate.d.ts +4 -3
  52. package/lib/components/templates/ArrayFieldItemTemplate.d.ts.map +1 -0
  53. package/lib/components/templates/ArrayFieldItemTemplate.js +7 -6
  54. package/lib/components/templates/ArrayFieldTemplate.d.ts +2 -1
  55. package/lib/components/templates/ArrayFieldTemplate.d.ts.map +1 -0
  56. package/lib/components/templates/ArrayFieldTemplate.js +3 -4
  57. package/lib/components/templates/ArrayFieldTitleTemplate.d.ts +1 -0
  58. package/lib/components/templates/ArrayFieldTitleTemplate.d.ts.map +1 -0
  59. package/lib/components/templates/ArrayFieldTitleTemplate.js +0 -1
  60. package/lib/components/templates/BaseInputTemplate.d.ts +1 -0
  61. package/lib/components/templates/BaseInputTemplate.d.ts.map +1 -0
  62. package/lib/components/templates/BaseInputTemplate.js +0 -1
  63. package/lib/components/templates/ButtonTemplates/AddButton.d.ts +1 -0
  64. package/lib/components/templates/ButtonTemplates/AddButton.d.ts.map +1 -0
  65. package/lib/components/templates/ButtonTemplates/AddButton.js +1 -2
  66. package/lib/components/templates/ButtonTemplates/IconButton.d.ts +1 -0
  67. package/lib/components/templates/ButtonTemplates/IconButton.d.ts.map +1 -0
  68. package/lib/components/templates/ButtonTemplates/IconButton.js +4 -5
  69. package/lib/components/templates/ButtonTemplates/SubmitButton.d.ts +1 -0
  70. package/lib/components/templates/ButtonTemplates/SubmitButton.d.ts.map +1 -0
  71. package/lib/components/templates/ButtonTemplates/SubmitButton.js +0 -1
  72. package/lib/components/templates/ButtonTemplates/index.d.ts +1 -0
  73. package/lib/components/templates/ButtonTemplates/index.d.ts.map +1 -0
  74. package/lib/components/templates/ButtonTemplates/index.js +3 -4
  75. package/lib/components/templates/DescriptionField.d.ts +1 -0
  76. package/lib/components/templates/DescriptionField.d.ts.map +1 -0
  77. package/lib/components/templates/DescriptionField.js +0 -1
  78. package/lib/components/templates/ErrorList.d.ts +1 -0
  79. package/lib/components/templates/ErrorList.d.ts.map +1 -0
  80. package/lib/components/templates/ErrorList.js +0 -1
  81. package/lib/components/templates/FieldErrorTemplate.d.ts +1 -0
  82. package/lib/components/templates/FieldErrorTemplate.d.ts.map +1 -0
  83. package/lib/components/templates/FieldErrorTemplate.js +0 -1
  84. package/lib/components/templates/FieldHelpTemplate.d.ts +1 -0
  85. package/lib/components/templates/FieldHelpTemplate.d.ts.map +1 -0
  86. package/lib/components/templates/FieldHelpTemplate.js +0 -1
  87. package/lib/components/templates/FieldTemplate/FieldTemplate.d.ts +1 -0
  88. package/lib/components/templates/FieldTemplate/FieldTemplate.d.ts.map +1 -0
  89. package/lib/components/templates/FieldTemplate/FieldTemplate.js +1 -2
  90. package/lib/components/templates/FieldTemplate/Label.d.ts +1 -0
  91. package/lib/components/templates/FieldTemplate/Label.d.ts.map +1 -0
  92. package/lib/components/templates/FieldTemplate/Label.js +0 -1
  93. package/lib/components/templates/FieldTemplate/index.d.ts +2 -1
  94. package/lib/components/templates/FieldTemplate/index.d.ts.map +1 -0
  95. package/lib/components/templates/FieldTemplate/index.js +1 -2
  96. package/lib/components/templates/GridTemplate.d.ts +8 -0
  97. package/lib/components/templates/GridTemplate.d.ts.map +1 -0
  98. package/lib/components/templates/GridTemplate.js +10 -0
  99. package/lib/components/templates/ObjectFieldTemplate.d.ts +1 -0
  100. package/lib/components/templates/ObjectFieldTemplate.d.ts.map +1 -0
  101. package/lib/components/templates/ObjectFieldTemplate.js +2 -3
  102. package/lib/components/templates/TitleField.d.ts +1 -0
  103. package/lib/components/templates/TitleField.d.ts.map +1 -0
  104. package/lib/components/templates/TitleField.js +0 -1
  105. package/lib/components/templates/UnsupportedField.d.ts +1 -0
  106. package/lib/components/templates/UnsupportedField.d.ts.map +1 -0
  107. package/lib/components/templates/UnsupportedField.js +0 -1
  108. package/lib/components/templates/WrapIfAdditionalTemplate.d.ts +1 -0
  109. package/lib/components/templates/WrapIfAdditionalTemplate.d.ts.map +1 -0
  110. package/lib/components/templates/WrapIfAdditionalTemplate.js +10 -6
  111. package/lib/components/templates/index.d.ts +1 -0
  112. package/lib/components/templates/index.d.ts.map +1 -0
  113. package/lib/components/templates/index.js +19 -16
  114. package/lib/components/widgets/AltDateTimeWidget.d.ts +1 -0
  115. package/lib/components/widgets/AltDateTimeWidget.d.ts.map +1 -0
  116. package/lib/components/widgets/AltDateTimeWidget.js +0 -1
  117. package/lib/components/widgets/AltDateWidget.d.ts +1 -0
  118. package/lib/components/widgets/AltDateWidget.d.ts.map +1 -0
  119. package/lib/components/widgets/AltDateWidget.js +0 -1
  120. package/lib/components/widgets/CheckboxWidget.d.ts +1 -0
  121. package/lib/components/widgets/CheckboxWidget.d.ts.map +1 -0
  122. package/lib/components/widgets/CheckboxWidget.js +1 -3
  123. package/lib/components/widgets/CheckboxesWidget.d.ts +1 -0
  124. package/lib/components/widgets/CheckboxesWidget.d.ts.map +1 -0
  125. package/lib/components/widgets/CheckboxesWidget.js +0 -1
  126. package/lib/components/widgets/ColorWidget.d.ts +1 -0
  127. package/lib/components/widgets/ColorWidget.d.ts.map +1 -0
  128. package/lib/components/widgets/ColorWidget.js +0 -1
  129. package/lib/components/widgets/DateTimeWidget.d.ts +1 -0
  130. package/lib/components/widgets/DateTimeWidget.d.ts.map +1 -0
  131. package/lib/components/widgets/DateTimeWidget.js +0 -1
  132. package/lib/components/widgets/DateWidget.d.ts +1 -0
  133. package/lib/components/widgets/DateWidget.d.ts.map +1 -0
  134. package/lib/components/widgets/DateWidget.js +0 -1
  135. package/lib/components/widgets/EmailWidget.d.ts +1 -0
  136. package/lib/components/widgets/EmailWidget.d.ts.map +1 -0
  137. package/lib/components/widgets/EmailWidget.js +0 -1
  138. package/lib/components/widgets/FileWidget.d.ts +1 -0
  139. package/lib/components/widgets/FileWidget.d.ts.map +1 -0
  140. package/lib/components/widgets/FileWidget.js +3 -5
  141. package/lib/components/widgets/HiddenWidget.d.ts +1 -0
  142. package/lib/components/widgets/HiddenWidget.d.ts.map +1 -0
  143. package/lib/components/widgets/HiddenWidget.js +0 -1
  144. package/lib/components/widgets/PasswordWidget.d.ts +1 -0
  145. package/lib/components/widgets/PasswordWidget.d.ts.map +1 -0
  146. package/lib/components/widgets/PasswordWidget.js +0 -1
  147. package/lib/components/widgets/RadioWidget.d.ts +1 -0
  148. package/lib/components/widgets/RadioWidget.d.ts.map +1 -0
  149. package/lib/components/widgets/RadioWidget.js +3 -4
  150. package/lib/components/widgets/RangeWidget.d.ts +1 -0
  151. package/lib/components/widgets/RangeWidget.d.ts.map +1 -0
  152. package/lib/components/widgets/RangeWidget.js +0 -1
  153. package/lib/components/widgets/RatingWidget.d.ts +15 -0
  154. package/lib/components/widgets/RatingWidget.d.ts.map +1 -0
  155. package/lib/components/widgets/RatingWidget.js +63 -0
  156. package/lib/components/widgets/SelectWidget.d.ts +1 -0
  157. package/lib/components/widgets/SelectWidget.d.ts.map +1 -0
  158. package/lib/components/widgets/SelectWidget.js +4 -5
  159. package/lib/components/widgets/TextWidget.d.ts +1 -0
  160. package/lib/components/widgets/TextWidget.d.ts.map +1 -0
  161. package/lib/components/widgets/TextWidget.js +0 -1
  162. package/lib/components/widgets/TextareaWidget.d.ts +1 -0
  163. package/lib/components/widgets/TextareaWidget.d.ts.map +1 -0
  164. package/lib/components/widgets/TextareaWidget.js +0 -1
  165. package/lib/components/widgets/TimeWidget.d.ts +1 -0
  166. package/lib/components/widgets/TimeWidget.d.ts.map +1 -0
  167. package/lib/components/widgets/TimeWidget.js +0 -1
  168. package/lib/components/widgets/URLWidget.d.ts +1 -0
  169. package/lib/components/widgets/URLWidget.d.ts.map +1 -0
  170. package/lib/components/widgets/URLWidget.js +0 -1
  171. package/lib/components/widgets/UpDownWidget.d.ts +1 -0
  172. package/lib/components/widgets/UpDownWidget.d.ts.map +1 -0
  173. package/lib/components/widgets/UpDownWidget.js +0 -1
  174. package/lib/components/widgets/index.d.ts +1 -0
  175. package/lib/components/widgets/index.d.ts.map +1 -0
  176. package/lib/components/widgets/index.js +21 -20
  177. package/lib/getDefaultRegistry.d.ts +1 -0
  178. package/lib/getDefaultRegistry.d.ts.map +1 -0
  179. package/lib/getDefaultRegistry.js +3 -4
  180. package/lib/index.d.ts +4 -3
  181. package/lib/index.d.ts.map +1 -0
  182. package/lib/index.js +3 -4
  183. package/lib/tsconfig.tsbuildinfo +1 -1
  184. package/lib/withTheme.d.ts +2 -1
  185. package/lib/withTheme.d.ts.map +1 -0
  186. package/lib/withTheme.js +7 -8
  187. package/package.json +46 -37
  188. package/src/components/Form.tsx +127 -41
  189. package/src/components/fields/ArrayField.tsx +34 -24
  190. package/src/components/fields/BooleanField.tsx +6 -14
  191. package/src/components/fields/LayoutGridField.tsx +967 -0
  192. package/src/components/fields/LayoutHeaderField.tsx +49 -0
  193. package/src/components/fields/LayoutMultiSchemaField.tsx +228 -0
  194. package/src/components/fields/MultiSchemaField.tsx +9 -4
  195. package/src/components/fields/NullField.tsx +1 -1
  196. package/src/components/fields/NumberField.tsx +5 -5
  197. package/src/components/fields/ObjectField.tsx +32 -24
  198. package/src/components/fields/SchemaField.tsx +16 -22
  199. package/src/components/fields/StringField.tsx +2 -2
  200. package/src/components/fields/index.ts +7 -1
  201. package/src/components/templates/ArrayFieldDescriptionTemplate.tsx +2 -2
  202. package/src/components/templates/ArrayFieldItemButtonsTemplate.tsx +85 -0
  203. package/src/components/templates/ArrayFieldItemTemplate.tsx +18 -57
  204. package/src/components/templates/ArrayFieldTemplate.tsx +10 -8
  205. package/src/components/templates/ArrayFieldTitleTemplate.tsx +2 -2
  206. package/src/components/templates/BaseInputTemplate.tsx +4 -4
  207. package/src/components/templates/ButtonTemplates/IconButton.tsx +9 -36
  208. package/src/components/templates/ButtonTemplates/SubmitButton.tsx +1 -1
  209. package/src/components/templates/ButtonTemplates/index.ts +1 -1
  210. package/src/components/templates/DescriptionField.tsx +1 -1
  211. package/src/components/templates/FieldErrorTemplate.tsx +1 -1
  212. package/src/components/templates/FieldHelpTemplate.tsx +1 -1
  213. package/src/components/templates/FieldTemplate/FieldTemplate.tsx +2 -2
  214. package/src/components/templates/GridTemplate.tsx +15 -0
  215. package/src/components/templates/ObjectFieldTemplate.tsx +5 -3
  216. package/src/components/templates/TitleField.tsx +1 -1
  217. package/src/components/templates/UnsupportedField.tsx +1 -1
  218. package/src/components/templates/WrapIfAdditionalTemplate.tsx +14 -4
  219. package/src/components/templates/index.ts +4 -0
  220. package/src/components/widgets/AltDateWidget.tsx +9 -6
  221. package/src/components/widgets/CheckboxWidget.tsx +4 -4
  222. package/src/components/widgets/CheckboxesWidget.tsx +2 -2
  223. package/src/components/widgets/ColorWidget.tsx +1 -1
  224. package/src/components/widgets/DateTimeWidget.tsx +1 -1
  225. package/src/components/widgets/DateWidget.tsx +1 -1
  226. package/src/components/widgets/EmailWidget.tsx +1 -1
  227. package/src/components/widgets/FileWidget.tsx +5 -5
  228. package/src/components/widgets/PasswordWidget.tsx +1 -1
  229. package/src/components/widgets/RadioWidget.tsx +3 -3
  230. package/src/components/widgets/RangeWidget.tsx +1 -1
  231. package/src/components/widgets/RatingWidget.tsx +129 -0
  232. package/src/components/widgets/SelectWidget.tsx +4 -3
  233. package/src/components/widgets/TextWidget.tsx +1 -1
  234. package/src/components/widgets/TextareaWidget.tsx +3 -3
  235. package/src/components/widgets/TimeWidget.tsx +1 -1
  236. package/src/components/widgets/URLWidget.tsx +1 -1
  237. package/src/components/widgets/UpDownWidget.tsx +1 -1
  238. package/src/components/widgets/index.ts +3 -1
  239. package/src/getDefaultRegistry.ts +1 -1
  240. package/src/tsconfig.json +14 -6
  241. package/src/withTheme.tsx +4 -3
  242. package/LICENSE.md +0 -201
  243. package/lib/components/Form.js.map +0 -1
  244. package/lib/components/fields/ArrayField.js.map +0 -1
  245. package/lib/components/fields/BooleanField.js.map +0 -1
  246. package/lib/components/fields/MultiSchemaField.js.map +0 -1
  247. package/lib/components/fields/NullField.js.map +0 -1
  248. package/lib/components/fields/NumberField.js.map +0 -1
  249. package/lib/components/fields/ObjectField.js.map +0 -1
  250. package/lib/components/fields/SchemaField.js.map +0 -1
  251. package/lib/components/fields/StringField.js.map +0 -1
  252. package/lib/components/fields/index.js.map +0 -1
  253. package/lib/components/templates/ArrayFieldDescriptionTemplate.js.map +0 -1
  254. package/lib/components/templates/ArrayFieldItemTemplate.js.map +0 -1
  255. package/lib/components/templates/ArrayFieldTemplate.js.map +0 -1
  256. package/lib/components/templates/ArrayFieldTitleTemplate.js.map +0 -1
  257. package/lib/components/templates/BaseInputTemplate.js.map +0 -1
  258. package/lib/components/templates/ButtonTemplates/AddButton.js.map +0 -1
  259. package/lib/components/templates/ButtonTemplates/IconButton.js.map +0 -1
  260. package/lib/components/templates/ButtonTemplates/SubmitButton.js.map +0 -1
  261. package/lib/components/templates/ButtonTemplates/index.js.map +0 -1
  262. package/lib/components/templates/DescriptionField.js.map +0 -1
  263. package/lib/components/templates/ErrorList.js.map +0 -1
  264. package/lib/components/templates/FieldErrorTemplate.js.map +0 -1
  265. package/lib/components/templates/FieldHelpTemplate.js.map +0 -1
  266. package/lib/components/templates/FieldTemplate/FieldTemplate.js.map +0 -1
  267. package/lib/components/templates/FieldTemplate/Label.js.map +0 -1
  268. package/lib/components/templates/FieldTemplate/index.js.map +0 -1
  269. package/lib/components/templates/ObjectFieldTemplate.js.map +0 -1
  270. package/lib/components/templates/TitleField.js.map +0 -1
  271. package/lib/components/templates/UnsupportedField.js.map +0 -1
  272. package/lib/components/templates/WrapIfAdditionalTemplate.js.map +0 -1
  273. package/lib/components/templates/index.js.map +0 -1
  274. package/lib/components/widgets/AltDateTimeWidget.js.map +0 -1
  275. package/lib/components/widgets/AltDateWidget.js.map +0 -1
  276. package/lib/components/widgets/CheckboxWidget.js.map +0 -1
  277. package/lib/components/widgets/CheckboxesWidget.js.map +0 -1
  278. package/lib/components/widgets/ColorWidget.js.map +0 -1
  279. package/lib/components/widgets/DateTimeWidget.js.map +0 -1
  280. package/lib/components/widgets/DateWidget.js.map +0 -1
  281. package/lib/components/widgets/EmailWidget.js.map +0 -1
  282. package/lib/components/widgets/FileWidget.js.map +0 -1
  283. package/lib/components/widgets/HiddenWidget.js.map +0 -1
  284. package/lib/components/widgets/PasswordWidget.js.map +0 -1
  285. package/lib/components/widgets/RadioWidget.js.map +0 -1
  286. package/lib/components/widgets/RangeWidget.js.map +0 -1
  287. package/lib/components/widgets/SelectWidget.js.map +0 -1
  288. package/lib/components/widgets/TextWidget.js.map +0 -1
  289. package/lib/components/widgets/TextareaWidget.js.map +0 -1
  290. package/lib/components/widgets/TimeWidget.js.map +0 -1
  291. package/lib/components/widgets/URLWidget.js.map +0 -1
  292. package/lib/components/widgets/UpDownWidget.js.map +0 -1
  293. package/lib/components/widgets/index.js.map +0 -1
  294. package/lib/getDefaultRegistry.js.map +0 -1
  295. package/lib/index.js.map +0 -1
  296. package/lib/withTheme.js.map +0 -1
package/dist/core.umd.js CHANGED
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@rjsf/utils'), require('lodash/forEach'), require('lodash/get'), require('lodash/isEmpty'), require('lodash/pick'), require('lodash/toPath'), require('lodash/cloneDeep'), require('lodash/isObject'), require('lodash/set'), require('nanoid'), require('react/jsx-runtime'), require('lodash/omit'), require('markdown-to-jsx'), require('lodash/has'), require('lodash/unset')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'react', '@rjsf/utils', 'lodash/forEach', 'lodash/get', 'lodash/isEmpty', 'lodash/pick', 'lodash/toPath', 'lodash/cloneDeep', 'lodash/isObject', 'lodash/set', 'nanoid', 'react/jsx-runtime', 'lodash/omit', 'markdown-to-jsx', 'lodash/has', 'lodash/unset'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.JSONSchemaForm = {}, global.react, global.utils, global._forEach, global.get3, global.isEmpty, global._pick, global._toPath, global.cloneDeep, global.isObject, global.set, global.nanoid, global.jsxRuntime, global.omit2, global.Markdown, global.has, global.unset));
5
- })(this, (function (exports, react, utils, _forEach, get3, isEmpty, _pick, _toPath, cloneDeep, isObject, set, nanoid, jsxRuntime, omit2, Markdown, has, unset) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@rjsf/utils'), require('lodash/forEach'), require('lodash/get'), require('lodash/isEmpty'), require('lodash/isNil'), require('lodash/pick'), require('lodash/toPath'), require('lodash/cloneDeep'), require('lodash/isObject'), require('lodash/set'), require('nanoid'), require('react/jsx-runtime'), require('lodash/each'), require('lodash/flatten'), require('lodash/has'), require('lodash/includes'), require('lodash/intersection'), require('lodash/isFunction'), require('lodash/isEqual'), require('lodash/isPlainObject'), require('lodash/isString'), require('lodash/isUndefined'), require('lodash/noop'), require('lodash/omit'), require('markdown-to-jsx'), require('lodash/unset')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'react', '@rjsf/utils', 'lodash/forEach', 'lodash/get', 'lodash/isEmpty', 'lodash/isNil', 'lodash/pick', 'lodash/toPath', 'lodash/cloneDeep', 'lodash/isObject', 'lodash/set', 'nanoid', 'react/jsx-runtime', 'lodash/each', 'lodash/flatten', 'lodash/has', 'lodash/includes', 'lodash/intersection', 'lodash/isFunction', 'lodash/isEqual', 'lodash/isPlainObject', 'lodash/isString', 'lodash/isUndefined', 'lodash/noop', 'lodash/omit', 'markdown-to-jsx', 'lodash/unset'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.JSONSchemaForm = {}, global.react, global.utils, global._forEach, global.get2, global.isEmpty, global._isNil, global._pick, global._toPath, global.cloneDeep2, global.isObject, global.set, global.nanoid, global.jsxRuntime, global.each, global.flatten, global.has, global.includes, global.intersection, global.isFunction, global.isEqual, global.isPlainObject, global.isString, global.isUndefined, global.noop, global.omit3, global.Markdown, global.unset));
5
+ })(this, (function (exports, react, utils, _forEach, get2, isEmpty, _isNil, _pick, _toPath, cloneDeep2, isObject, set, nanoid, jsxRuntime, each, flatten, has, includes, intersection, isFunction, isEqual, isPlainObject, isString, isUndefined, noop, omit3, Markdown, unset) { 'use strict';
6
6
 
7
7
  // src/components/Form.tsx
8
8
  function generateRowId() {
@@ -29,189 +29,6 @@
29
29
  */
30
30
  constructor(props) {
31
31
  super(props);
32
- /** Returns the default form information for an item based on the schema for that item. Deals with the possibility
33
- * that the schema is fixed and allows additional items.
34
- */
35
- this._getNewFormDataRow = () => {
36
- const { schema, registry } = this.props;
37
- const { schemaUtils } = registry;
38
- let itemSchema = schema.items;
39
- if (utils.isFixedItems(schema) && utils.allowAdditionalItems(schema)) {
40
- itemSchema = schema.additionalItems;
41
- }
42
- return schemaUtils.getDefaultFormState(itemSchema);
43
- };
44
- /** Callback handler for when the user clicks on the add button. Creates a new row of keyed form data at the end of
45
- * the list, adding it into the state, and then returning `onChange()` with the plain form data converted from the
46
- * keyed data
47
- *
48
- * @param event - The event for the click
49
- */
50
- this.onAddClick = (event) => {
51
- this._handleAddClick(event);
52
- };
53
- /** Callback handler for when the user clicks on the add button on an existing array element. Creates a new row of
54
- * keyed form data inserted at the `index`, adding it into the state, and then returning `onChange()` with the plain
55
- * form data converted from the keyed data
56
- *
57
- * @param index - The index at which the add button is clicked
58
- */
59
- this.onAddIndexClick = (index) => {
60
- return (event) => {
61
- this._handleAddClick(event, index);
62
- };
63
- };
64
- /** Callback handler for when the user clicks on the copy button on an existing array element. Clones the row of
65
- * keyed form data at the `index` into the next position in the state, and then returning `onChange()` with the plain
66
- * form data converted from the keyed data
67
- *
68
- * @param index - The index at which the copy button is clicked
69
- */
70
- this.onCopyIndexClick = (index) => {
71
- return (event) => {
72
- if (event) {
73
- event.preventDefault();
74
- }
75
- const { onChange, errorSchema } = this.props;
76
- const { keyedFormData } = this.state;
77
- let newErrorSchema;
78
- if (errorSchema) {
79
- newErrorSchema = {};
80
- for (const idx in errorSchema) {
81
- const i = parseInt(idx);
82
- if (i <= index) {
83
- set(newErrorSchema, [i], errorSchema[idx]);
84
- } else if (i > index) {
85
- set(newErrorSchema, [i + 1], errorSchema[idx]);
86
- }
87
- }
88
- }
89
- const newKeyedFormDataRow = {
90
- key: generateRowId(),
91
- item: cloneDeep(keyedFormData[index].item)
92
- };
93
- const newKeyedFormData = [...keyedFormData];
94
- if (index !== void 0) {
95
- newKeyedFormData.splice(index + 1, 0, newKeyedFormDataRow);
96
- } else {
97
- newKeyedFormData.push(newKeyedFormDataRow);
98
- }
99
- this.setState(
100
- {
101
- keyedFormData: newKeyedFormData,
102
- updatedKeyedFormData: true
103
- },
104
- () => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
105
- );
106
- };
107
- };
108
- /** Callback handler for when the user clicks on the remove button on an existing array element. Removes the row of
109
- * keyed form data at the `index` in the state, and then returning `onChange()` with the plain form data converted
110
- * from the keyed data
111
- *
112
- * @param index - The index at which the remove button is clicked
113
- */
114
- this.onDropIndexClick = (index) => {
115
- return (event) => {
116
- if (event) {
117
- event.preventDefault();
118
- }
119
- const { onChange, errorSchema } = this.props;
120
- const { keyedFormData } = this.state;
121
- let newErrorSchema;
122
- if (errorSchema) {
123
- newErrorSchema = {};
124
- for (const idx in errorSchema) {
125
- const i = parseInt(idx);
126
- if (i < index) {
127
- set(newErrorSchema, [i], errorSchema[idx]);
128
- } else if (i > index) {
129
- set(newErrorSchema, [i - 1], errorSchema[idx]);
130
- }
131
- }
132
- }
133
- const newKeyedFormData = keyedFormData.filter((_, i) => i !== index);
134
- this.setState(
135
- {
136
- keyedFormData: newKeyedFormData,
137
- updatedKeyedFormData: true
138
- },
139
- () => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
140
- );
141
- };
142
- };
143
- /** Callback handler for when the user clicks on one of the move item buttons on an existing array element. Moves the
144
- * row of keyed form data at the `index` to the `newIndex` in the state, and then returning `onChange()` with the
145
- * plain form data converted from the keyed data
146
- *
147
- * @param index - The index of the item to move
148
- * @param newIndex - The index to where the item is to be moved
149
- */
150
- this.onReorderClick = (index, newIndex) => {
151
- return (event) => {
152
- if (event) {
153
- event.preventDefault();
154
- event.currentTarget.blur();
155
- }
156
- const { onChange, errorSchema } = this.props;
157
- let newErrorSchema;
158
- if (errorSchema) {
159
- newErrorSchema = {};
160
- for (const idx in errorSchema) {
161
- const i = parseInt(idx);
162
- if (i == index) {
163
- set(newErrorSchema, [newIndex], errorSchema[index]);
164
- } else if (i == newIndex) {
165
- set(newErrorSchema, [index], errorSchema[newIndex]);
166
- } else {
167
- set(newErrorSchema, [idx], errorSchema[i]);
168
- }
169
- }
170
- }
171
- const { keyedFormData } = this.state;
172
- function reOrderArray() {
173
- const _newKeyedFormData = keyedFormData.slice();
174
- _newKeyedFormData.splice(index, 1);
175
- _newKeyedFormData.splice(newIndex, 0, keyedFormData[index]);
176
- return _newKeyedFormData;
177
- }
178
- const newKeyedFormData = reOrderArray();
179
- this.setState(
180
- {
181
- keyedFormData: newKeyedFormData
182
- },
183
- () => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
184
- );
185
- };
186
- };
187
- /** Callback handler used to deal with changing the value of the data in the array at the `index`. Calls the
188
- * `onChange` callback with the updated form data
189
- *
190
- * @param index - The index of the item being changed
191
- */
192
- this.onChangeForIndex = (index) => {
193
- return (value, newErrorSchema, id) => {
194
- const { formData, onChange, errorSchema } = this.props;
195
- const arrayData = Array.isArray(formData) ? formData : [];
196
- const newFormData = arrayData.map((item, i) => {
197
- const jsonValue = typeof value === "undefined" ? null : value;
198
- return index === i ? jsonValue : item;
199
- });
200
- onChange(
201
- newFormData,
202
- errorSchema && errorSchema && {
203
- ...errorSchema,
204
- [index]: newErrorSchema
205
- },
206
- id
207
- );
208
- };
209
- };
210
- /** Callback handler used to change the value for a checkbox */
211
- this.onSelectChange = (value) => {
212
- const { onChange, idSchema } = this.props;
213
- onChange(value, void 0, idSchema && idSchema.$id);
214
- };
215
32
  const { formData = [] } = props;
216
33
  const keyedFormData = generateKeyedFormData(formData);
217
34
  this.state = {
@@ -249,10 +66,10 @@
249
66
  get itemTitle() {
250
67
  const { schema, registry } = this.props;
251
68
  const { translateString } = registry;
252
- return get3(
69
+ return get2(
253
70
  schema,
254
71
  [utils.ITEMS_KEY, "title"],
255
- get3(schema, [utils.ITEMS_KEY, "description"], translateString(utils.TranslatableString.ArrayItemTitle))
72
+ get2(schema, [utils.ITEMS_KEY, "description"], translateString(utils.TranslatableString.ArrayItemTitle))
256
73
  );
257
74
  }
258
75
  /** Determines whether the item described in the schema is always required, which is determined by whether any item
@@ -286,6 +103,18 @@
286
103
  }
287
104
  return addable;
288
105
  }
106
+ /** Returns the default form information for an item based on the schema for that item. Deals with the possibility
107
+ * that the schema is fixed and allows additional items.
108
+ */
109
+ _getNewFormDataRow = () => {
110
+ const { schema, registry } = this.props;
111
+ const { schemaUtils } = registry;
112
+ let itemSchema = schema.items;
113
+ if (utils.isFixedItems(schema) && utils.allowAdditionalItems(schema)) {
114
+ itemSchema = schema.additionalItems;
115
+ }
116
+ return schemaUtils.getDefaultFormState(itemSchema);
117
+ };
289
118
  /** Callback handler for when the user clicks on the add or add at index buttons. Creates a new row of keyed form data
290
119
  * either at the end of the list (when index is not specified) or inserted at the `index` when it is, adding it into
291
120
  * the state, and then returning `onChange()` with the plain form data converted from the keyed data
@@ -329,6 +158,177 @@
329
158
  () => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
330
159
  );
331
160
  }
161
+ /** Callback handler for when the user clicks on the add button. Creates a new row of keyed form data at the end of
162
+ * the list, adding it into the state, and then returning `onChange()` with the plain form data converted from the
163
+ * keyed data
164
+ *
165
+ * @param event - The event for the click
166
+ */
167
+ onAddClick = (event) => {
168
+ this._handleAddClick(event);
169
+ };
170
+ /** Callback handler for when the user clicks on the add button on an existing array element. Creates a new row of
171
+ * keyed form data inserted at the `index`, adding it into the state, and then returning `onChange()` with the plain
172
+ * form data converted from the keyed data
173
+ *
174
+ * @param index - The index at which the add button is clicked
175
+ */
176
+ onAddIndexClick = (index) => {
177
+ return (event) => {
178
+ this._handleAddClick(event, index);
179
+ };
180
+ };
181
+ /** Callback handler for when the user clicks on the copy button on an existing array element. Clones the row of
182
+ * keyed form data at the `index` into the next position in the state, and then returning `onChange()` with the plain
183
+ * form data converted from the keyed data
184
+ *
185
+ * @param index - The index at which the copy button is clicked
186
+ */
187
+ onCopyIndexClick = (index) => {
188
+ return (event) => {
189
+ if (event) {
190
+ event.preventDefault();
191
+ }
192
+ const { onChange, errorSchema } = this.props;
193
+ const { keyedFormData } = this.state;
194
+ let newErrorSchema;
195
+ if (errorSchema) {
196
+ newErrorSchema = {};
197
+ for (const idx in errorSchema) {
198
+ const i = parseInt(idx);
199
+ if (i <= index) {
200
+ set(newErrorSchema, [i], errorSchema[idx]);
201
+ } else if (i > index) {
202
+ set(newErrorSchema, [i + 1], errorSchema[idx]);
203
+ }
204
+ }
205
+ }
206
+ const newKeyedFormDataRow = {
207
+ key: generateRowId(),
208
+ item: cloneDeep2(keyedFormData[index].item)
209
+ };
210
+ const newKeyedFormData = [...keyedFormData];
211
+ if (index !== void 0) {
212
+ newKeyedFormData.splice(index + 1, 0, newKeyedFormDataRow);
213
+ } else {
214
+ newKeyedFormData.push(newKeyedFormDataRow);
215
+ }
216
+ this.setState(
217
+ {
218
+ keyedFormData: newKeyedFormData,
219
+ updatedKeyedFormData: true
220
+ },
221
+ () => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
222
+ );
223
+ };
224
+ };
225
+ /** Callback handler for when the user clicks on the remove button on an existing array element. Removes the row of
226
+ * keyed form data at the `index` in the state, and then returning `onChange()` with the plain form data converted
227
+ * from the keyed data
228
+ *
229
+ * @param index - The index at which the remove button is clicked
230
+ */
231
+ onDropIndexClick = (index) => {
232
+ return (event) => {
233
+ if (event) {
234
+ event.preventDefault();
235
+ }
236
+ const { onChange, errorSchema } = this.props;
237
+ const { keyedFormData } = this.state;
238
+ let newErrorSchema;
239
+ if (errorSchema) {
240
+ newErrorSchema = {};
241
+ for (const idx in errorSchema) {
242
+ const i = parseInt(idx);
243
+ if (i < index) {
244
+ set(newErrorSchema, [i], errorSchema[idx]);
245
+ } else if (i > index) {
246
+ set(newErrorSchema, [i - 1], errorSchema[idx]);
247
+ }
248
+ }
249
+ }
250
+ const newKeyedFormData = keyedFormData.filter((_, i) => i !== index);
251
+ this.setState(
252
+ {
253
+ keyedFormData: newKeyedFormData,
254
+ updatedKeyedFormData: true
255
+ },
256
+ () => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
257
+ );
258
+ };
259
+ };
260
+ /** Callback handler for when the user clicks on one of the move item buttons on an existing array element. Moves the
261
+ * row of keyed form data at the `index` to the `newIndex` in the state, and then returning `onChange()` with the
262
+ * plain form data converted from the keyed data
263
+ *
264
+ * @param index - The index of the item to move
265
+ * @param newIndex - The index to where the item is to be moved
266
+ */
267
+ onReorderClick = (index, newIndex) => {
268
+ return (event) => {
269
+ if (event) {
270
+ event.preventDefault();
271
+ event.currentTarget.blur();
272
+ }
273
+ const { onChange, errorSchema } = this.props;
274
+ let newErrorSchema;
275
+ if (errorSchema) {
276
+ newErrorSchema = {};
277
+ for (const idx in errorSchema) {
278
+ const i = parseInt(idx);
279
+ if (i == index) {
280
+ set(newErrorSchema, [newIndex], errorSchema[index]);
281
+ } else if (i == newIndex) {
282
+ set(newErrorSchema, [index], errorSchema[newIndex]);
283
+ } else {
284
+ set(newErrorSchema, [idx], errorSchema[i]);
285
+ }
286
+ }
287
+ }
288
+ const { keyedFormData } = this.state;
289
+ function reOrderArray() {
290
+ const _newKeyedFormData = keyedFormData.slice();
291
+ _newKeyedFormData.splice(index, 1);
292
+ _newKeyedFormData.splice(newIndex, 0, keyedFormData[index]);
293
+ return _newKeyedFormData;
294
+ }
295
+ const newKeyedFormData = reOrderArray();
296
+ this.setState(
297
+ {
298
+ keyedFormData: newKeyedFormData
299
+ },
300
+ () => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
301
+ );
302
+ };
303
+ };
304
+ /** Callback handler used to deal with changing the value of the data in the array at the `index`. Calls the
305
+ * `onChange` callback with the updated form data
306
+ *
307
+ * @param index - The index of the item being changed
308
+ */
309
+ onChangeForIndex = (index) => {
310
+ return (value, newErrorSchema, id) => {
311
+ const { formData, onChange, errorSchema } = this.props;
312
+ const arrayData = Array.isArray(formData) ? formData : [];
313
+ const newFormData = arrayData.map((item, i) => {
314
+ const jsonValue = typeof value === "undefined" ? null : value;
315
+ return index === i ? jsonValue : item;
316
+ });
317
+ onChange(
318
+ newFormData,
319
+ errorSchema && errorSchema && {
320
+ ...errorSchema,
321
+ [index]: newErrorSchema
322
+ },
323
+ id
324
+ );
325
+ };
326
+ };
327
+ /** Callback handler used to change the value for a checkbox */
328
+ onSelectChange = (value) => {
329
+ const { onChange, idSchema } = this.props;
330
+ onChange(value, void 0, idSchema && idSchema.$id);
331
+ };
332
332
  /** Renders the `ArrayField` depending on the specific needs of the schema and uischema elements
333
333
  */
334
334
  render() {
@@ -423,7 +423,7 @@
423
423
  totalItems: keyedFormData.length
424
424
  });
425
425
  }),
426
- className: `field field-array field-array-of-${itemsSchema.type}`,
426
+ className: `rjsf-field rjsf-field-array rjsf-field-array-of-${itemsSchema.type}`,
427
427
  disabled,
428
428
  idSchema,
429
429
  uiSchema,
@@ -631,7 +631,7 @@
631
631
  const canAdd = this.canAddItem(items) && !!additionalSchema;
632
632
  const arrayProps = {
633
633
  canAdd,
634
- className: "field field-array field-array-fixed-items",
634
+ className: "rjsf-field rjsf-field-array rjsf-field-array-fixed-items",
635
635
  disabled,
636
636
  idSchema,
637
637
  formData,
@@ -712,14 +712,14 @@
712
712
  } = registry;
713
713
  const ItemSchemaField = ArraySchemaField || SchemaField2;
714
714
  const { orderable = true, removable = true, copyable = false } = utils.getUiOptions(uiSchema, globalUiOptions);
715
- const has2 = {
715
+ const has4 = {
716
716
  moveUp: orderable && canMoveUp,
717
717
  moveDown: orderable && canMoveDown,
718
718
  copy: copyable && canAdd,
719
719
  remove: removable && canRemove,
720
720
  toolbar: false
721
721
  };
722
- has2.toolbar = Object.keys(has2).some((key2) => has2[key2]);
722
+ has4.toolbar = Object.keys(has4).some((key2) => has4[key2]);
723
723
  return {
724
724
  children: /* @__PURE__ */ jsxRuntime.jsx(
725
725
  ItemSchemaField,
@@ -747,21 +747,31 @@
747
747
  rawErrors
748
748
  }
749
749
  ),
750
- className: "array-item",
750
+ buttonsProps: {
751
+ idSchema: itemIdSchema,
752
+ disabled,
753
+ readonly,
754
+ canAdd,
755
+ hasCopy: has4.copy,
756
+ hasMoveUp: has4.moveUp,
757
+ hasMoveDown: has4.moveDown,
758
+ hasRemove: has4.remove,
759
+ index,
760
+ totalItems,
761
+ onAddIndexClick: this.onAddIndexClick,
762
+ onCopyIndexClick: this.onCopyIndexClick,
763
+ onDropIndexClick: this.onDropIndexClick,
764
+ onReorderClick: this.onReorderClick,
765
+ registry,
766
+ schema: itemSchema,
767
+ uiSchema: itemUiSchema
768
+ },
769
+ className: "rjsf-array-item",
751
770
  disabled,
752
- canAdd,
753
- hasCopy: has2.copy,
754
- hasToolbar: has2.toolbar,
755
- hasMoveUp: has2.moveUp,
756
- hasMoveDown: has2.moveDown,
757
- hasRemove: has2.remove,
771
+ hasToolbar: has4.toolbar,
758
772
  index,
759
773
  totalItems,
760
774
  key,
761
- onAddIndexClick: this.onAddIndexClick,
762
- onCopyIndexClick: this.onCopyIndexClick,
763
- onDropIndexClick: this.onDropIndexClick,
764
- onReorderClick: this.onReorderClick,
765
775
  readonly,
766
776
  registry,
767
777
  schema: itemSchema,
@@ -796,6 +806,7 @@
796
806
  title: uiTitle,
797
807
  // Unlike the other fields, don't use `getDisplayLabel()` since it always returns false for the boolean type
798
808
  label: displayLabel = true,
809
+ enumNames,
799
810
  ...options
800
811
  } = utils.getUiOptions(uiSchema, globalUiOptions);
801
812
  const Widget = utils.getWidget(schema, widget, widgets2);
@@ -820,9 +831,8 @@
820
831
  uiSchema
821
832
  );
822
833
  } else {
823
- const schemaWithEnumNames = schema;
824
834
  const enums = schema.enum ?? [true, false];
825
- if (!schemaWithEnumNames.enumNames && enums.length === 2 && enums.every((v) => typeof v === "boolean")) {
835
+ if (!enumNames && enums.length === 2 && enums.every((v) => typeof v === "boolean")) {
826
836
  enumOptions = [
827
837
  {
828
838
  value: enums[0],
@@ -834,42 +844,717 @@
834
844
  }
835
845
  ];
836
846
  } else {
837
- enumOptions = utils.optionsList(
847
+ enumOptions = utils.optionsList({ enum: enums }, uiSchema);
848
+ }
849
+ }
850
+ return /* @__PURE__ */ jsxRuntime.jsx(
851
+ Widget,
852
+ {
853
+ options: { ...options, enumOptions },
854
+ schema,
855
+ uiSchema,
856
+ id: idSchema.$id,
857
+ name,
858
+ onChange,
859
+ onFocus,
860
+ onBlur,
861
+ label,
862
+ hideLabel: !displayLabel,
863
+ value: formData,
864
+ required,
865
+ disabled,
866
+ readonly,
867
+ hideError,
868
+ registry,
869
+ formContext,
870
+ autofocus,
871
+ rawErrors
872
+ }
873
+ );
874
+ }
875
+ var BooleanField_default = BooleanField;
876
+ var LOOKUP_REGEX = /^\$lookup=(.+)/;
877
+ var LAYOUT_GRID_UI_OPTION = "layoutGrid";
878
+ var UI_GLOBAL_OPTIONS = "ui:global_options";
879
+ function getNonNullishValue(value, fallback) {
880
+ return value ?? fallback;
881
+ }
882
+ var LayoutGridField = class _LayoutGridField extends react.PureComponent {
883
+ static defaultProps = {
884
+ layoutGridSchema: void 0
885
+ };
886
+ static TEST_IDS = utils.getTestIds();
887
+ /** Computes the uiSchema for the field with `name` from the `uiProps` and `uiSchema` provided. The field UI Schema
888
+ * will always contain a copy of the global options from the `uiSchema` (so they can be passed down) as well as
889
+ * copying them into the local ui options. When the `forceReadonly` flag is true, then the field UI Schema is
890
+ * updated to make "readonly" be true. When the `schemaReadonly` flag is true AND the field UI Schema does NOT have
891
+ * the flag already provided, then we also make "readonly" true. We always make sure to return the final value of the
892
+ * field UI Schema's "readonly" flag as `uiReadonly` along with the `fieldUiSchema` in the return value.
893
+ *
894
+ * @param field - The name of the field to pull the existing UI Schema for
895
+ * @param uiProps - Any props that should be put into the field's uiSchema
896
+ * @param [uiSchema] - The optional UI Schema from which to get the UI schema for the field
897
+ * @param [schemaReadonly] - Optional flag indicating whether the schema indicates the field is readonly
898
+ * @param [forceReadonly] - Optional flag indicating whether the Form itself is in readonly mode
899
+ */
900
+ static computeFieldUiSchema(field, uiProps, uiSchema, schemaReadonly, forceReadonly) {
901
+ const globalUiOptions = get2(uiSchema, [UI_GLOBAL_OPTIONS], {});
902
+ const localUiSchema = get2(uiSchema, field);
903
+ const localUiOptions = { ...get2(localUiSchema, [utils.UI_OPTIONS_KEY], {}), ...uiProps, ...globalUiOptions };
904
+ const fieldUiSchema = { ...localUiSchema };
905
+ if (!isEmpty(localUiOptions)) {
906
+ set(fieldUiSchema, [utils.UI_OPTIONS_KEY], localUiOptions);
907
+ }
908
+ if (!isEmpty(globalUiOptions)) {
909
+ set(fieldUiSchema, [UI_GLOBAL_OPTIONS], globalUiOptions);
910
+ }
911
+ let { readonly: uiReadonly } = utils.getUiOptions(fieldUiSchema);
912
+ if (forceReadonly === true || isUndefined(uiReadonly) && schemaReadonly === true) {
913
+ uiReadonly = true;
914
+ if (has(localUiOptions, utils.READONLY_KEY)) {
915
+ set(fieldUiSchema, [utils.UI_OPTIONS_KEY, utils.READONLY_KEY], true);
916
+ } else {
917
+ set(fieldUiSchema, `ui:${utils.READONLY_KEY}`, true);
918
+ }
919
+ }
920
+ return { fieldUiSchema, uiReadonly };
921
+ }
922
+ /** Given an `operator`, `datum` and `value` determines whether this condition is considered matching. Matching
923
+ * depends on the `operator`. The `datum` and `value` are converted into arrays if they aren't already and then the
924
+ * contents of the two arrays are compared using the `operator`. When `operator` is All, then the two arrays must be
925
+ * equal to match. When `operator` is SOME then the intersection of the two arrays must have at least one value in
926
+ * common to match. When `operator` is NONE then the intersection of the two arrays must not have any values in common
927
+ * to match.
928
+ *
929
+ * @param [operator] - The optional operator for the condition
930
+ * @param [datum] - The optional datum for the condition, this can be an item or a list of items of type unknown
931
+ * @param [value='$0m3tH1nG Un3xP3cT3d'] The optional value for the condition, defaulting to a highly unlikely value
932
+ * to avoid comparing two undefined elements when `value` was forgotten in the condition definition.
933
+ * This can be an item or a list of items of type unknown
934
+ * @returns - True if the condition matches, false otherwise
935
+ */
936
+ static conditionMatches(operator, datum, value = "$0m3tH1nG Un3xP3cT3d") {
937
+ const data = flatten([datum]).sort();
938
+ const values = flatten([value]).sort();
939
+ switch (operator) {
940
+ case "all" /* ALL */:
941
+ return isEqual(data, values);
942
+ case "some" /* SOME */:
943
+ return intersection(data, values).length > 0;
944
+ case "none" /* NONE */:
945
+ return intersection(data, values).length === 0;
946
+ default:
947
+ return false;
948
+ }
949
+ }
950
+ /** From within the `layoutGridSchema` finds the `children` and any extra `gridProps` from the object keyed by
951
+ * `schemaKey`. If the `children` contains extra `gridProps` and those props contain a `className` string, try to
952
+ * lookup whether that `className` has a replacement value in the `registry` using the `FORM_CONTEXT_LOOKUP_BASE`.
953
+ * When the `className` value contains multiple classNames separated by a space, the lookup will look for a
954
+ * replacement value for each `className` and combine them into one.
955
+ *
956
+ * @param layoutGridSchema - The GridSchemaType instance from which to obtain the `schemaKey` children and extra props
957
+ * @param schemaKey - A `GridType` value, used to get the children and extra props from within the `layoutGridSchema`
958
+ * @param registry - The `@rjsf` Registry from which to look up `classNames` if they are present in the extra props
959
+ * @returns - An object containing the list of `LayoutGridSchemaType` `children` and any extra `gridProps`
960
+ * @throws - A `TypeError` when the `children` is not an array
961
+ */
962
+ static findChildrenAndProps(layoutGridSchema, schemaKey, registry) {
963
+ let gridProps = {};
964
+ let children = layoutGridSchema[schemaKey];
965
+ if (isPlainObject(children)) {
966
+ const { children: elements, className: toMapClassNames, ...otherProps } = children;
967
+ children = elements;
968
+ if (toMapClassNames) {
969
+ const classes = toMapClassNames.split(" ");
970
+ const className = classes.map((ele) => utils.lookupFromFormContext(registry, ele, ele)).join(" ");
971
+ gridProps = { ...otherProps, className };
972
+ } else {
973
+ gridProps = otherProps;
974
+ }
975
+ }
976
+ if (!Array.isArray(children)) {
977
+ throw new TypeError(`Expected array for "${schemaKey}" in ${JSON.stringify(layoutGridSchema)}`);
978
+ }
979
+ return { children, gridProps };
980
+ }
981
+ /** Generates an idSchema for the `schema` using `@rjsf`'s `toIdSchema` util, passing the `baseIdSchema`'s `$id` value
982
+ * as the id prefix.
983
+ *
984
+ * @param schemaUtils - The `SchemaUtilsType` used to call `toIdSchema`
985
+ * @param schema - The schema to generate the idSchema for
986
+ * @param baseIdSchema - The IdSchema for the base
987
+ * @param formData - The formData to pass the `toIdSchema`
988
+ * @param [idSeparator] - The param to pass into the `toIdSchema` util which will use it to join the `idSchema` paths
989
+ * @returns - The generated `idSchema` for the `schema`
990
+ */
991
+ static getIdSchema(schemaUtils, baseIdSchema, formData, schema = {}, idSeparator) {
992
+ const baseId = get2(baseIdSchema, utils.ID_KEY);
993
+ return schemaUtils.toIdSchema(schema, baseId, formData, baseId, idSeparator);
994
+ }
995
+ /** Given a `dottedPath` to a field in the `initialSchema`, iterate through each individual path in the schema until
996
+ * the leaf path is found and returned (along with whether that leaf path `isRequired`) OR no schema exists for an
997
+ * element in the path. If the leaf schema element happens to be a oneOf/anyOf then also return the oneOf/anyOf as
998
+ * `options`.
999
+ *
1000
+ * @param schemaUtils - The `SchemaUtilsType` used to call `retrieveSchema`
1001
+ * @param dottedPath - The dotted-path to the field for which to get the schema
1002
+ * @param initialSchema - The initial schema to start the search from
1003
+ * @param formData - The formData, useful for resolving a oneOf/anyOf selection in the path hierarchy
1004
+ * @param initialIdSchema - The initial idSchema to start the search from
1005
+ * @param [idSeparator] - The param to pass into the `toIdSchema` util which will use it to join the `idSchema` paths
1006
+ * @returns - An object containing the destination schema, isRequired and isReadonly flags for the field and options
1007
+ * info if a oneOf/anyOf
1008
+ */
1009
+ static getSchemaDetailsForField(schemaUtils, dottedPath, initialSchema, formData, initialIdSchema, idSeparator) {
1010
+ let rawSchema = initialSchema;
1011
+ let idSchema = initialIdSchema;
1012
+ const parts = dottedPath.split(".");
1013
+ const leafPath = parts.pop();
1014
+ let schema = schemaUtils.retrieveSchema(rawSchema, formData);
1015
+ let innerData = formData;
1016
+ let isReadonly = schema.readOnly;
1017
+ parts.forEach((part) => {
1018
+ if (has(schema, utils.PROPERTIES_KEY)) {
1019
+ rawSchema = get2(schema, [utils.PROPERTIES_KEY, part], {});
1020
+ idSchema = get2(idSchema, part, {});
1021
+ } else if (schema && (has(schema, utils.ONE_OF_KEY) || has(schema, utils.ANY_OF_KEY))) {
1022
+ const xxx = has(schema, utils.ONE_OF_KEY) ? utils.ONE_OF_KEY : utils.ANY_OF_KEY;
1023
+ const selectedSchema = schemaUtils.findSelectedOptionInXxxOf(schema, part, xxx, innerData);
1024
+ const selectedIdSchema = _LayoutGridField.getIdSchema(
1025
+ schemaUtils,
1026
+ idSchema,
1027
+ formData,
1028
+ selectedSchema,
1029
+ idSeparator
1030
+ );
1031
+ rawSchema = get2(selectedSchema, [utils.PROPERTIES_KEY, part], {});
1032
+ idSchema = get2(selectedIdSchema, part, {});
1033
+ } else {
1034
+ rawSchema = {};
1035
+ }
1036
+ innerData = get2(innerData, part, {});
1037
+ schema = schemaUtils.retrieveSchema(rawSchema, innerData);
1038
+ isReadonly = getNonNullishValue(schema.readOnly, isReadonly);
1039
+ });
1040
+ let optionsInfo;
1041
+ let isRequired = false;
1042
+ if (isEmpty(schema)) {
1043
+ schema = void 0;
1044
+ }
1045
+ if (schema && leafPath) {
1046
+ if (schema && (has(schema, utils.ONE_OF_KEY) || has(schema, utils.ANY_OF_KEY))) {
1047
+ const xxx = has(schema, utils.ONE_OF_KEY) ? utils.ONE_OF_KEY : utils.ANY_OF_KEY;
1048
+ schema = schemaUtils.findSelectedOptionInXxxOf(schema, leafPath, xxx, innerData);
1049
+ const rawIdSchema = _LayoutGridField.getIdSchema(schemaUtils, idSchema, formData, schema, idSeparator);
1050
+ idSchema = utils.mergeObjects(rawIdSchema, idSchema);
1051
+ }
1052
+ isRequired = schema !== void 0 && Array.isArray(schema.required) && includes(schema.required, leafPath);
1053
+ schema = get2(schema, [utils.PROPERTIES_KEY, leafPath]);
1054
+ schema = schema ? schemaUtils.retrieveSchema(schema) : schema;
1055
+ idSchema = get2(idSchema, leafPath, {});
1056
+ isReadonly = getNonNullishValue(schema?.readOnly, isReadonly);
1057
+ if (schema && (has(schema, utils.ONE_OF_KEY) || has(schema, utils.ANY_OF_KEY))) {
1058
+ const xxx = has(schema, utils.ONE_OF_KEY) ? utils.ONE_OF_KEY : utils.ANY_OF_KEY;
1059
+ const discriminator = utils.getDiscriminatorFieldFromSchema(schema);
1060
+ optionsInfo = { options: schema[xxx], hasDiscriminator: !!discriminator };
1061
+ }
1062
+ }
1063
+ return { schema, isRequired, isReadonly, optionsInfo, idSchema };
1064
+ }
1065
+ /** Gets the custom render component from the `render`, by either determining that it is either already a function or
1066
+ * it is a non-function value that can be used to look up the function in the registry. If no function can be found,
1067
+ * null is returned.
1068
+ *
1069
+ * @param render - The potential render function or lookup name to one
1070
+ * @param registry - The `@rjsf` Registry from which to look up `classNames` if they are present in the extra props
1071
+ * @returns - Either a render function if available, or null if not
1072
+ */
1073
+ static getCustomRenderComponent(render, registry) {
1074
+ let customRenderer = render;
1075
+ if (isString(customRenderer)) {
1076
+ customRenderer = utils.lookupFromFormContext(registry, customRenderer);
1077
+ }
1078
+ if (isFunction(customRenderer)) {
1079
+ return customRenderer;
1080
+ }
1081
+ return null;
1082
+ }
1083
+ /** Extract the `name`, and optional `render` and all other props from the `gridSchema`. We look up the `render` to
1084
+ * see if can be resolved to a UIComponent. If `name` does not exist and there is an optional `render` UIComponent, we
1085
+ * set the `rendered` component with only specified props for that component in the object.
1086
+ *
1087
+ * @param registry - The `@rjsf` Registry from which to look up `classNames` if they are present in the extra props
1088
+ * @param gridSchema - The string or object that represents the configuration for the grid field
1089
+ * @returns - The UIComponentPropsType computed from the gridSchema
1090
+ */
1091
+ static computeUIComponentPropsFromGridSchema(registry, gridSchema) {
1092
+ let name;
1093
+ let UIComponent = null;
1094
+ let uiProps = {};
1095
+ let rendered;
1096
+ if (isString(gridSchema) || isUndefined(gridSchema)) {
1097
+ name = gridSchema ?? "";
1098
+ } else {
1099
+ const { name: innerName, render, ...innerProps } = gridSchema;
1100
+ name = innerName;
1101
+ uiProps = innerProps;
1102
+ if (!isEmpty(uiProps)) {
1103
+ each(uiProps, (prop, key) => {
1104
+ if (isString(prop)) {
1105
+ const match = LOOKUP_REGEX.exec(prop);
1106
+ if (Array.isArray(match) && match.length > 1) {
1107
+ const name2 = match[1];
1108
+ uiProps[key] = utils.lookupFromFormContext(registry, name2, name2);
1109
+ }
1110
+ }
1111
+ });
1112
+ }
1113
+ UIComponent = _LayoutGridField.getCustomRenderComponent(render, registry);
1114
+ if (!innerName && UIComponent) {
1115
+ rendered = /* @__PURE__ */ jsxRuntime.jsx(UIComponent, { ...innerProps, "data-testid": _LayoutGridField.TEST_IDS.uiComponent });
1116
+ }
1117
+ }
1118
+ return { name, UIComponent, uiProps, rendered };
1119
+ }
1120
+ /** Constructs an `LayoutGridField` with the given `props`
1121
+ *
1122
+ * @param props - The `LayoutGridField` for this template
1123
+ */
1124
+ constructor(props) {
1125
+ super(props);
1126
+ }
1127
+ /** Generates an `onChange` handler for the field associated with the `dottedPath`. This handler will clone and update
1128
+ * the `formData` with the new `value` and the `errorSchema` if an `errSchema` is provided. After updating those two
1129
+ * elements, they will then be passed on to the `onChange` handler of the `LayoutFieldGrid`.
1130
+ *
1131
+ * @param dottedPath - The dotted-path to the field for which to generate the onChange handler
1132
+ * @returns - The `onChange` handling function for the `dottedPath` field
1133
+ */
1134
+ onFieldChange = (dottedPath) => {
1135
+ return (value, errSchema, id) => {
1136
+ const { onChange, errorSchema, formData } = this.props;
1137
+ const newFormData = cloneDeep2(formData || {});
1138
+ let newErrorSchema = errorSchema;
1139
+ if (errSchema && errorSchema) {
1140
+ newErrorSchema = cloneDeep2(errorSchema);
1141
+ set(newErrorSchema, dottedPath, errSchema);
1142
+ }
1143
+ set(newFormData, dottedPath, value);
1144
+ onChange(newFormData, newErrorSchema, id);
1145
+ };
1146
+ };
1147
+ /** Renders the `children` of the `GridType.CONDITION` if it passes. The `layoutGridSchema` for the
1148
+ * `GridType.CONDITION` is separated into the `children` and other `gridProps`. The `gridProps` are used to extract
1149
+ * the `operator`, `field` and `value` of the condition. If the condition matches, then all of the `children` are
1150
+ * rendered, otherwise null is returned.
1151
+ *
1152
+ * @param layoutGridSchema - The string or object that represents the configuration for the grid field
1153
+ * @returns - The rendered the children for the `GridType.CONDITION` or null
1154
+ */
1155
+ renderCondition(layoutGridSchema) {
1156
+ const { formData, registry } = this.props;
1157
+ const { children, gridProps } = _LayoutGridField.findChildrenAndProps(
1158
+ layoutGridSchema,
1159
+ "ui:condition" /* CONDITION */,
1160
+ registry
1161
+ );
1162
+ const { operator, field = "", value } = gridProps;
1163
+ const fieldData = get2(formData, field, null);
1164
+ if (_LayoutGridField.conditionMatches(operator, fieldData, value)) {
1165
+ return this.renderChildren(children);
1166
+ }
1167
+ return null;
1168
+ }
1169
+ /** Renders a material-ui `GridTemplate` as an item. The `layoutGridSchema` for the `GridType.COLUMN` is separated
1170
+ * into the `children` and other `gridProps`. The `gridProps` will be spread onto the outer `GridTemplate`. Inside
1171
+ * the `GridTemplate` all the `children` are rendered.
1172
+ *
1173
+ * @param layoutGridSchema - The string or object that represents the configuration for the grid field
1174
+ * @returns - The rendered `GridTemplate` containing the children for the `GridType.COLUMN`
1175
+ */
1176
+ renderCol(layoutGridSchema) {
1177
+ const { registry, uiSchema } = this.props;
1178
+ const { children, gridProps } = _LayoutGridField.findChildrenAndProps(
1179
+ layoutGridSchema,
1180
+ "ui:col" /* COLUMN */,
1181
+ registry
1182
+ );
1183
+ const uiOptions = utils.getUiOptions(uiSchema);
1184
+ const GridTemplate2 = utils.getTemplate("GridTemplate", registry, uiOptions);
1185
+ return /* @__PURE__ */ jsxRuntime.jsx(GridTemplate2, { column: true, "data-testid": _LayoutGridField.TEST_IDS.col, ...gridProps, children: this.renderChildren(children) });
1186
+ }
1187
+ /** Renders a material-ui `GridTemplate` as an item. The `layoutGridSchema` for the `GridType.COLUMNS` is separated
1188
+ * into the `children` and other `gridProps`. The `children` is iterated on and `gridProps` will be spread onto the
1189
+ * outer `GridTemplate`. Each child will have their own rendered `GridTemplate`.
1190
+ *
1191
+ * @param layoutGridSchema - The string or object that represents the configuration for the grid field
1192
+ * @returns - The rendered `GridTemplate` containing the children for the `GridType.COLUMNS`
1193
+ */
1194
+ renderColumns(layoutGridSchema) {
1195
+ const { registry, uiSchema } = this.props;
1196
+ const { children, gridProps } = _LayoutGridField.findChildrenAndProps(
1197
+ layoutGridSchema,
1198
+ "ui:columns" /* COLUMNS */,
1199
+ registry
1200
+ );
1201
+ const uiOptions = utils.getUiOptions(uiSchema);
1202
+ const GridTemplate2 = utils.getTemplate("GridTemplate", registry, uiOptions);
1203
+ return children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
1204
+ GridTemplate2,
1205
+ {
1206
+ column: true,
1207
+ "data-testid": _LayoutGridField.TEST_IDS.col,
1208
+ ...gridProps,
1209
+ children: this.renderChildren([child])
1210
+ },
1211
+ `column-${utils.hashObject(child)}`
1212
+ ));
1213
+ }
1214
+ /** Renders a material-ui `GridTemplate` as a container. The
1215
+ * `layoutGridSchema` for the `GridType.ROW` is separated into the `children` and other `gridProps`. The `gridProps`
1216
+ * will be spread onto the outer `GridTemplate`. Inside of the `GridTemplate` all of the `children` are rendered.
1217
+ *
1218
+ * @param layoutGridSchema - The string or object that represents the configuration for the grid field
1219
+ * @returns - The rendered `GridTemplate` containing the children for the `GridType.ROW`
1220
+ */
1221
+ renderRow(layoutGridSchema) {
1222
+ const { registry, uiSchema } = this.props;
1223
+ const { children, gridProps } = _LayoutGridField.findChildrenAndProps(
1224
+ layoutGridSchema,
1225
+ "ui:row" /* ROW */,
1226
+ registry
1227
+ );
1228
+ const uiOptions = utils.getUiOptions(uiSchema);
1229
+ const GridTemplate2 = utils.getTemplate("GridTemplate", registry, uiOptions);
1230
+ return /* @__PURE__ */ jsxRuntime.jsx(GridTemplate2, { ...gridProps, "data-testid": _LayoutGridField.TEST_IDS.row, children: this.renderChildren(children) });
1231
+ }
1232
+ /** Iterates through all the `childrenLayoutGridSchema`, rendering a nested `LayoutGridField` for each item in the
1233
+ * list, passing all the props for the current `LayoutGridField` along, updating the `schema` by calling
1234
+ * `retrieveSchema()` on it to resolve any `$ref`s. In addition to the updated `schema`, each item in
1235
+ * `childrenLayoutGridSchema` is passed as `layoutGridSchema`.
1236
+ *
1237
+ * @param childrenLayoutGridSchema - The list of strings or objects that represents the configurations for the
1238
+ * children fields
1239
+ * @returns - The nested `LayoutGridField`s
1240
+ */
1241
+ renderChildren(childrenLayoutGridSchema) {
1242
+ const { registry, schema: rawSchema, formData } = this.props;
1243
+ const { schemaUtils } = registry;
1244
+ const schema = schemaUtils.retrieveSchema(rawSchema, formData);
1245
+ return childrenLayoutGridSchema.map((layoutGridSchema) => /* @__PURE__ */ react.createElement(
1246
+ _LayoutGridField,
1247
+ {
1248
+ ...this.props,
1249
+ key: `layoutGrid-${utils.hashObject(layoutGridSchema)}`,
1250
+ schema,
1251
+ layoutGridSchema
1252
+ }
1253
+ ));
1254
+ }
1255
+ /** Renders the field described by `gridSchema`. If `gridSchema` is not an object, then is will be assumed
1256
+ * to be the dotted-path to the field in the schema. Otherwise, we extract the `name`, and optional `render` and all
1257
+ * other props. If `name` does not exist and there is an optional `render`, we return the `render` component with only
1258
+ * specified props for that component. If `name` exists, we take the name, the initial & root schemas and the formData
1259
+ * and get the destination schema, is required state and optional oneOf/anyOf options for it. If the destination
1260
+ * schema was located along with oneOf/anyOf options then a `LayoutMultiSchemaField` will be rendered with the
1261
+ * `uiSchema`, `errorSchema`, `idSchema` and `formData` drilled down to the dotted-path field, spreading any other
1262
+ * props from `gridSchema` into the `ui:options`. If the destination schema located without any oneOf/anyOf options,
1263
+ * then a `SchemaField` will be rendered with the same props as mentioned in the previous sentence. If no destination
1264
+ * schema was located, but a custom render component was found, then it will be rendered with many of the non-event
1265
+ * handling props. If none of the previous render paths are valid, then a null is returned.
1266
+ *
1267
+ * @param gridSchema - The string or object that represents the configuration for the grid field
1268
+ * @returns - One of `LayoutMultiSchemaField`, `SchemaField`, a custom render component or null, depending
1269
+ */
1270
+ renderField(gridSchema) {
1271
+ const {
1272
+ schema: initialSchema,
1273
+ uiSchema,
1274
+ errorSchema,
1275
+ idSchema,
1276
+ onBlur,
1277
+ onFocus,
1278
+ formData,
1279
+ readonly,
1280
+ registry,
1281
+ idSeparator,
1282
+ layoutGridSchema,
1283
+ // Used to pull this out of otherProps since we don't want to pass it through
1284
+ ...otherProps
1285
+ } = this.props;
1286
+ const { fields: fields2, schemaUtils } = registry;
1287
+ const { SchemaField: SchemaField2, LayoutMultiSchemaField: LayoutMultiSchemaField2 } = fields2;
1288
+ const uiComponentProps = _LayoutGridField.computeUIComponentPropsFromGridSchema(registry, gridSchema);
1289
+ if (uiComponentProps.rendered) {
1290
+ return uiComponentProps.rendered;
1291
+ }
1292
+ const { name, UIComponent, uiProps } = uiComponentProps;
1293
+ const {
1294
+ schema,
1295
+ isRequired,
1296
+ isReadonly,
1297
+ optionsInfo,
1298
+ idSchema: fieldIdSchema
1299
+ } = _LayoutGridField.getSchemaDetailsForField(
1300
+ schemaUtils,
1301
+ name,
1302
+ initialSchema,
1303
+ formData,
1304
+ idSchema,
1305
+ idSeparator
1306
+ );
1307
+ if (schema) {
1308
+ const Field = optionsInfo?.hasDiscriminator ? LayoutMultiSchemaField2 : SchemaField2;
1309
+ const { fieldUiSchema, uiReadonly } = _LayoutGridField.computeFieldUiSchema(
1310
+ name,
1311
+ uiProps,
1312
+ uiSchema,
1313
+ isReadonly,
1314
+ readonly
1315
+ );
1316
+ return /* @__PURE__ */ jsxRuntime.jsx(
1317
+ Field,
838
1318
  {
839
- enum: enums,
840
- // NOTE: enumNames is deprecated, but still supported for now.
841
- enumNames: schemaWithEnumNames.enumNames
842
- },
843
- uiSchema
1319
+ "data-testid": optionsInfo?.hasDiscriminator ? _LayoutGridField.TEST_IDS.layoutMultiSchemaField : _LayoutGridField.TEST_IDS.field,
1320
+ ...otherProps,
1321
+ name,
1322
+ required: isRequired,
1323
+ readonly: uiReadonly,
1324
+ schema,
1325
+ uiSchema: fieldUiSchema,
1326
+ errorSchema: get2(errorSchema, name),
1327
+ idSchema: fieldIdSchema,
1328
+ idSeparator,
1329
+ formData: get2(formData, name),
1330
+ onChange: this.onFieldChange(name),
1331
+ onBlur,
1332
+ onFocus,
1333
+ options: optionsInfo?.options,
1334
+ registry
1335
+ }
1336
+ );
1337
+ }
1338
+ if (UIComponent) {
1339
+ return /* @__PURE__ */ jsxRuntime.jsx(
1340
+ UIComponent,
1341
+ {
1342
+ "data-testid": _LayoutGridField.TEST_IDS.uiComponent,
1343
+ ...otherProps,
1344
+ name,
1345
+ required: isRequired,
1346
+ formData,
1347
+ readOnly: !!isReadonly || readonly,
1348
+ errorSchema,
1349
+ uiSchema,
1350
+ schema: initialSchema,
1351
+ idSchema,
1352
+ idSeparator,
1353
+ onBlur,
1354
+ onFocus,
1355
+ registry,
1356
+ ...uiProps
1357
+ }
844
1358
  );
845
1359
  }
1360
+ return null;
1361
+ }
1362
+ /** Renders the `LayoutGridField`. If there isn't a `layoutGridSchema` prop defined, then try pulling it out of the
1363
+ * `uiSchema` via `ui:LayoutGridField`. If `layoutGridSchema` is an object, then check to see if any of the properties
1364
+ * match one of the `GridType`s. If so, call the appropriate render function for the type. Otherwise, just call the
1365
+ * generic `renderField()` function with the `layoutGridSchema`.
1366
+ *
1367
+ * @returns - the rendered `LayoutGridField`
1368
+ */
1369
+ render() {
1370
+ const { uiSchema } = this.props;
1371
+ let { layoutGridSchema } = this.props;
1372
+ const uiOptions = utils.getUiOptions(uiSchema);
1373
+ if (!layoutGridSchema && LAYOUT_GRID_UI_OPTION in uiOptions && isObject(uiOptions[LAYOUT_GRID_UI_OPTION])) {
1374
+ layoutGridSchema = uiOptions[LAYOUT_GRID_UI_OPTION];
1375
+ }
1376
+ if (isObject(layoutGridSchema)) {
1377
+ if ("ui:row" /* ROW */ in layoutGridSchema) {
1378
+ return this.renderRow(layoutGridSchema);
1379
+ }
1380
+ if ("ui:col" /* COLUMN */ in layoutGridSchema) {
1381
+ return this.renderCol(layoutGridSchema);
1382
+ }
1383
+ if ("ui:columns" /* COLUMNS */ in layoutGridSchema) {
1384
+ return this.renderColumns(layoutGridSchema);
1385
+ }
1386
+ if ("ui:condition" /* CONDITION */ in layoutGridSchema) {
1387
+ return this.renderCondition(layoutGridSchema);
1388
+ }
1389
+ }
1390
+ return this.renderField(layoutGridSchema);
1391
+ }
1392
+ };
1393
+ function LayoutHeaderField(props) {
1394
+ const { idSchema, title, schema, uiSchema, required, registry, name } = props;
1395
+ const options = utils.getUiOptions(uiSchema, registry.globalUiOptions);
1396
+ const { title: uiTitle } = options;
1397
+ const { title: schemaTitle } = schema;
1398
+ const fieldTitle = uiTitle || title || schemaTitle || name;
1399
+ if (!fieldTitle) {
1400
+ return null;
1401
+ }
1402
+ const TitleFieldTemplate = utils.getTemplate(
1403
+ "TitleFieldTemplate",
1404
+ registry,
1405
+ options
1406
+ );
1407
+ return /* @__PURE__ */ jsxRuntime.jsx(
1408
+ TitleFieldTemplate,
1409
+ {
1410
+ id: utils.titleId(idSchema),
1411
+ title: fieldTitle,
1412
+ required,
1413
+ schema,
1414
+ uiSchema,
1415
+ registry
1416
+ }
1417
+ );
1418
+ }
1419
+ function getSelectedOption(options, selectorField, value) {
1420
+ const defaultValue = "!@#!@$@#$!@$#";
1421
+ const schemaOptions = options.map(({ schema }) => schema);
1422
+ return schemaOptions.find((option) => {
1423
+ const selector = get2(option, [utils.PROPERTIES_KEY, selectorField]);
1424
+ const result = get2(selector, utils.DEFAULT_KEY, get2(selector, utils.CONST_KEY, defaultValue));
1425
+ return result === value;
1426
+ });
1427
+ }
1428
+ function computeEnumOptions(schema, options, schemaUtils, uiSchema, formData) {
1429
+ const realOptions = options.map((opt) => schemaUtils.retrieveSchema(opt, formData));
1430
+ let tempSchema = schema;
1431
+ if (has(schema, utils.ONE_OF_KEY)) {
1432
+ tempSchema = { ...schema, [utils.ONE_OF_KEY]: realOptions };
1433
+ } else if (has(schema, utils.ANY_OF_KEY)) {
1434
+ tempSchema = { ...schema, [utils.ANY_OF_KEY]: realOptions };
1435
+ }
1436
+ const enumOptions = utils.optionsList(tempSchema, uiSchema);
1437
+ if (!enumOptions) {
1438
+ throw new Error(`No enumOptions were computed from the schema ${JSON.stringify(tempSchema)}`);
1439
+ }
1440
+ return enumOptions;
1441
+ }
1442
+ function LayoutMultiSchemaField(props) {
1443
+ const {
1444
+ name,
1445
+ baseType,
1446
+ disabled = false,
1447
+ formData,
1448
+ idSchema,
1449
+ onBlur,
1450
+ onChange,
1451
+ options,
1452
+ onFocus,
1453
+ registry,
1454
+ uiSchema,
1455
+ schema,
1456
+ formContext,
1457
+ autofocus,
1458
+ readonly,
1459
+ required,
1460
+ errorSchema,
1461
+ hideError = false
1462
+ } = props;
1463
+ const { widgets: widgets2, schemaUtils, globalUiOptions } = registry;
1464
+ const [enumOptions, setEnumOptions] = react.useState(computeEnumOptions(schema, options, schemaUtils, uiSchema, formData));
1465
+ const id = get2(idSchema, utils.ID_KEY);
1466
+ const discriminator = utils.getDiscriminatorFieldFromSchema(schema);
1467
+ const FieldErrorTemplate2 = utils.getTemplate("FieldErrorTemplate", registry, options);
1468
+ const FieldTemplate2 = utils.getTemplate("FieldTemplate", registry, options);
1469
+ const schemaHash = utils.hashObject(schema);
1470
+ const optionsHash = utils.hashObject(options);
1471
+ const uiSchemaHash = uiSchema ? utils.hashObject(uiSchema) : "";
1472
+ const formDataHash = formData ? utils.hashObject(formData) : "";
1473
+ react.useEffect(() => {
1474
+ setEnumOptions(computeEnumOptions(schema, options, schemaUtils, uiSchema, formData));
1475
+ }, [schemaHash, optionsHash, schemaUtils, uiSchemaHash, formDataHash]);
1476
+ const {
1477
+ widget = discriminator ? "radio" : "select",
1478
+ title = "",
1479
+ placeholder = "",
1480
+ optionsSchemaSelector: selectorField = discriminator,
1481
+ hideError: uiSchemaHideError,
1482
+ ...uiOptions
1483
+ } = utils.getUiOptions(uiSchema);
1484
+ if (!selectorField) {
1485
+ throw new Error("No selector field provided for the LayoutMultiSchemaField");
846
1486
  }
1487
+ const selectedOption = get2(formData, selectorField);
1488
+ let optionSchema = get2(enumOptions[0]?.schema, [utils.PROPERTIES_KEY, selectorField], {});
1489
+ const option = getSelectedOption(enumOptions, selectorField, selectedOption);
1490
+ optionSchema = optionSchema?.type ? optionSchema : { ...optionSchema, type: option?.type || baseType };
1491
+ const Widget = utils.getWidget(optionSchema, widget, widgets2);
1492
+ const hideFieldError = uiSchemaHideError === void 0 ? hideError : Boolean(uiSchemaHideError);
1493
+ const rawErrors = get2(errorSchema, [utils.ERRORS_KEY], []);
1494
+ const fieldErrorSchema = omit3(errorSchema, [utils.ERRORS_KEY]);
1495
+ const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
1496
+ const onOptionChange = (opt) => {
1497
+ const newOption = getSelectedOption(enumOptions, selectorField, opt);
1498
+ const oldOption = getSelectedOption(enumOptions, selectorField, selectedOption);
1499
+ let newFormData = schemaUtils.sanitizeDataForNewSchema(newOption, oldOption, formData);
1500
+ if (newFormData && newOption) {
1501
+ newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, "excludeObjectChildren");
1502
+ }
1503
+ if (newFormData) {
1504
+ set(newFormData, selectorField, opt);
1505
+ }
1506
+ onChange(newFormData, void 0, id);
1507
+ };
1508
+ const widgetOptions = { enumOptions, ...uiOptions };
1509
+ const errors = !hideFieldError && rawErrors.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(FieldErrorTemplate2, { idSchema, schema, errors: rawErrors, registry }) : void 0;
1510
+ const ignored = (value) => noop;
847
1511
  return /* @__PURE__ */ jsxRuntime.jsx(
848
- Widget,
1512
+ FieldTemplate2,
849
1513
  {
850
- options: { ...options, enumOptions },
1514
+ id,
851
1515
  schema,
1516
+ label: (title || schema.title) ?? "",
1517
+ disabled: disabled || Array.isArray(enumOptions) && isEmpty(enumOptions),
852
1518
  uiSchema,
853
- id: idSchema.$id,
854
- name,
855
- onChange,
856
- onFocus,
857
- onBlur,
858
- label,
859
- hideLabel: !displayLabel,
860
- value: formData,
1519
+ formContext,
861
1520
  required,
862
- disabled,
863
- readonly,
864
- hideError,
1521
+ readonly: !!readonly,
865
1522
  registry,
866
- formContext,
867
- autofocus,
868
- rawErrors
1523
+ displayLabel,
1524
+ errors,
1525
+ onChange,
1526
+ onDropPropertyClick: ignored,
1527
+ onKeyChange: ignored,
1528
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1529
+ Widget,
1530
+ {
1531
+ id,
1532
+ name,
1533
+ schema,
1534
+ label: (title || schema.title) ?? "",
1535
+ disabled: disabled || Array.isArray(enumOptions) && isEmpty(enumOptions),
1536
+ uiSchema,
1537
+ formContext,
1538
+ autofocus,
1539
+ readonly,
1540
+ required,
1541
+ registry,
1542
+ multiple: false,
1543
+ rawErrors,
1544
+ hideError: hideFieldError,
1545
+ hideLabel: !displayLabel,
1546
+ errorSchema: fieldErrorSchema,
1547
+ placeholder,
1548
+ onChange: onOptionChange,
1549
+ onBlur,
1550
+ onFocus,
1551
+ value: selectedOption,
1552
+ options: widgetOptions
1553
+ }
1554
+ )
869
1555
  }
870
1556
  );
871
1557
  }
872
- var BooleanField_default = BooleanField;
873
1558
  var AnyOfField = class extends react.Component {
874
1559
  /** Constructs an `AnyOfField` with the given `props` to initialize the initially selected option in state
875
1560
  *
@@ -877,29 +1562,6 @@
877
1562
  */
878
1563
  constructor(props) {
879
1564
  super(props);
880
- /** Callback handler to remember what the currently selected option is. In addition to that the `formData` is updated
881
- * to remove properties that are not part of the newly selected option schema, and then the updated data is passed to
882
- * the `onChange` handler.
883
- *
884
- * @param option - The new option value being selected
885
- */
886
- this.onOptionChange = (option) => {
887
- const { selectedOption, retrievedOptions } = this.state;
888
- const { formData, onChange, registry } = this.props;
889
- const { schemaUtils } = registry;
890
- const intOption = option !== void 0 ? parseInt(option, 10) : -1;
891
- if (intOption === selectedOption) {
892
- return;
893
- }
894
- const newOption = intOption >= 0 ? retrievedOptions[intOption] : void 0;
895
- const oldOption = selectedOption >= 0 ? retrievedOptions[selectedOption] : void 0;
896
- let newFormData = schemaUtils.sanitizeDataForNewSchema(newOption, oldOption, formData);
897
- if (newFormData && newOption) {
898
- newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, "excludeObjectChildren");
899
- }
900
- onChange(newFormData, void 0, this.getFieldId());
901
- this.setState({ selectedOption: intOption });
902
- };
903
1565
  const {
904
1566
  formData,
905
1567
  options,
@@ -954,6 +1616,30 @@
954
1616
  const option = schemaUtils.getClosestMatchingOption(formData, options, selectedOption, discriminator);
955
1617
  return option;
956
1618
  }
1619
+ /** Callback handler to remember what the currently selected option is. In addition to that the `formData` is updated
1620
+ * to remove properties that are not part of the newly selected option schema, and then the updated data is passed to
1621
+ * the `onChange` handler.
1622
+ *
1623
+ * @param option - The new option value being selected
1624
+ */
1625
+ onOptionChange = (option) => {
1626
+ const { selectedOption, retrievedOptions } = this.state;
1627
+ const { formData, onChange, registry } = this.props;
1628
+ const { schemaUtils } = registry;
1629
+ const intOption = option !== void 0 ? parseInt(option, 10) : -1;
1630
+ if (intOption === selectedOption) {
1631
+ return;
1632
+ }
1633
+ const newOption = intOption >= 0 ? retrievedOptions[intOption] : void 0;
1634
+ const oldOption = selectedOption >= 0 ? retrievedOptions[selectedOption] : void 0;
1635
+ let newFormData = schemaUtils.sanitizeDataForNewSchema(newOption, oldOption, formData);
1636
+ if (newOption) {
1637
+ newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, "excludeObjectChildren");
1638
+ }
1639
+ this.setState({ selectedOption: intOption }, () => {
1640
+ onChange(newFormData, void 0, this.getFieldId());
1641
+ });
1642
+ };
957
1643
  getFieldId() {
958
1644
  const { idSchema, schema } = this.props;
959
1645
  return `${idSchema.$id}${schema.oneOf ? "__oneof_select" : "__anyof_select"}`;
@@ -968,6 +1654,7 @@
968
1654
  formContext,
969
1655
  onBlur,
970
1656
  onFocus,
1657
+ readonly,
971
1658
  registry,
972
1659
  schema,
973
1660
  uiSchema
@@ -984,8 +1671,8 @@
984
1671
  ...uiOptions
985
1672
  } = utils.getUiOptions(uiSchema, globalUiOptions);
986
1673
  const Widget = utils.getWidget({ type: "number" }, widget, widgets2);
987
- const rawErrors = get3(errorSchema, utils.ERRORS_KEY, []);
988
- const fieldErrorSchema = omit2(errorSchema, [utils.ERRORS_KEY]);
1674
+ const rawErrors = get2(errorSchema, utils.ERRORS_KEY, []);
1675
+ const fieldErrorSchema = omit3(errorSchema, [utils.ERRORS_KEY]);
989
1676
  const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
990
1677
  const option = selectedOption >= 0 ? retrievedOptions[selectedOption] || null : null;
991
1678
  let optionSchema;
@@ -1042,10 +1729,11 @@
1042
1729
  autocomplete,
1043
1730
  autofocus,
1044
1731
  label: title ?? name,
1045
- hideLabel: !displayLabel
1732
+ hideLabel: !displayLabel,
1733
+ readonly
1046
1734
  }
1047
1735
  ) }),
1048
- optionSchema && /* @__PURE__ */ jsxRuntime.jsx(_SchemaField, { ...this.props, schema: optionSchema, uiSchema: optionUiSchema })
1736
+ optionSchema && optionSchema.type !== "null" && /* @__PURE__ */ jsxRuntime.jsx(_SchemaField, { ...this.props, schema: optionSchema, uiSchema: optionUiSchema })
1049
1737
  ] });
1050
1738
  }
1051
1739
  };
@@ -1058,13 +1746,13 @@
1058
1746
  const { StringField: StringField2 } = registry.fields;
1059
1747
  let value = formData;
1060
1748
  const handleChange = react.useCallback(
1061
- (value2) => {
1749
+ (value2, errorSchema, id) => {
1062
1750
  setLastValue(value2);
1063
1751
  if (`${value2}`.charAt(0) === ".") {
1064
1752
  value2 = `0${value2}`;
1065
1753
  }
1066
1754
  const processed = typeof value2 === "string" && value2.match(trailingCharMatcherWithPrefix) ? utils.asNumber(value2.replace(trailingCharMatcher, "")) : utils.asNumber(value2);
1067
- onChange(processed);
1755
+ onChange(processed, errorSchema, id);
1068
1756
  },
1069
1757
  [onChange]
1070
1758
  );
@@ -1078,134 +1766,11 @@
1078
1766
  }
1079
1767
  var NumberField_default = NumberField;
1080
1768
  var ObjectField = class extends react.Component {
1081
- constructor() {
1082
- super(...arguments);
1083
- /** Set up the initial state */
1084
- this.state = {
1085
- wasPropertyKeyModified: false,
1086
- additionalProperties: {}
1087
- };
1088
- /** Returns the `onPropertyChange` handler for the `name` field. Handles the special case where a user is attempting
1089
- * to clear the data for a field added as an additional property. Calls the `onChange()` handler with the updated
1090
- * formData.
1091
- *
1092
- * @param name - The name of the property
1093
- * @param addedByAdditionalProperties - Flag indicating whether this property is an additional property
1094
- * @returns - The onPropertyChange callback for the `name` property
1095
- */
1096
- this.onPropertyChange = (name, addedByAdditionalProperties = false) => {
1097
- return (value, newErrorSchema, id) => {
1098
- const { formData, onChange, errorSchema } = this.props;
1099
- if (value === void 0 && addedByAdditionalProperties) {
1100
- value = "";
1101
- }
1102
- const newFormData = { ...formData, [name]: value };
1103
- onChange(
1104
- newFormData,
1105
- errorSchema && errorSchema && {
1106
- ...errorSchema,
1107
- [name]: newErrorSchema
1108
- },
1109
- id
1110
- );
1111
- };
1112
- };
1113
- /** Returns a callback to handle the onDropPropertyClick event for the given `key` which removes the old `key` data
1114
- * and calls the `onChange` callback with it
1115
- *
1116
- * @param key - The key for which the drop callback is desired
1117
- * @returns - The drop property click callback
1118
- */
1119
- this.onDropPropertyClick = (key) => {
1120
- return (event) => {
1121
- event.preventDefault();
1122
- const { onChange, formData } = this.props;
1123
- const copiedFormData = { ...formData };
1124
- unset(copiedFormData, key);
1125
- onChange(copiedFormData);
1126
- };
1127
- };
1128
- /** Computes the next available key name from the `preferredKey`, indexing through the already existing keys until one
1129
- * that is already not assigned is found.
1130
- *
1131
- * @param preferredKey - The preferred name of a new key
1132
- * @param [formData] - The form data in which to check if the desired key already exists
1133
- * @returns - The name of the next available key from `preferredKey`
1134
- */
1135
- this.getAvailableKey = (preferredKey, formData) => {
1136
- const { uiSchema, registry } = this.props;
1137
- const { duplicateKeySuffixSeparator = "-" } = utils.getUiOptions(uiSchema, registry.globalUiOptions);
1138
- let index = 0;
1139
- let newKey = preferredKey;
1140
- while (has(formData, newKey)) {
1141
- newKey = `${preferredKey}${duplicateKeySuffixSeparator}${++index}`;
1142
- }
1143
- return newKey;
1144
- };
1145
- /** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
1146
- * callback will attempt to rename the key and move the existing data to that key, calling `onChange` when it does.
1147
- *
1148
- * @param oldValue - The old value of a field
1149
- * @returns - The key change callback function
1150
- */
1151
- this.onKeyChange = (oldValue) => {
1152
- return (value, newErrorSchema) => {
1153
- if (oldValue === value) {
1154
- return;
1155
- }
1156
- const { formData, onChange, errorSchema } = this.props;
1157
- value = this.getAvailableKey(value, formData);
1158
- const newFormData = {
1159
- ...formData
1160
- };
1161
- const newKeys = { [oldValue]: value };
1162
- const keyValues = Object.keys(newFormData).map((key) => {
1163
- const newKey = newKeys[key] || key;
1164
- return { [newKey]: newFormData[key] };
1165
- });
1166
- const renamedObj = Object.assign({}, ...keyValues);
1167
- this.setState({ wasPropertyKeyModified: true });
1168
- onChange(
1169
- renamedObj,
1170
- errorSchema && errorSchema && {
1171
- ...errorSchema,
1172
- [value]: newErrorSchema
1173
- }
1174
- );
1175
- };
1176
- };
1177
- /** Handles the adding of a new additional property on the given `schema`. Calls the `onChange` callback once the new
1178
- * default data for that field has been added to the formData.
1179
- *
1180
- * @param schema - The schema element to which the new property is being added
1181
- */
1182
- this.handleAddClick = (schema) => () => {
1183
- if (!schema.additionalProperties) {
1184
- return;
1185
- }
1186
- const { formData, onChange, registry } = this.props;
1187
- const newFormData = { ...formData };
1188
- let type = void 0;
1189
- let defaultValue = void 0;
1190
- if (isObject(schema.additionalProperties)) {
1191
- type = schema.additionalProperties.type;
1192
- defaultValue = schema.additionalProperties.default;
1193
- let apSchema = schema.additionalProperties;
1194
- if (utils.REF_KEY in apSchema) {
1195
- const { schemaUtils } = registry;
1196
- apSchema = schemaUtils.retrieveSchema({ $ref: apSchema[utils.REF_KEY] }, formData);
1197
- type = apSchema.type;
1198
- defaultValue = apSchema.default;
1199
- }
1200
- if (!type && (utils.ANY_OF_KEY in apSchema || utils.ONE_OF_KEY in apSchema)) {
1201
- type = "object";
1202
- }
1203
- }
1204
- const newKey = this.getAvailableKey("newKey", newFormData);
1205
- set(newFormData, newKey, defaultValue ?? this.getDefaultValue(type));
1206
- onChange(newFormData);
1207
- };
1208
- }
1769
+ /** Set up the initial state */
1770
+ state = {
1771
+ wasPropertyKeyModified: false,
1772
+ additionalProperties: {}
1773
+ };
1209
1774
  /** Returns a flag indicating whether the `name` field is required in the object schema
1210
1775
  *
1211
1776
  * @param name - The name of the field to check for required-ness
@@ -1215,6 +1780,95 @@
1215
1780
  const { schema } = this.props;
1216
1781
  return Array.isArray(schema.required) && schema.required.indexOf(name) !== -1;
1217
1782
  }
1783
+ /** Returns the `onPropertyChange` handler for the `name` field. Handles the special case where a user is attempting
1784
+ * to clear the data for a field added as an additional property. Calls the `onChange()` handler with the updated
1785
+ * formData.
1786
+ *
1787
+ * @param name - The name of the property
1788
+ * @param addedByAdditionalProperties - Flag indicating whether this property is an additional property
1789
+ * @returns - The onPropertyChange callback for the `name` property
1790
+ */
1791
+ onPropertyChange = (name, addedByAdditionalProperties = false) => {
1792
+ return (value, newErrorSchema, id) => {
1793
+ const { formData, onChange, errorSchema } = this.props;
1794
+ if (value === void 0 && addedByAdditionalProperties) {
1795
+ value = "";
1796
+ }
1797
+ const newFormData = { ...formData, [name]: value };
1798
+ onChange(
1799
+ newFormData,
1800
+ errorSchema && errorSchema && {
1801
+ ...errorSchema,
1802
+ [name]: newErrorSchema
1803
+ },
1804
+ id
1805
+ );
1806
+ };
1807
+ };
1808
+ /** Returns a callback to handle the onDropPropertyClick event for the given `key` which removes the old `key` data
1809
+ * and calls the `onChange` callback with it
1810
+ *
1811
+ * @param key - The key for which the drop callback is desired
1812
+ * @returns - The drop property click callback
1813
+ */
1814
+ onDropPropertyClick = (key) => {
1815
+ return (event) => {
1816
+ event.preventDefault();
1817
+ const { onChange, formData } = this.props;
1818
+ const copiedFormData = { ...formData };
1819
+ unset(copiedFormData, key);
1820
+ onChange(copiedFormData);
1821
+ };
1822
+ };
1823
+ /** Computes the next available key name from the `preferredKey`, indexing through the already existing keys until one
1824
+ * that is already not assigned is found.
1825
+ *
1826
+ * @param preferredKey - The preferred name of a new key
1827
+ * @param [formData] - The form data in which to check if the desired key already exists
1828
+ * @returns - The name of the next available key from `preferredKey`
1829
+ */
1830
+ getAvailableKey = (preferredKey, formData) => {
1831
+ const { uiSchema, registry } = this.props;
1832
+ const { duplicateKeySuffixSeparator = "-" } = utils.getUiOptions(uiSchema, registry.globalUiOptions);
1833
+ let index = 0;
1834
+ let newKey = preferredKey;
1835
+ while (has(formData, newKey)) {
1836
+ newKey = `${preferredKey}${duplicateKeySuffixSeparator}${++index}`;
1837
+ }
1838
+ return newKey;
1839
+ };
1840
+ /** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
1841
+ * callback will attempt to rename the key and move the existing data to that key, calling `onChange` when it does.
1842
+ *
1843
+ * @param oldValue - The old value of a field
1844
+ * @returns - The key change callback function
1845
+ */
1846
+ onKeyChange = (oldValue) => {
1847
+ return (value, newErrorSchema) => {
1848
+ if (oldValue === value) {
1849
+ return;
1850
+ }
1851
+ const { formData, onChange, errorSchema } = this.props;
1852
+ value = this.getAvailableKey(value, formData);
1853
+ const newFormData = {
1854
+ ...formData
1855
+ };
1856
+ const newKeys = { [oldValue]: value };
1857
+ const keyValues = Object.keys(newFormData).map((key) => {
1858
+ const newKey = newKeys[key] || key;
1859
+ return { [newKey]: newFormData[key] };
1860
+ });
1861
+ const renamedObj = Object.assign({}, ...keyValues);
1862
+ this.setState({ wasPropertyKeyModified: true });
1863
+ onChange(
1864
+ renamedObj,
1865
+ errorSchema && errorSchema && {
1866
+ ...errorSchema,
1867
+ [value]: newErrorSchema
1868
+ }
1869
+ );
1870
+ };
1871
+ };
1218
1872
  /** Returns a default value to be used for a new additional schema property of the given `type`
1219
1873
  *
1220
1874
  * @param type - The type of the new additional schema property
@@ -1239,6 +1893,45 @@
1239
1893
  return translateString(utils.TranslatableString.NewStringDefault);
1240
1894
  }
1241
1895
  }
1896
+ /** Handles the adding of a new additional property on the given `schema`. Calls the `onChange` callback once the new
1897
+ * default data for that field has been added to the formData.
1898
+ *
1899
+ * @param schema - The schema element to which the new property is being added
1900
+ */
1901
+ handleAddClick = (schema) => () => {
1902
+ if (!(schema.additionalProperties || schema.patternProperties)) {
1903
+ return;
1904
+ }
1905
+ const { formData, onChange, registry } = this.props;
1906
+ const newFormData = { ...formData };
1907
+ const newKey = this.getAvailableKey("newKey", newFormData);
1908
+ if (schema.patternProperties) {
1909
+ set(newFormData, newKey, null);
1910
+ } else {
1911
+ let type = void 0;
1912
+ let constValue = void 0;
1913
+ let defaultValue = void 0;
1914
+ if (isObject(schema.additionalProperties)) {
1915
+ type = schema.additionalProperties.type;
1916
+ constValue = schema.additionalProperties.const;
1917
+ defaultValue = schema.additionalProperties.default;
1918
+ let apSchema = schema.additionalProperties;
1919
+ if (utils.REF_KEY in apSchema) {
1920
+ const { schemaUtils } = registry;
1921
+ apSchema = schemaUtils.retrieveSchema({ $ref: apSchema[utils.REF_KEY] }, formData);
1922
+ type = apSchema.type;
1923
+ constValue = apSchema.const;
1924
+ defaultValue = apSchema.default;
1925
+ }
1926
+ if (!type && (utils.ANY_OF_KEY in apSchema || utils.ONE_OF_KEY in apSchema)) {
1927
+ type = "object";
1928
+ }
1929
+ }
1930
+ const newValue = constValue ?? defaultValue ?? this.getDefaultValue(type);
1931
+ set(newFormData, newKey, newValue);
1932
+ }
1933
+ onChange(newFormData);
1934
+ };
1242
1935
  /** Renders the `ObjectField` from the given props
1243
1936
  */
1244
1937
  render() {
@@ -1273,7 +1966,7 @@
1273
1966
  orderedProperties = utils.orderProperties(properties, uiOptions.order);
1274
1967
  } catch (err) {
1275
1968
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1276
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "config-error", style: { color: "red" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { options: { disableParsingRawHTML: true }, children: translateString(utils.TranslatableString.InvalidObjectField, [name || "root", err.message]) }) }),
1969
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "rjsf-config-error", style: { color: "red" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { options: { disableParsingRawHTML: true }, children: translateString(utils.TranslatableString.InvalidObjectField, [name || "root", err.message]) }) }),
1277
1970
  /* @__PURE__ */ jsxRuntime.jsx("pre", { children: JSON.stringify(schema) })
1278
1971
  ] });
1279
1972
  }
@@ -1286,20 +1979,20 @@
1286
1979
  const addedByAdditionalProperties = has(schema, [utils.PROPERTIES_KEY, name2, utils.ADDITIONAL_PROPERTY_FLAG]);
1287
1980
  const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[name2];
1288
1981
  const hidden = utils.getUiOptions(fieldUiSchema).widget === "hidden";
1289
- const fieldIdSchema = get3(idSchema, [name2], {});
1982
+ const fieldIdSchema = get2(idSchema, [name2], {});
1290
1983
  return {
1291
1984
  content: /* @__PURE__ */ jsxRuntime.jsx(
1292
1985
  SchemaField2,
1293
1986
  {
1294
1987
  name: name2,
1295
1988
  required: this.isRequired(name2),
1296
- schema: get3(schema, [utils.PROPERTIES_KEY, name2], {}),
1989
+ schema: get2(schema, [utils.PROPERTIES_KEY, name2], {}),
1297
1990
  uiSchema: fieldUiSchema,
1298
- errorSchema: get3(errorSchema, name2),
1991
+ errorSchema: get2(errorSchema, name2),
1299
1992
  idSchema: fieldIdSchema,
1300
1993
  idPrefix,
1301
1994
  idSeparator,
1302
- formData: get3(formData, name2),
1995
+ formData: get2(formData, name2),
1303
1996
  formContext,
1304
1997
  wasPropertyKeyModified: this.state.wasPropertyKeyModified,
1305
1998
  onKeyChange: this.onKeyChange(name2),
@@ -1432,9 +2125,9 @@
1432
2125
  }
1433
2126
  const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
1434
2127
  const { __errors, ...fieldErrorSchema } = errorSchema || {};
1435
- const fieldUiSchema = omit2(uiSchema, ["ui:classNames", "classNames", "ui:style"]);
2128
+ const fieldUiSchema = omit3(uiSchema, ["ui:classNames", "classNames", "ui:style"]);
1436
2129
  if (utils.UI_OPTIONS_KEY in fieldUiSchema) {
1437
- fieldUiSchema[utils.UI_OPTIONS_KEY] = omit2(fieldUiSchema[utils.UI_OPTIONS_KEY], ["classNames", "style"]);
2130
+ fieldUiSchema[utils.UI_OPTIONS_KEY] = omit3(fieldUiSchema[utils.UI_OPTIONS_KEY], ["classNames", "style"]);
1438
2131
  }
1439
2132
  const field = /* @__PURE__ */ jsxRuntime.jsx(
1440
2133
  FieldComponent,
@@ -1464,17 +2157,9 @@
1464
2157
  const richDescription = uiOptions.enableMarkdownInDescription ? /* @__PURE__ */ jsxRuntime.jsx(Markdown, { options: { disableParsingRawHTML: true }, children: description }) : description;
1465
2158
  const help = uiOptions.help;
1466
2159
  const hidden = uiOptions.widget === "hidden";
1467
- const classNames = ["form-group", "field", `field-${utils.getSchemaType(schema)}`];
2160
+ const classNames = ["rjsf-field", `rjsf-field-${utils.getSchemaType(schema)}`];
1468
2161
  if (!hideError && __errors && __errors.length > 0) {
1469
- classNames.push("field-error has-error has-danger");
1470
- }
1471
- if (uiSchema?.classNames) {
1472
- {
1473
- console.warn(
1474
- "'uiSchema.classNames' is deprecated and may be removed in a major release; Use 'ui:classNames' instead."
1475
- );
1476
- }
1477
- classNames.push(uiSchema.classNames);
2162
+ classNames.push("rjsf-field-error");
1478
2163
  }
1479
2164
  if (uiOptions.classNames) {
1480
2165
  classNames.push(uiOptions.classNames);
@@ -1561,6 +2246,7 @@
1561
2246
  (_schema2) => schemaUtils.retrieveSchema(isObject(_schema2) ? _schema2 : {}, formData)
1562
2247
  ),
1563
2248
  registry,
2249
+ required,
1564
2250
  schema,
1565
2251
  uiSchema
1566
2252
  }
@@ -1585,6 +2271,7 @@
1585
2271
  (_schema2) => schemaUtils.retrieveSchema(isObject(_schema2) ? _schema2 : {}, formData)
1586
2272
  ),
1587
2273
  registry,
2274
+ required,
1588
2275
  schema,
1589
2276
  uiSchema
1590
2277
  }
@@ -1674,6 +2361,9 @@
1674
2361
  ArrayField: ArrayField_default,
1675
2362
  // ArrayField falls back to SchemaField if ArraySchemaField is not defined, which it isn't by default
1676
2363
  BooleanField: BooleanField_default,
2364
+ LayoutGridField,
2365
+ LayoutHeaderField,
2366
+ LayoutMultiSchemaField,
1677
2367
  NumberField: NumberField_default,
1678
2368
  ObjectField: ObjectField_default,
1679
2369
  OneOfField: MultiSchemaField_default,
@@ -1707,24 +2397,13 @@
1707
2397
  );
1708
2398
  }
1709
2399
  function ArrayFieldItemTemplate(props) {
1710
- const {
1711
- children,
1712
- className,
1713
- disabled,
1714
- hasToolbar,
1715
- hasMoveDown,
1716
- hasMoveUp,
1717
- hasRemove,
1718
- hasCopy,
1719
- index,
1720
- onCopyIndexClick,
1721
- onDropIndexClick,
1722
- onReorderClick,
1723
- readonly,
2400
+ const { children, className, buttonsProps, hasToolbar, registry, uiSchema } = props;
2401
+ const uiOptions = utils.getUiOptions(uiSchema);
2402
+ const ArrayFieldItemButtonsTemplate2 = utils.getTemplate(
2403
+ "ArrayFieldItemButtonsTemplate",
1724
2404
  registry,
1725
- uiSchema
1726
- } = props;
1727
- const { CopyButton: CopyButton2, MoveDownButton: MoveDownButton2, MoveUpButton: MoveUpButton2, RemoveButton: RemoveButton2 } = registry.templates.ButtonTemplates;
2405
+ uiOptions
2406
+ );
1728
2407
  const btnStyle = {
1729
2408
  flex: 1,
1730
2409
  paddingLeft: 6,
@@ -1733,7 +2412,7 @@
1733
2412
  };
1734
2413
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
1735
2414
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: hasToolbar ? "col-xs-9" : "col-xs-12", children }),
1736
- hasToolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-3 array-item-toolbox", children: /* @__PURE__ */ jsxRuntime.jsxs(
2415
+ hasToolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-3 array-item-toolbox", children: /* @__PURE__ */ jsxRuntime.jsx(
1737
2416
  "div",
1738
2417
  {
1739
2418
  className: "btn-group",
@@ -1741,52 +2420,79 @@
1741
2420
  display: "flex",
1742
2421
  justifyContent: "space-around"
1743
2422
  },
1744
- children: [
1745
- (hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxRuntime.jsx(
1746
- MoveUpButton2,
1747
- {
1748
- style: btnStyle,
1749
- disabled: disabled || readonly || !hasMoveUp,
1750
- onClick: onReorderClick(index, index - 1),
1751
- uiSchema,
1752
- registry
1753
- }
1754
- ),
1755
- (hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxRuntime.jsx(
1756
- MoveDownButton2,
1757
- {
1758
- style: btnStyle,
1759
- disabled: disabled || readonly || !hasMoveDown,
1760
- onClick: onReorderClick(index, index + 1),
1761
- uiSchema,
1762
- registry
1763
- }
1764
- ),
1765
- hasCopy && /* @__PURE__ */ jsxRuntime.jsx(
1766
- CopyButton2,
1767
- {
1768
- style: btnStyle,
1769
- disabled: disabled || readonly,
1770
- onClick: onCopyIndexClick(index),
1771
- uiSchema,
1772
- registry
1773
- }
1774
- ),
1775
- hasRemove && /* @__PURE__ */ jsxRuntime.jsx(
1776
- RemoveButton2,
1777
- {
1778
- style: btnStyle,
1779
- disabled: disabled || readonly,
1780
- onClick: onDropIndexClick(index),
1781
- uiSchema,
1782
- registry
1783
- }
1784
- )
1785
- ]
2423
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrayFieldItemButtonsTemplate2, { ...buttonsProps, style: btnStyle })
1786
2424
  }
1787
2425
  ) })
1788
2426
  ] });
1789
2427
  }
2428
+ function ArrayFieldItemButtonsTemplate(props) {
2429
+ const {
2430
+ disabled,
2431
+ hasCopy,
2432
+ hasMoveDown,
2433
+ hasMoveUp,
2434
+ hasRemove,
2435
+ idSchema,
2436
+ index,
2437
+ onCopyIndexClick,
2438
+ onDropIndexClick,
2439
+ onReorderClick,
2440
+ readonly,
2441
+ registry,
2442
+ uiSchema
2443
+ } = props;
2444
+ const { CopyButton: CopyButton2, MoveDownButton: MoveDownButton2, MoveUpButton: MoveUpButton2, RemoveButton: RemoveButton2 } = registry.templates.ButtonTemplates;
2445
+ const onCopyClick = react.useMemo(() => onCopyIndexClick(index), [index, onCopyIndexClick]);
2446
+ const onRemoveClick = react.useMemo(() => onDropIndexClick(index), [index, onDropIndexClick]);
2447
+ const onArrowUpClick = react.useMemo(() => onReorderClick(index, index - 1), [index, onReorderClick]);
2448
+ const onArrowDownClick = react.useMemo(() => onReorderClick(index, index + 1), [index, onReorderClick]);
2449
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2450
+ (hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxRuntime.jsx(
2451
+ MoveUpButton2,
2452
+ {
2453
+ id: utils.buttonId(idSchema, "moveUp"),
2454
+ className: "rjsf-array-item-move-up",
2455
+ disabled: disabled || readonly || !hasMoveUp,
2456
+ onClick: onArrowUpClick,
2457
+ uiSchema,
2458
+ registry
2459
+ }
2460
+ ),
2461
+ (hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxRuntime.jsx(
2462
+ MoveDownButton2,
2463
+ {
2464
+ id: utils.buttonId(idSchema, "moveDown"),
2465
+ className: "rjsf-array-item-move-down",
2466
+ disabled: disabled || readonly || !hasMoveDown,
2467
+ onClick: onArrowDownClick,
2468
+ uiSchema,
2469
+ registry
2470
+ }
2471
+ ),
2472
+ hasCopy && /* @__PURE__ */ jsxRuntime.jsx(
2473
+ CopyButton2,
2474
+ {
2475
+ id: utils.buttonId(idSchema, "copy"),
2476
+ className: "rjsf-array-item-copy",
2477
+ disabled: disabled || readonly,
2478
+ onClick: onCopyClick,
2479
+ uiSchema,
2480
+ registry
2481
+ }
2482
+ ),
2483
+ hasRemove && /* @__PURE__ */ jsxRuntime.jsx(
2484
+ RemoveButton2,
2485
+ {
2486
+ id: utils.buttonId(idSchema, "remove"),
2487
+ className: "rjsf-array-item-remove",
2488
+ disabled: disabled || readonly,
2489
+ onClick: onRemoveClick,
2490
+ uiSchema,
2491
+ registry
2492
+ }
2493
+ )
2494
+ ] });
2495
+ }
1790
2496
  function ArrayFieldTemplate(props) {
1791
2497
  const {
1792
2498
  canAdd,
@@ -1847,7 +2553,8 @@
1847
2553
  canAdd && /* @__PURE__ */ jsxRuntime.jsx(
1848
2554
  AddButton2,
1849
2555
  {
1850
- className: "array-item-add",
2556
+ id: utils.buttonId(idSchema, "add"),
2557
+ className: "rjsf-array-item-add",
1851
2558
  onClick: onAddClick,
1852
2559
  disabled: disabled || readonly,
1853
2560
  uiSchema,
@@ -1967,62 +2674,29 @@
1967
2674
  const { iconType = "default", icon, className, uiSchema, registry, ...otherProps } = props;
1968
2675
  return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: `btn btn-${iconType} ${className}`, ...otherProps, children: /* @__PURE__ */ jsxRuntime.jsx("i", { className: `glyphicon glyphicon-${icon}` }) });
1969
2676
  }
1970
- function CopyButton(props) {
1971
- const {
1972
- registry: { translateString }
1973
- } = props;
1974
- return /* @__PURE__ */ jsxRuntime.jsx(
1975
- IconButton,
1976
- {
1977
- title: translateString(utils.TranslatableString.CopyButton),
1978
- className: "array-item-copy",
1979
- ...props,
1980
- icon: "copy"
1981
- }
1982
- );
2677
+ function CopyButton(props) {
2678
+ const {
2679
+ registry: { translateString }
2680
+ } = props;
2681
+ return /* @__PURE__ */ jsxRuntime.jsx(IconButton, { title: translateString(utils.TranslatableString.CopyButton), ...props, icon: "copy" });
1983
2682
  }
1984
2683
  function MoveDownButton(props) {
1985
2684
  const {
1986
2685
  registry: { translateString }
1987
2686
  } = props;
1988
- return /* @__PURE__ */ jsxRuntime.jsx(
1989
- IconButton,
1990
- {
1991
- title: translateString(utils.TranslatableString.MoveDownButton),
1992
- className: "array-item-move-down",
1993
- ...props,
1994
- icon: "arrow-down"
1995
- }
1996
- );
2687
+ return /* @__PURE__ */ jsxRuntime.jsx(IconButton, { title: translateString(utils.TranslatableString.MoveDownButton), ...props, icon: "arrow-down" });
1997
2688
  }
1998
2689
  function MoveUpButton(props) {
1999
2690
  const {
2000
2691
  registry: { translateString }
2001
2692
  } = props;
2002
- return /* @__PURE__ */ jsxRuntime.jsx(
2003
- IconButton,
2004
- {
2005
- title: translateString(utils.TranslatableString.MoveUpButton),
2006
- className: "array-item-move-up",
2007
- ...props,
2008
- icon: "arrow-up"
2009
- }
2010
- );
2693
+ return /* @__PURE__ */ jsxRuntime.jsx(IconButton, { title: translateString(utils.TranslatableString.MoveUpButton), ...props, icon: "arrow-up" });
2011
2694
  }
2012
2695
  function RemoveButton(props) {
2013
2696
  const {
2014
2697
  registry: { translateString }
2015
2698
  } = props;
2016
- return /* @__PURE__ */ jsxRuntime.jsx(
2017
- IconButton,
2018
- {
2019
- title: translateString(utils.TranslatableString.RemoveButton),
2020
- className: "array-item-remove",
2021
- ...props,
2022
- iconType: "danger",
2023
- icon: "remove"
2024
- }
2025
- );
2699
+ return /* @__PURE__ */ jsxRuntime.jsx(IconButton, { title: translateString(utils.TranslatableString.RemoveButton), ...props, iconType: "danger", icon: "remove" });
2026
2700
  }
2027
2701
  function AddButton({
2028
2702
  className,
@@ -2134,6 +2808,10 @@
2134
2808
  }
2135
2809
  return /* @__PURE__ */ jsxRuntime.jsx("div", { id, className: "help-block", children: help });
2136
2810
  }
2811
+ function GridTemplate(props) {
2812
+ const { children, column, className, ...rest } = props;
2813
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, ...rest, children });
2814
+ }
2137
2815
  function ObjectFieldTemplate(props) {
2138
2816
  const {
2139
2817
  description,
@@ -2185,7 +2863,8 @@
2185
2863
  utils.canExpand(schema, uiSchema, formData) && /* @__PURE__ */ jsxRuntime.jsx(
2186
2864
  AddButton2,
2187
2865
  {
2188
- className: "object-property-expand",
2866
+ id: utils.buttonId(idSchema, "add"),
2867
+ className: "rjsf-object-property-expand",
2189
2868
  onClick: onAddClick(schema),
2190
2869
  disabled: disabled || readonly,
2191
2870
  uiSchema,
@@ -2233,6 +2912,8 @@
2233
2912
  readonly,
2234
2913
  required,
2235
2914
  schema,
2915
+ hideError,
2916
+ rawErrors,
2236
2917
  children,
2237
2918
  uiSchema,
2238
2919
  registry
@@ -2241,10 +2922,15 @@
2241
2922
  const { RemoveButton: RemoveButton2 } = templates2.ButtonTemplates;
2242
2923
  const keyLabel = translateString(utils.TranslatableString.KeyLabel, [label]);
2243
2924
  const additional = utils.ADDITIONAL_PROPERTY_FLAG in schema;
2925
+ const classNamesList = ["form-group", classNames];
2926
+ if (!hideError && rawErrors && rawErrors.length > 0) {
2927
+ classNamesList.push("has-error has-danger");
2928
+ }
2929
+ const uiClassNames = classNamesList.join(" ").trim();
2244
2930
  if (!additional) {
2245
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames, style, children });
2931
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: uiClassNames, style, children });
2246
2932
  }
2247
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames, style, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "row", children: [
2933
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: uiClassNames, style, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "row", children: [
2248
2934
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-5 form-additional", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "form-group", children: [
2249
2935
  /* @__PURE__ */ jsxRuntime.jsx(Label, { label: keyLabel, required, id: `${id}-key` }),
2250
2936
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2262,7 +2948,8 @@
2262
2948
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-2", children: /* @__PURE__ */ jsxRuntime.jsx(
2263
2949
  RemoveButton2,
2264
2950
  {
2265
- className: "array-item-remove btn-block",
2951
+ id: utils.buttonId(id, "remove"),
2952
+ className: "rjsf-object-property-remove btn-block",
2266
2953
  style: { border: "0" },
2267
2954
  disabled: disabled || readonly,
2268
2955
  onClick: onDropPropertyClick(label),
@@ -2278,6 +2965,7 @@
2278
2965
  return {
2279
2966
  ArrayFieldDescriptionTemplate,
2280
2967
  ArrayFieldItemTemplate,
2968
+ ArrayFieldItemButtonsTemplate,
2281
2969
  ArrayFieldTemplate,
2282
2970
  ArrayFieldTitleTemplate,
2283
2971
  ButtonTemplates: ButtonTemplates_default(),
@@ -2287,6 +2975,7 @@
2287
2975
  FieldTemplate: FieldTemplate_default,
2288
2976
  FieldErrorTemplate,
2289
2977
  FieldHelpTemplate,
2978
+ GridTemplate,
2290
2979
  ObjectFieldTemplate,
2291
2980
  TitleFieldTemplate: TitleField,
2292
2981
  UnsupportedFieldTemplate: UnsupportedField_default,
@@ -2351,9 +3040,12 @@
2351
3040
  }) {
2352
3041
  const { translateString } = registry;
2353
3042
  const [lastValue, setLastValue] = react.useState(value);
2354
- const [state, setState] = react.useReducer((state2, action) => {
2355
- return { ...state2, ...action };
2356
- }, utils.parseDateString(value, time));
3043
+ const [state, setState] = react.useReducer(
3044
+ (state2, action) => {
3045
+ return { ...state2, ...action };
3046
+ },
3047
+ utils.parseDateString(value, time)
3048
+ );
2357
3049
  react.useEffect(() => {
2358
3050
  const stateValue = utils.toDateString(state, time);
2359
3051
  if (readyForChange(state) && stateValue !== value) {
@@ -2661,7 +3353,7 @@
2661
3353
  type: blob.type
2662
3354
  }
2663
3355
  ];
2664
- } catch (e) {
3356
+ } catch {
2665
3357
  return acc;
2666
3358
  }
2667
3359
  }, []);
@@ -2677,7 +3369,7 @@
2677
3369
  processFiles(event.target.files).then((filesInfoEvent) => {
2678
3370
  const newValue = filesInfoEvent.map((fileInfo) => fileInfo.dataURL);
2679
3371
  if (multiple) {
2680
- onChange(value.concat(newValue[0]));
3372
+ onChange(value.concat(newValue));
2681
3373
  } else {
2682
3374
  onChange(newValue[0]);
2683
3375
  }
@@ -2750,13 +3442,13 @@
2750
3442
  const { enumOptions, enumDisabled, inline, emptyValue } = options;
2751
3443
  const handleBlur = react.useCallback(
2752
3444
  ({ target }) => onBlur(id, utils.enumOptionsValueForIndex(target && target.value, enumOptions, emptyValue)),
2753
- [onBlur, id]
3445
+ [onBlur, enumOptions, emptyValue, id]
2754
3446
  );
2755
3447
  const handleFocus = react.useCallback(
2756
3448
  ({ target }) => onFocus(id, utils.enumOptionsValueForIndex(target && target.value, enumOptions, emptyValue)),
2757
- [onFocus, id]
3449
+ [onFocus, enumOptions, emptyValue, id]
2758
3450
  );
2759
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "field-radio-group", id, children: Array.isArray(enumOptions) && enumOptions.map((option, i) => {
3451
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "field-radio-group", id, role: "radiogroup", children: Array.isArray(enumOptions) && enumOptions.map((option, i) => {
2760
3452
  const checked = utils.enumOptionsIsSelected(option.value, value);
2761
3453
  const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1;
2762
3454
  const disabledCls = disabled || itemDisabled || readonly ? "disabled" : "";
@@ -2797,6 +3489,105 @@
2797
3489
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "range-view", children: value })
2798
3490
  ] });
2799
3491
  }
3492
+ function RatingWidget({
3493
+ id,
3494
+ value,
3495
+ required,
3496
+ disabled,
3497
+ readonly,
3498
+ autofocus,
3499
+ onChange,
3500
+ onFocus,
3501
+ onBlur,
3502
+ schema,
3503
+ options
3504
+ }) {
3505
+ const { stars = 5, shape = "star" } = options;
3506
+ const numStars = schema.maximum ? Math.min(schema.maximum, 5) : Math.min(Math.max(stars, 1), 5);
3507
+ const min = schema.minimum || 0;
3508
+ const handleStarClick = react.useCallback(
3509
+ (starValue) => {
3510
+ if (!disabled && !readonly) {
3511
+ onChange(starValue);
3512
+ }
3513
+ },
3514
+ [onChange, disabled, readonly]
3515
+ );
3516
+ const handleFocus = react.useCallback(
3517
+ (event) => {
3518
+ if (onFocus) {
3519
+ const starValue = Number(event.target.dataset.value);
3520
+ onFocus(id, starValue);
3521
+ }
3522
+ },
3523
+ [onFocus, id]
3524
+ );
3525
+ const handleBlur = react.useCallback(
3526
+ (event) => {
3527
+ if (onBlur) {
3528
+ const starValue = Number(event.target.dataset.value);
3529
+ onBlur(id, starValue);
3530
+ }
3531
+ },
3532
+ [onBlur, id]
3533
+ );
3534
+ const getSymbol = (isFilled) => {
3535
+ if (shape === "heart") {
3536
+ return isFilled ? "\u2665" : "\u2661";
3537
+ }
3538
+ return isFilled ? "\u2605" : "\u2606";
3539
+ };
3540
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(
3541
+ "div",
3542
+ {
3543
+ className: "rating-widget",
3544
+ style: {
3545
+ display: "inline-flex",
3546
+ fontSize: "1.5rem",
3547
+ cursor: disabled || readonly ? "default" : "pointer"
3548
+ },
3549
+ children: [
3550
+ [...Array(numStars)].map((_, index) => {
3551
+ const starValue = min + index;
3552
+ const isFilled = starValue <= value;
3553
+ return /* @__PURE__ */ jsxRuntime.jsx(
3554
+ "span",
3555
+ {
3556
+ onClick: () => handleStarClick(starValue),
3557
+ onFocus: handleFocus,
3558
+ onBlur: handleBlur,
3559
+ "data-value": starValue,
3560
+ tabIndex: disabled || readonly ? -1 : 0,
3561
+ role: "radio",
3562
+ "aria-checked": starValue === value,
3563
+ "aria-label": `${starValue} ${shape === "heart" ? "heart" : "star"}${starValue === 1 ? "" : "s"}`,
3564
+ style: {
3565
+ color: isFilled ? "#FFD700" : "#ccc",
3566
+ padding: "0 0.2rem",
3567
+ transition: "color 0.2s",
3568
+ userSelect: "none"
3569
+ },
3570
+ children: getSymbol(isFilled)
3571
+ },
3572
+ index
3573
+ );
3574
+ }),
3575
+ /* @__PURE__ */ jsxRuntime.jsx(
3576
+ "input",
3577
+ {
3578
+ type: "hidden",
3579
+ id,
3580
+ name: id,
3581
+ value: value || "",
3582
+ required,
3583
+ disabled: disabled || readonly,
3584
+ "aria-hidden": "true"
3585
+ }
3586
+ )
3587
+ ]
3588
+ }
3589
+ ) });
3590
+ }
2800
3591
  function getValue(event, multiple) {
2801
3592
  if (multiple) {
2802
3593
  return Array.from(event.target.options).slice().filter((o) => o.selected).map((o) => o.value);
@@ -2825,21 +3616,21 @@
2825
3616
  const newValue = getValue(event, multiple);
2826
3617
  return onFocus(id, utils.enumOptionsValueForIndex(newValue, enumOptions, optEmptyVal));
2827
3618
  },
2828
- [onFocus, id, schema, multiple, enumOptions, optEmptyVal]
3619
+ [onFocus, id, multiple, enumOptions, optEmptyVal]
2829
3620
  );
2830
3621
  const handleBlur = react.useCallback(
2831
3622
  (event) => {
2832
3623
  const newValue = getValue(event, multiple);
2833
3624
  return onBlur(id, utils.enumOptionsValueForIndex(newValue, enumOptions, optEmptyVal));
2834
3625
  },
2835
- [onBlur, id, schema, multiple, enumOptions, optEmptyVal]
3626
+ [onBlur, id, multiple, enumOptions, optEmptyVal]
2836
3627
  );
2837
3628
  const handleChange = react.useCallback(
2838
3629
  (event) => {
2839
3630
  const newValue = getValue(event, multiple);
2840
3631
  return onChange(utils.enumOptionsValueForIndex(newValue, enumOptions, optEmptyVal));
2841
3632
  },
2842
- [onChange, schema, multiple, enumOptions, optEmptyVal]
3633
+ [onChange, multiple, enumOptions, optEmptyVal]
2843
3634
  );
2844
3635
  const selectedIndexes = utils.enumOptionsIndexForValue(value, enumOptions, multiple);
2845
3636
  const showPlaceholderOption = !multiple && schema.default === void 0;
@@ -2849,6 +3640,7 @@
2849
3640
  id,
2850
3641
  name: id,
2851
3642
  multiple,
3643
+ role: "combobox",
2852
3644
  className: "form-control",
2853
3645
  value: typeof selectedIndexes === "undefined" ? emptyValue : selectedIndexes,
2854
3646
  required,
@@ -2957,6 +3749,7 @@
2957
3749
  PasswordWidget,
2958
3750
  RadioWidget: RadioWidget_default,
2959
3751
  RangeWidget,
3752
+ RatingWidget,
2960
3753
  SelectWidget: SelectWidget_default,
2961
3754
  TextWidget,
2962
3755
  TextareaWidget: TextareaWidget_default,
@@ -2979,6 +3772,10 @@
2979
3772
  };
2980
3773
  }
2981
3774
  var Form = class extends react.Component {
3775
+ /** The ref used to hold the `form` element, this needs to be `any` because `tagName` or `_internalFormWrapper` can
3776
+ * provide any possible type here
3777
+ */
3778
+ formElement;
2982
3779
  /** Constructs the `Form` from the `props`. Will setup the initial state from the props. It will also call the
2983
3780
  * `onChange` handler if the initially provided `formData` is modified to add missing default values as part of the
2984
3781
  * state construction.
@@ -2987,266 +3784,6 @@
2987
3784
  */
2988
3785
  constructor(props) {
2989
3786
  super(props);
2990
- /** Returns the `formData` with only the elements specified in the `fields` list
2991
- *
2992
- * @param formData - The data for the `Form`
2993
- * @param fields - The fields to keep while filtering
2994
- */
2995
- this.getUsedFormData = (formData, fields2) => {
2996
- if (fields2.length === 0 && typeof formData !== "object") {
2997
- return formData;
2998
- }
2999
- const data = _pick(formData, fields2);
3000
- if (Array.isArray(formData)) {
3001
- return Object.keys(data).map((key) => data[key]);
3002
- }
3003
- return data;
3004
- };
3005
- /** Returns the list of field names from inspecting the `pathSchema` as well as using the `formData`
3006
- *
3007
- * @param pathSchema - The `PathSchema` object for the form
3008
- * @param [formData] - The form data to use while checking for empty objects/arrays
3009
- */
3010
- this.getFieldNames = (pathSchema, formData) => {
3011
- const getAllPaths = (_obj, acc = [], paths = [[]]) => {
3012
- Object.keys(_obj).forEach((key) => {
3013
- if (typeof _obj[key] === "object") {
3014
- const newPaths = paths.map((path) => [...path, key]);
3015
- if (_obj[key][utils.RJSF_ADDITIONAL_PROPERTIES_FLAG] && _obj[key][utils.NAME_KEY] !== "") {
3016
- acc.push(_obj[key][utils.NAME_KEY]);
3017
- } else {
3018
- getAllPaths(_obj[key], acc, newPaths);
3019
- }
3020
- } else if (key === utils.NAME_KEY && _obj[key] !== "") {
3021
- paths.forEach((path) => {
3022
- const formValue = get3(formData, path);
3023
- if (typeof formValue !== "object" || isEmpty(formValue) || Array.isArray(formValue) && formValue.every((val) => typeof val !== "object")) {
3024
- acc.push(path);
3025
- }
3026
- });
3027
- }
3028
- });
3029
- return acc;
3030
- };
3031
- return getAllPaths(pathSchema);
3032
- };
3033
- /** Returns the `formData` after filtering to remove any extra data not in a form field
3034
- *
3035
- * @param formData - The data for the `Form`
3036
- * @returns The `formData` after omitting extra data
3037
- */
3038
- this.omitExtraData = (formData) => {
3039
- const { schema, schemaUtils } = this.state;
3040
- const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
3041
- const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", formData);
3042
- const fieldNames = this.getFieldNames(pathSchema, formData);
3043
- const newFormData = this.getUsedFormData(formData, fieldNames);
3044
- return newFormData;
3045
- };
3046
- /** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the
3047
- * `formData` along with a new `ErrorSchema`. It will first update the `formData` with any missing default fields and
3048
- * then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not
3049
- * in a form field. Then, the resulting formData will be validated if required. The state will be updated with the new
3050
- * updated (potentially filtered) `formData`, any errors that resulted from validation. Finally the `onChange`
3051
- * callback will be called if specified with the updated state.
3052
- *
3053
- * @param formData - The new form data from a change to a field
3054
- * @param newErrorSchema - The new `ErrorSchema` based on the field change
3055
- * @param id - The id of the field that caused the change
3056
- */
3057
- this.onChange = (formData, newErrorSchema, id) => {
3058
- const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange } = this.props;
3059
- const { schemaUtils, schema, retrievedSchema } = this.state;
3060
- if (utils.isObject(formData) || Array.isArray(formData)) {
3061
- const newState = this.getStateFromProps(this.props, formData, retrievedSchema);
3062
- formData = newState.formData;
3063
- }
3064
- const mustValidate = !noValidate && liveValidate;
3065
- let state = { formData, schema };
3066
- let newFormData = formData;
3067
- if (omitExtraData === true && liveOmit === true) {
3068
- newFormData = this.omitExtraData(formData);
3069
- state = {
3070
- formData: newFormData
3071
- };
3072
- }
3073
- if (mustValidate) {
3074
- const schemaValidation = this.validate(newFormData, schema, schemaUtils, retrievedSchema);
3075
- let errors = schemaValidation.errors;
3076
- let errorSchema = schemaValidation.errorSchema;
3077
- const schemaValidationErrors = errors;
3078
- const schemaValidationErrorSchema = errorSchema;
3079
- if (extraErrors) {
3080
- const merged = utils.validationDataMerge(schemaValidation, extraErrors);
3081
- errorSchema = merged.errorSchema;
3082
- errors = merged.errors;
3083
- }
3084
- if (newErrorSchema) {
3085
- const filteredErrors = this.filterErrorsBasedOnSchema(newErrorSchema, retrievedSchema, newFormData);
3086
- errorSchema = utils.mergeObjects(errorSchema, filteredErrors, "preventDuplicates");
3087
- }
3088
- state = {
3089
- formData: newFormData,
3090
- errors,
3091
- errorSchema,
3092
- schemaValidationErrors,
3093
- schemaValidationErrorSchema
3094
- };
3095
- } else if (!noValidate && newErrorSchema) {
3096
- const errorSchema = extraErrors ? utils.mergeObjects(newErrorSchema, extraErrors, "preventDuplicates") : newErrorSchema;
3097
- state = {
3098
- formData: newFormData,
3099
- errorSchema,
3100
- errors: utils.toErrorList(errorSchema)
3101
- };
3102
- }
3103
- this.setState(state, () => onChange && onChange({ ...this.state, ...state }, id));
3104
- };
3105
- /**
3106
- * Callback function to handle reset form data.
3107
- * - Reset all fields with default values.
3108
- * - Reset validations and errors
3109
- *
3110
- */
3111
- this.reset = () => {
3112
- const { onChange } = this.props;
3113
- const newState = this.getStateFromProps(this.props, void 0);
3114
- const newFormData = newState.formData;
3115
- const state = {
3116
- formData: newFormData,
3117
- errorSchema: {},
3118
- errors: [],
3119
- schemaValidationErrors: [],
3120
- schemaValidationErrorSchema: {}
3121
- };
3122
- this.setState(state, () => onChange && onChange({ ...this.state, ...state }));
3123
- };
3124
- /** Callback function to handle when a field on the form is blurred. Calls the `onBlur` callback for the `Form` if it
3125
- * was provided.
3126
- *
3127
- * @param id - The unique `id` of the field that was blurred
3128
- * @param data - The data associated with the field that was blurred
3129
- */
3130
- this.onBlur = (id, data) => {
3131
- const { onBlur } = this.props;
3132
- if (onBlur) {
3133
- onBlur(id, data);
3134
- }
3135
- };
3136
- /** Callback function to handle when a field on the form is focused. Calls the `onFocus` callback for the `Form` if it
3137
- * was provided.
3138
- *
3139
- * @param id - The unique `id` of the field that was focused
3140
- * @param data - The data associated with the field that was focused
3141
- */
3142
- this.onFocus = (id, data) => {
3143
- const { onFocus } = this.props;
3144
- if (onFocus) {
3145
- onFocus(id, data);
3146
- }
3147
- };
3148
- /** Callback function to handle when the form is submitted. First, it prevents the default event behavior. Nothing
3149
- * happens if the target and currentTarget of the event are not the same. It will omit any extra data in the
3150
- * `formData` in the state if `omitExtraData` is true. It will validate the resulting `formData`, reporting errors
3151
- * via the `onError()` callback unless validation is disabled. Finally, it will add in any `extraErrors` and then call
3152
- * back the `onSubmit` callback if it was provided.
3153
- *
3154
- * @param event - The submit HTML form event
3155
- */
3156
- this.onSubmit = (event) => {
3157
- event.preventDefault();
3158
- if (event.target !== event.currentTarget) {
3159
- return;
3160
- }
3161
- event.persist();
3162
- const { omitExtraData, extraErrors, noValidate, onSubmit } = this.props;
3163
- let { formData: newFormData } = this.state;
3164
- if (omitExtraData === true) {
3165
- newFormData = this.omitExtraData(newFormData);
3166
- }
3167
- if (noValidate || this.validateFormWithFormData(newFormData)) {
3168
- const errorSchema = extraErrors || {};
3169
- const errors = extraErrors ? utils.toErrorList(extraErrors) : [];
3170
- this.setState(
3171
- {
3172
- formData: newFormData,
3173
- errors,
3174
- errorSchema,
3175
- schemaValidationErrors: [],
3176
- schemaValidationErrorSchema: {}
3177
- },
3178
- () => {
3179
- if (onSubmit) {
3180
- onSubmit({ ...this.state, formData: newFormData, status: "submitted" }, event);
3181
- }
3182
- }
3183
- );
3184
- }
3185
- };
3186
- /** Provides a function that can be used to programmatically submit the `Form` */
3187
- this.submit = () => {
3188
- if (this.formElement.current) {
3189
- const submitCustomEvent = new CustomEvent("submit", {
3190
- cancelable: true
3191
- });
3192
- submitCustomEvent.preventDefault();
3193
- this.formElement.current.dispatchEvent(submitCustomEvent);
3194
- this.formElement.current.requestSubmit();
3195
- }
3196
- };
3197
- /** Validates the form using the given `formData`. For use on form submission or on programmatic validation.
3198
- * If `onError` is provided, then it will be called with the list of errors.
3199
- *
3200
- * @param formData - The form data to validate
3201
- * @returns - True if the form is valid, false otherwise.
3202
- */
3203
- this.validateFormWithFormData = (formData) => {
3204
- const { extraErrors, extraErrorsBlockSubmit, focusOnFirstError, onError } = this.props;
3205
- const { errors: prevErrors } = this.state;
3206
- const schemaValidation = this.validate(formData);
3207
- let errors = schemaValidation.errors;
3208
- let errorSchema = schemaValidation.errorSchema;
3209
- const schemaValidationErrors = errors;
3210
- const schemaValidationErrorSchema = errorSchema;
3211
- const hasError = errors.length > 0 || extraErrors && extraErrorsBlockSubmit;
3212
- if (hasError) {
3213
- if (extraErrors) {
3214
- const merged = utils.validationDataMerge(schemaValidation, extraErrors);
3215
- errorSchema = merged.errorSchema;
3216
- errors = merged.errors;
3217
- }
3218
- if (focusOnFirstError) {
3219
- if (typeof focusOnFirstError === "function") {
3220
- focusOnFirstError(errors[0]);
3221
- } else {
3222
- this.focusOnError(errors[0]);
3223
- }
3224
- }
3225
- this.setState(
3226
- {
3227
- errors,
3228
- errorSchema,
3229
- schemaValidationErrors,
3230
- schemaValidationErrorSchema
3231
- },
3232
- () => {
3233
- if (onError) {
3234
- onError(errors);
3235
- } else {
3236
- console.error("Form validation failed", errors);
3237
- }
3238
- }
3239
- );
3240
- } else if (prevErrors.length > 0) {
3241
- this.setState({
3242
- errors: [],
3243
- errorSchema: {},
3244
- schemaValidationErrors: [],
3245
- schemaValidationErrorSchema: {}
3246
- });
3247
- }
3248
- return !hasError;
3249
- };
3250
3787
  if (!props.validator) {
3251
3788
  throw new Error("A validator is required for Form functionality to work");
3252
3789
  }
@@ -3276,8 +3813,9 @@
3276
3813
  */
3277
3814
  getSnapshotBeforeUpdate(prevProps, prevState) {
3278
3815
  if (!utils.deepEquals(this.props, prevProps)) {
3816
+ const formDataChangedFields = utils.getChangedFields(this.props.formData, prevProps.formData);
3279
3817
  const isSchemaChanged = !utils.deepEquals(prevProps.schema, this.props.schema);
3280
- const isFormDataChanged = !utils.deepEquals(prevProps.formData, this.props.formData);
3818
+ const isFormDataChanged = formDataChangedFields.length > 0 || !utils.deepEquals(prevProps.formData, this.props.formData);
3281
3819
  const nextState = this.getStateFromProps(
3282
3820
  this.props,
3283
3821
  this.props.formData,
@@ -3285,7 +3823,8 @@
3285
3823
  // Or if the `formData` changes, for example in the case of a schema with dependencies that need to
3286
3824
  // match one of the subSchemas, the retrieved schema must be updated.
3287
3825
  isSchemaChanged || isFormDataChanged ? void 0 : this.state.retrievedSchema,
3288
- isSchemaChanged
3826
+ isSchemaChanged,
3827
+ formDataChangedFields
3289
3828
  );
3290
3829
  const shouldUpdate = !utils.deepEquals(nextState, prevState);
3291
3830
  return { nextState, shouldUpdate };
@@ -3300,9 +3839,6 @@
3300
3839
  * If an update is required, it applies the next state and, if needed, triggers the `onChange` handler to inform about
3301
3840
  * changes.
3302
3841
  *
3303
- * This method effectively replaces the deprecated `UNSAFE_componentWillReceiveProps`, providing a safer alternative
3304
- * to handle prop changes and state updates.
3305
- *
3306
3842
  * @param _ - The previous set of props.
3307
3843
  * @param prevState - The previous state of the component before the update.
3308
3844
  * @param snapshot - The value returned from `getSnapshotBeforeUpdate`.
@@ -3324,9 +3860,10 @@
3324
3860
  * @param inputFormData - The new or current data for the `Form`
3325
3861
  * @param retrievedSchema - An expanded schema, if not provided, it will be retrieved from the `schema` and `formData`.
3326
3862
  * @param isSchemaChanged - A flag indicating whether the schema has changed.
3863
+ * @param formDataChangedFields - The changed fields of `formData`
3327
3864
  * @returns - The new state for the `Form`
3328
3865
  */
3329
- getStateFromProps(props, inputFormData, retrievedSchema, isSchemaChanged = false) {
3866
+ getStateFromProps(props, inputFormData, retrievedSchema, isSchemaChanged = false, formDataChangedFields = []) {
3330
3867
  const state = this.state || {};
3331
3868
  const schema = "schema" in props ? props.schema : this.props.schema;
3332
3869
  const uiSchema = ("uiSchema" in props ? props.uiSchema : this.props.uiSchema) || {};
@@ -3335,12 +3872,25 @@
3335
3872
  const mustValidate = edit && !props.noValidate && liveValidate;
3336
3873
  const rootSchema = schema;
3337
3874
  const experimental_defaultFormStateBehavior = "experimental_defaultFormStateBehavior" in props ? props.experimental_defaultFormStateBehavior : this.props.experimental_defaultFormStateBehavior;
3875
+ const experimental_customMergeAllOf = "experimental_customMergeAllOf" in props ? props.experimental_customMergeAllOf : this.props.experimental_customMergeAllOf;
3338
3876
  let schemaUtils = state.schemaUtils;
3339
- if (!schemaUtils || schemaUtils.doesSchemaUtilsDiffer(props.validator, rootSchema, experimental_defaultFormStateBehavior)) {
3340
- schemaUtils = utils.createSchemaUtils(props.validator, rootSchema, experimental_defaultFormStateBehavior);
3877
+ if (!schemaUtils || schemaUtils.doesSchemaUtilsDiffer(
3878
+ props.validator,
3879
+ rootSchema,
3880
+ experimental_defaultFormStateBehavior,
3881
+ experimental_customMergeAllOf
3882
+ )) {
3883
+ schemaUtils = utils.createSchemaUtils(
3884
+ props.validator,
3885
+ rootSchema,
3886
+ experimental_defaultFormStateBehavior,
3887
+ experimental_customMergeAllOf
3888
+ );
3341
3889
  }
3342
3890
  const formData = schemaUtils.getDefaultFormState(schema, inputFormData);
3343
- const _retrievedSchema = retrievedSchema ?? schemaUtils.retrieveSchema(schema, formData);
3891
+ const _retrievedSchema = this.updateRetrievedSchema(
3892
+ retrievedSchema ?? schemaUtils.retrieveSchema(schema, formData)
3893
+ );
3344
3894
  const getCurrentErrors = () => {
3345
3895
  if (props.noValidate || isSchemaChanged) {
3346
3896
  return { errors: [], errorSchema: {} };
@@ -3362,7 +3912,7 @@
3362
3912
  if (mustValidate) {
3363
3913
  const schemaValidation = this.validate(formData, schema, schemaUtils, _retrievedSchema);
3364
3914
  errors = schemaValidation.errors;
3365
- if (isSchemaChanged) {
3915
+ if (retrievedSchema === void 0) {
3366
3916
  errorSchema = schemaValidation.errorSchema;
3367
3917
  } else {
3368
3918
  errorSchema = utils.mergeObjects(
@@ -3377,6 +3927,20 @@
3377
3927
  const currentErrors = getCurrentErrors();
3378
3928
  errors = currentErrors.errors;
3379
3929
  errorSchema = currentErrors.errorSchema;
3930
+ if (formDataChangedFields.length > 0) {
3931
+ const newErrorSchema = formDataChangedFields.reduce(
3932
+ (acc, key) => {
3933
+ acc[key] = void 0;
3934
+ return acc;
3935
+ },
3936
+ {}
3937
+ );
3938
+ errorSchema = schemaValidationErrorSchema = utils.mergeObjects(
3939
+ currentErrors.errorSchema,
3940
+ newErrorSchema,
3941
+ "preventDuplicates"
3942
+ );
3943
+ }
3380
3944
  }
3381
3945
  if (props.extraErrors) {
3382
3946
  const merged = utils.validationDataMerge({ errorSchema, errors }, props.extraErrors);
@@ -3414,6 +3978,21 @@
3414
3978
  shouldComponentUpdate(nextProps, nextState) {
3415
3979
  return utils.shouldRender(this, nextProps, nextState);
3416
3980
  }
3981
+ /** Gets the previously raised customValidate errors.
3982
+ *
3983
+ * @returns the previous customValidate errors
3984
+ */
3985
+ getPreviousCustomValidateErrors() {
3986
+ const { customValidate, uiSchema } = this.props;
3987
+ const prevFormData = this.state.formData;
3988
+ let customValidateErrors = {};
3989
+ if (typeof customValidate === "function") {
3990
+ const errorHandler = customValidate(prevFormData, utils.createErrorHandler(prevFormData), uiSchema);
3991
+ const userErrorSchema = utils.unwrapErrorHandler(errorHandler);
3992
+ customValidateErrors = userErrorSchema;
3993
+ }
3994
+ return customValidateErrors;
3995
+ }
3417
3996
  /** Validates the `formData` against the `schema` using the `altSchemaUtils` (if provided otherwise it uses the
3418
3997
  * `schemaUtils` in the state), returning the results.
3419
3998
  *
@@ -3448,6 +4027,62 @@
3448
4027
  }
3449
4028
  return null;
3450
4029
  }
4030
+ /** Returns the `formData` with only the elements specified in the `fields` list
4031
+ *
4032
+ * @param formData - The data for the `Form`
4033
+ * @param fields - The fields to keep while filtering
4034
+ */
4035
+ getUsedFormData = (formData, fields2) => {
4036
+ if (fields2.length === 0 && typeof formData !== "object") {
4037
+ return formData;
4038
+ }
4039
+ const data = _pick(formData, fields2);
4040
+ if (Array.isArray(formData)) {
4041
+ return Object.keys(data).map((key) => data[key]);
4042
+ }
4043
+ return data;
4044
+ };
4045
+ /** Returns the list of field names from inspecting the `pathSchema` as well as using the `formData`
4046
+ *
4047
+ * @param pathSchema - The `PathSchema` object for the form
4048
+ * @param [formData] - The form data to use while checking for empty objects/arrays
4049
+ */
4050
+ getFieldNames = (pathSchema, formData) => {
4051
+ const getAllPaths = (_obj, acc = [], paths = [[]]) => {
4052
+ Object.keys(_obj).forEach((key) => {
4053
+ if (typeof _obj[key] === "object") {
4054
+ const newPaths = paths.map((path) => [...path, key]);
4055
+ if (_obj[key][utils.RJSF_ADDITIONAL_PROPERTIES_FLAG] && _obj[key][utils.NAME_KEY] !== "") {
4056
+ acc.push(_obj[key][utils.NAME_KEY]);
4057
+ } else {
4058
+ getAllPaths(_obj[key], acc, newPaths);
4059
+ }
4060
+ } else if (key === utils.NAME_KEY && _obj[key] !== "") {
4061
+ paths.forEach((path) => {
4062
+ const formValue = get2(formData, path);
4063
+ if (typeof formValue !== "object" || isEmpty(formValue) || Array.isArray(formValue) && formValue.every((val) => typeof val !== "object")) {
4064
+ acc.push(path);
4065
+ }
4066
+ });
4067
+ }
4068
+ });
4069
+ return acc;
4070
+ };
4071
+ return getAllPaths(pathSchema);
4072
+ };
4073
+ /** Returns the `formData` after filtering to remove any extra data not in a form field
4074
+ *
4075
+ * @param formData - The data for the `Form`
4076
+ * @returns The `formData` after omitting extra data
4077
+ */
4078
+ omitExtraData = (formData) => {
4079
+ const { schema, schemaUtils } = this.state;
4080
+ const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
4081
+ const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", formData);
4082
+ const fieldNames = this.getFieldNames(pathSchema, formData);
4083
+ const newFormData = this.getUsedFormData(formData, fieldNames);
4084
+ return newFormData;
4085
+ };
3451
4086
  // Filtering errors based on your retrieved schema to only show errors for properties in the selected branch.
3452
4087
  filterErrorsBasedOnSchema(schemaErrors, resolvedSchema, formData) {
3453
4088
  const { retrievedSchema, schemaUtils } = this.state;
@@ -3458,18 +4093,185 @@
3458
4093
  if (resolvedSchema?.type !== "object" && resolvedSchema?.type !== "array") {
3459
4094
  filteredErrors.__errors = schemaErrors.__errors;
3460
4095
  }
3461
- const filterUndefinedErrors = (errors) => {
4096
+ const prevCustomValidateErrors = this.getPreviousCustomValidateErrors();
4097
+ const filterPreviousCustomErrors = (errors = [], prevCustomErrors) => {
4098
+ if (errors.length === 0) {
4099
+ return errors;
4100
+ }
4101
+ return errors.filter((error) => {
4102
+ return !prevCustomErrors.includes(error);
4103
+ });
4104
+ };
4105
+ const filterNilOrEmptyErrors = (errors, previousCustomValidateErrors = {}) => {
3462
4106
  _forEach(errors, (errorAtKey, errorKey) => {
3463
- if (errorAtKey === void 0) {
4107
+ const prevCustomValidateErrorAtKey = previousCustomValidateErrors[errorKey];
4108
+ if (_isNil(errorAtKey) || Array.isArray(errorAtKey) && errorAtKey.length === 0) {
3464
4109
  delete errors[errorKey];
4110
+ } else if (utils.isObject(errorAtKey) && utils.isObject(prevCustomValidateErrorAtKey) && Array.isArray(prevCustomValidateErrorAtKey?.__errors)) {
4111
+ errors[errorKey] = filterPreviousCustomErrors(errorAtKey.__errors, prevCustomValidateErrorAtKey.__errors);
3465
4112
  } else if (typeof errorAtKey === "object" && !Array.isArray(errorAtKey.__errors)) {
3466
- filterUndefinedErrors(errorAtKey);
4113
+ filterNilOrEmptyErrors(errorAtKey, previousCustomValidateErrors[errorKey]);
3467
4114
  }
3468
4115
  });
3469
4116
  return errors;
3470
4117
  };
3471
- return filterUndefinedErrors(filteredErrors);
4118
+ return filterNilOrEmptyErrors(filteredErrors, prevCustomValidateErrors);
4119
+ }
4120
+ /** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the
4121
+ * `formData` along with a new `ErrorSchema`. It will first update the `formData` with any missing default fields and
4122
+ * then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filtered to remove any extra data not
4123
+ * in a form field. Then, the resulting formData will be validated if required. The state will be updated with the new
4124
+ * updated (potentially filtered) `formData`, any errors that resulted from validation. Finally the `onChange`
4125
+ * callback will be called if specified with the updated state.
4126
+ *
4127
+ * @param formData - The new form data from a change to a field
4128
+ * @param newErrorSchema - The new `ErrorSchema` based on the field change
4129
+ * @param id - The id of the field that caused the change
4130
+ */
4131
+ onChange = (formData, newErrorSchema, id) => {
4132
+ const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange } = this.props;
4133
+ const { schemaUtils, schema } = this.state;
4134
+ let retrievedSchema = this.state.retrievedSchema;
4135
+ if (utils.isObject(formData) || Array.isArray(formData)) {
4136
+ const newState = this.getStateFromProps(this.props, formData);
4137
+ formData = newState.formData;
4138
+ retrievedSchema = newState.retrievedSchema;
4139
+ }
4140
+ const mustValidate = !noValidate && liveValidate;
4141
+ let state = { formData, schema };
4142
+ let newFormData = formData;
4143
+ if (omitExtraData === true && liveOmit === true) {
4144
+ newFormData = this.omitExtraData(formData);
4145
+ state = {
4146
+ formData: newFormData
4147
+ };
4148
+ }
4149
+ if (mustValidate) {
4150
+ const schemaValidation = this.validate(newFormData, schema, schemaUtils, retrievedSchema);
4151
+ let errors = schemaValidation.errors;
4152
+ let errorSchema = schemaValidation.errorSchema;
4153
+ const schemaValidationErrors = errors;
4154
+ const schemaValidationErrorSchema = errorSchema;
4155
+ if (extraErrors) {
4156
+ const merged = utils.validationDataMerge(schemaValidation, extraErrors);
4157
+ errorSchema = merged.errorSchema;
4158
+ errors = merged.errors;
4159
+ }
4160
+ if (newErrorSchema) {
4161
+ const filteredErrors = this.filterErrorsBasedOnSchema(newErrorSchema, retrievedSchema, newFormData);
4162
+ errorSchema = utils.mergeObjects(errorSchema, filteredErrors, "preventDuplicates");
4163
+ }
4164
+ state = {
4165
+ formData: newFormData,
4166
+ errors,
4167
+ errorSchema,
4168
+ schemaValidationErrors,
4169
+ schemaValidationErrorSchema
4170
+ };
4171
+ } else if (!noValidate && newErrorSchema) {
4172
+ const errorSchema = extraErrors ? utils.mergeObjects(newErrorSchema, extraErrors, "preventDuplicates") : newErrorSchema;
4173
+ state = {
4174
+ formData: newFormData,
4175
+ errorSchema,
4176
+ errors: utils.toErrorList(errorSchema)
4177
+ };
4178
+ }
4179
+ this.setState(state, () => onChange && onChange({ ...this.state, ...state }, id));
4180
+ };
4181
+ /**
4182
+ * If the retrievedSchema has changed the new retrievedSchema is returned.
4183
+ * Otherwise, the old retrievedSchema is returned to persist reference.
4184
+ * - This ensures that AJV retrieves the schema from the cache when it has not changed,
4185
+ * avoiding the performance cost of recompiling the schema.
4186
+ *
4187
+ * @param retrievedSchema The new retrieved schema.
4188
+ * @returns The new retrieved schema if it has changed, else the old retrieved schema.
4189
+ */
4190
+ updateRetrievedSchema(retrievedSchema) {
4191
+ const isTheSame = utils.deepEquals(retrievedSchema, this.state?.retrievedSchema);
4192
+ return isTheSame ? this.state.retrievedSchema : retrievedSchema;
3472
4193
  }
4194
+ /**
4195
+ * Callback function to handle reset form data.
4196
+ * - Reset all fields with default values.
4197
+ * - Reset validations and errors
4198
+ *
4199
+ */
4200
+ reset = () => {
4201
+ const { onChange } = this.props;
4202
+ const newState = this.getStateFromProps(this.props, void 0);
4203
+ const newFormData = newState.formData;
4204
+ const state = {
4205
+ formData: newFormData,
4206
+ errorSchema: {},
4207
+ errors: [],
4208
+ schemaValidationErrors: [],
4209
+ schemaValidationErrorSchema: {}
4210
+ };
4211
+ this.setState(state, () => onChange && onChange({ ...this.state, ...state }));
4212
+ };
4213
+ /** Callback function to handle when a field on the form is blurred. Calls the `onBlur` callback for the `Form` if it
4214
+ * was provided.
4215
+ *
4216
+ * @param id - The unique `id` of the field that was blurred
4217
+ * @param data - The data associated with the field that was blurred
4218
+ */
4219
+ onBlur = (id, data) => {
4220
+ const { onBlur } = this.props;
4221
+ if (onBlur) {
4222
+ onBlur(id, data);
4223
+ }
4224
+ };
4225
+ /** Callback function to handle when a field on the form is focused. Calls the `onFocus` callback for the `Form` if it
4226
+ * was provided.
4227
+ *
4228
+ * @param id - The unique `id` of the field that was focused
4229
+ * @param data - The data associated with the field that was focused
4230
+ */
4231
+ onFocus = (id, data) => {
4232
+ const { onFocus } = this.props;
4233
+ if (onFocus) {
4234
+ onFocus(id, data);
4235
+ }
4236
+ };
4237
+ /** Callback function to handle when the form is submitted. First, it prevents the default event behavior. Nothing
4238
+ * happens if the target and currentTarget of the event are not the same. It will omit any extra data in the
4239
+ * `formData` in the state if `omitExtraData` is true. It will validate the resulting `formData`, reporting errors
4240
+ * via the `onError()` callback unless validation is disabled. Finally, it will add in any `extraErrors` and then call
4241
+ * back the `onSubmit` callback if it was provided.
4242
+ *
4243
+ * @param event - The submit HTML form event
4244
+ */
4245
+ onSubmit = (event) => {
4246
+ event.preventDefault();
4247
+ if (event.target !== event.currentTarget) {
4248
+ return;
4249
+ }
4250
+ event.persist();
4251
+ const { omitExtraData, extraErrors, noValidate, onSubmit } = this.props;
4252
+ let { formData: newFormData } = this.state;
4253
+ if (omitExtraData === true) {
4254
+ newFormData = this.omitExtraData(newFormData);
4255
+ }
4256
+ if (noValidate || this.validateFormWithFormData(newFormData)) {
4257
+ const errorSchema = extraErrors || {};
4258
+ const errors = extraErrors ? utils.toErrorList(extraErrors) : [];
4259
+ this.setState(
4260
+ {
4261
+ formData: newFormData,
4262
+ errors,
4263
+ errorSchema,
4264
+ schemaValidationErrors: [],
4265
+ schemaValidationErrorSchema: {}
4266
+ },
4267
+ () => {
4268
+ if (onSubmit) {
4269
+ onSubmit({ ...this.state, formData: newFormData, status: "submitted" }, event);
4270
+ }
4271
+ }
4272
+ );
4273
+ }
4274
+ };
3473
4275
  /** Returns the registry for the form */
3474
4276
  getRegistry() {
3475
4277
  const { translateString: customTranslateString, uiSchema = {} } = this.props;
@@ -3493,6 +4295,17 @@
3493
4295
  globalUiOptions: uiSchema[utils.UI_GLOBAL_OPTIONS_KEY]
3494
4296
  };
3495
4297
  }
4298
+ /** Provides a function that can be used to programmatically submit the `Form` */
4299
+ submit = () => {
4300
+ if (this.formElement.current) {
4301
+ const submitCustomEvent = new CustomEvent("submit", {
4302
+ cancelable: true
4303
+ });
4304
+ submitCustomEvent.preventDefault();
4305
+ this.formElement.current.dispatchEvent(submitCustomEvent);
4306
+ this.formElement.current.requestSubmit();
4307
+ }
4308
+ };
3496
4309
  /** Attempts to focus on the field associated with the `error`. Uses the `property` field to compute path of the error
3497
4310
  * field, then, using the `idPrefix` and `idSeparator` converts that path into an id. Then the input element with that
3498
4311
  * id is attempted to be found using the `formElement` ref. If it is located, then it is focused.
@@ -3511,7 +4324,7 @@
3511
4324
  const elementId = path.join(idSeparator);
3512
4325
  let field = this.formElement.current.elements[elementId];
3513
4326
  if (!field) {
3514
- field = this.formElement.current.querySelector(`input[id^=${elementId}`);
4327
+ field = this.formElement.current.querySelector(`input[id^="${elementId}"`);
3515
4328
  }
3516
4329
  if (field && field.length) {
3517
4330
  field = field[0];
@@ -3520,6 +4333,59 @@
3520
4333
  field.focus();
3521
4334
  }
3522
4335
  }
4336
+ /** Validates the form using the given `formData`. For use on form submission or on programmatic validation.
4337
+ * If `onError` is provided, then it will be called with the list of errors.
4338
+ *
4339
+ * @param formData - The form data to validate
4340
+ * @returns - True if the form is valid, false otherwise.
4341
+ */
4342
+ validateFormWithFormData = (formData) => {
4343
+ const { extraErrors, extraErrorsBlockSubmit, focusOnFirstError, onError } = this.props;
4344
+ const { errors: prevErrors } = this.state;
4345
+ const schemaValidation = this.validate(formData);
4346
+ let errors = schemaValidation.errors;
4347
+ let errorSchema = schemaValidation.errorSchema;
4348
+ const schemaValidationErrors = errors;
4349
+ const schemaValidationErrorSchema = errorSchema;
4350
+ const hasError = errors.length > 0 || extraErrors && extraErrorsBlockSubmit;
4351
+ if (hasError) {
4352
+ if (extraErrors) {
4353
+ const merged = utils.validationDataMerge(schemaValidation, extraErrors);
4354
+ errorSchema = merged.errorSchema;
4355
+ errors = merged.errors;
4356
+ }
4357
+ if (focusOnFirstError) {
4358
+ if (typeof focusOnFirstError === "function") {
4359
+ focusOnFirstError(errors[0]);
4360
+ } else {
4361
+ this.focusOnError(errors[0]);
4362
+ }
4363
+ }
4364
+ this.setState(
4365
+ {
4366
+ errors,
4367
+ errorSchema,
4368
+ schemaValidationErrors,
4369
+ schemaValidationErrorSchema
4370
+ },
4371
+ () => {
4372
+ if (onError) {
4373
+ onError(errors);
4374
+ } else {
4375
+ console.error("Form validation failed", errors);
4376
+ }
4377
+ }
4378
+ );
4379
+ } else if (prevErrors.length > 0) {
4380
+ this.setState({
4381
+ errors: [],
4382
+ errorSchema: {},
4383
+ schemaValidationErrors: [],
4384
+ schemaValidationErrorSchema: {}
4385
+ });
4386
+ }
4387
+ return !hasError;
4388
+ };
3523
4389
  /** Programmatically validate the form. If `omitExtraData` is true, the `formData` will first be filtered to remove
3524
4390
  * any extra data not in a form field. If `onError` is provided, then it will be called with the list of errors the
3525
4391
  * same way as would happen on form submission.
@@ -3551,7 +4417,6 @@
3551
4417
  action,
3552
4418
  autoComplete,
3553
4419
  enctype,
3554
- acceptcharset,
3555
4420
  acceptCharset,
3556
4421
  noHtml5Validate = false,
3557
4422
  disabled,
@@ -3582,7 +4447,7 @@
3582
4447
  action,
3583
4448
  autoComplete,
3584
4449
  encType: enctype,
3585
- acceptCharset: acceptCharset || acceptcharset,
4450
+ acceptCharset,
3586
4451
  noValidate: noHtml5Validate,
3587
4452
  onSubmit: this.onSubmit,
3588
4453
  as,
@@ -3645,9 +4510,9 @@
3645
4510
  }
3646
4511
 
3647
4512
  // src/index.ts
3648
- var src_default = Form;
4513
+ var index_default = Form;
3649
4514
 
3650
- exports.default = src_default;
4515
+ exports.default = index_default;
3651
4516
  exports.getDefaultRegistry = getDefaultRegistry;
3652
4517
  exports.withTheme = withTheme;
3653
4518