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.
- package/README.md +4 -3
- package/dist/bin/index.js +9 -24
- package/dist/bin/index.js.map +1 -1
- package/dist/src/commands/add.d.ts +2 -2
- package/dist/src/commands/add.d.ts.map +1 -1
- package/dist/src/commands/add.js +4 -70
- package/dist/src/commands/add.js.map +1 -1
- package/dist/src/commands/hook.d.ts +5 -4
- package/dist/src/commands/hook.d.ts.map +1 -1
- package/dist/src/commands/hook.js +7 -75
- package/dist/src/commands/hook.js.map +1 -1
- package/dist/src/commands/init.js +1 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/layout.d.ts +5 -4
- package/dist/src/commands/layout.d.ts.map +1 -1
- package/dist/src/commands/layout.js +7 -75
- package/dist/src/commands/layout.js.map +1 -1
- package/dist/src/commands/provider.d.ts +5 -4
- package/dist/src/commands/provider.d.ts.map +1 -1
- package/dist/src/commands/provider.js +7 -75
- package/dist/src/commands/provider.js.map +1 -1
- package/dist/src/commands/update.d.ts.map +1 -1
- package/dist/src/commands/update.js +78 -43
- package/dist/src/commands/update.js.map +1 -1
- package/dist/src/commands/utils.d.ts +5 -4
- package/dist/src/commands/utils.d.ts.map +1 -1
- package/dist/src/commands/utils.js +7 -80
- package/dist/src/commands/utils.js.map +1 -1
- package/dist/src/shared/addFromRegistry.d.ts +16 -0
- package/dist/src/shared/addFromRegistry.d.ts.map +1 -0
- package/dist/src/shared/addFromRegistry.js +88 -0
- package/dist/src/shared/addFromRegistry.js.map +1 -0
- package/dist/src/shared/getInstallCommand.d.ts.map +1 -1
- package/dist/src/shared/getInstallCommand.js +5 -0
- package/dist/src/shared/getInstallCommand.js.map +1 -1
- package/dist/src/shared/installDependencies.d.ts +0 -10
- package/dist/src/shared/installDependencies.d.ts.map +1 -1
- package/dist/src/shared/installDependencies.js +0 -17
- package/dist/src/shared/installDependencies.js.map +1 -1
- package/dist/src/shared/installFromPlan.d.ts +7 -5
- package/dist/src/shared/installFromPlan.d.ts.map +1 -1
- package/dist/src/shared/installFromPlan.js +103 -36
- package/dist/src/shared/installFromPlan.js.map +1 -1
- package/dist/src/shared/loadRegistry.d.ts +12 -3
- package/dist/src/shared/loadRegistry.d.ts.map +1 -1
- package/dist/src/shared/loadRegistry.js +19 -20
- package/dist/src/shared/loadRegistry.js.map +1 -1
- package/dist/src/shared/registryClient.d.ts +19 -0
- package/dist/src/shared/registryClient.d.ts.map +1 -0
- package/dist/src/shared/registryClient.js +128 -0
- package/dist/src/shared/registryClient.js.map +1 -0
- package/dist/src/shared/resolveEntry.d.ts +10 -7
- package/dist/src/shared/resolveEntry.d.ts.map +1 -1
- package/dist/src/shared/resolveEntry.js +18 -13
- package/dist/src/shared/resolveEntry.js.map +1 -1
- package/dist/src/shared/suggestOtherCommand.d.ts +7 -1
- package/dist/src/shared/suggestOtherCommand.d.ts.map +1 -1
- package/dist/src/shared/suggestOtherCommand.js +29 -23
- package/dist/src/shared/suggestOtherCommand.js.map +1 -1
- package/dist/src/types/main.d.ts +31 -2
- package/dist/src/types/main.d.ts.map +1 -1
- package/package.json +6 -11
- package/apps/lib/components/ActionButton.tsx +0 -93
- package/apps/lib/components/ActionsGroup.tsx +0 -27
- package/apps/lib/components/AlertDialog.tsx +0 -204
- package/apps/lib/components/Avatar.tsx +0 -46
- package/apps/lib/components/Badge.tsx +0 -250
- package/apps/lib/components/BadgeField.tsx +0 -403
- package/apps/lib/components/Breadcrumb.tsx +0 -280
- package/apps/lib/components/Button.tsx +0 -325
- package/apps/lib/components/ButtonGroup.tsx +0 -190
- package/apps/lib/components/Calendar.tsx +0 -115
- package/apps/lib/components/Card.tsx +0 -95
- package/apps/lib/components/Checkbox.tsx +0 -42
- package/apps/lib/components/ColorPicker.tsx +0 -441
- package/apps/lib/components/ConclusionHeader.tsx +0 -148
- package/apps/lib/components/ContextMenu.tsx +0 -571
- package/apps/lib/components/CountBadge.tsx +0 -52
- package/apps/lib/components/DataTable.tsx +0 -213
- package/apps/lib/components/DataViews/badge.ts +0 -49
- package/apps/lib/components/DataViews/cell.tsx +0 -324
- package/apps/lib/components/DataViews/context.ts +0 -144
- package/apps/lib/components/DataViews/data-views.tsx +0 -395
- package/apps/lib/components/DataViews/filters/children.tsx +0 -98
- package/apps/lib/components/DataViews/filters/custom.tsx +0 -34
- package/apps/lib/components/DataViews/filters/filters.tsx +0 -157
- package/apps/lib/components/DataViews/filters/index.ts +0 -4
- package/apps/lib/components/DataViews/filters/labelled.tsx +0 -20
- package/apps/lib/components/DataViews/filters/presets.tsx +0 -65
- package/apps/lib/components/DataViews/filters/sync.tsx +0 -35
- package/apps/lib/components/DataViews/filters/values.ts +0 -173
- package/apps/lib/components/DataViews/header.tsx +0 -220
- package/apps/lib/components/DataViews/hooks/index.ts +0 -5
- package/apps/lib/components/DataViews/hooks/useActiveRow.ts +0 -22
- package/apps/lib/components/DataViews/hooks/useControllable.ts +0 -52
- package/apps/lib/components/DataViews/index.ts +0 -88
- package/apps/lib/components/DataViews/panel/columns.tsx +0 -153
- package/apps/lib/components/DataViews/panel/controls.tsx +0 -106
- package/apps/lib/components/DataViews/panel/index.ts +0 -3
- package/apps/lib/components/DataViews/panel/panel.tsx +0 -164
- package/apps/lib/components/DataViews/panel/saved-views.tsx +0 -67
- package/apps/lib/components/DataViews/panel/section.tsx +0 -81
- package/apps/lib/components/DataViews/panel/sort.tsx +0 -42
- package/apps/lib/components/DataViews/panel/tab.tsx +0 -31
- package/apps/lib/components/DataViews/slots.ts +0 -72
- package/apps/lib/components/DataViews/states.tsx +0 -73
- package/apps/lib/components/DataViews/types.ts +0 -510
- package/apps/lib/components/DataViews/views/board-view.tsx +0 -381
- package/apps/lib/components/DataViews/views/card-rows.tsx +0 -36
- package/apps/lib/components/DataViews/views/inbox-view.tsx +0 -260
- package/apps/lib/components/DataViews/views/pane-views.tsx +0 -196
- package/apps/lib/components/DataViews/views/table-view.tsx +0 -493
- package/apps/lib/components/DataViews/views/tree-view.tsx +0 -367
- package/apps/lib/components/DatePicker.tsx +0 -232
- package/apps/lib/components/Dialog.tsx +0 -116
- package/apps/lib/components/Divider.tsx +0 -28
- package/apps/lib/components/Drawer.tsx +0 -451
- package/apps/lib/components/DropdownMenu.tsx +0 -554
- package/apps/lib/components/FieldHint.tsx +0 -69
- package/apps/lib/components/Form.tsx +0 -182
- package/apps/lib/components/FormBuilder/context.ts +0 -85
- package/apps/lib/components/FormBuilder/field-kind.ts +0 -28
- package/apps/lib/components/FormBuilder/fields/ChoiceFields.tsx +0 -60
- package/apps/lib/components/FormBuilder/fields/ColorField.tsx +0 -59
- package/apps/lib/components/FormBuilder/fields/CustomField.tsx +0 -11
- package/apps/lib/components/FormBuilder/fields/DateField.tsx +0 -32
- package/apps/lib/components/FormBuilder/fields/FieldArray.tsx +0 -74
- package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +0 -168
- package/apps/lib/components/FormBuilder/fields/FileField.tsx +0 -39
- package/apps/lib/components/FormBuilder/fields/OptionListFields.tsx +0 -132
- package/apps/lib/components/FormBuilder/fields/OtpField.tsx +0 -31
- package/apps/lib/components/FormBuilder/fields/PhoneField.tsx +0 -109
- package/apps/lib/components/FormBuilder/fields/RichTextEditorField.tsx +0 -31
- package/apps/lib/components/FormBuilder/fields/SelectField.tsx +0 -114
- package/apps/lib/components/FormBuilder/fields/SignatureField.tsx +0 -157
- package/apps/lib/components/FormBuilder/fields/SliderField.tsx +0 -67
- package/apps/lib/components/FormBuilder/fields/SwitchBoxField.tsx +0 -41
- package/apps/lib/components/FormBuilder/fields/TableField.tsx +0 -336
- package/apps/lib/components/FormBuilder/fields/TextField.tsx +0 -213
- package/apps/lib/components/FormBuilder/fields/TreeSelectField.tsx +0 -43
- package/apps/lib/components/FormBuilder/fields/countries.ts +0 -303
- package/apps/lib/components/FormBuilder/fields/index.ts +0 -25
- package/apps/lib/components/FormBuilder/form-builder.tsx +0 -198
- package/apps/lib/components/FormBuilder/index.ts +0 -31
- package/apps/lib/components/FormBuilder/numberFormat.ts +0 -16
- package/apps/lib/components/FormBuilder/submit.tsx +0 -67
- package/apps/lib/components/FormBuilder/types.ts +0 -316
- package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -250
- package/apps/lib/components/FormRenderer/detail.tsx +0 -256
- package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -358
- package/apps/lib/components/FormRenderer/header.tsx +0 -88
- package/apps/lib/components/FormRenderer/index.ts +0 -17
- package/apps/lib/components/FormRenderer/notch-action.tsx +0 -64
- package/apps/lib/components/FormRenderer/section.tsx +0 -39
- package/apps/lib/components/FormRenderer/stepper.tsx +0 -393
- package/apps/lib/components/FormRenderer/types.ts +0 -115
- package/apps/lib/components/FormSummary.tsx +0 -282
- package/apps/lib/components/HeaderBar.tsx +0 -117
- package/apps/lib/components/ImageAttachment.tsx +0 -209
- package/apps/lib/components/InnerLabelField.tsx +0 -154
- package/apps/lib/components/Input.tsx +0 -224
- package/apps/lib/components/InputField.tsx +0 -147
- package/apps/lib/components/InputOTP.tsx +0 -84
- package/apps/lib/components/Label.tsx +0 -129
- package/apps/lib/components/LabelField.tsx +0 -76
- package/apps/lib/components/LabeledCheckBox.tsx +0 -51
- package/apps/lib/components/LabeledRadio.tsx +0 -51
- package/apps/lib/components/LinkButton.tsx +0 -94
- package/apps/lib/components/LoginButton.tsx +0 -51
- package/apps/lib/components/PasswordLevel.tsx +0 -58
- package/apps/lib/components/Popover.tsx +0 -312
- package/apps/lib/components/ProfileMenu.tsx +0 -85
- package/apps/lib/components/Radio.tsx +0 -59
- package/apps/lib/components/RadioCard.tsx +0 -50
- package/apps/lib/components/ScrollArea.tsx +0 -54
- package/apps/lib/components/SearchField.tsx +0 -62
- package/apps/lib/components/SearchableSelect.tsx +0 -318
- package/apps/lib/components/SearchableTable.tsx +0 -344
- package/apps/lib/components/SearchableTree.tsx +0 -485
- package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
- package/apps/lib/components/SectionBlock.tsx +0 -168
- package/apps/lib/components/Select.tsx +0 -347
- package/apps/lib/components/SimpleSelect.tsx +0 -225
- package/apps/lib/components/Skeleton.tsx +0 -12
- package/apps/lib/components/SlideDatePicker.tsx +0 -255
- package/apps/lib/components/SpinLoading.tsx +0 -174
- package/apps/lib/components/Stepper.tsx +0 -480
- package/apps/lib/components/Switch.tsx +0 -82
- package/apps/lib/components/TabFormItem.tsx +0 -153
- package/apps/lib/components/TabSwitch.tsx +0 -172
- package/apps/lib/components/Table.tsx +0 -597
- package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
- package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
- package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
- package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
- package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
- package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
- package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
- package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
- package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
- package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
- package/apps/lib/components/TextEditor/index.ts +0 -7
- package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
- package/apps/lib/components/Textarea.tsx +0 -117
- package/apps/lib/components/Timeline.tsx +0 -263
- package/apps/lib/components/Toast.tsx +0 -87
- package/apps/lib/components/Toggle.tsx +0 -125
- package/apps/lib/components/ToggleButton.tsx +0 -140
- package/apps/lib/components/Tooltip.tsx +0 -116
- package/apps/lib/components/TransparentLabel.tsx +0 -71
- package/apps/lib/components/TreeDropDown.tsx +0 -115
- package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
- package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
- package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
- package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
- package/apps/lib/components/TreeFolder/icons.tsx +0 -60
- package/apps/lib/components/TreeFolder/index.ts +0 -24
- package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
- package/apps/lib/components/TreeFolder/types.ts +0 -77
- package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
- package/apps/lib/hooks/useActiveTreeItem.ts +0 -61
- package/apps/lib/hooks/useClickOutside.ts +0 -27
- package/apps/lib/hooks/useDragDrop.tsx +0 -365
- package/apps/lib/hooks/useHtmlDir.ts +0 -31
- package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
- package/apps/lib/hooks/useIsMobile.ts +0 -21
- package/apps/lib/hooks/useResize.ts +0 -67
- package/apps/lib/hooks/useTagSelection.ts +0 -300
- package/apps/lib/layouts/CNLayout.tsx +0 -372
- package/apps/lib/layouts/DataViewCard.tsx +0 -62
- package/apps/lib/layouts/FieldSection.tsx +0 -91
- package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
- package/apps/lib/providers/ThemeProvider.tsx +0 -84
- package/apps/lib/registry.json +0 -1217
- package/apps/lib/tsconfig.json +0 -9
- package/apps/lib/tsconfig.tsbuildinfo +0 -1
- package/apps/lib/utils/cn.ts +0 -6
- package/apps/lib/utils/color.ts +0 -175
- package/apps/lib/utils/dataViews/path.ts +0 -67
- package/apps/lib/utils/dataViews/query.ts +0 -73
- package/apps/lib/utils/dataViews/types.ts +0 -187
- package/apps/lib/utils/dateFormat.ts +0 -108
- package/apps/lib/utils/resize.ts +0 -31
- package/apps/lib/utils/scroller.ts +0 -26
- package/apps/lib/utils/types.ts +0 -16
- package/docs/BLOCKS.md +0 -129
- package/docs/CHANGELOG-1.1.16.md +0 -108
- package/docs/Cover.png +0 -0
- package/docs/README.md +0 -215
- package/docs/components/action-button.md +0 -638
- package/docs/components/actions-group.md +0 -708
- package/docs/components/alert-dialog.md +0 -920
- package/docs/components/avatar.md +0 -709
- package/docs/components/badge-field.md +0 -738
- package/docs/components/badge.md +0 -301
- package/docs/components/breadcrumb.md +0 -930
- package/docs/components/button-group.md +0 -650
- package/docs/components/button.md +0 -639
- package/docs/components/calendar.md +0 -555
- package/docs/components/card.md +0 -622
- package/docs/components/chart-block-tool.md +0 -129
- package/docs/components/checkbox.md +0 -699
- package/docs/components/cn-layout.md +0 -854
- package/docs/components/color-picker.md +0 -101
- package/docs/components/conclusion-header.md +0 -80
- package/docs/components/context-menu.md +0 -483
- package/docs/components/count-badge.md +0 -560
- package/docs/components/data-table.md +0 -854
- package/docs/components/data-views/backend-response.md +0 -324
- package/docs/components/data-views/examples/a11y-rtl.md +0 -250
- package/docs/components/data-views/examples/api-orders-route.md +0 -130
- package/docs/components/data-views/examples/fields.md +0 -362
- package/docs/components/data-views/examples/filters.md +0 -307
- package/docs/components/data-views/examples/inbox-routing.md +0 -218
- package/docs/components/data-views/examples/index.md +0 -29
- package/docs/components/data-views/examples/overview.md +0 -244
- package/docs/components/data-views/examples/panel.md +0 -212
- package/docs/components/data-views/examples/scale.md +0 -231
- package/docs/components/data-views/examples/server-side.md +0 -210
- package/docs/components/data-views/examples/state.md +0 -250
- package/docs/components/data-views/examples/tree-custom.md +0 -388
- package/docs/components/data-views/examples/view-registry.md +0 -313
- package/docs/components/data-views/examples/views.md +0 -534
- package/docs/components/data-views/guide.md +0 -405
- package/docs/components/data-views/index.md +0 -1521
- package/docs/components/data-views/migration.md +0 -81
- package/docs/components/date-picker.md +0 -857
- package/docs/components/dialog.md +0 -929
- package/docs/components/divider.md +0 -766
- package/docs/components/drawer.md +0 -654
- package/docs/components/dropdown-menu.md +0 -668
- package/docs/components/field-hint.md +0 -898
- package/docs/components/field-section.md +0 -781
- package/docs/components/form-builder.md +0 -284
- package/docs/components/form-renderer.md +0 -396
- package/docs/components/form-summary.md +0 -138
- package/docs/components/form.md +0 -785
- package/docs/components/header-bar.md +0 -188
- package/docs/components/image-attachment.md +0 -906
- package/docs/components/inner-label-field.md +0 -819
- package/docs/components/input-field.md +0 -623
- package/docs/components/input-otp.md +0 -756
- package/docs/components/input.md +0 -634
- package/docs/components/label-field.md +0 -770
- package/docs/components/label.md +0 -761
- package/docs/components/labeled-check-box.md +0 -642
- package/docs/components/labeled-radio.md +0 -796
- package/docs/components/link-button.md +0 -685
- package/docs/components/login-button.md +0 -872
- package/docs/components/password-level.md +0 -803
- package/docs/components/popover.md +0 -649
- package/docs/components/profile-menu.md +0 -656
- package/docs/components/radio-card.md +0 -801
- package/docs/components/radio.md +0 -735
- package/docs/components/scroll-area.md +0 -691
- package/docs/components/search-field.md +0 -702
- package/docs/components/searchable-select.md +0 -368
- package/docs/components/searchable-table.md +0 -438
- package/docs/components/searchable-tree-dialog.md +0 -190
- package/docs/components/searchable-tree.md +0 -200
- package/docs/components/section-block.md +0 -483
- package/docs/components/select.md +0 -709
- package/docs/components/simple-select.md +0 -741
- package/docs/components/skeleton.md +0 -706
- package/docs/components/slide-date-picker.md +0 -837
- package/docs/components/spin-loading.md +0 -696
- package/docs/components/stepper.md +0 -316
- package/docs/components/switch.md +0 -770
- package/docs/components/tab-form-item.md +0 -773
- package/docs/components/tab-switch.md +0 -170
- package/docs/components/table-dnd-wrapper.md +0 -107
- package/docs/components/table.md +0 -1088
- package/docs/components/text-editor.md +0 -735
- package/docs/components/textarea.md +0 -681
- package/docs/components/timeline.md +0 -254
- package/docs/components/toast.md +0 -773
- package/docs/components/toggle-button.md +0 -643
- package/docs/components/toggle.md +0 -882
- package/docs/components/tooltip.md +0 -513
- package/docs/components/transparent-label.md +0 -721
- package/docs/components/tree-drop-down.md +0 -740
- package/docs/components/tree-folder.md +0 -110
- package/docs/components/tree-sub-layout.md +0 -707
- package/docs/explanation/architecture.md +0 -54
- package/docs/explanation/design-system.md +0 -52
- package/docs/how-to/form-and-list-recipes.md +0 -386
- package/docs/how-to/forms-with-form-builder.md +0 -472
- package/docs/how-to/guides.md +0 -1027
- package/docs/migration/changelog.md +0 -60
- package/docs/migration/form-builder-2.5.2.md +0 -113
- package/docs/reference/cli.md +0 -112
- package/docs/reference/components.md +0 -572
- package/docs/reference/hooks.md +0 -1523
- package/docs/reference/providers.md +0 -866
- package/docs/reference/tailwind-plugins.md +0 -942
- package/docs/reference/theme.md +0 -85
- package/docs/reference/types.md +0 -1016
- package/docs/reference/utilities.md +0 -726
- package/docs/tutorials/building-first-form.md +0 -846
- package/docs/tutorials/component-composition.md +0 -882
- package/docs/tutorials/getting-started.md +0 -302
- package/docs/tutorials/theming-basics.md +0 -785
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Architecture
|
|
3
|
-
description: How TORCH Glare is structured — the copy-in distribution model, the CLI, and the registry.
|
|
4
|
-
group: explanation
|
|
5
|
-
keywords: [architecture, copy-in, cli, registry, shadcn]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Architecture
|
|
9
|
-
|
|
10
|
-
## Copy-in distribution
|
|
11
|
-
|
|
12
|
-
TORCH Glare does **not** ship compiled components you import from a package. Instead, the
|
|
13
|
-
published `torch-glare` package contains a CLI plus the raw component source, and
|
|
14
|
-
`npx torch-glare add <Component>` copies that source into your project. This is the same
|
|
15
|
-
model popularized by shadcn/ui.
|
|
16
|
-
|
|
17
|
-
Consequences:
|
|
18
|
-
|
|
19
|
-
- **You own the code.** Copied components live in your repo and can be edited freely.
|
|
20
|
-
- **No runtime package dependency.** You import from your own path (`@/components/…`), not
|
|
21
|
-
from `torch-glare`.
|
|
22
|
-
- **Explicit dependencies.** `add` also copies the component's internal dependencies
|
|
23
|
-
(nested components, hooks, utils) and installs required npm packages such as `@radix-ui/*`.
|
|
24
|
-
|
|
25
|
-
## The registry
|
|
26
|
-
|
|
27
|
-
The dependency graph is described by a generated manifest, `apps/lib/registry.json`. Each
|
|
28
|
-
entry lists a component's npm dependencies and its internal (component/hook/util)
|
|
29
|
-
dependencies. The CLI reads this manifest to resolve the full closure to copy when you run
|
|
30
|
-
`add`, so results are deterministic and testable rather than inferred at install time.
|
|
31
|
-
|
|
32
|
-
The registry is generated from source (`pnpm run registry`) and validated in CI, so it never
|
|
33
|
-
drifts from the actual imports.
|
|
34
|
-
|
|
35
|
-
## Layers
|
|
36
|
-
|
|
37
|
-
| Layer | Location | Role |
|
|
38
|
-
| --- | --- | --- |
|
|
39
|
-
| Components | `components/` | UI built with Radix primitives + CVA variants. |
|
|
40
|
-
| Hooks | `hooks/` | Reusable behavior (e.g. `useClickOutside`). |
|
|
41
|
-
| Utils | `utils/` | Helpers like `cn` (class merging) and types. |
|
|
42
|
-
| Providers | `providers/` | Context providers such as `ThemeProvider`. |
|
|
43
|
-
| Layouts | `layouts/` | Composed page/section scaffolds. |
|
|
44
|
-
|
|
45
|
-
## AI-facing docs
|
|
46
|
-
|
|
47
|
-
`llms.txt`, `llms-full.txt`, and `llms-manifest.json` are generated from source
|
|
48
|
-
(`pnpm run llms`) so assistants always get accurate component lists, dependencies, variants,
|
|
49
|
-
and examples. A doc lint (`pnpm run check:ai-docs`) blocks incorrect usage patterns.
|
|
50
|
-
|
|
51
|
-
## See also
|
|
52
|
-
|
|
53
|
-
- [Design system](./design-system.md)
|
|
54
|
-
- [CLI reference](../reference/cli.md)
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Design System
|
|
3
|
-
description: The conventions behind TORCH Glare — CVA variants, semantic tokens, sizing, and theming.
|
|
4
|
-
group: explanation
|
|
5
|
-
keywords: [design system, cva, variants, tokens, tailwind, sizing]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Design System
|
|
9
|
-
|
|
10
|
-
TORCH Glare components share a small set of conventions so they compose predictably and
|
|
11
|
-
theme uniformly.
|
|
12
|
-
|
|
13
|
-
## Variants via CVA
|
|
14
|
-
|
|
15
|
-
Component styling is defined with [class-variance-authority](https://cva.style) (`cva`). Each
|
|
16
|
-
component exposes a `variant` and/or `size` prop whose allowed values come directly from its
|
|
17
|
-
`cva` definition. For example, `Button` has variants
|
|
18
|
-
`PrimeStyle, BluSecStyle, YelSecStyle, RedSecStyle, BorderStyle, PrimeContStyle, BluContStyle, RedContStyle`
|
|
19
|
-
and sizes `S, M, L, XL`.
|
|
20
|
-
|
|
21
|
-
Because variant names are the source of truth, docs and the `llms.*` files generate their
|
|
22
|
-
variant lists from these definitions — they can't drift.
|
|
23
|
-
|
|
24
|
-
## Semantic tokens
|
|
25
|
-
|
|
26
|
-
Colors are addressed through semantic CSS variables, not raw hex, so a single component works
|
|
27
|
-
across themes. Names follow a `--{category}-{context}-{component}-{state}` shape, e.g.
|
|
28
|
-
`background-presentation-action-primary` or `content-presentation-state-negative`. Components
|
|
29
|
-
reference these via Tailwind classes like `bg-background-presentation-action-secondary`.
|
|
30
|
-
|
|
31
|
-
## Sizing scale
|
|
32
|
-
|
|
33
|
-
Interactive components use a consistent `S / M / L / XL` scale (some also `XS`). Typography
|
|
34
|
-
components such as `TransparentLabel` instead take a typography-scale `size`
|
|
35
|
-
(e.g. `body-medium-regular`, `headers-large-bold`).
|
|
36
|
-
|
|
37
|
-
## Theming
|
|
38
|
-
|
|
39
|
-
Theme is driven by `data-theme` (`light | dark | default`) and `data-theme-mode`
|
|
40
|
-
(`CSS | TORCH`). Every component accepts a `theme` prop for local overrides; app-wide theming
|
|
41
|
-
uses `ThemeProvider`. See the [theme reference](../reference/theme.md).
|
|
42
|
-
|
|
43
|
-
## Accessibility
|
|
44
|
-
|
|
45
|
-
Interactive components build on Radix UI primitives for keyboard and ARIA behavior. Custom
|
|
46
|
-
controls add the appropriate attributes directly (for example, a loading `Button` sets
|
|
47
|
-
`aria-busy` and exposes its spinner with `role="status"`).
|
|
48
|
-
|
|
49
|
-
## See also
|
|
50
|
-
|
|
51
|
-
- [Architecture](./architecture.md)
|
|
52
|
-
- [Theme reference](../reference/theme.md)
|
|
@@ -1,386 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Form & List Page Recipes
|
|
3
|
-
description: Production-tested patterns for building create dialogs, list pages, journal-line grids, and login layouts with TORCH Glare. Captures the "what actually ships" decisions for app-builders.
|
|
4
|
-
keywords: [recipes, patterns, form, list, dialog, journal, line-items, login, filter-bar, grid]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Form & List Page Recipes
|
|
8
|
-
|
|
9
|
-
Battle-tested layouts and component combinations from production frontend work.
|
|
10
|
-
Use these as the starting point for create dialogs, list/filter pages,
|
|
11
|
-
line-item grids, and login flows.
|
|
12
|
-
|
|
13
|
-
> **For actual forms, reach for [`FormBuilder`](../components/form-builder.md) first.** The
|
|
14
|
-
> multi-column form rows below are a layout escape hatch for the rare case that needs bespoke
|
|
15
|
-
> positioning — they are **not** the default way to build a form. A normal create/edit form is
|
|
16
|
-
> `FormBuilder` fields as JSX children with a resolver; see the
|
|
17
|
-
> [Forms with FormBuilder](./forms-with-form-builder.md) guide. Don't hand-wire `FormField` /
|
|
18
|
-
> `InputField` rows or hold field state in `useState` when `FormBuilder` would do it.
|
|
19
|
-
|
|
20
|
-
> All examples use the `presentation` color tokens. Never substitute
|
|
21
|
-
> `*-system-*` tokens or `variant="SystemStyle"` — see the rules banner at
|
|
22
|
-
> the top of every doc response.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Recipe 1 — Multi-column form row with consistent baselines
|
|
27
|
-
|
|
28
|
-
**Use case:** A row in a create dialog that mixes `InputField`, `Select`, and
|
|
29
|
-
date inputs. Default heights don't match across components, so you have to
|
|
30
|
-
opt in to alignment explicitly.
|
|
31
|
-
|
|
32
|
-
```tsx
|
|
33
|
-
<div className="grid grid-cols-3 gap-4">
|
|
34
|
-
<div className="flex flex-col gap-1.5">
|
|
35
|
-
<Label>Voucher Type *</Label>
|
|
36
|
-
<Select
|
|
37
|
-
className="w-full h-10"
|
|
38
|
-
value={type}
|
|
39
|
-
onValueChange={setType}
|
|
40
|
-
options={typeOptions}
|
|
41
|
-
placeholder="Select type"
|
|
42
|
-
/>
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
<div className="flex flex-col gap-1.5">
|
|
46
|
-
<Label>Date *</Label>
|
|
47
|
-
<InputField
|
|
48
|
-
className="h-10"
|
|
49
|
-
type="date"
|
|
50
|
-
icon={<i className="ri-calendar-line text-base" />}
|
|
51
|
-
{...register("date")}
|
|
52
|
-
/>
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<div className="flex flex-col gap-1.5">
|
|
56
|
-
<Label>Fiscal Period *</Label>
|
|
57
|
-
<Select
|
|
58
|
-
className="w-full h-10"
|
|
59
|
-
value={period}
|
|
60
|
-
onValueChange={setPeriod}
|
|
61
|
-
options={periodOptions}
|
|
62
|
-
placeholder="Select period"
|
|
63
|
-
/>
|
|
64
|
-
</div>
|
|
65
|
-
</div>
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Key rules:
|
|
69
|
-
|
|
70
|
-
- **Every form control gets `h-10`** — both `InputField` and `Select` (which
|
|
71
|
-
also needs `w-full`).
|
|
72
|
-
- **Wrap each field in `flex flex-col gap-1.5`**, not `space-y-1.5`, so labels
|
|
73
|
-
sit cleanly at the top of the row.
|
|
74
|
-
- **Use `<InputField type="date">`** instead of a native `<input type="date">`
|
|
75
|
-
so you keep the icon slot and consistent styling.
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## Recipe 2 — List page with filter bar + data table
|
|
80
|
-
|
|
81
|
-
**Use case:** Every list page (vouchers, accounts, bank accounts, etc.) needs
|
|
82
|
-
the same filter bar — a search input + one or more select filters above a
|
|
83
|
-
data table.
|
|
84
|
-
|
|
85
|
-
```tsx
|
|
86
|
-
{
|
|
87
|
-
/* Filter bar */
|
|
88
|
-
}
|
|
89
|
-
<div className="flex items-center gap-3">
|
|
90
|
-
<div className="flex-1 max-w-sm">
|
|
91
|
-
<InputField
|
|
92
|
-
className="h-10"
|
|
93
|
-
icon={<i className="ri-search-line text-base" />}
|
|
94
|
-
placeholder="Search..."
|
|
95
|
-
value={search}
|
|
96
|
-
onChange={(e) => setSearch(e.target.value)}
|
|
97
|
-
/>
|
|
98
|
-
</div>
|
|
99
|
-
|
|
100
|
-
<SimpleSelect
|
|
101
|
-
className="w-48 h-10"
|
|
102
|
-
value={statusFilter || "ALL"}
|
|
103
|
-
onValueChange={(val) => setStatusFilter(val === "ALL" ? "" : val)}
|
|
104
|
-
options={[
|
|
105
|
-
{ value: "ALL", label: "All Statuses" },
|
|
106
|
-
{ value: "DRAFT", label: "Draft" },
|
|
107
|
-
{ value: "POSTED", label: "Posted" },
|
|
108
|
-
]}
|
|
109
|
-
placeholder="All Statuses"
|
|
110
|
-
/>
|
|
111
|
-
</div>;
|
|
112
|
-
|
|
113
|
-
{
|
|
114
|
-
/* Data table */
|
|
115
|
-
}
|
|
116
|
-
<Card className="p-0 overflow-hidden">
|
|
117
|
-
<CardContent className="p-0 overflow-x-auto">
|
|
118
|
-
<Table className="w-full">
|
|
119
|
-
<TableHeader>
|
|
120
|
-
<TableRow>
|
|
121
|
-
<TableHead>Number</TableHead>
|
|
122
|
-
<TableHead>Status</TableHead>
|
|
123
|
-
<TableHead className="text-right">Total Debit</TableHead>
|
|
124
|
-
<TableHead className="text-right">Total Credit</TableHead>
|
|
125
|
-
</TableRow>
|
|
126
|
-
</TableHeader>
|
|
127
|
-
<TableBody>
|
|
128
|
-
{rows.length === 0 ? (
|
|
129
|
-
<TableRow>
|
|
130
|
-
<TableCell
|
|
131
|
-
colSpan={4}
|
|
132
|
-
childrenClassName="flex flex-col items-center justify-center gap-3 py-12 w-full min-w-0 text-content-presentation-global-secondary"
|
|
133
|
-
>
|
|
134
|
-
<i className="ri-inbox-line text-4xl opacity-60" />
|
|
135
|
-
<p className="typography-body-medium-regular">No vouchers</p>
|
|
136
|
-
<p className="typography-body-small-regular opacity-80">Try adjusting your filters</p>
|
|
137
|
-
</TableCell>
|
|
138
|
-
</TableRow>
|
|
139
|
-
) : (
|
|
140
|
-
rows.map((v) => (
|
|
141
|
-
<TableRow key={v.id}>
|
|
142
|
-
<TableCell className="whitespace-nowrap">{v.number}</TableCell>
|
|
143
|
-
<TableCell>{v.status}</TableCell>
|
|
144
|
-
<TableCell className="text-right font-mono whitespace-nowrap">
|
|
145
|
-
{v.totalDebit}
|
|
146
|
-
</TableCell>
|
|
147
|
-
<TableCell className="text-right font-mono whitespace-nowrap">
|
|
148
|
-
{v.totalCredit}
|
|
149
|
-
</TableCell>
|
|
150
|
-
</TableRow>
|
|
151
|
-
))
|
|
152
|
-
)}
|
|
153
|
-
</TableBody>
|
|
154
|
-
</Table>
|
|
155
|
-
</CardContent>
|
|
156
|
-
</Card>;
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Key rules:
|
|
160
|
-
|
|
161
|
-
- **Never use a native `<select>`** — `SimpleSelect` keeps styling consistent
|
|
162
|
-
with the rest of your forms.
|
|
163
|
-
- **Never manually position a search icon with absolute positioning** —
|
|
164
|
-
`InputField`'s `icon` prop is built for this.
|
|
165
|
-
- **Numeric columns get `text-right` on both `TableHead` and `TableCell`**,
|
|
166
|
-
plus `font-mono` on the cell so digits line up.
|
|
167
|
-
- **Empty states use `childrenClassName`** on `TableCell` to bypass the
|
|
168
|
-
default `flex-row justify-start min-w-[200px]` wrapper. See `Table.md`
|
|
169
|
-
→ "TableCell force-wraps children" for why.
|
|
170
|
-
- **The "All / Any" filter option needs a sentinel value** (`"ALL"` here)
|
|
171
|
-
because Radix forbids `value=""`. See `SimpleSelect.md` for details.
|
|
172
|
-
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
## Recipe 3 — Journal lines / line-item grid (display: contents)
|
|
176
|
-
|
|
177
|
-
**Use case:** A repeating-row layout (journal lines, invoice line items,
|
|
178
|
-
purchase order rows) with a header, N data rows, and a totals row — where
|
|
179
|
-
columns must align across all rows.
|
|
180
|
-
|
|
181
|
-
The naïve approach (each row is its own `display: grid`) breaks: short
|
|
182
|
-
footer content collapses to a different width than long input content,
|
|
183
|
-
and columns drift across rows. The fix is **one parent grid** with
|
|
184
|
-
`className="contents"` on each row wrapper so the row's children become
|
|
185
|
-
direct grid items of the parent.
|
|
186
|
-
|
|
187
|
-
```tsx
|
|
188
|
-
<div className="grid w-full grid-cols-[32px_minmax(0,2.5fr)_minmax(0,3fr)_minmax(0,1.5fr)_minmax(0,1.5fr)_36px] gap-x-3 gap-y-2 px-2">
|
|
189
|
-
{/* Header cells (direct grid items) */}
|
|
190
|
-
<div>#</div>
|
|
191
|
-
<div>Account</div>
|
|
192
|
-
<div>Description</div>
|
|
193
|
-
<div>Debit</div>
|
|
194
|
-
<div>Credit</div>
|
|
195
|
-
<div />
|
|
196
|
-
|
|
197
|
-
{/* Data rows — wrapper uses className="contents" so its children become
|
|
198
|
-
direct grid items of the parent grid */}
|
|
199
|
-
{lines.map((line, idx) => (
|
|
200
|
-
<div key={line.key} className="contents">
|
|
201
|
-
<div>{idx + 1}</div>
|
|
202
|
-
<Select
|
|
203
|
-
className="w-full h-10"
|
|
204
|
-
value={line.accountId}
|
|
205
|
-
onValueChange={(v) => updateLine(line.key, { accountId: v })}
|
|
206
|
-
options={accountOptions}
|
|
207
|
-
/>
|
|
208
|
-
<InputField
|
|
209
|
-
className="h-10"
|
|
210
|
-
value={line.description}
|
|
211
|
-
onChange={(e) => updateLine(line.key, { description: e.target.value })}
|
|
212
|
-
/>
|
|
213
|
-
<InputField
|
|
214
|
-
className="h-10 text-right font-mono"
|
|
215
|
-
type="number"
|
|
216
|
-
value={line.debit}
|
|
217
|
-
onChange={(e) => updateLine(line.key, { debit: e.target.value })}
|
|
218
|
-
/>
|
|
219
|
-
<InputField
|
|
220
|
-
className="h-10 text-right font-mono"
|
|
221
|
-
type="number"
|
|
222
|
-
value={line.credit}
|
|
223
|
-
onChange={(e) => updateLine(line.key, { credit: e.target.value })}
|
|
224
|
-
/>
|
|
225
|
-
<button onClick={() => removeLine(line.key)} aria-label="Delete row">
|
|
226
|
-
<i className="ri-delete-bin-line" />
|
|
227
|
-
</button>
|
|
228
|
-
</div>
|
|
229
|
-
))}
|
|
230
|
-
|
|
231
|
-
{/* Totals row — direct grid items, no wrapper */}
|
|
232
|
-
<div />
|
|
233
|
-
<div />
|
|
234
|
-
<div className="text-right">Totals</div>
|
|
235
|
-
<div className="text-right font-mono">{totalDebit}</div>
|
|
236
|
-
<div className="text-right font-mono">{totalCredit}</div>
|
|
237
|
-
<div />
|
|
238
|
-
</div>
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
Key rules:
|
|
242
|
-
|
|
243
|
-
- **`className="contents"`** on the row wrapper is the critical trick. The
|
|
244
|
-
wrapper renders nothing of its own, so its children become direct grid
|
|
245
|
-
items of the parent.
|
|
246
|
-
- **`minmax(0, Xfr)`** columns prevent content-driven blowout when a single
|
|
247
|
-
cell has a long value.
|
|
248
|
-
- **Fixed-width columns** (the `32px` row-number column, the `36px` delete
|
|
249
|
-
column) are absolute pixel widths; flexible columns use `fr`.
|
|
250
|
-
- **Header alignment**: Debit/Credit headers are `text-left` because the
|
|
251
|
-
column starts at the input's left edge — right-aligning the header would
|
|
252
|
-
visually disconnect it from the column. The values inside the input are
|
|
253
|
-
right-aligned via `text-right font-mono` on the input itself.
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
|
-
## Recipe 4 — `DialogTitle` with icon
|
|
258
|
-
|
|
259
|
-
**Use case:** Plain `<DialogTitle>Create Account</DialogTitle>` lacks visual
|
|
260
|
-
hierarchy. Adding a relevant icon makes dialogs instantly recognizable.
|
|
261
|
-
|
|
262
|
-
```tsx
|
|
263
|
-
<DialogHeader>
|
|
264
|
-
<DialogTitle>
|
|
265
|
-
<div className="flex items-center gap-2">
|
|
266
|
-
<i className="ri-bank-line text-content-presentation-state-information" />
|
|
267
|
-
<span>Create Account</span>
|
|
268
|
-
</div>
|
|
269
|
-
</DialogTitle>
|
|
270
|
-
</DialogHeader>
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
Pick an icon that matches the entity:
|
|
274
|
-
|
|
275
|
-
| Entity | Icon |
|
|
276
|
-
| -------------------- | -------------------- |
|
|
277
|
-
| Account | `ri-bank-line` |
|
|
278
|
-
| Fiscal period / year | `ri-calendar-line` |
|
|
279
|
-
| Voucher / journal | `ri-receipt-line` |
|
|
280
|
-
| Number series | `ri-hashtag` |
|
|
281
|
-
| Posting rule | `ri-settings-3-line` |
|
|
282
|
-
| Exchange rate | `ri-exchange-line` |
|
|
283
|
-
| Bank / cash account | `ri-bank-card-line` |
|
|
284
|
-
|
|
285
|
-
---
|
|
286
|
-
|
|
287
|
-
## Recipe 5 — Two-column login layout
|
|
288
|
-
|
|
289
|
-
**Use case:** A login page with brand panel on the left and form on the right.
|
|
290
|
-
Communicates product identity better than a single centered card.
|
|
291
|
-
|
|
292
|
-
```tsx
|
|
293
|
-
import { Card, CardContent } from "@/components/Card";
|
|
294
|
-
import { InputField } from "@/components/InputField";
|
|
295
|
-
import { LoginButton } from "@/components/LoginButton";
|
|
296
|
-
|
|
297
|
-
export function LoginPage() {
|
|
298
|
-
return (
|
|
299
|
-
<div className="grid min-h-screen grid-cols-1 lg:grid-cols-2">
|
|
300
|
-
{/* Brand panel — hidden on mobile */}
|
|
301
|
-
<div
|
|
302
|
-
className={[
|
|
303
|
-
"hidden lg:flex flex-col justify-center gap-6 p-12",
|
|
304
|
-
"bg-linear-to-br from-background-presentation-action-primary/20",
|
|
305
|
-
"via-background-presentation-form-base",
|
|
306
|
-
"to-background-presentation-state-information/10",
|
|
307
|
-
].join(" ")}
|
|
308
|
-
>
|
|
309
|
-
<h1 className="typography-headers-large-medium">Welcome to Torch Finance</h1>
|
|
310
|
-
<ul className="flex flex-col gap-3">
|
|
311
|
-
{features.map((f) => (
|
|
312
|
-
<li key={f.title} className="flex items-start gap-3">
|
|
313
|
-
<span
|
|
314
|
-
className={[
|
|
315
|
-
"mt-0.5 inline-flex h-6 w-6 items-center justify-center",
|
|
316
|
-
"rounded-full bg-background-presentation-state-success-primary",
|
|
317
|
-
"text-content-presentation-action-dark-primary",
|
|
318
|
-
].join(" ")}
|
|
319
|
-
>
|
|
320
|
-
<i className="ri-check-line" />
|
|
321
|
-
</span>
|
|
322
|
-
<div>
|
|
323
|
-
<p className="typography-body-medium-medium">{f.title}</p>
|
|
324
|
-
<p className="typography-body-small-regular text-content-presentation-global-secondary">
|
|
325
|
-
{f.description}
|
|
326
|
-
</p>
|
|
327
|
-
</div>
|
|
328
|
-
</li>
|
|
329
|
-
))}
|
|
330
|
-
</ul>
|
|
331
|
-
</div>
|
|
332
|
-
|
|
333
|
-
{/* Form panel */}
|
|
334
|
-
<div className="flex items-center justify-center p-6">
|
|
335
|
-
<Card className="w-full max-w-md">
|
|
336
|
-
<CardContent className="flex flex-col gap-4 p-8">
|
|
337
|
-
<h2 className="typography-headers-medium-medium">Sign in</h2>
|
|
338
|
-
|
|
339
|
-
<InputField
|
|
340
|
-
className="h-10"
|
|
341
|
-
type="email"
|
|
342
|
-
icon={<i className="ri-mail-line text-base" />}
|
|
343
|
-
placeholder="Email"
|
|
344
|
-
errorMessage={errors.email?.message}
|
|
345
|
-
{...register("email")}
|
|
346
|
-
/>
|
|
347
|
-
|
|
348
|
-
<InputField
|
|
349
|
-
className="h-10"
|
|
350
|
-
type={showPassword ? "text" : "password"}
|
|
351
|
-
icon={<i className="ri-lock-line text-base" />}
|
|
352
|
-
childrenSide={
|
|
353
|
-
<button
|
|
354
|
-
type="button"
|
|
355
|
-
onClick={() => setShowPassword((v) => !v)}
|
|
356
|
-
aria-label={showPassword ? "Hide password" : "Show password"}
|
|
357
|
-
>
|
|
358
|
-
<i className={showPassword ? "ri-eye-off-line" : "ri-eye-line"} />
|
|
359
|
-
</button>
|
|
360
|
-
}
|
|
361
|
-
placeholder="Password"
|
|
362
|
-
errorMessage={errors.password?.message}
|
|
363
|
-
{...register("password")}
|
|
364
|
-
/>
|
|
365
|
-
|
|
366
|
-
<LoginButton isLoading={isSubmitting} type="submit">
|
|
367
|
-
Sign in
|
|
368
|
-
</LoginButton>
|
|
369
|
-
</CardContent>
|
|
370
|
-
</Card>
|
|
371
|
-
</div>
|
|
372
|
-
</div>
|
|
373
|
-
);
|
|
374
|
-
}
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
Key rules:
|
|
378
|
-
|
|
379
|
-
- **`hidden lg:flex`** hides the brand panel on mobile; the form panel
|
|
380
|
-
stretches to full width below the breakpoint.
|
|
381
|
-
- **`bg-linear-to-br from-* via-* to-*`** is Tailwind v4 gradient syntax. For
|
|
382
|
-
v3 use `bg-gradient-to-br`.
|
|
383
|
-
- **`LoginButton` has a built-in `isLoading` prop** — wire it to your form's
|
|
384
|
-
submitting state instead of writing your own loading spinner.
|
|
385
|
-
- **Use `InputField`'s `childrenSide`** for the password show/hide toggle —
|
|
386
|
-
the slot is built for trailing actions like this.
|