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,393 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { useFormState, type Control, type FieldPath, type FieldValues } from "react-hook-form";
|
|
5
|
-
|
|
6
|
-
import { cn } from "../../utils/cn";
|
|
7
|
-
import { Button } from "../Button";
|
|
8
|
-
// The step *registry* stays with the fields: `FieldShell` registers each field name into it, so
|
|
9
|
-
// it must ship with FormBuilder (which is installable on its own). Everything else about the
|
|
10
|
-
// stepper — the rail, the state, Back/Next — is chrome and lives here. The dependency only ever
|
|
11
|
-
// points this way: FormRenderer → FormBuilder, never back.
|
|
12
|
-
import { StepContext, type StepRegistry } from "../FormBuilder/context";
|
|
13
|
-
// Aliased: this module exports its own `Stepper` and `Step` (the wizard behaviour —
|
|
14
|
-
// `FormRenderer.Stepper` / `.Step`), which would otherwise collide with the presentational
|
|
15
|
-
// component of the same name.
|
|
16
|
-
import {
|
|
17
|
-
Stepper as StepperRail,
|
|
18
|
-
Step as StepPill,
|
|
19
|
-
StepIndicator,
|
|
20
|
-
StepLabel,
|
|
21
|
-
StepConnector,
|
|
22
|
-
} from "../Stepper";
|
|
23
|
-
|
|
24
|
-
// ─── Stepper state context ───────────────────────────────────────────────────
|
|
25
|
-
|
|
26
|
-
/** Stepper state shared by the nav, the step slots and the Back/Next buttons. */
|
|
27
|
-
export interface StepperContextValue {
|
|
28
|
-
currentStep: number;
|
|
29
|
-
totalSteps: number;
|
|
30
|
-
titles: string[];
|
|
31
|
-
isFirstStep: boolean;
|
|
32
|
-
isLastStep: boolean;
|
|
33
|
-
goToNext: () => void | Promise<void>;
|
|
34
|
-
goToPrevious: () => void;
|
|
35
|
-
goToStep: (index: number) => void;
|
|
36
|
-
/** Field names registered per step, for per-step validation. */
|
|
37
|
-
stepFields: Record<number, Set<string>>;
|
|
38
|
-
/** Steps that have passed validation — stay checked even after navigating back. */
|
|
39
|
-
completedSteps: Set<number>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export const StepperContext = React.createContext<StepperContextValue | null>(null);
|
|
43
|
-
|
|
44
|
-
export const useStepper = () => {
|
|
45
|
-
const ctx = React.useContext(StepperContext);
|
|
46
|
-
if (!ctx) throw new Error("FormRenderer.Step/Back/Next must be used within FormRenderer.Stepper");
|
|
47
|
-
return ctx;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// ─── Step (declaration only — the Stepper reads its props) ───────────────────
|
|
51
|
-
|
|
52
|
-
export interface StepProps {
|
|
53
|
-
title: string;
|
|
54
|
-
description?: string;
|
|
55
|
-
children: React.ReactNode;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Declares a wizard step. It renders nothing itself — `FormRenderer.Stepper`
|
|
60
|
-
* collects Step elements as an array and renders every step's fields (so the
|
|
61
|
-
* **whole form is registered**), toggling visibility per the active step.
|
|
62
|
-
*/
|
|
63
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- props are read by Stepper, not rendered here
|
|
64
|
-
export function Step(_props: StepProps) {
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
(Step as unknown as { __isFormStep: boolean }).__isFormStep = true;
|
|
68
|
-
|
|
69
|
-
export function isStepElement(node: React.ReactNode): node is React.ReactElement<StepProps> {
|
|
70
|
-
return (
|
|
71
|
-
React.isValidElement(node) && (node.type as { __isFormStep?: boolean })?.__isFormStep === true
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ─── StepSlot — mounts one step's fields; hidden when not active ─────────────
|
|
76
|
-
|
|
77
|
-
function StepSlot({
|
|
78
|
-
index,
|
|
79
|
-
active,
|
|
80
|
-
children,
|
|
81
|
-
}: {
|
|
82
|
-
index: number;
|
|
83
|
-
active: boolean;
|
|
84
|
-
children: React.ReactNode;
|
|
85
|
-
}) {
|
|
86
|
-
const stepper = useStepper();
|
|
87
|
-
const registry: StepRegistry = React.useMemo(
|
|
88
|
-
() => ({
|
|
89
|
-
register: (name) => {
|
|
90
|
-
(stepper.stepFields[index] ??= new Set()).add(name);
|
|
91
|
-
},
|
|
92
|
-
unregister: (name) => {
|
|
93
|
-
stepper.stepFields[index]?.delete(name);
|
|
94
|
-
},
|
|
95
|
-
}),
|
|
96
|
-
[stepper, index],
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
// Always mounted (fields stay registered); CSS hides inactive steps.
|
|
100
|
-
return (
|
|
101
|
-
<div className={cn("flex flex-col gap-4", !active && "hidden")}>
|
|
102
|
-
<StepContext.Provider value={registry}>{children}</StepContext.Provider>
|
|
103
|
-
</div>
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// ─── Stepper navigation (style only) ─────────────────────────────────────────
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Vertical step rail (matches `Tabs.svg`): the numbered state badges stacked top
|
|
111
|
-
* to bottom, joined by a short vertical connector between consecutive steps.
|
|
112
|
-
*
|
|
113
|
-
* `control` is passed in rather than read from context: the rail renders in its own grid column
|
|
114
|
-
* **outside** the `<form>`, so there is no `FormProvider` above it to read. Same reason
|
|
115
|
-
* `useStepperState` takes `trigger` as an argument.
|
|
116
|
-
*/
|
|
117
|
-
function StepperNav({ control }: { control: Control<FieldValues> }) {
|
|
118
|
-
const { titles, currentStep, goToStep, stepFields, completedSteps } = useStepper();
|
|
119
|
-
const { errors } = useFormState({ control });
|
|
120
|
-
|
|
121
|
-
const stepHasError = (index: number) =>
|
|
122
|
-
[...(stepFields[index] ?? [])].some((name) => name in errors);
|
|
123
|
-
|
|
124
|
-
return (
|
|
125
|
-
// `min-w-0` so the rail can be squeezed: its grid track no longer grows to fit a long label
|
|
126
|
-
// (see form-renderer.tsx), so the column has to be allowed to shrink and let the labels
|
|
127
|
-
// truncate instead of spilling over the fields column.
|
|
128
|
-
//
|
|
129
|
-
// The rail is navigation, so it stays put while the fields scroll past it. Two of these three
|
|
130
|
-
// classes are load-bearing in a way that is easy to get wrong:
|
|
131
|
-
//
|
|
132
|
-
// `self-start` is NOT optional. The rail is a grid item, and a grid item defaults to
|
|
133
|
-
// `align-self: stretch` — its box is already the full row height, so `sticky` alone has no room
|
|
134
|
-
// to move within and does exactly nothing. This is the silent-no-op version of this fix.
|
|
135
|
-
//
|
|
136
|
-
// `top-[72px]`, not `top-0`. `FormHeaderBar` is `absolute inset-x-0 top-0` over a 44px pill at a
|
|
137
|
-
// 4px inset, so it covers the scrollport's first 48px, and the body's own `pt-[72px]` is inside
|
|
138
|
-
// the scrollport and does not push sticky down. `top-0` parks the rail under the floating
|
|
139
|
-
// header; 72px clears it and matches the offset used across this component family.
|
|
140
|
-
//
|
|
141
|
-
// No height cap: the scrollport is the form body, not the viewport, so a `100dvh`-based
|
|
142
|
-
// `max-h` would be wrong in any bounded container (a drawer, the 640px docs frame). A rail
|
|
143
|
-
// taller than the body simply scrolls until its end is reached, which is standard sticky
|
|
144
|
-
// behaviour and correct here.
|
|
145
|
-
<StepperRail
|
|
146
|
-
activeStep={currentStep}
|
|
147
|
-
orientation="vertical"
|
|
148
|
-
className="min-w-0 shrink-0 sticky self-start top-[72px]"
|
|
149
|
-
>
|
|
150
|
-
{titles.map((title, index) => {
|
|
151
|
-
// The step buttons ARE the navigation: click to move. Backward is free;
|
|
152
|
-
// clicking forward validates the steps in between (goToStep) and stops at
|
|
153
|
-
// the first one with errors. A live error shows red; a step that has passed
|
|
154
|
-
// validation stays checked (success) even after navigating back to it.
|
|
155
|
-
const type = stepHasError(index)
|
|
156
|
-
? "negative"
|
|
157
|
-
: completedSteps.has(index)
|
|
158
|
-
? "success"
|
|
159
|
-
: "default";
|
|
160
|
-
return (
|
|
161
|
-
<React.Fragment key={title}>
|
|
162
|
-
{/* The shrink/truncate pair is passed in rather than changed in `Stepper`, so its
|
|
163
|
-
other consumers keep sizing to their labels. `shrink` beats the pill's own
|
|
164
|
-
`shrink-0` and `truncate` beats the label's `whitespace-nowrap` — both via
|
|
165
|
-
tailwind-merge, which `Stepper` runs the caller's className through. */}
|
|
166
|
-
<StepPill
|
|
167
|
-
index={index}
|
|
168
|
-
type={type}
|
|
169
|
-
onClick={() => void goToStep(index)}
|
|
170
|
-
// `max-w-full` is what actually makes the label truncate: the rail is
|
|
171
|
-
// `items-start`, so without a cap the pill shrink-wraps its label and grows straight
|
|
172
|
-
// past the track instead of clipping inside it.
|
|
173
|
-
className="min-w-0 max-w-full shrink"
|
|
174
|
-
>
|
|
175
|
-
<StepIndicator />
|
|
176
|
-
{/* `max-w-none` opts out of the component's 106px cap: the rail sizes to its own
|
|
177
|
-
grid track, so the label should truncate there rather than 106px early. */}
|
|
178
|
-
<StepLabel className="max-w-none truncate">{title}</StepLabel>
|
|
179
|
-
</StepPill>
|
|
180
|
-
{/* Connector between steps — the component centres it under the indicator per size. */}
|
|
181
|
-
{index < titles.length - 1 && <StepConnector />}
|
|
182
|
-
</React.Fragment>
|
|
183
|
-
);
|
|
184
|
-
})}
|
|
185
|
-
</StepperRail>
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// ─── Back / Next chevron nav (the Figma header action bar) ───────────────────
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Shared chevron nav button, matching the Figma header action bar (Body-HeaderBar-1.0) — the
|
|
193
|
-
* Glare `Button` icon variant, the same control Select/SearchableSelect use for their chevrons.
|
|
194
|
-
*/
|
|
195
|
-
function StepNavButton({
|
|
196
|
-
dir,
|
|
197
|
-
onClick,
|
|
198
|
-
disabled,
|
|
199
|
-
}: {
|
|
200
|
-
dir: "left" | "right";
|
|
201
|
-
onClick: () => void;
|
|
202
|
-
disabled: boolean;
|
|
203
|
-
}) {
|
|
204
|
-
return (
|
|
205
|
-
<Button
|
|
206
|
-
type="button"
|
|
207
|
-
buttonType="icon"
|
|
208
|
-
size="M"
|
|
209
|
-
onClick={onClick}
|
|
210
|
-
disabled={disabled}
|
|
211
|
-
aria-label={dir === "left" ? "Previous step" : "Next step"}
|
|
212
|
-
>
|
|
213
|
-
<i
|
|
214
|
-
className={cn(
|
|
215
|
-
"text-[18px]",
|
|
216
|
-
dir === "left" ? "ri-arrow-left-s-line" : "ri-arrow-right-s-line",
|
|
217
|
-
)}
|
|
218
|
-
/>
|
|
219
|
-
</Button>
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/** `FormRenderer.Back` — chevron to the previous step; disabled on the first. */
|
|
224
|
-
export function Back() {
|
|
225
|
-
const { goToPrevious, isFirstStep } = useStepper();
|
|
226
|
-
return <StepNavButton dir="left" onClick={goToPrevious} disabled={isFirstStep} />;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/** `FormRenderer.Next` — chevron to the next step (validates first); disabled on the last. */
|
|
230
|
-
export function Next() {
|
|
231
|
-
const { goToNext, isLastStep } = useStepper();
|
|
232
|
-
return <StepNavButton dir="right" onClick={() => void goToNext()} disabled={isLastStep} />;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// ─── Stepper action bar (Back/Next + divider, then the Submit) ────────────────
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* The FormRenderer root wraps its `actions` in this. When the form is a stepper it prepends the
|
|
239
|
-
* chevron `Back`/`Next` controls + a divider before the (user-provided) Submit — the Figma
|
|
240
|
-
* `Body-HeaderBar-1.0` layout. Outside a stepper there's no `StepperContext`, so it renders
|
|
241
|
-
* the actions untouched.
|
|
242
|
-
*/
|
|
243
|
-
export function StepperActions({ children }: { children?: React.ReactNode }) {
|
|
244
|
-
const stepper = React.useContext(StepperContext);
|
|
245
|
-
if (!stepper) return <>{children}</>;
|
|
246
|
-
return (
|
|
247
|
-
<div className="flex items-center gap-2">
|
|
248
|
-
<Back />
|
|
249
|
-
<Next />
|
|
250
|
-
{/* Divider — white-alpha hairline between the nav and the Submit. */}
|
|
251
|
-
<span aria-hidden className="mx-1 h-5 w-px rounded-[2px] bg-white-alpha-20" />
|
|
252
|
-
{children}
|
|
253
|
-
</div>
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// ─── Stepper root (marker) + state hook ──────────────────────────────────────
|
|
258
|
-
|
|
259
|
-
export interface StepperProps {
|
|
260
|
-
children: React.ReactNode;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* `FormRenderer.Stepper` — declares a wizard. It renders **nothing itself**: the
|
|
265
|
-
* FormRenderer root detects it, lifts its state (so the nav can live in its own
|
|
266
|
-
* grid column *outside* the `<form>`), and renders `[nav | active step's fields]`.
|
|
267
|
-
* Children are `FormRenderer.Step`s (plus an optional custom footer).
|
|
268
|
-
*
|
|
269
|
-
* Every step's fields stay registered with react-hook-form at all times — the
|
|
270
|
-
* stepper only controls which step is *visible*. **Navigation is the step buttons
|
|
271
|
-
* themselves**: click a step to move there. Backward is free; clicking forward
|
|
272
|
-
* validates every step in between and stops at the first with errors (which shows a
|
|
273
|
-
* red indicator). Only the last step shows the Submit button.
|
|
274
|
-
*/
|
|
275
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- children are read by the FormRenderer root
|
|
276
|
-
export function Stepper(_props: StepperProps) {
|
|
277
|
-
return null;
|
|
278
|
-
}
|
|
279
|
-
(Stepper as unknown as { __isFormStepper: boolean }).__isFormStepper = true;
|
|
280
|
-
|
|
281
|
-
export function isStepperElement(node: React.ReactNode): node is React.ReactElement<StepperProps> {
|
|
282
|
-
return (
|
|
283
|
-
React.isValidElement(node) &&
|
|
284
|
-
(node.type as { __isFormStepper?: boolean })?.__isFormStepper === true
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
type TriggerFn = (names?: FieldPath<FieldValues>[]) => Promise<boolean>;
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Stepper state — lifted to the FormRenderer root so the nav (rail) and the step
|
|
292
|
-
* fields can render in separate grid columns while sharing one state. `trigger` is
|
|
293
|
-
* the form's `trigger` (passed in — no `useFormContext` needed). Inert when
|
|
294
|
-
* `steps` is empty (a form without a stepper still calls this, for hooks order).
|
|
295
|
-
*/
|
|
296
|
-
/**
|
|
297
|
-
* LOCAL PATCH (Contact Center): optional external control of the active step.
|
|
298
|
-
*
|
|
299
|
-
* Upstream owns `currentStep` outright and advances it by clicking a step, gated on validating
|
|
300
|
-
* every step in between. That is right for a wizard whose steps are pages of one form — but not
|
|
301
|
-
* for one whose steps are owned by a SERVER: the import wizard goes upload → (job created) →
|
|
302
|
-
* mapping → (columns mapped, import started) → progress, and the user cannot click ahead to a
|
|
303
|
-
* step that does not exist yet.
|
|
304
|
-
*
|
|
305
|
-
* Passing `activeStep`/`onStepChange` makes the rail a display of someone else's state: internal
|
|
306
|
-
* advancement is suppressed and click-to-navigate is reported rather than applied. Omit both and
|
|
307
|
-
* every existing caller behaves exactly as before.
|
|
308
|
-
*/
|
|
309
|
-
export interface StepperControl {
|
|
310
|
-
activeStep?: number;
|
|
311
|
-
onStepChange?: (index: number) => void;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
export function useStepperState(
|
|
315
|
-
steps: React.ReactElement<StepProps>[],
|
|
316
|
-
trigger: TriggerFn,
|
|
317
|
-
control?: StepperControl,
|
|
318
|
-
): StepperContextValue {
|
|
319
|
-
const [internalStep, setInternalStep] = React.useState(0);
|
|
320
|
-
// LOCAL PATCH (Contact Center): controlled when `activeStep` is supplied — see `StepperControl`.
|
|
321
|
-
const isControlled = control?.activeStep !== undefined;
|
|
322
|
-
const currentStep = isControlled ? (control?.activeStep as number) : internalStep;
|
|
323
|
-
const setCurrentStep: React.Dispatch<React.SetStateAction<number>> = (value) => {
|
|
324
|
-
const next = typeof value === "function" ? (value as (p: number) => number)(currentStep) : value;
|
|
325
|
-
if (isControlled) control?.onStepChange?.(next);
|
|
326
|
-
else setInternalStep(next);
|
|
327
|
-
};
|
|
328
|
-
// Steps that have passed their last validation — kept so their checkmark persists when the
|
|
329
|
-
// user navigates back to an earlier step.
|
|
330
|
-
const [completedSteps, setCompletedSteps] = React.useState<Set<number>>(new Set());
|
|
331
|
-
const stepFieldsRef = React.useRef<Record<number, Set<string>>>({});
|
|
332
|
-
const titles = steps.map((s) => s.props.title);
|
|
333
|
-
const lastIndex = steps.length - 1;
|
|
334
|
-
|
|
335
|
-
const markStep = (step: number, passed: boolean) =>
|
|
336
|
-
setCompletedSteps((prev) => {
|
|
337
|
-
if (passed === prev.has(step)) return prev; // no change
|
|
338
|
-
const next = new Set(prev);
|
|
339
|
-
if (passed) next.add(step);
|
|
340
|
-
else next.delete(step);
|
|
341
|
-
return next;
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
const validateStep = async (step: number) => {
|
|
345
|
-
const names = [...(stepFieldsRef.current[step] ?? [])] as FieldPath<FieldValues>[];
|
|
346
|
-
const passed = names.length === 0 ? true : await trigger(names);
|
|
347
|
-
markStep(step, passed);
|
|
348
|
-
return passed;
|
|
349
|
-
};
|
|
350
|
-
|
|
351
|
-
// Navigation runs through the step buttons. Backward is free; going forward
|
|
352
|
-
// validates every step between the current one and the target, and stops at
|
|
353
|
-
// the first step that has errors (so you can't skip past an invalid step).
|
|
354
|
-
const goToStep = async (index: number) => {
|
|
355
|
-
const target = Math.max(0, Math.min(index, Math.max(0, lastIndex)));
|
|
356
|
-
// LOCAL PATCH (Contact Center): controlled — the owner decides whether the move is allowed,
|
|
357
|
-
// so report it and do not run the forward-validation gauntlet.
|
|
358
|
-
if (isControlled) {
|
|
359
|
-
control?.onStepChange?.(target);
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
if (target <= currentStep) {
|
|
363
|
-
setCurrentStep(target);
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
for (let s = currentStep; s < target; s++) {
|
|
367
|
-
if (!(await validateStep(s))) {
|
|
368
|
-
setCurrentStep(s);
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
setCurrentStep(target);
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
const goToNext = async () => {
|
|
376
|
-
if (await validateStep(currentStep)) setCurrentStep((s) => Math.min(s + 1, lastIndex));
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
return {
|
|
380
|
-
currentStep,
|
|
381
|
-
totalSteps: steps.length,
|
|
382
|
-
titles,
|
|
383
|
-
isFirstStep: currentStep === 0,
|
|
384
|
-
isLastStep: currentStep === lastIndex,
|
|
385
|
-
goToNext,
|
|
386
|
-
goToPrevious: () => setCurrentStep((s) => Math.max(s - 1, 0)),
|
|
387
|
-
goToStep,
|
|
388
|
-
stepFields: stepFieldsRef.current,
|
|
389
|
-
completedSteps,
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
export { StepperNav, StepSlot };
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from "react";
|
|
2
|
-
import type {
|
|
3
|
-
DefaultValues,
|
|
4
|
-
FieldErrors,
|
|
5
|
-
FieldValues,
|
|
6
|
-
Resolver,
|
|
7
|
-
UseFormReturn,
|
|
8
|
-
} from "react-hook-form";
|
|
9
|
-
import type { FormDrawerProps } from "./FormDrawer";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* FormRenderer — the chrome around a `FormBuilder`. You author the fields as **JSX children**
|
|
13
|
-
* (`FormRenderer.Section`, `FormBuilder.Text`, …); the renderer owns everything drawn around
|
|
14
|
-
* them: page-vs-drawer display, the absolute title header, the `actions` bar, the titled section
|
|
15
|
-
* cards, the page gutters and scroll shell, the wizard rail, the `summary` column, and vertical
|
|
16
|
-
* field layout inside a drawer.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
export type FormRendererDisplay = "page" | "drawer";
|
|
20
|
-
export type FieldDirection = "horizontal" | "vertical" | "flexible";
|
|
21
|
-
|
|
22
|
-
export interface FormRendererProps<T extends FieldValues = FieldValues> {
|
|
23
|
-
/** The form body — `FormRenderer.Section` / field / `FormRenderer.Stepper` JSX. */
|
|
24
|
-
children: ReactNode;
|
|
25
|
-
|
|
26
|
-
// --- react-hook-form root (forwarded to FormBuilder) ---
|
|
27
|
-
/** Submit handler. Optional — a display-only detail-tabs view (`FormRenderer.Sidebar`) has no form. */
|
|
28
|
-
onSubmit?: (values: T) => void | Promise<void>;
|
|
29
|
-
onInvalid?: (errors: FieldErrors<T>) => void;
|
|
30
|
-
resolver?: Resolver<T>;
|
|
31
|
-
defaultValues?: DefaultValues<T>;
|
|
32
|
-
values?: T;
|
|
33
|
-
loading?: boolean;
|
|
34
|
-
resetOnSuccess?: boolean;
|
|
35
|
-
/** Row layout; defaults to vertical inside a drawer. */
|
|
36
|
-
fieldDirection?: FieldDirection;
|
|
37
|
-
/**
|
|
38
|
-
* A hoisted `useForm` instance to bind the form to. Pass this when something outside the
|
|
39
|
-
* form (e.g. a `summary` `FormSummary`) must read the same live values; the caller owns
|
|
40
|
-
* `resolver`/`defaultValues` on that instance. Omit to let FormRenderer create its own.
|
|
41
|
-
*/
|
|
42
|
-
form?: UseFormReturn<T>;
|
|
43
|
-
|
|
44
|
-
// --- display ---
|
|
45
|
-
display?: FormRendererDisplay;
|
|
46
|
-
/**
|
|
47
|
-
* A live panel rendered beside the form (page) or in the drawer tray (drawer) — typically a
|
|
48
|
-
* `FormSummary`. Give FormRenderer the same hoisted `form` so the panel reads live values.
|
|
49
|
-
*/
|
|
50
|
-
summary?: ReactNode;
|
|
51
|
-
/**
|
|
52
|
-
* Lands on the form's outermost element (page display). Use it to let the form fill its
|
|
53
|
-
* parent — e.g. `"flex-1 min-h-0"` inside a flex column that has a height.
|
|
54
|
-
*/
|
|
55
|
-
className?: string;
|
|
56
|
-
/**
|
|
57
|
-
* Absolute title header + action bar. Used by **both** displays — the page and the
|
|
58
|
-
* drawer render the same `HeaderBar` title pill, so a form looks identical in either.
|
|
59
|
-
*/
|
|
60
|
-
header?: { title: string; label?: string; variant?: "new" | "edit" | "detail" };
|
|
61
|
-
/**
|
|
62
|
-
* The form's action bar — rendered in the header's right-hand action pill (page) or the drawer
|
|
63
|
-
* header (drawer). Put the Save here: `actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}`.
|
|
64
|
-
* A bare `FormBuilder.Submit` auto-targets this form (see `FormBuilder`'s form-id context), so it
|
|
65
|
-
* submits even though the header sits outside the `<form>`.
|
|
66
|
-
*/
|
|
67
|
-
actions?: ReactNode;
|
|
68
|
-
/** `id` on the underlying `<form>`. Optional — FormRenderer generates and wires one otherwise. */
|
|
69
|
-
id?: string;
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* LOCAL PATCH (Contact Center): detail-tabs control (when the children are a
|
|
73
|
-
* `FormRenderer.Sidebar` + `FormRenderer.Tab`s). Inert in form mode.
|
|
74
|
-
*
|
|
75
|
-
* `activeTab`/`onTabChange` make the rail controlled, so the caller can keep the tab in the URL
|
|
76
|
-
* (`useTabPersistence` → `?tab=`); omit both for the library's uncontrolled default.
|
|
77
|
-
* `embedded` renders without the rounded body card, for a host that already draws one.
|
|
78
|
-
*/
|
|
79
|
-
activeTab?: string;
|
|
80
|
-
onTabChange?: (tab: string) => void;
|
|
81
|
-
embedded?: boolean;
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* LOCAL PATCH (Contact Center): external control of a `FormRenderer.Stepper`'s active step,
|
|
85
|
-
* for a wizard whose steps are owned by something other than form validity — a server job,
|
|
86
|
-
* say. Omit both and the stepper owns its own step exactly as before. Inert without a Stepper.
|
|
87
|
-
*/
|
|
88
|
-
activeStep?: number;
|
|
89
|
-
onStepChange?: (index: number) => void;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* LOCAL PATCH (Contact Center): drawer layout, forwarded to `FormDrawer`. One object rather
|
|
93
|
-
* than eight flat props, since none of it means anything on a page. See `FormDrawerProps`.
|
|
94
|
-
*/
|
|
95
|
-
drawer?: Pick<
|
|
96
|
-
FormDrawerProps,
|
|
97
|
-
| "side"
|
|
98
|
-
| "nested"
|
|
99
|
-
| "framed"
|
|
100
|
-
| "hideHeader"
|
|
101
|
-
| "bareBody"
|
|
102
|
-
| "description"
|
|
103
|
-
| "wrapperClassName"
|
|
104
|
-
| "className"
|
|
105
|
-
>;
|
|
106
|
-
|
|
107
|
-
/** Drawer control (when `display === "drawer"`). */
|
|
108
|
-
open?: boolean;
|
|
109
|
-
onOpenChange?: (open: boolean) => void;
|
|
110
|
-
/** Overrides `header.title` for the drawer. Plain text — it renders via `HeaderBar`. */
|
|
111
|
-
title?: string;
|
|
112
|
-
/** Overrides `header.label` for the drawer. */
|
|
113
|
-
badge?: string;
|
|
114
|
-
onOpenInNewTab?: () => void;
|
|
115
|
-
}
|