torch-glare 2.5.6 → 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 (362) 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 -403
  69. package/apps/lib/components/Breadcrumb.tsx +0 -280
  70. package/apps/lib/components/Button.tsx +0 -325
  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 -395
  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 -88
  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 -72
  106. package/apps/lib/components/DataViews/states.tsx +0 -73
  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 -451
  118. package/apps/lib/components/DropdownMenu.tsx +0 -554
  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 -85
  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 -168
  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 -114
  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 -67
  147. package/apps/lib/components/FormBuilder/types.ts +0 -316
  148. package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -250
  149. package/apps/lib/components/FormRenderer/detail.tsx +0 -256
  150. package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -358
  151. package/apps/lib/components/FormRenderer/header.tsx +0 -88
  152. package/apps/lib/components/FormRenderer/index.ts +0 -17
  153. package/apps/lib/components/FormRenderer/notch-action.tsx +0 -64
  154. package/apps/lib/components/FormRenderer/section.tsx +0 -39
  155. package/apps/lib/components/FormRenderer/stepper.tsx +0 -393
  156. package/apps/lib/components/FormRenderer/types.ts +0 -115
  157. package/apps/lib/components/FormSummary.tsx +0 -282
  158. package/apps/lib/components/HeaderBar.tsx +0 -117
  159. package/apps/lib/components/ImageAttachment.tsx +0 -209
  160. package/apps/lib/components/InnerLabelField.tsx +0 -154
  161. package/apps/lib/components/Input.tsx +0 -224
  162. package/apps/lib/components/InputField.tsx +0 -147
  163. package/apps/lib/components/InputOTP.tsx +0 -84
  164. package/apps/lib/components/Label.tsx +0 -129
  165. package/apps/lib/components/LabelField.tsx +0 -76
  166. package/apps/lib/components/LabeledCheckBox.tsx +0 -51
  167. package/apps/lib/components/LabeledRadio.tsx +0 -51
  168. package/apps/lib/components/LinkButton.tsx +0 -94
  169. package/apps/lib/components/LoginButton.tsx +0 -51
  170. package/apps/lib/components/PasswordLevel.tsx +0 -58
  171. package/apps/lib/components/Popover.tsx +0 -312
  172. package/apps/lib/components/ProfileMenu.tsx +0 -85
  173. package/apps/lib/components/Radio.tsx +0 -59
  174. package/apps/lib/components/RadioCard.tsx +0 -50
  175. package/apps/lib/components/ScrollArea.tsx +0 -54
  176. package/apps/lib/components/SearchField.tsx +0 -62
  177. package/apps/lib/components/SearchableSelect.tsx +0 -318
  178. package/apps/lib/components/SearchableTable.tsx +0 -344
  179. package/apps/lib/components/SearchableTree.tsx +0 -485
  180. package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
  181. package/apps/lib/components/SectionBlock.tsx +0 -168
  182. package/apps/lib/components/Select.tsx +0 -347
  183. package/apps/lib/components/SimpleSelect.tsx +0 -225
  184. package/apps/lib/components/Skeleton.tsx +0 -12
  185. package/apps/lib/components/SlideDatePicker.tsx +0 -255
  186. package/apps/lib/components/SpinLoading.tsx +0 -174
  187. package/apps/lib/components/Stepper.tsx +0 -480
  188. package/apps/lib/components/Switch.tsx +0 -82
  189. package/apps/lib/components/TabFormItem.tsx +0 -153
  190. package/apps/lib/components/TabSwitch.tsx +0 -172
  191. package/apps/lib/components/Table.tsx +0 -597
  192. package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
  193. package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
  194. package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
  195. package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
  196. package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
  197. package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
  198. package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
  199. package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
  200. package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
  201. package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
  202. package/apps/lib/components/TextEditor/index.ts +0 -7
  203. package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
  204. package/apps/lib/components/Textarea.tsx +0 -117
  205. package/apps/lib/components/Timeline.tsx +0 -263
  206. package/apps/lib/components/Toast.tsx +0 -87
  207. package/apps/lib/components/Toggle.tsx +0 -125
  208. package/apps/lib/components/ToggleButton.tsx +0 -140
  209. package/apps/lib/components/Tooltip.tsx +0 -116
  210. package/apps/lib/components/TransparentLabel.tsx +0 -71
  211. package/apps/lib/components/TreeDropDown.tsx +0 -115
  212. package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
  213. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
  214. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
  215. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
  216. package/apps/lib/components/TreeFolder/icons.tsx +0 -60
  217. package/apps/lib/components/TreeFolder/index.ts +0 -24
  218. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
  219. package/apps/lib/components/TreeFolder/types.ts +0 -77
  220. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
  221. package/apps/lib/hooks/useActiveTreeItem.ts +0 -61
  222. package/apps/lib/hooks/useClickOutside.ts +0 -27
  223. package/apps/lib/hooks/useDragDrop.tsx +0 -365
  224. package/apps/lib/hooks/useHtmlDir.ts +0 -31
  225. package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
  226. package/apps/lib/hooks/useIsMobile.ts +0 -21
  227. package/apps/lib/hooks/useResize.ts +0 -67
  228. package/apps/lib/hooks/useTagSelection.ts +0 -300
  229. package/apps/lib/layouts/CNLayout.tsx +0 -372
  230. package/apps/lib/layouts/DataViewCard.tsx +0 -62
  231. package/apps/lib/layouts/FieldSection.tsx +0 -91
  232. package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
  233. package/apps/lib/providers/ThemeProvider.tsx +0 -84
  234. package/apps/lib/registry.json +0 -1217
  235. package/apps/lib/tsconfig.json +0 -9
  236. package/apps/lib/tsconfig.tsbuildinfo +0 -1
  237. package/apps/lib/utils/cn.ts +0 -6
  238. package/apps/lib/utils/color.ts +0 -175
  239. package/apps/lib/utils/dataViews/path.ts +0 -67
  240. package/apps/lib/utils/dataViews/query.ts +0 -73
  241. package/apps/lib/utils/dataViews/types.ts +0 -187
  242. package/apps/lib/utils/dateFormat.ts +0 -108
  243. package/apps/lib/utils/resize.ts +0 -31
  244. package/apps/lib/utils/scroller.ts +0 -26
  245. package/apps/lib/utils/types.ts +0 -16
  246. package/docs/BLOCKS.md +0 -129
  247. package/docs/CHANGELOG-1.1.16.md +0 -108
  248. package/docs/Cover.png +0 -0
  249. package/docs/README.md +0 -215
  250. package/docs/components/action-button.md +0 -638
  251. package/docs/components/actions-group.md +0 -708
  252. package/docs/components/alert-dialog.md +0 -920
  253. package/docs/components/avatar.md +0 -709
  254. package/docs/components/badge-field.md +0 -738
  255. package/docs/components/badge.md +0 -301
  256. package/docs/components/breadcrumb.md +0 -930
  257. package/docs/components/button-group.md +0 -650
  258. package/docs/components/button.md +0 -639
  259. package/docs/components/calendar.md +0 -555
  260. package/docs/components/card.md +0 -622
  261. package/docs/components/chart-block-tool.md +0 -129
  262. package/docs/components/checkbox.md +0 -699
  263. package/docs/components/cn-layout.md +0 -854
  264. package/docs/components/color-picker.md +0 -101
  265. package/docs/components/conclusion-header.md +0 -80
  266. package/docs/components/context-menu.md +0 -483
  267. package/docs/components/count-badge.md +0 -560
  268. package/docs/components/data-table.md +0 -854
  269. package/docs/components/data-views/backend-response.md +0 -324
  270. package/docs/components/data-views/examples/a11y-rtl.md +0 -250
  271. package/docs/components/data-views/examples/api-orders-route.md +0 -130
  272. package/docs/components/data-views/examples/fields.md +0 -362
  273. package/docs/components/data-views/examples/filters.md +0 -307
  274. package/docs/components/data-views/examples/inbox-routing.md +0 -218
  275. package/docs/components/data-views/examples/index.md +0 -29
  276. package/docs/components/data-views/examples/overview.md +0 -244
  277. package/docs/components/data-views/examples/panel.md +0 -212
  278. package/docs/components/data-views/examples/scale.md +0 -231
  279. package/docs/components/data-views/examples/server-side.md +0 -210
  280. package/docs/components/data-views/examples/state.md +0 -250
  281. package/docs/components/data-views/examples/tree-custom.md +0 -388
  282. package/docs/components/data-views/examples/view-registry.md +0 -313
  283. package/docs/components/data-views/examples/views.md +0 -534
  284. package/docs/components/data-views/guide.md +0 -405
  285. package/docs/components/data-views/index.md +0 -1521
  286. package/docs/components/data-views/migration.md +0 -81
  287. package/docs/components/date-picker.md +0 -857
  288. package/docs/components/dialog.md +0 -929
  289. package/docs/components/divider.md +0 -766
  290. package/docs/components/drawer.md +0 -654
  291. package/docs/components/dropdown-menu.md +0 -668
  292. package/docs/components/field-hint.md +0 -898
  293. package/docs/components/field-section.md +0 -781
  294. package/docs/components/form-builder.md +0 -284
  295. package/docs/components/form-renderer.md +0 -396
  296. package/docs/components/form-summary.md +0 -138
  297. package/docs/components/form.md +0 -785
  298. package/docs/components/header-bar.md +0 -188
  299. package/docs/components/image-attachment.md +0 -906
  300. package/docs/components/inner-label-field.md +0 -819
  301. package/docs/components/input-field.md +0 -623
  302. package/docs/components/input-otp.md +0 -756
  303. package/docs/components/input.md +0 -634
  304. package/docs/components/label-field.md +0 -770
  305. package/docs/components/label.md +0 -761
  306. package/docs/components/labeled-check-box.md +0 -642
  307. package/docs/components/labeled-radio.md +0 -796
  308. package/docs/components/link-button.md +0 -685
  309. package/docs/components/login-button.md +0 -872
  310. package/docs/components/password-level.md +0 -803
  311. package/docs/components/popover.md +0 -649
  312. package/docs/components/profile-menu.md +0 -656
  313. package/docs/components/radio-card.md +0 -801
  314. package/docs/components/radio.md +0 -735
  315. package/docs/components/scroll-area.md +0 -691
  316. package/docs/components/search-field.md +0 -702
  317. package/docs/components/searchable-select.md +0 -368
  318. package/docs/components/searchable-table.md +0 -438
  319. package/docs/components/searchable-tree-dialog.md +0 -190
  320. package/docs/components/searchable-tree.md +0 -200
  321. package/docs/components/section-block.md +0 -483
  322. package/docs/components/select.md +0 -709
  323. package/docs/components/simple-select.md +0 -741
  324. package/docs/components/skeleton.md +0 -706
  325. package/docs/components/slide-date-picker.md +0 -837
  326. package/docs/components/spin-loading.md +0 -696
  327. package/docs/components/stepper.md +0 -316
  328. package/docs/components/switch.md +0 -770
  329. package/docs/components/tab-form-item.md +0 -773
  330. package/docs/components/tab-switch.md +0 -170
  331. package/docs/components/table-dnd-wrapper.md +0 -107
  332. package/docs/components/table.md +0 -1088
  333. package/docs/components/text-editor.md +0 -735
  334. package/docs/components/textarea.md +0 -681
  335. package/docs/components/timeline.md +0 -254
  336. package/docs/components/toast.md +0 -773
  337. package/docs/components/toggle-button.md +0 -643
  338. package/docs/components/toggle.md +0 -882
  339. package/docs/components/tooltip.md +0 -513
  340. package/docs/components/transparent-label.md +0 -721
  341. package/docs/components/tree-drop-down.md +0 -740
  342. package/docs/components/tree-folder.md +0 -110
  343. package/docs/components/tree-sub-layout.md +0 -707
  344. package/docs/explanation/architecture.md +0 -54
  345. package/docs/explanation/design-system.md +0 -52
  346. package/docs/how-to/form-and-list-recipes.md +0 -386
  347. package/docs/how-to/forms-with-form-builder.md +0 -472
  348. package/docs/how-to/guides.md +0 -1027
  349. package/docs/migration/changelog.md +0 -60
  350. package/docs/migration/form-builder-2.5.2.md +0 -113
  351. package/docs/reference/cli.md +0 -112
  352. package/docs/reference/components.md +0 -572
  353. package/docs/reference/hooks.md +0 -1523
  354. package/docs/reference/providers.md +0 -866
  355. package/docs/reference/tailwind-plugins.md +0 -942
  356. package/docs/reference/theme.md +0 -85
  357. package/docs/reference/types.md +0 -1016
  358. package/docs/reference/utilities.md +0 -726
  359. package/docs/tutorials/building-first-form.md +0 -846
  360. package/docs/tutorials/component-composition.md +0 -882
  361. package/docs/tutorials/getting-started.md +0 -302
  362. package/docs/tutorials/theming-basics.md +0 -785
@@ -1,396 +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
- | `FormRenderer.NotchAction` | A pill in the drawer's notch. You own the label, so it translates. |
62
-
63
- ### `FormRenderer.Section`
64
-
65
- Props `title`, `color`, `icon`, `action`, `variant`. It groups fields in a Glare `SectionBlock`:
66
- `color` is one of `Blue`, `Yellow`, `Green`, `Red`, `Orange`, `Purple`, `Pink`, `Gray`; `action`
67
- puts buttons on the title row; `variant="Table"` switches to the full-bleed table shell (what
68
- `FormBuilder.Table` uses internally).
69
-
70
- It holds no form state, which is why it lives here and not on `FormBuilder` — the same component
71
- groups editable fields on a form and read-only `FormRenderer.Row` cells on a detail page.
72
-
73
- Because it reads no context, it also works **outside** `<FormRenderer>` — e.g. wrapping fields in a
74
- bare `<FormBuilder>` that you are laying out yourself. It is the one compound part that does.
75
-
76
- > Not to be confused with `FieldSection`, the per-field row layout (label · control) that every
77
- > field draws for itself. That one stays inside FormBuilder.
78
-
79
- ## Installation
80
-
81
- ```bash
82
- npx torch-glare@latest init
83
- npx torch-glare@latest add FormRenderer
84
- ```
85
-
86
- `add` also pulls in `FormBuilder`, which FormRenderer renders through.
87
-
88
- ## Imports
89
-
90
- ```tsx
91
- import { FormRenderer, FormDrawer } from "@/components/FormRenderer";
92
- import { FormBuilder } from "@/components/FormBuilder";
93
- ```
94
-
95
- ## Props
96
-
97
- | Prop | Type | Notes |
98
- | -------------------------------------------------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
99
- | `children` | `ReactNode` | The form body — `FormRenderer.Section` / field / `FormRenderer.Stepper` JSX. |
100
- | `onSubmit?` / `onInvalid?` | fns | Submit / validation-fail callbacks. Optional — a detail-tabs view has no form, so omit them there. |
101
- | `resolver` | `Resolver` | Any react-hook-form resolver, e.g. `zodResolver(schema)`. |
102
- | `defaultValues` / `values` | `DefaultValues` / `T` | Initial values; `values` re-syncs on change (edit). |
103
- | `loading` / `resetOnSuccess` | `boolean` | Forwarded to `FormBuilder`. |
104
- | `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. |
105
- | `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. |
106
- | `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. |
107
- | `display` | `'page' \| 'drawer'` | `'drawer'` wraps the form in `FormDrawer`. |
108
- | `header` | `{ title; label?; variant? }` | Absolute title header + action bar (page display); `actions` render in it. |
109
- | `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. |
110
- | `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. |
111
- | `id` | `string` | `id` on the underlying `<form>`. Optional — FormRenderer generates and wires one otherwise. |
112
- | `open` / `onOpenChange` / `title` / `badge` / `onOpenInNewTab` | — | Drawer control (when `display="drawer"`). `title` / `badge` are strings that override `header.title` / `header.label`. |
113
- | `embedded` | `boolean` | Render without the rounded body card, for a host that already draws one. Defaults to `true` in a drawer. |
114
- | `activeTab` / `onTabChange` | `string` / `(tab) => void` | Make the [detail-tabs](#detail-tabs-sidebar) rail controlled, so the tab can live in the URL (`?tab=audit`) and survive a reload. Omit both for the uncontrolled default. Inert in form mode. |
115
- | `activeStep` / `onStepChange` | `number` / `(index) => void` | External control of a `FormRenderer.Stepper`'s step, for a wizard owned by something other than form validity. In controlled mode internal advancement is suppressed and a click is *reported*, not applied. Omit both and the stepper behaves exactly as before. |
116
- | `drawer` | `{ side?; nested?; framed?; hideHeader?; bareBody?; description?; wrapperClassName?; className? }` | Drawer layout, forwarded to `FormDrawer` — see [Drawer layout](#drawer-layout). One object rather than eight flat props, since none of it means anything on a page. |
117
-
118
- ## Drawer
119
-
120
- ```tsx
121
- // drawer — pass the Save via `actions`; it renders in the drawer header
122
- <FormRenderer
123
- display="drawer"
124
- open={open}
125
- onOpenChange={setOpen}
126
- title="New item"
127
- badge="New"
128
- onSubmit={save}
129
- resolver={r}
130
- defaultValues={d}
131
- actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}
132
- >
133
- {fields}
134
- </FormRenderer>
135
- ```
136
-
137
- ### Drawer layout
138
-
139
- Everything about how the drawer is *shaped* goes in one `drawer` object, because none of it means
140
- anything on a page:
141
-
142
- | Key | Type | Default | What it does |
143
- | ----------------- | ----------------------------- | --------------- | -------------------------------------------------------------------------------------------------- |
144
- | `side` | `'inline-end' \| 'bottom'` | `'inline-end'` | Which edge it slides from. `'bottom'` is a sheet and drops the notch — there is no inline edge to hang it from. The default follows document direction. |
145
- | `nested` | `boolean` | `false` | **Required** when this drawer opens inside another one, or the two roots fight over the overlay and the scroll lock. Throws without a parent Drawer. |
146
- | `framed` | `boolean` | `true` | The dark tray frame and the panel's border / inset shadow. |
147
- | `hideHeader` | `boolean` | `false` | Skip the header bar, for a child that draws its own. Also drops the body's top padding. |
148
- | `bareBody` | `boolean` | `false` | Skip the padded scroll wrapper, for a child that already scrolls and offsets for its own header. |
149
- | `description` | `string` | — | Screen-reader-only description. vaul warns when a drawer has none. |
150
- | `wrapperClassName`| `string` | per `side` | Lands on the positioner — width, height, insets. Replaces the default sizing. |
151
- | `className` | `string` | — | Lands on the tray. |
152
-
153
- ```tsx
154
- // A bottom sheet, opened from inside another drawer.
155
- <FormRenderer
156
- display="drawer"
157
- open={open}
158
- onOpenChange={setOpen}
159
- title="Quick add"
160
- drawer={{ side: "bottom", nested: true, description: "Add a line item" }}
161
- onSubmit={save}
162
- actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}
163
- >
164
- {fields}
165
- </FormRenderer>
166
- ```
167
-
168
- ### `FormRenderer.NotchAction`
169
-
170
- Buttons in the drawer's notch, authored by you. `onOpenInNewTab` still works, but it hardcodes an
171
- English label and allows only one action — write `NotchAction` children instead and you own both.
172
- They render nothing where you write them; the renderer lifts them into the notch.
173
-
174
- ```tsx
175
- <FormRenderer display="drawer" open={open} onOpenChange={setOpen} title={t("invoice")}>
176
- <FormRenderer.NotchAction onClick={openFullPage}>
177
- {t("openInNewTab")}
178
- <i className="ri-arrow-right-up-line text-[12px]" />
179
- </FormRenderer.NotchAction>
180
- <FormRenderer.NotchAction color="Blue" onClick={print}>
181
- {t("print")}
182
- </FormRenderer.NotchAction>
183
-
184
- {fields}
185
- </FormRenderer>
186
- ```
187
-
188
- `color` matches `DrawerNotchPill` and defaults to `"Yellow"`. Ignored on a page-display form, and a
189
- `side: "bottom"` sheet has no notch to put them in.
190
-
191
- ## Stepper
192
-
193
- Drop a `FormRenderer.Stepper` in as the child. The Save lives in the header `actions` and
194
- submits every step's registered fields at once (steps stay mounted, so the whole form is live).
195
-
196
- For a stepper, FormRenderer **automatically prepends chevron Back/Next nav + a divider** before
197
- your Submit, so the action bar reads `[◀] [▶] │ Save`. Back is disabled on the first step; Next
198
- validates the current step, then advances (disabled on the last step). A step that passes
199
- validation **stays checked** in the rail — even after you navigate back — while a live validation
200
- error overrides it to red. You still pass just the Submit; the nav is wired for you:
201
-
202
- The rail **stays put while the fields scroll**. It is navigation, so it pins below the header rather
203
- than scrolling out of view with the form; a rail taller than the form body scrolls to its end first,
204
- as any sticky element does.
205
-
206
- ```tsx
207
- <FormRenderer
208
- onSubmit={save}
209
- resolver={r}
210
- defaultValues={d}
211
- header={{ title: "New item", variant: "new" }}
212
- actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}
213
- >
214
- <FormRenderer.Stepper>
215
- <FormRenderer.Step title="Basics">
216
- <FormBuilder.Text name="name" label="Name" required />
217
- </FormRenderer.Step>
218
- </FormRenderer.Stepper>
219
- </FormRenderer>
220
- ```
221
-
222
- ## Detail tabs (sidebar)
223
-
224
- Give FormRenderer `FormRenderer.Sidebar` + `FormRenderer.Tab` children (instead of fields) and it
225
- switches to a **display-only detail page**: a left **sidebar** where each item swaps in its matching
226
- tab panel — no `<form>`, no submit. The sidebar sits **where a stepper's rail would**, and only the
227
- active panel shows (built on the same Radix Tabs primitive shadcn uses, so it's keyboard-accessible).
228
- Pair it with `header` (`variant="detail"` → a "View" badge) + `actions` (Print / Approve / …).
229
-
230
- Each `Tab` holds read-only `FormRenderer.Section` blocks; `FormRenderer.Grid` + `FormRenderer.Row` lay
231
- out the label/value display cells (the display counterpart of form fields).
232
-
233
- ```tsx
234
- <FormRenderer
235
- header={{ title: "Order DE-344", variant: "detail" }}
236
- actions={<Button variant="BorderStyle">Print</Button>}
237
- >
238
- {/* The rail — one Item per tab, tied to a Tab by `value`. */}
239
- <FormRenderer.Sidebar>
240
- <FormRenderer.Sidebar.Item value="overview" icon={<i className="ri-layout-grid-line" />}>
241
- Overview
242
- </FormRenderer.Sidebar.Item>
243
- <FormRenderer.Sidebar.Item value="items" icon={<i className="ri-table-line" />}>
244
- Items Table
245
- </FormRenderer.Sidebar.Item>
246
- </FormRenderer.Sidebar>
247
-
248
- {/* One panel per tab — read-only Section blocks. */}
249
- <FormRenderer.Tab value="overview">
250
- <FormRenderer.Section title="Main Information" color="Blue">
251
- <FormRenderer.Grid>
252
- <FormRenderer.Row label="PO Number" value="PO-000123" />
253
- <FormRenderer.Row label="Status" value={<Badge label="Submitted" color="yellow" />} />
254
- </FormRenderer.Grid>
255
- </FormRenderer.Section>
256
- </FormRenderer.Tab>
257
-
258
- <FormRenderer.Tab value="items">…</FormRenderer.Tab>
259
- </FormRenderer>
260
- ```
261
-
262
- | Component | Props | Renders |
263
- | -------------- | -------------------------- | ------------------------------------------------------------------ |
264
- | `Sidebar` | `children` | The tab rail (a Radix `Tabs.List`), fixed at the stepper's place. |
265
- | `Sidebar.Item` | `value`, `icon?`, children | A rail nav row (a `Tabs.Trigger`); the active one is a black pill. |
266
- | `Tab` | `value`, children | A content panel (a `Tabs.Content`) shown when its tab is active. |
267
- | `Grid` | `columns?` (1–3), children | A padded grid of display `Row`s (default 2 columns). |
268
- | `Row` | `label`, `value` | A read-only label/value display cell. |
269
-
270
- The first `Tab` is active by default. Only the active panel is visible; the rail stays fixed while the
271
- content column scrolls.
272
-
273
- ## Summary panel
274
-
275
- Pass a hoisted `useForm` as `form` and a `FormSummary` as `summary` — FormRenderer binds
276
- the form to that instance and lays the panel beside the form (page) or in the drawer tray
277
- (drawer), so it recomputes live as fields change.
278
-
279
- ```tsx
280
- const form = useForm<Invoice>({ resolver, defaultValues })
281
-
282
- <FormRenderer
283
- form={form}
284
- onSubmit={save}
285
- header={{ title: 'Invoice', variant: 'new' }}
286
- actions={<FormBuilder.Submit>Save invoice</FormBuilder.Submit>}
287
- summary={
288
- <FormSummary form={form} title="Invoice" subtitle="Summary">
289
- <FormSummary.Group title="Total">
290
- <FormSummary.Row label="Overall Total" emphasized compute={overallTotal} />
291
- </FormSummary.Group>
292
- </FormSummary>
293
- }
294
- >
295
- {fields}
296
- </FormRenderer>
297
- ```
298
-
299
- Works with `display="drawer"` too — the summary moves into the drawer's tray.
300
-
301
- ## `FormDrawer` — the drawer wrapper
302
-
303
- `FormRenderer` uses `FormDrawer` internally for `display: 'drawer'`. It's also exported
304
- so you can put a hand-composed `FormBuilder` in a drawer directly. Since the header sits
305
- outside the `<form>`, wire the Save button to the form via `id` / `form={id}`:
306
-
307
- ```tsx
308
- <FormDrawer
309
- open={open}
310
- onOpenChange={setOpen}
311
- title="New item"
312
- badge="New"
313
- actions={
314
- <Button type="submit" form="item-form" is_loading={saving}>
315
- Save
316
- </Button>
317
- }
318
- >
319
- <FormBuilder
320
- id="item-form"
321
- onSubmit={save}
322
- resolver={r}
323
- defaultValues={d}
324
- fieldDirection="vertical"
325
- >
326
- …fields…
327
- </FormBuilder>
328
- </FormDrawer>
329
- ```
330
-
331
- `FormDrawer` props: `open`, `onOpenChange`, `title`, `badge`, `variant`, `actions`,
332
- `onOpenInNewTab`, `notchActions`, `children`, `summary`, plus the layout flags listed under
333
- [Drawer layout](#drawer-layout) — `side`, `nested`, `framed`, `hideHeader`, `bareBody`,
334
- `description`, `wrapperClassName`, `className`. It owns no form state.
335
-
336
- `notchActions` is the notch's button slot. Going through `FormRenderer` you rarely set it directly —
337
- write `FormRenderer.NotchAction` children and they are lifted into it for you. Using `FormDrawer` on
338
- its own, pass the buttons here. When both `notchActions` and `onOpenInNewTab` are given, the former
339
- wins; `onOpenInNewTab` remains only for callers happy with its built-in English label.
340
-
341
- ### The title
342
-
343
- The drawer renders the **same floating header as the page form** — a [HeaderBar](./header-bar.md)
344
- title pill on the left, a dark action pill on the right — so a form's title looks identical in
345
- either display. `title` is the plain (uppercased) text, `badge` the colored emphasis pill, and
346
- `variant` (`new` / `edit` / `detail`) picks the badge colors; `badge` defaults from it
347
- (New / Edit / View).
348
-
349
- ```tsx
350
- <FormDrawer title="Sales Invoice" badge="New" variant="new" … />
351
- ```
352
-
353
- Driving it through `FormRenderer`, the `header` prop feeds both displays — including
354
- `header.variant`, which the drawer previously ignored:
355
-
356
- ```tsx
357
- <FormRenderer display="drawer" header={{ title: "Sales Invoice", variant: "edit" }} … />
358
- ```
359
-
360
- `title` and `badge` are **plain strings** (they were `ReactNode` before this shared-header
361
- change) because they render through `HeaderBar`'s uppercase text treatment.
362
-
363
- ### A summary beside the form
364
-
365
- `summary` renders a conclusion panel — typically a [FormSummary](./form-summary.md) — _beside_
366
- the form rather than inside its scrollable body. `FormDrawer` puts the form in a
367
- [`DrawerPanel`](./drawer.md#drawerpanel) (the light surface) and the summary next to it with a
368
- 6px gutter; the tray paints nothing, so the summary keeps its own dark background and full
369
- height, scrolling internally when it outruns the drawer.
370
-
371
- Hoist the form so both read the same instance:
372
-
373
- ```tsx
374
- const form = useForm({ resolver, defaultValues })
375
-
376
- <FormDrawer
377
- open={open} onOpenChange={setOpen} title="New item" badge="New"
378
- summary={
379
- <FormSummary form={form} title="Item" subtitle="Summary">
380
- <FormSummary.Group title="Pricing">…rows…</FormSummary.Group>
381
- </FormSummary>
382
- }
383
- >
384
- <FormBuilder form={form} id="item-form" onSubmit={save} fieldDirection="vertical">
385
- …fields…
386
- </FormBuilder>
387
- </FormDrawer>
388
- ```
389
-
390
- > `childrenOutside` is the deprecated former name for `FormDrawer`'s `summary`. It still
391
- > works — it long predates the FormBuilder/FormRenderer split and is unrelated to it (that
392
- > move ships no aliases; see the
393
- > [migration note](../migration/form-builder-2.5.2.md)).
394
-
395
- `FormRenderer` forwards `summary` straight into the drawer tray, so you rarely need
396
- `FormDrawer` directly — reach for it only when you want the drawer without a form.
@@ -1,138 +0,0 @@
1
- ---
2
- title: FormSummary
3
- description: A read-only calculation panel displayed beside a form. Each row declares a compute(values) that runs against the live form values, so totals recalculate as the user types.
4
- component: true
5
- group: Forms
6
- keywords: [form-summary, summary, totals, calculation, invoice, panel, react-hook-form, useWatch]
7
- ---
8
-
9
- # FormSummary
10
-
11
- A read-only **calculation panel** that sits **beside a form** — the invoice-summary
12
- look: grouped rows of computed totals, right-aligned, in Glare's dark `SystemStyle`
13
- fields.
14
-
15
- Each `FormSummary.Row` declares a **`compute(values)`** that runs against the **live**
16
- form values, so every total recalculates as the user types.
17
-
18
- The panel renders **outside** the form, beside it. Both read the same form, so
19
- **hoist `useForm`** and hand the instance to each.
20
-
21
- > **Normally you do not lay this out by hand.** Pass the panel to
22
- > [`FormRenderer`](./form-renderer.md)'s `summary` prop and it places it for you — beside the form
23
- > on a page, in the tray in a drawer. The manual version below is what `summary` does, and is what
24
- > you want only when you are composing a bare `<FormBuilder>` yourself.
25
-
26
- ```tsx
27
- const form = useForm({ resolver: zodResolver(schema), defaultValues })
28
-
29
- <div className="flex gap-4">
30
- <FormBuilder form={form} onSubmit={save} className="min-w-0 flex-1">
31
- <FormRenderer.Section title="Line items">…fields…</FormRenderer.Section>
32
- </FormBuilder>
33
-
34
- <FormSummary form={form} title="Invoice" subtitle="Summary">
35
- <FormSummary.Group title="Total">
36
- <FormSummary.Row label="Total Discount" compute={totalDiscount} />
37
- <FormSummary.Row label="Overall Total" emphasized compute={overallTotal} />
38
- <FormSummary.Row label="Overall Total" currency="IQD" tone="success"
39
- compute={v => overallTotal(v) * v.iqdRate} decimals={0} />
40
- <FormSummary.Row label="Overall Total" currency="USD" tone="info" compute={overallTotal} />
41
- </FormSummary.Group>
42
- </FormSummary>
43
- </div>
44
- ```
45
-
46
- `FormBuilder` stays purely an input renderer — it knows nothing about the panel, and
47
- **you** own the side-by-side layout. Passing `form` to `FormBuilder` makes it use that
48
- instance instead of creating its own.
49
-
50
- ### Height
51
-
52
- The panel is `h-full` and fills whatever height its parent gives it, scrolling its groups
53
- (header pinned) once they outrun it. That means **the parent has to have a height** — the
54
- usual mistake is `items-start` on the flex row, which collapses the panel to its content
55
- instead. Leave the row at its default `items-stretch`, as above.
56
-
57
- To make the panel own the viewport rather than grow with the form, bound the row:
58
-
59
- ```tsx
60
- <div className="flex h-[calc(100vh-2rem)] gap-4">
61
- <FormBuilder … className="min-w-0 flex-1 overflow-y-auto" />
62
- <FormSummary … />
63
- </div>
64
- ```
65
-
66
- > Hoisting the form means a remount `key` no longer resets it. Call `form.reset(defaults)`
67
- > instead (e.g. when opening a drawer).
68
-
69
- ## Installation
70
-
71
- ```bash
72
- npx torch-glare@latest init
73
- npx torch-glare@latest add FormSummary
74
- ```
75
-
76
- ## Imports
77
-
78
- ```tsx
79
- import { useForm } from 'react-hook-form'
80
-
81
- import { FormBuilder } from '@/components/FormBuilder'
82
- import { FormRenderer } from '@/components/FormRenderer'
83
- import { FormSummary } from '@/components/FormSummary'
84
- ```
85
-
86
- ## `FormSummary` props
87
-
88
- | Prop | Type | Notes |
89
- |---|---|---|
90
- | `title` | `ReactNode` | Panel title, e.g. `"Invoice"`. |
91
- | `subtitle` | `ReactNode` | Muted text beside the title, e.g. `"Summary"`. |
92
- | `form` | `UseFormReturn` | The form to read values from. The panel always renders outside the `<form>`, so pass the same hoisted instance you gave `FormRenderer` / `FormBuilder`. |
93
- | `width` | `number \| string` | Panel width; default `228`. |
94
- | `children` | `ReactNode` | `FormSummary.Group` children. |
95
-
96
- ## `FormSummary.Group` props
97
-
98
- | Prop | Type | Notes |
99
- |---|---|---|
100
- | `title` | `ReactNode` | The group heading (Customer / Total / Tax / …). Groups are separated by a divider. |
101
- | `collapsible` | `boolean` | When titled, the heading is a [ConclusionHeader](./conclusion-header.md) that opens/closes **this group's** rows; default `true`. |
102
- | `defaultOpen` | `boolean` | Initial open state when collapsible; default `true`. |
103
-
104
- The main panel title is a plain header — collapsing happens **per group**, not on the whole panel.
105
-
106
- ## `FormSummary.Row` props
107
-
108
- | Prop | Type | Notes |
109
- |---|---|---|
110
- | `label` | `ReactNode` | Row label, above the value. |
111
- | `compute` | `(values) => number \| string` | **The calculation** — receives the live form values. |
112
- | `value` | `number \| string` | Static value, when there's nothing to compute. |
113
- | `currency` | `ReactNode` | Currency code, e.g. `"IQD"` — rendered **inside** the field's trailing edge. |
114
- | `tone` | `'neutral' \| 'success' \| 'info'` | Color of the currency code (green / blue). |
115
- | `emphasized` | `boolean` | The primary result — lighter, emphasized border. |
116
- | `decimals` | `number` | Decimal places; default `2` (→ `0.00`). |
117
- | `action` | `ReactNode` | Trailing slot inside the field, e.g. an `ActionButton`. Shares the slot with `currency`. |
118
- | `format` | `(value) => string` | Override the default number formatting. |
119
-
120
- ## Computing totals
121
-
122
- `compute` is a plain function of the form values — keep the maths outside the JSX:
123
-
124
- ```tsx
125
- const subTotal = v => v.items.reduce((s, i) => s + i.qty * i.price, 0)
126
- const totalDiscount = v => v.items.reduce((s, i) => s + i.discount, 0)
127
- const taxable = v => Math.max(0, subTotal(v) - totalDiscount(v))
128
- const totalTax = v => taxable(v) * (v.taxRate / 100)
129
- const overallTotal = v => taxable(v) + totalTax(v)
130
- ```
131
-
132
- The panel is **read-only** — it contributes nothing to the submitted values.
133
-
134
- ## Related
135
-
136
- - [FormRenderer](./form-renderer.md) — its `summary` prop places this panel for you
137
- - [FormBuilder](./form-builder.md) — the fields the totals read from
138
- - [ConclusionHeader](./conclusion-header.md) — the header this panel uses