torch-glare 2.5.5 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/README.md +4 -3
  2. package/dist/bin/index.js +9 -24
  3. package/dist/bin/index.js.map +1 -1
  4. package/dist/src/commands/add.d.ts +2 -2
  5. package/dist/src/commands/add.d.ts.map +1 -1
  6. package/dist/src/commands/add.js +4 -70
  7. package/dist/src/commands/add.js.map +1 -1
  8. package/dist/src/commands/hook.d.ts +5 -4
  9. package/dist/src/commands/hook.d.ts.map +1 -1
  10. package/dist/src/commands/hook.js +7 -75
  11. package/dist/src/commands/hook.js.map +1 -1
  12. package/dist/src/commands/init.js +1 -1
  13. package/dist/src/commands/init.js.map +1 -1
  14. package/dist/src/commands/layout.d.ts +5 -4
  15. package/dist/src/commands/layout.d.ts.map +1 -1
  16. package/dist/src/commands/layout.js +7 -75
  17. package/dist/src/commands/layout.js.map +1 -1
  18. package/dist/src/commands/provider.d.ts +5 -4
  19. package/dist/src/commands/provider.d.ts.map +1 -1
  20. package/dist/src/commands/provider.js +7 -75
  21. package/dist/src/commands/provider.js.map +1 -1
  22. package/dist/src/commands/update.d.ts.map +1 -1
  23. package/dist/src/commands/update.js +78 -43
  24. package/dist/src/commands/update.js.map +1 -1
  25. package/dist/src/commands/utils.d.ts +5 -4
  26. package/dist/src/commands/utils.d.ts.map +1 -1
  27. package/dist/src/commands/utils.js +7 -80
  28. package/dist/src/commands/utils.js.map +1 -1
  29. package/dist/src/shared/addFromRegistry.d.ts +16 -0
  30. package/dist/src/shared/addFromRegistry.d.ts.map +1 -0
  31. package/dist/src/shared/addFromRegistry.js +88 -0
  32. package/dist/src/shared/addFromRegistry.js.map +1 -0
  33. package/dist/src/shared/getInstallCommand.d.ts.map +1 -1
  34. package/dist/src/shared/getInstallCommand.js +5 -0
  35. package/dist/src/shared/getInstallCommand.js.map +1 -1
  36. package/dist/src/shared/installDependencies.d.ts +0 -10
  37. package/dist/src/shared/installDependencies.d.ts.map +1 -1
  38. package/dist/src/shared/installDependencies.js +0 -17
  39. package/dist/src/shared/installDependencies.js.map +1 -1
  40. package/dist/src/shared/installFromPlan.d.ts +7 -5
  41. package/dist/src/shared/installFromPlan.d.ts.map +1 -1
  42. package/dist/src/shared/installFromPlan.js +103 -36
  43. package/dist/src/shared/installFromPlan.js.map +1 -1
  44. package/dist/src/shared/loadRegistry.d.ts +12 -3
  45. package/dist/src/shared/loadRegistry.d.ts.map +1 -1
  46. package/dist/src/shared/loadRegistry.js +19 -20
  47. package/dist/src/shared/loadRegistry.js.map +1 -1
  48. package/dist/src/shared/registryClient.d.ts +19 -0
  49. package/dist/src/shared/registryClient.d.ts.map +1 -0
  50. package/dist/src/shared/registryClient.js +128 -0
  51. package/dist/src/shared/registryClient.js.map +1 -0
  52. package/dist/src/shared/resolveEntry.d.ts +10 -7
  53. package/dist/src/shared/resolveEntry.d.ts.map +1 -1
  54. package/dist/src/shared/resolveEntry.js +18 -13
  55. package/dist/src/shared/resolveEntry.js.map +1 -1
  56. package/dist/src/shared/suggestOtherCommand.d.ts +7 -1
  57. package/dist/src/shared/suggestOtherCommand.d.ts.map +1 -1
  58. package/dist/src/shared/suggestOtherCommand.js +29 -23
  59. package/dist/src/shared/suggestOtherCommand.js.map +1 -1
  60. package/dist/src/types/main.d.ts +31 -2
  61. package/dist/src/types/main.d.ts.map +1 -1
  62. package/package.json +6 -11
  63. package/apps/lib/components/ActionButton.tsx +0 -93
  64. package/apps/lib/components/ActionsGroup.tsx +0 -27
  65. package/apps/lib/components/AlertDialog.tsx +0 -204
  66. package/apps/lib/components/Avatar.tsx +0 -46
  67. package/apps/lib/components/Badge.tsx +0 -250
  68. package/apps/lib/components/BadgeField.tsx +0 -338
  69. package/apps/lib/components/Breadcrumb.tsx +0 -280
  70. package/apps/lib/components/Button.tsx +0 -317
  71. package/apps/lib/components/ButtonGroup.tsx +0 -190
  72. package/apps/lib/components/Calendar.tsx +0 -115
  73. package/apps/lib/components/Card.tsx +0 -95
  74. package/apps/lib/components/Checkbox.tsx +0 -42
  75. package/apps/lib/components/ColorPicker.tsx +0 -441
  76. package/apps/lib/components/ConclusionHeader.tsx +0 -148
  77. package/apps/lib/components/ContextMenu.tsx +0 -571
  78. package/apps/lib/components/CountBadge.tsx +0 -52
  79. package/apps/lib/components/DataTable.tsx +0 -213
  80. package/apps/lib/components/DataViews/badge.ts +0 -49
  81. package/apps/lib/components/DataViews/cell.tsx +0 -324
  82. package/apps/lib/components/DataViews/context.ts +0 -144
  83. package/apps/lib/components/DataViews/data-views.tsx +0 -383
  84. package/apps/lib/components/DataViews/filters/children.tsx +0 -98
  85. package/apps/lib/components/DataViews/filters/custom.tsx +0 -34
  86. package/apps/lib/components/DataViews/filters/filters.tsx +0 -157
  87. package/apps/lib/components/DataViews/filters/index.ts +0 -4
  88. package/apps/lib/components/DataViews/filters/labelled.tsx +0 -20
  89. package/apps/lib/components/DataViews/filters/presets.tsx +0 -65
  90. package/apps/lib/components/DataViews/filters/sync.tsx +0 -35
  91. package/apps/lib/components/DataViews/filters/values.ts +0 -173
  92. package/apps/lib/components/DataViews/header.tsx +0 -220
  93. package/apps/lib/components/DataViews/hooks/index.ts +0 -5
  94. package/apps/lib/components/DataViews/hooks/useActiveRow.ts +0 -22
  95. package/apps/lib/components/DataViews/hooks/useControllable.ts +0 -52
  96. package/apps/lib/components/DataViews/index.ts +0 -84
  97. package/apps/lib/components/DataViews/panel/columns.tsx +0 -153
  98. package/apps/lib/components/DataViews/panel/controls.tsx +0 -106
  99. package/apps/lib/components/DataViews/panel/index.ts +0 -3
  100. package/apps/lib/components/DataViews/panel/panel.tsx +0 -164
  101. package/apps/lib/components/DataViews/panel/saved-views.tsx +0 -67
  102. package/apps/lib/components/DataViews/panel/section.tsx +0 -81
  103. package/apps/lib/components/DataViews/panel/sort.tsx +0 -42
  104. package/apps/lib/components/DataViews/panel/tab.tsx +0 -31
  105. package/apps/lib/components/DataViews/slots.ts +0 -63
  106. package/apps/lib/components/DataViews/states.tsx +0 -38
  107. package/apps/lib/components/DataViews/types.ts +0 -510
  108. package/apps/lib/components/DataViews/views/board-view.tsx +0 -381
  109. package/apps/lib/components/DataViews/views/card-rows.tsx +0 -36
  110. package/apps/lib/components/DataViews/views/inbox-view.tsx +0 -260
  111. package/apps/lib/components/DataViews/views/pane-views.tsx +0 -196
  112. package/apps/lib/components/DataViews/views/table-view.tsx +0 -493
  113. package/apps/lib/components/DataViews/views/tree-view.tsx +0 -367
  114. package/apps/lib/components/DatePicker.tsx +0 -232
  115. package/apps/lib/components/Dialog.tsx +0 -116
  116. package/apps/lib/components/Divider.tsx +0 -28
  117. package/apps/lib/components/Drawer.tsx +0 -420
  118. package/apps/lib/components/DropdownMenu.tsx +0 -540
  119. package/apps/lib/components/FieldHint.tsx +0 -69
  120. package/apps/lib/components/Form.tsx +0 -182
  121. package/apps/lib/components/FormBuilder/context.ts +0 -73
  122. package/apps/lib/components/FormBuilder/field-kind.ts +0 -28
  123. package/apps/lib/components/FormBuilder/fields/ChoiceFields.tsx +0 -60
  124. package/apps/lib/components/FormBuilder/fields/ColorField.tsx +0 -59
  125. package/apps/lib/components/FormBuilder/fields/CustomField.tsx +0 -11
  126. package/apps/lib/components/FormBuilder/fields/DateField.tsx +0 -32
  127. package/apps/lib/components/FormBuilder/fields/FieldArray.tsx +0 -74
  128. package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +0 -163
  129. package/apps/lib/components/FormBuilder/fields/FileField.tsx +0 -39
  130. package/apps/lib/components/FormBuilder/fields/OptionListFields.tsx +0 -132
  131. package/apps/lib/components/FormBuilder/fields/OtpField.tsx +0 -31
  132. package/apps/lib/components/FormBuilder/fields/PhoneField.tsx +0 -109
  133. package/apps/lib/components/FormBuilder/fields/RichTextEditorField.tsx +0 -31
  134. package/apps/lib/components/FormBuilder/fields/SelectField.tsx +0 -91
  135. package/apps/lib/components/FormBuilder/fields/SignatureField.tsx +0 -157
  136. package/apps/lib/components/FormBuilder/fields/SliderField.tsx +0 -67
  137. package/apps/lib/components/FormBuilder/fields/SwitchBoxField.tsx +0 -41
  138. package/apps/lib/components/FormBuilder/fields/TableField.tsx +0 -336
  139. package/apps/lib/components/FormBuilder/fields/TextField.tsx +0 -213
  140. package/apps/lib/components/FormBuilder/fields/TreeSelectField.tsx +0 -43
  141. package/apps/lib/components/FormBuilder/fields/countries.ts +0 -303
  142. package/apps/lib/components/FormBuilder/fields/index.ts +0 -25
  143. package/apps/lib/components/FormBuilder/form-builder.tsx +0 -198
  144. package/apps/lib/components/FormBuilder/index.ts +0 -31
  145. package/apps/lib/components/FormBuilder/numberFormat.ts +0 -16
  146. package/apps/lib/components/FormBuilder/submit.tsx +0 -47
  147. package/apps/lib/components/FormBuilder/types.ts +0 -311
  148. package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -128
  149. package/apps/lib/components/FormRenderer/detail.tsx +0 -207
  150. package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -297
  151. package/apps/lib/components/FormRenderer/header.tsx +0 -88
  152. package/apps/lib/components/FormRenderer/index.ts +0 -15
  153. package/apps/lib/components/FormRenderer/section.tsx +0 -39
  154. package/apps/lib/components/FormRenderer/stepper.tsx +0 -339
  155. package/apps/lib/components/FormRenderer/types.ts +0 -78
  156. package/apps/lib/components/FormSummary.tsx +0 -282
  157. package/apps/lib/components/HeaderBar.tsx +0 -117
  158. package/apps/lib/components/ImageAttachment.tsx +0 -209
  159. package/apps/lib/components/InnerLabelField.tsx +0 -154
  160. package/apps/lib/components/Input.tsx +0 -224
  161. package/apps/lib/components/InputField.tsx +0 -147
  162. package/apps/lib/components/InputOTP.tsx +0 -84
  163. package/apps/lib/components/Label.tsx +0 -129
  164. package/apps/lib/components/LabelField.tsx +0 -76
  165. package/apps/lib/components/LabeledCheckBox.tsx +0 -51
  166. package/apps/lib/components/LabeledRadio.tsx +0 -51
  167. package/apps/lib/components/LinkButton.tsx +0 -94
  168. package/apps/lib/components/LoginButton.tsx +0 -51
  169. package/apps/lib/components/PasswordLevel.tsx +0 -58
  170. package/apps/lib/components/Popover.tsx +0 -312
  171. package/apps/lib/components/ProfileMenu.tsx +0 -85
  172. package/apps/lib/components/Radio.tsx +0 -59
  173. package/apps/lib/components/RadioCard.tsx +0 -50
  174. package/apps/lib/components/ScrollArea.tsx +0 -54
  175. package/apps/lib/components/SearchField.tsx +0 -62
  176. package/apps/lib/components/SearchableSelect.tsx +0 -318
  177. package/apps/lib/components/SearchableTable.tsx +0 -344
  178. package/apps/lib/components/SearchableTree.tsx +0 -485
  179. package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
  180. package/apps/lib/components/SectionBlock.tsx +0 -147
  181. package/apps/lib/components/Select.tsx +0 -347
  182. package/apps/lib/components/SimpleSelect.tsx +0 -225
  183. package/apps/lib/components/Skeleton.tsx +0 -12
  184. package/apps/lib/components/SlideDatePicker.tsx +0 -253
  185. package/apps/lib/components/SpinLoading.tsx +0 -174
  186. package/apps/lib/components/Stepper.tsx +0 -480
  187. package/apps/lib/components/Switch.tsx +0 -82
  188. package/apps/lib/components/TabFormItem.tsx +0 -153
  189. package/apps/lib/components/TabSwitch.tsx +0 -172
  190. package/apps/lib/components/Table.tsx +0 -610
  191. package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
  192. package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
  193. package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
  194. package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
  195. package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
  196. package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
  197. package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
  198. package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
  199. package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
  200. package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
  201. package/apps/lib/components/TextEditor/index.ts +0 -7
  202. package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
  203. package/apps/lib/components/Textarea.tsx +0 -117
  204. package/apps/lib/components/Timeline.tsx +0 -263
  205. package/apps/lib/components/Toast.tsx +0 -87
  206. package/apps/lib/components/Toggle.tsx +0 -125
  207. package/apps/lib/components/ToggleButton.tsx +0 -140
  208. package/apps/lib/components/Tooltip.tsx +0 -116
  209. package/apps/lib/components/TransparentLabel.tsx +0 -71
  210. package/apps/lib/components/TreeDropDown.tsx +0 -115
  211. package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
  212. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
  213. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
  214. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
  215. package/apps/lib/components/TreeFolder/icons.tsx +0 -60
  216. package/apps/lib/components/TreeFolder/index.ts +0 -24
  217. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
  218. package/apps/lib/components/TreeFolder/types.ts +0 -77
  219. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
  220. package/apps/lib/hooks/useActiveTreeItem.ts +0 -58
  221. package/apps/lib/hooks/useClickOutside.ts +0 -27
  222. package/apps/lib/hooks/useDragDrop.tsx +0 -365
  223. package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
  224. package/apps/lib/hooks/useIsMobile.ts +0 -21
  225. package/apps/lib/hooks/useResize.ts +0 -67
  226. package/apps/lib/hooks/useTagSelection.ts +0 -214
  227. package/apps/lib/layouts/CNLayout.tsx +0 -372
  228. package/apps/lib/layouts/DataViewCard.tsx +0 -62
  229. package/apps/lib/layouts/FieldSection.tsx +0 -91
  230. package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
  231. package/apps/lib/providers/ThemeProvider.tsx +0 -84
  232. package/apps/lib/registry.json +0 -1201
  233. package/apps/lib/tsconfig.json +0 -9
  234. package/apps/lib/tsconfig.tsbuildinfo +0 -1
  235. package/apps/lib/utils/cn.ts +0 -6
  236. package/apps/lib/utils/color.ts +0 -175
  237. package/apps/lib/utils/dataViews/path.ts +0 -67
  238. package/apps/lib/utils/dataViews/query.ts +0 -73
  239. package/apps/lib/utils/dataViews/types.ts +0 -187
  240. package/apps/lib/utils/dateFormat.ts +0 -108
  241. package/apps/lib/utils/resize.ts +0 -31
  242. package/apps/lib/utils/types.ts +0 -16
  243. package/docs/BLOCKS.md +0 -129
  244. package/docs/CHANGELOG-1.1.16.md +0 -108
  245. package/docs/Cover.png +0 -0
  246. package/docs/README.md +0 -215
  247. package/docs/components/action-button.md +0 -638
  248. package/docs/components/actions-group.md +0 -708
  249. package/docs/components/alert-dialog.md +0 -920
  250. package/docs/components/avatar.md +0 -709
  251. package/docs/components/badge-field.md +0 -712
  252. package/docs/components/badge.md +0 -301
  253. package/docs/components/breadcrumb.md +0 -930
  254. package/docs/components/button-group.md +0 -650
  255. package/docs/components/button.md +0 -639
  256. package/docs/components/calendar.md +0 -555
  257. package/docs/components/card.md +0 -622
  258. package/docs/components/chart-block-tool.md +0 -129
  259. package/docs/components/checkbox.md +0 -699
  260. package/docs/components/cn-layout.md +0 -854
  261. package/docs/components/color-picker.md +0 -101
  262. package/docs/components/conclusion-header.md +0 -80
  263. package/docs/components/context-menu.md +0 -483
  264. package/docs/components/count-badge.md +0 -560
  265. package/docs/components/data-table.md +0 -854
  266. package/docs/components/data-views/backend-response.md +0 -324
  267. package/docs/components/data-views/examples/a11y-rtl.md +0 -250
  268. package/docs/components/data-views/examples/api-orders-route.md +0 -130
  269. package/docs/components/data-views/examples/fields.md +0 -362
  270. package/docs/components/data-views/examples/filters.md +0 -307
  271. package/docs/components/data-views/examples/inbox-routing.md +0 -218
  272. package/docs/components/data-views/examples/index.md +0 -29
  273. package/docs/components/data-views/examples/overview.md +0 -244
  274. package/docs/components/data-views/examples/panel.md +0 -212
  275. package/docs/components/data-views/examples/scale.md +0 -231
  276. package/docs/components/data-views/examples/server-side.md +0 -210
  277. package/docs/components/data-views/examples/state.md +0 -250
  278. package/docs/components/data-views/examples/tree-custom.md +0 -388
  279. package/docs/components/data-views/examples/view-registry.md +0 -313
  280. package/docs/components/data-views/examples/views.md +0 -534
  281. package/docs/components/data-views/guide.md +0 -405
  282. package/docs/components/data-views/index.md +0 -1495
  283. package/docs/components/data-views/migration.md +0 -79
  284. package/docs/components/date-picker.md +0 -857
  285. package/docs/components/dialog.md +0 -929
  286. package/docs/components/divider.md +0 -766
  287. package/docs/components/drawer.md +0 -654
  288. package/docs/components/dropdown-menu.md +0 -668
  289. package/docs/components/field-hint.md +0 -898
  290. package/docs/components/field-section.md +0 -781
  291. package/docs/components/form-builder.md +0 -276
  292. package/docs/components/form-renderer.md +0 -326
  293. package/docs/components/form-summary.md +0 -138
  294. package/docs/components/form.md +0 -785
  295. package/docs/components/header-bar.md +0 -188
  296. package/docs/components/image-attachment.md +0 -906
  297. package/docs/components/inner-label-field.md +0 -819
  298. package/docs/components/input-field.md +0 -623
  299. package/docs/components/input-otp.md +0 -756
  300. package/docs/components/input.md +0 -634
  301. package/docs/components/label-field.md +0 -770
  302. package/docs/components/label.md +0 -761
  303. package/docs/components/labeled-check-box.md +0 -642
  304. package/docs/components/labeled-radio.md +0 -796
  305. package/docs/components/link-button.md +0 -685
  306. package/docs/components/login-button.md +0 -872
  307. package/docs/components/password-level.md +0 -803
  308. package/docs/components/popover.md +0 -649
  309. package/docs/components/profile-menu.md +0 -656
  310. package/docs/components/radio-card.md +0 -801
  311. package/docs/components/radio.md +0 -735
  312. package/docs/components/scroll-area.md +0 -691
  313. package/docs/components/search-field.md +0 -702
  314. package/docs/components/searchable-select.md +0 -368
  315. package/docs/components/searchable-table.md +0 -438
  316. package/docs/components/searchable-tree-dialog.md +0 -190
  317. package/docs/components/searchable-tree.md +0 -200
  318. package/docs/components/section-block.md +0 -477
  319. package/docs/components/select.md +0 -709
  320. package/docs/components/simple-select.md +0 -741
  321. package/docs/components/skeleton.md +0 -706
  322. package/docs/components/slide-date-picker.md +0 -837
  323. package/docs/components/spin-loading.md +0 -696
  324. package/docs/components/stepper.md +0 -316
  325. package/docs/components/switch.md +0 -770
  326. package/docs/components/tab-form-item.md +0 -773
  327. package/docs/components/tab-switch.md +0 -170
  328. package/docs/components/table-dnd-wrapper.md +0 -107
  329. package/docs/components/table.md +0 -1088
  330. package/docs/components/text-editor.md +0 -735
  331. package/docs/components/textarea.md +0 -681
  332. package/docs/components/timeline.md +0 -254
  333. package/docs/components/toast.md +0 -773
  334. package/docs/components/toggle-button.md +0 -643
  335. package/docs/components/toggle.md +0 -882
  336. package/docs/components/tooltip.md +0 -513
  337. package/docs/components/transparent-label.md +0 -721
  338. package/docs/components/tree-drop-down.md +0 -740
  339. package/docs/components/tree-folder.md +0 -110
  340. package/docs/components/tree-sub-layout.md +0 -707
  341. package/docs/explanation/architecture.md +0 -54
  342. package/docs/explanation/design-system.md +0 -52
  343. package/docs/how-to/form-and-list-recipes.md +0 -386
  344. package/docs/how-to/forms-with-form-builder.md +0 -472
  345. package/docs/how-to/guides.md +0 -1027
  346. package/docs/migration/changelog.md +0 -54
  347. package/docs/migration/form-builder-2.5.2.md +0 -113
  348. package/docs/reference/cli.md +0 -112
  349. package/docs/reference/components.md +0 -572
  350. package/docs/reference/hooks.md +0 -1500
  351. package/docs/reference/providers.md +0 -866
  352. package/docs/reference/tailwind-plugins.md +0 -942
  353. package/docs/reference/theme.md +0 -85
  354. package/docs/reference/types.md +0 -1016
  355. package/docs/reference/utilities.md +0 -704
  356. package/docs/tutorials/building-first-form.md +0 -846
  357. package/docs/tutorials/component-composition.md +0 -882
  358. package/docs/tutorials/getting-started.md +0 -302
  359. package/docs/tutorials/theming-basics.md +0 -785
@@ -1,276 +0,0 @@
1
- ---
2
- title: FormBuilder
3
- description: The fields. A compound, composition-based form — author fields as JSX children (FormBuilder.Text, FormBuilder.Select, …) wired to any react-hook-form resolver. All chrome around the fields lives in FormRenderer.
4
- component: true
5
- group: Forms
6
- keywords:
7
- [
8
- form-builder,
9
- form,
10
- compound,
11
- composition,
12
- react-hook-form,
13
- resolver,
14
- fields,
15
- validation,
16
- table,
17
- field-array,
18
- submit,
19
- ]
20
- ---
21
-
22
- # FormBuilder
23
-
24
- A **compound, composition-based** form. You author a form as JSX children — each
25
- field is a `FormBuilder.*` component wired to [react-hook-form](https://react-hook-form.com/)
26
- for you.
27
-
28
- ```tsx
29
- <FormBuilder onSubmit={save} resolver={zodResolver(schema)} defaultValues={d}>
30
- <FormBuilder.Text name="name" label="Name" required />
31
- <FormBuilder.Currency name="price" label="Price" currencySymbol="$" />
32
- </FormBuilder>
33
- ```
34
-
35
- ## FormBuilder is the fields — nothing else
36
-
37
- FormBuilder renders a `<form>`, its react-hook-form context, and your fields. Each field draws
38
- its own row (label, required marker, hint). Beyond that it draws **no frame at all**: no titled
39
- section cards, no page gutters, no scroll shell, no title header, no stepper rail, no summary
40
- column. Rendered bare it simply fills its container — which is what an embedded form wants (a
41
- settings rail, a `DataViews` filter panel).
42
-
43
- Everything drawn *around* the fields lives in **[FormRenderer](./form-renderer.md)**:
44
-
45
- | You want | Use |
46
- | ------------------------------------- | ---------------------------------------------------- |
47
- | A titled card grouping fields | `FormRenderer.Section` |
48
- | A page title header + Save action bar | `FormRenderer`'s `header` and `actions` props |
49
- | A wizard | `FormRenderer.Stepper` + `FormRenderer.Step` |
50
- | A drawer | `FormRenderer` with `display="drawer"` |
51
- | Live totals beside the form | `FormRenderer`'s `summary` prop + [FormSummary](./form-summary.md) |
52
- | A read-only detail page | `FormRenderer.Sidebar` + `FormRenderer.Tab` |
53
-
54
- > **For real forms, reach for [FormRenderer](./form-renderer.md), not raw FormBuilder.** You still
55
- > author the fields as `FormBuilder.*` children — FormRenderer just wraps them.
56
-
57
- `FormBuilder.Submit` is the one non-field part that stays here — see
58
- [Field components](#field-components) for what it does. It renders the **primary action**: the blue
59
- filled button. There is deliberately no `variant` prop — a form has one primary action, and letting
60
- each call site pick a style is how that stops being true.
61
-
62
- ## Installation
63
-
64
- TORCH Glare is a copy-in library: the CLI copies this component's source into your project.
65
-
66
- ```bash
67
- npx torch-glare@latest init
68
- npx torch-glare@latest add FormBuilder
69
- ```
70
-
71
- ## Imports
72
-
73
- ```tsx
74
- import { FormBuilder } from "@/components/FormBuilder";
75
- ```
76
-
77
- ## Root props
78
-
79
- | Prop | Type | Notes |
80
- | ---------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
81
- | `onSubmit` | `(values) => void \| Promise<void>` | Called on a valid submit. |
82
- | `onInvalid` | `(errors) => void` | Called when validation fails. |
83
- | `resolver` | `Resolver` | Any react-hook-form resolver, e.g. `zodResolver(schema)`. |
84
- | `defaultValues` | `DefaultValues` | Initial values (create). |
85
- | `values` | `T` | Controlled values (edit) — the form re-syncs when this changes. |
86
- | `loading` | `boolean` | Submit shows a spinner; inputs disable. |
87
- | `fieldDirection` | `'horizontal' \| 'vertical' \| 'flexible'` | Row layout. Unset is responsive; a `FormRenderer` drawer pins `'vertical'`, and `'flexible'` asks for the responsive layout back. |
88
- | `resetOnSuccess` | `boolean` | Reset to defaults after a successful submit. |
89
- | `form` | `UseFormReturn` | A hoisted `useForm` to bind to — pass when something outside the form must read the same values. |
90
- | `id` | `string` | Sets the underlying `<form id>`, so a button outside the form can submit it via `form={id}` (e.g. a drawer header's Save). |
91
- | `className` | `string` | Lands on the `<form>` element itself — e.g. `"min-w-0 flex-1"` to fill a flex parent. |
92
-
93
- There is no `layout` prop and no `conclusion` prop: the fields always fill their container, and a
94
- panel beside the form is `FormRenderer`'s `summary`.
95
-
96
- ## Field components
97
-
98
- Each is a JSX child taking at least `name`, plus `label`, `placeholder`,
99
- `description`, `required`, `disabled`, `hidden`, `fullWidth`, `hints`.
100
-
101
- ### Hints
102
-
103
- `hints` stacks alerts under a field — helper text, a caveat, a confirmation. Each entry mirrors
104
- `FieldHint`: `label`, an optional `state` of `info` (default) / `warning` / `error` / `success`, and
105
- an optional `icon`.
106
-
107
- ```tsx
108
- <FormBuilder.Text
109
- name="sku"
110
- label="SKU"
111
- required
112
- hints={[
113
- { state: "info", label: "Must be unique across the catalogue." },
114
- { state: "warning", label: "Changing this breaks existing links." },
115
- ]}
116
- />
117
- ```
118
-
119
- The validation error is not one of these — it is rendered automatically and always comes **first**,
120
- because it is the actionable message; your hints follow in the order given. A field with no `hints`
121
- renders exactly as before.
122
-
123
- Hints are ignored inside a `FormBuilder.Table` cell (and any other `bare` context): there errors
124
- surface as a tooltip on the control so a row stays one line tall, and stacking alerts would defeat
125
- that.
126
-
127
- | Component | Input | Value |
128
- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
129
- | `FormBuilder.Text` / `.Email` / `.Password` | `InputField` | `string` |
130
- | `FormBuilder.Number` | numeric `InputField` | `number` |
131
- | `FormBuilder.Currency` (`currencySymbol`) | `InputField` + symbol | `number` |
132
- | `FormBuilder.Textarea` | `Textarea` | `string` |
133
- | `FormBuilder.Slider` (`min,max,step,range`) | `@radix-ui/react-slider` | `number` / `[number,number]` |
134
- | `FormBuilder.Color` (`presets`, `alpha`) | `ColorPicker` (full palette: SV area, hue, opacity, eyedropper, HEX/RGB/HSL, presets) | hex `string` (`#rrggbb`, or `#rrggbbaa` when opacity < 100%) |
135
- | `FormBuilder.Phone` (`defaultCountry`) | `SearchableSelect` + `InputField` | `string` |
136
- | `FormBuilder.Select` (`options`) | `Select` | `string` |
137
- | `FormBuilder.SearchableSelect` (`options`, async: `onSearchChange`/`onLoadMore`/`hasMore`) | `SearchableSelect` | `string` |
138
- | `FormBuilder.MultiSelect` / `.Tags` (`options`) | `BadgeField` | `string[]` |
139
- | `FormBuilder.RadioList` (`options`, each with optional `description`) | boxed radio list | `string` |
140
- | `FormBuilder.CheckboxGroup` (`options`, each with optional `description`) | boxed checkbox list | `string[]` |
141
- | `FormBuilder.RadioCards` (`options` with `description`) | `RadioCard` | `string` |
142
- | `FormBuilder.Checkbox` (`subLabel`) | `Checkbox` + inline label | `boolean` |
143
- | `FormBuilder.SwitchBox` (`subLabel`) | `Switch` in a `#f9f9f9` box | `boolean` |
144
- | `FormBuilder.Otp` (`length`) | `InputOTP` | `string` |
145
- | `FormBuilder.Date` | `DatePicker` | `Date` |
146
- | `FormBuilder.DateRange` | `DatePicker` (range) | `{from,to}` |
147
- | `FormBuilder.DateMultiple` | `DatePicker` (multiple) | `Date[]` |
148
- | `FormBuilder.DateTime` | `DatePicker` (timePicker) | `Date` |
149
- | `FormBuilder.TreeSelect` (`nodes`, `getNodeId`, `getNodeLabel`, …) | `SearchableTree` | node id (`string`) |
150
- | `FormBuilder.File` / `.Image` (`accept`, `multiple`) | `ImageAttachment` | `File \| File[]` |
151
- | `FormBuilder.RichText` | `TextEditor` (EditorJS) | `OutputData` |
152
- | `FormBuilder.Signature` (`penColor`) | canvas pad | PNG data-URL `string` |
153
- | `FormBuilder.FieldArray` (`children` render fn, `defaultItem`) | RHF `useFieldArray` | `object[]` |
154
- | `FormBuilder.Table` (`columns`, `selectable`, `reorderable`, `defaultItem`) | editable grid in a `SectionBlock` | `object[]` |
155
- | `FormBuilder.Custom` (`render`) | your control | anything |
156
-
157
- `FormBuilder.Password` accepts `strengthMeter` (shows a `PasswordLevel` meter). `FormBuilder.FieldArray`
158
- renders a repeating list — its `children` is a render fn `(rowName, index, remove) => …` and sub-fields
159
- are named `${rowName}.field`.
160
-
161
- `FormBuilder.Table` is the **table-shaped** counterpart of `FieldArray` (value `object[]`): an editable
162
- grid where each row is a record and each column cell is any `FormBuilder.*` field. It renders its own
163
- `SectionBlock` (`variant="Table"` — the full-bleed table shell), so place it as a **top-level child** of
164
- the form, **not** inside a `FormRenderer.Section` — nesting produces a card inside a card. When you need a
165
- table that isn't a form field, compose the shell yourself with `SectionBlock variant="Table"` (see
166
- [SectionBlock → Table Variant](./section-block.md#table-variant)).
167
-
168
- Each column pairs a `header` with a `cell(rowName, index)` renderer — name the cell's field
169
- `${rowName}.<key>`. Set `width` to size a column; it is applied to both the header and the body cells.
170
- The section header carries the actions: an **Add New** button and a **Delete Row** button that's disabled
171
- until rows are checkbox-selected. A second **+ Add New** sits below the grid. Both live *outside* the
172
- horizontal scroll container, so they stay put when a wide table is scrolled sideways. Rows support
173
- **checkbox selection** (+ select-all), **drag-drop reordering**, and — per column, via `sortKey` — a
174
- sort toggle in the header. Cells render
175
- "bare" (control only) with validation errors shown as a tooltip on the control, so a row stays one line
176
- tall, and each field passes `onTable` so it's borderless and blends into the grid. Practical cell fields
177
- are the compact ones — `Text`, `Number`, `Currency`, `Select`, `SearchableSelect`, `Date`, `Phone`,
178
- `Checkbox`, `SwitchBox`; wide fields (`RichText`, `Signature`, `File`) work but aren't suited to a cell.
179
- `FormBuilder.Phone` collapses to a **plain number input** in a cell — two controls in one cell is not a
180
- table column, so add a separate column (e.g. a `FormBuilder.Select` of dial codes) if you need the
181
- country code.
182
-
183
- ```tsx
184
- <FormBuilder.Table
185
- name="items"
186
- title="Items"
187
- color="Green"
188
- addLabel="Add item"
189
- defaultItem={{ item: "", category: "hardware", qty: 1, price: 0 }}
190
- columns={[
191
- {
192
- header: "Item",
193
- width: 200,
194
- cell: (row) => <FormBuilder.Text name={`${row}.item`} required />,
195
- },
196
- {
197
- header: "Category",
198
- cell: (row) => <FormBuilder.Select name={`${row}.category`} options={CATEGORY} required />,
199
- },
200
- {
201
- header: "Qty",
202
- width: 110,
203
- cell: (row) => <FormBuilder.Number name={`${row}.qty`} required />,
204
- },
205
- {
206
- header: "Price",
207
- width: 140,
208
- cell: (row) => <FormBuilder.Currency name={`${row}.price`} currencySymbol="$" required />,
209
- },
210
- ]}
211
- />
212
- ```
213
-
214
- `FormBuilder.RadioList` (single-select, `string`) and `FormBuilder.CheckboxGroup` (multi-select,
215
- `string[]`) render their `options` as a boxed, divided list — control on the left, primary
216
- label, and an optional per-option `description` shown as a secondary label. The whole row is
217
- clickable. Multi-select is also available as `.MultiSelect` / `.Tags` (a tag-chip picker).
218
-
219
- `FormBuilder.SwitchBox` (value `boolean`) is a switch wrapped in a `#f9f9f9` field box. It
220
- renders like any other field — the `label` sits in the normal label column — and the box holds
221
- an optional inline `subLabel`, a vertical divider, and the switch.
222
-
223
- To group fields into a titled card, use [`FormRenderer.Section`](./form-renderer.md) — it is
224
- presentation, so it lives there.
225
-
226
- `FormBuilder.Submit` is a loading-aware submit button. It **auto-associates with the enclosing
227
- form** (via context), so it submits even when placed in a header / action bar that renders
228
- _outside_ the `<form>` — no manual `form={id}` wiring.
229
-
230
- ## Moved to FormRenderer
231
-
232
- These all used to live here. They are chrome, so they now live on
233
- [FormRenderer](./form-renderer.md):
234
-
235
- | Was | Now |
236
- | --- | --- |
237
- | `FormBuilder.Section` | `FormRenderer.Section` |
238
- | `FormBuilder.Stepper` / `.Step` / `.Back` / `.Next` | `FormRenderer.Stepper` / `.Step` / `.Back` / `.Next` |
239
- | `FormBuilder.Header` | `FormRenderer`'s `header` prop |
240
- | the `layout` prop | gone — the fields always fill their container |
241
- | the `conclusion` prop | `FormRenderer`'s `summary` prop |
242
-
243
- See [the migration note](../migration/form-builder-2.5.2.md) for the full upgrade path.
244
-
245
- ## Calculation panel
246
-
247
- To show computed totals **beside** the form, render a [FormSummary](./form-summary.md)
248
- next to it (not inside it) and share one hoisted form via the `form` prop:
249
-
250
- ```tsx
251
- const form = useForm({ resolver: r, defaultValues: d })
252
-
253
- <div className="flex items-start gap-4">
254
- <FormBuilder form={form} onSubmit={save} className="min-w-0 flex-1">…fields…</FormBuilder>
255
- <FormSummary form={form} title="Invoice">…rows…</FormSummary>
256
- </div>
257
- ```
258
-
259
- `form` makes FormBuilder use an existing react-hook-form instance instead of creating its
260
- own — that's what lets something outside the form read the same live values.
261
-
262
- ## Editing a record
263
-
264
- Pass `values` (not just `defaultValues`); the form repopulates when the data loads. Use a
265
- remount `key` so initial-only inputs (date, rich text) re-seed.
266
-
267
- ```tsx
268
- <FormBuilder key={entity.id} values={entity} onSubmit={save} resolver={r} defaultValues={d}>
269
- …the same fields…
270
- </FormBuilder>
271
- ```
272
-
273
- ## Validation
274
-
275
- Resolver-agnostic — pass any react-hook-form `resolver` (`zodResolver`, a plain
276
- resolver function, etc.). The library never depends on zod.
@@ -1,326 +0,0 @@
1
- ---
2
- title: FormRenderer
3
- description: The chrome around a FormBuilder. Author fields as JSX children; FormRenderer owns page-vs-drawer display, the title header, the actions bar, titled Sections, the stepper, and the summary panel. Prefer it over raw FormBuilder for real forms.
4
- component: true
5
- group: Forms
6
- keywords:
7
- [form-renderer, form, drawer, header, display, actions, section, stepper, summary, react-hook-form]
8
- ---
9
-
10
- # FormRenderer
11
-
12
- The **chrome** around a [FormBuilder](./form-builder.md). You author the fields as **JSX
13
- children** (`FormBuilder.Text`, `FormBuilder.Select`, …); `FormRenderer` draws everything
14
- around them:
15
-
16
- - **page vs drawer** display (`display="drawer"` hosts the form in a `FormDrawer`),
17
- - the **absolute title header** + `actions` bar,
18
- - **`FormRenderer.Section`** — the titled cards that group fields,
19
- - the **stepper** (`FormRenderer.Stepper` / `.Step`) and its nav rail,
20
- - the **`summary`** panel beside the form,
21
- - the page gutters and scroll shell, and **vertical field layout** inside a drawer.
22
-
23
- `FormBuilder` on its own is the fields and nothing else — no card, no header, no frame — so it
24
- fills whatever it is placed in. **For real forms, use `FormRenderer`**; reach for bare
25
- `FormBuilder` only when you are embedding fields inside something that already provides its own
26
- chrome (a settings rail, a filter panel).
27
-
28
- FormRenderer has **two modes**: a **form** (author fields as children, as below), or a display-only
29
- **detail page** — give it `FormRenderer.Sidebar` + `FormRenderer.Tab` children instead of fields and the
30
- sidebar swaps `FormRenderer.Tab` panels, whose content is `FormRenderer.Section` blocks (no `<form>`,
31
- no submit — see [Detail tabs](#detail-tabs-sidebar)).
32
-
33
- FormRenderer never manufactures a Submit — **you compose the Save and hand it to `actions`**.
34
- It renders in the form's header action pill (page) or the drawer header (drawer), and a bare
35
- `<FormBuilder.Submit>` auto-targets this form (even though the header sits outside the `<form>`).
36
-
37
- ```tsx
38
- <FormRenderer
39
- onSubmit={save}
40
- resolver={zodResolver(schema)}
41
- defaultValues={d}
42
- header={{ title: "Item", variant: "new" }}
43
- actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}
44
- >
45
- <FormRenderer.Section title="Identity" color="Blue">
46
- <FormBuilder.Text name="name" label="Name" required />
47
- <FormBuilder.Currency name="price" label="Price" currencySymbol="$" />
48
- </FormRenderer.Section>
49
- </FormRenderer>
50
- ```
51
-
52
- ## Compound parts
53
-
54
- | Part | What it is |
55
- | ------------------------------------------- | ------------------------------------------------------------------------------ |
56
- | `FormRenderer.Section` | A titled `SectionBlock` card grouping fields (or display rows). |
57
- | `FormRenderer.Stepper` / `.Step` | The wizard — see [Stepper](#stepper). |
58
- | `FormRenderer.Back` / `.Next` | Chevron step controls. The header's action bar prepends them for you. |
59
- | `FormRenderer.Sidebar` / `.Tab` | The display-only [detail-tabs](#detail-tabs-sidebar) view. |
60
- | `FormRenderer.Grid` / `.Row` | Read-only display cells inside a detail tab. |
61
-
62
- ### `FormRenderer.Section`
63
-
64
- Props `title`, `color`, `icon`, `action`, `variant`. It groups fields in a Glare `SectionBlock`:
65
- `color` is one of `Blue`, `Yellow`, `Green`, `Red`, `Orange`, `Purple`, `Pink`, `Gray`; `action`
66
- puts buttons on the title row; `variant="Table"` switches to the full-bleed table shell (what
67
- `FormBuilder.Table` uses internally).
68
-
69
- It holds no form state, which is why it lives here and not on `FormBuilder` — the same component
70
- groups editable fields on a form and read-only `FormRenderer.Row` cells on a detail page.
71
-
72
- Because it reads no context, it also works **outside** `<FormRenderer>` — e.g. wrapping fields in a
73
- bare `<FormBuilder>` that you are laying out yourself. It is the one compound part that does.
74
-
75
- > Not to be confused with `FieldSection`, the per-field row layout (label · control) that every
76
- > field draws for itself. That one stays inside FormBuilder.
77
-
78
- ## Installation
79
-
80
- ```bash
81
- npx torch-glare@latest init
82
- npx torch-glare@latest add FormRenderer
83
- ```
84
-
85
- `add` also pulls in `FormBuilder`, which FormRenderer renders through.
86
-
87
- ## Imports
88
-
89
- ```tsx
90
- import { FormRenderer, FormDrawer } from "@/components/FormRenderer";
91
- import { FormBuilder } from "@/components/FormBuilder";
92
- ```
93
-
94
- ## Props
95
-
96
- | Prop | Type | Notes |
97
- | -------------------------------------------------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98
- | `children` | `ReactNode` | The form body — `FormRenderer.Section` / field / `FormRenderer.Stepper` JSX. |
99
- | `onSubmit?` / `onInvalid?` | fns | Submit / validation-fail callbacks. Optional — a detail-tabs view has no form, so omit them there. |
100
- | `resolver` | `Resolver` | Any react-hook-form resolver, e.g. `zodResolver(schema)`. |
101
- | `defaultValues` / `values` | `DefaultValues` / `T` | Initial values; `values` re-syncs on change (edit). |
102
- | `loading` / `resetOnSuccess` | `boolean` | Forwarded to `FormBuilder`. |
103
- | `fieldDirection` | `'horizontal' \| 'vertical' \| 'flexible'` | Unset means responsive: stacked, then label-beside-control once the field row passes the container `md` breakpoint. A drawer defaults to `'vertical'` — pass `'flexible'` there to get the responsive layout back. |
104
- | `form` | `UseFormReturn<T>` | A hoisted `useForm` to bind to — pass when a sibling (e.g. a `summary` `FormSummary`) must read the same live values; the caller owns `resolver`/`defaultValues` on it. Omit to let FormRenderer create its own. |
105
- | `className` | `string` | Lands on FormRenderer's outermost element (page display) — e.g. `"min-h-0 flex-1"` to fill a flex column. Note this is the page frame, not the `<form>`; `FormBuilder`'s own `className` lands on the `<form>` element itself. |
106
- | `display` | `'page' \| 'drawer'` | `'drawer'` wraps the form in `FormDrawer`. |
107
- | `header` | `{ title; label?; variant? }` | Absolute title header + action bar (page display); `actions` render in it. |
108
- | `summary` | `ReactNode` | A live panel (typically `FormSummary`) rendered beside the form (page) or in the drawer tray (drawer). Give the same hoisted `form` so it reads live values. On a page, a `summary` **plus** a `FormRenderer.Stepper` lays out as three columns — stepper nav · fields · summary. |
109
- | `actions` | `ReactNode` | The form's action bar — rendered in the header action pill (page) or drawer header (drawer). Put the Save here: `actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}`. A bare `FormBuilder.Submit` auto-targets this form. |
110
- | `id` | `string` | `id` on the underlying `<form>`. Optional — FormRenderer generates and wires one otherwise. |
111
- | `open` / `onOpenChange` / `title` / `badge` / `onOpenInNewTab` | — | Drawer control (when `display="drawer"`). `title` / `badge` are strings that override `header.title` / `header.label`. |
112
-
113
- ## Drawer
114
-
115
- ```tsx
116
- // drawer — pass the Save via `actions`; it renders in the drawer header
117
- <FormRenderer
118
- display="drawer"
119
- open={open}
120
- onOpenChange={setOpen}
121
- title="New item"
122
- badge="New"
123
- onSubmit={save}
124
- resolver={r}
125
- defaultValues={d}
126
- actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}
127
- >
128
- {fields}
129
- </FormRenderer>
130
- ```
131
-
132
- ## Stepper
133
-
134
- Drop a `FormRenderer.Stepper` in as the child. The Save lives in the header `actions` and
135
- submits every step's registered fields at once (steps stay mounted, so the whole form is live).
136
-
137
- For a stepper, FormRenderer **automatically prepends chevron Back/Next nav + a divider** before
138
- your Submit, so the action bar reads `[◀] [▶] │ Save`. Back is disabled on the first step; Next
139
- validates the current step, then advances (disabled on the last step). A step that passes
140
- validation **stays checked** in the rail — even after you navigate back — while a live validation
141
- error overrides it to red. You still pass just the Submit; the nav is wired for you:
142
-
143
- ```tsx
144
- <FormRenderer
145
- onSubmit={save}
146
- resolver={r}
147
- defaultValues={d}
148
- header={{ title: "New item", variant: "new" }}
149
- actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}
150
- >
151
- <FormRenderer.Stepper>
152
- <FormRenderer.Step title="Basics">
153
- <FormBuilder.Text name="name" label="Name" required />
154
- </FormRenderer.Step>
155
- </FormRenderer.Stepper>
156
- </FormRenderer>
157
- ```
158
-
159
- ## Detail tabs (sidebar)
160
-
161
- Give FormRenderer `FormRenderer.Sidebar` + `FormRenderer.Tab` children (instead of fields) and it
162
- switches to a **display-only detail page**: a left **sidebar** where each item swaps in its matching
163
- tab panel — no `<form>`, no submit. The sidebar sits **where a stepper's rail would**, and only the
164
- active panel shows (built on the same Radix Tabs primitive shadcn uses, so it's keyboard-accessible).
165
- Pair it with `header` (`variant="detail"` → a "View" badge) + `actions` (Print / Approve / …).
166
-
167
- Each `Tab` holds read-only `FormRenderer.Section` blocks; `FormRenderer.Grid` + `FormRenderer.Row` lay
168
- out the label/value display cells (the display counterpart of form fields).
169
-
170
- ```tsx
171
- <FormRenderer
172
- header={{ title: "Order DE-344", variant: "detail" }}
173
- actions={<Button variant="BorderStyle">Print</Button>}
174
- >
175
- {/* The rail — one Item per tab, tied to a Tab by `value`. */}
176
- <FormRenderer.Sidebar>
177
- <FormRenderer.Sidebar.Item value="overview" icon={<i className="ri-layout-grid-line" />}>
178
- Overview
179
- </FormRenderer.Sidebar.Item>
180
- <FormRenderer.Sidebar.Item value="items" icon={<i className="ri-table-line" />}>
181
- Items Table
182
- </FormRenderer.Sidebar.Item>
183
- </FormRenderer.Sidebar>
184
-
185
- {/* One panel per tab — read-only Section blocks. */}
186
- <FormRenderer.Tab value="overview">
187
- <FormRenderer.Section title="Main Information" color="Blue">
188
- <FormRenderer.Grid>
189
- <FormRenderer.Row label="PO Number" value="PO-000123" />
190
- <FormRenderer.Row label="Status" value={<Badge label="Submitted" color="yellow" />} />
191
- </FormRenderer.Grid>
192
- </FormRenderer.Section>
193
- </FormRenderer.Tab>
194
-
195
- <FormRenderer.Tab value="items">…</FormRenderer.Tab>
196
- </FormRenderer>
197
- ```
198
-
199
- | Component | Props | Renders |
200
- | -------------- | -------------------------- | ------------------------------------------------------------------ |
201
- | `Sidebar` | `children` | The tab rail (a Radix `Tabs.List`), fixed at the stepper's place. |
202
- | `Sidebar.Item` | `value`, `icon?`, children | A rail nav row (a `Tabs.Trigger`); the active one is a black pill. |
203
- | `Tab` | `value`, children | A content panel (a `Tabs.Content`) shown when its tab is active. |
204
- | `Grid` | `columns?` (1–3), children | A padded grid of display `Row`s (default 2 columns). |
205
- | `Row` | `label`, `value` | A read-only label/value display cell. |
206
-
207
- The first `Tab` is active by default. Only the active panel is visible; the rail stays fixed while the
208
- content column scrolls.
209
-
210
- ## Summary panel
211
-
212
- Pass a hoisted `useForm` as `form` and a `FormSummary` as `summary` — FormRenderer binds
213
- the form to that instance and lays the panel beside the form (page) or in the drawer tray
214
- (drawer), so it recomputes live as fields change.
215
-
216
- ```tsx
217
- const form = useForm<Invoice>({ resolver, defaultValues })
218
-
219
- <FormRenderer
220
- form={form}
221
- onSubmit={save}
222
- header={{ title: 'Invoice', variant: 'new' }}
223
- actions={<FormBuilder.Submit>Save invoice</FormBuilder.Submit>}
224
- summary={
225
- <FormSummary form={form} title="Invoice" subtitle="Summary">
226
- <FormSummary.Group title="Total">
227
- <FormSummary.Row label="Overall Total" emphasized compute={overallTotal} />
228
- </FormSummary.Group>
229
- </FormSummary>
230
- }
231
- >
232
- {fields}
233
- </FormRenderer>
234
- ```
235
-
236
- Works with `display="drawer"` too — the summary moves into the drawer's tray.
237
-
238
- ## `FormDrawer` — the drawer wrapper
239
-
240
- `FormRenderer` uses `FormDrawer` internally for `display: 'drawer'`. It's also exported
241
- so you can put a hand-composed `FormBuilder` in a drawer directly. Since the header sits
242
- outside the `<form>`, wire the Save button to the form via `id` / `form={id}`:
243
-
244
- ```tsx
245
- <FormDrawer
246
- open={open}
247
- onOpenChange={setOpen}
248
- title="New item"
249
- badge="New"
250
- actions={
251
- <Button type="submit" form="item-form" is_loading={saving}>
252
- Save
253
- </Button>
254
- }
255
- >
256
- <FormBuilder
257
- id="item-form"
258
- onSubmit={save}
259
- resolver={r}
260
- defaultValues={d}
261
- fieldDirection="vertical"
262
- >
263
- …fields…
264
- </FormBuilder>
265
- </FormDrawer>
266
- ```
267
-
268
- `FormDrawer` props: `open`, `onOpenChange`, `title`, `badge`, `variant`, `actions`,
269
- `onOpenInNewTab`, `children`, `summary`. It owns no form state.
270
-
271
- ### The title
272
-
273
- The drawer renders the **same floating header as the page form** — a [HeaderBar](./header-bar.md)
274
- title pill on the left, a dark action pill on the right — so a form's title looks identical in
275
- either display. `title` is the plain (uppercased) text, `badge` the colored emphasis pill, and
276
- `variant` (`new` / `edit` / `detail`) picks the badge colors; `badge` defaults from it
277
- (New / Edit / View).
278
-
279
- ```tsx
280
- <FormDrawer title="Sales Invoice" badge="New" variant="new" … />
281
- ```
282
-
283
- Driving it through `FormRenderer`, the `header` prop feeds both displays — including
284
- `header.variant`, which the drawer previously ignored:
285
-
286
- ```tsx
287
- <FormRenderer display="drawer" header={{ title: "Sales Invoice", variant: "edit" }} … />
288
- ```
289
-
290
- `title` and `badge` are **plain strings** (they were `ReactNode` before this shared-header
291
- change) because they render through `HeaderBar`'s uppercase text treatment.
292
-
293
- ### A summary beside the form
294
-
295
- `summary` renders a conclusion panel — typically a [FormSummary](./form-summary.md) — _beside_
296
- the form rather than inside its scrollable body. `FormDrawer` puts the form in a
297
- [`DrawerPanel`](./drawer.md#drawerpanel) (the light surface) and the summary next to it with a
298
- 6px gutter; the tray paints nothing, so the summary keeps its own dark background and full
299
- height, scrolling internally when it outruns the drawer.
300
-
301
- Hoist the form so both read the same instance:
302
-
303
- ```tsx
304
- const form = useForm({ resolver, defaultValues })
305
-
306
- <FormDrawer
307
- open={open} onOpenChange={setOpen} title="New item" badge="New"
308
- summary={
309
- <FormSummary form={form} title="Item" subtitle="Summary">
310
- <FormSummary.Group title="Pricing">…rows…</FormSummary.Group>
311
- </FormSummary>
312
- }
313
- >
314
- <FormBuilder form={form} id="item-form" onSubmit={save} fieldDirection="vertical">
315
- …fields…
316
- </FormBuilder>
317
- </FormDrawer>
318
- ```
319
-
320
- > `childrenOutside` is the deprecated former name for `FormDrawer`'s `summary`. It still
321
- > works — it long predates the FormBuilder/FormRenderer split and is unrelated to it (that
322
- > move ships no aliases; see the
323
- > [migration note](../migration/form-builder-2.5.2.md)).
324
-
325
- `FormRenderer` forwards `summary` straight into the drawer tray, so you rarely need
326
- `FormDrawer` directly — reach for it only when you want the drawer without a form.