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,250 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { ReactNode } from "react";
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
Drawer,
|
|
7
|
-
DrawerContent,
|
|
8
|
-
DrawerDescription,
|
|
9
|
-
DrawerNested,
|
|
10
|
-
DrawerPanel,
|
|
11
|
-
DrawerTitle,
|
|
12
|
-
DrawerNotch,
|
|
13
|
-
DrawerNotchClose,
|
|
14
|
-
DrawerNotchDivider,
|
|
15
|
-
DrawerNotchPill,
|
|
16
|
-
} from "../Drawer";
|
|
17
|
-
import { cn } from "../../utils/cn";
|
|
18
|
-
import { FormHeaderBar, type HeaderVariant } from "./header";
|
|
19
|
-
// Only for vaul's `direction` — every other mirror below is native CSS. See `slideFrom`.
|
|
20
|
-
import { useHtmlDir } from "../../hooks/useHtmlDir";
|
|
21
|
-
|
|
22
|
-
export interface FormDrawerProps {
|
|
23
|
-
open: boolean;
|
|
24
|
-
onOpenChange: (open: boolean) => void;
|
|
25
|
-
/** The `<FormBuilder>` (or any content) to host inside the drawer. */
|
|
26
|
-
children: ReactNode;
|
|
27
|
-
/**
|
|
28
|
-
* The conclusion panel rendered **beside** the form, outside the drawer's scrollable
|
|
29
|
-
* body — typically a `<FormSummary>` reading the same hoisted `form`. `FormDrawer` owns
|
|
30
|
-
* the box around it (full height, shrinkable), which is what lets the panel's own
|
|
31
|
-
* `h-full` and internal scrolling work. The panel sizes itself — a `FormSummary` is
|
|
32
|
-
* 228px wide by default — and brings its own (dark) background.
|
|
33
|
-
*/
|
|
34
|
-
summary?: ReactNode;
|
|
35
|
-
/** @deprecated Renamed to `summary`. */
|
|
36
|
-
childrenOutside?: ReactNode;
|
|
37
|
-
/**
|
|
38
|
-
* Plain title text (uppercased) in the header's title pill — also the a11y title.
|
|
39
|
-
* A string, because it renders through the same `HeaderBar` as the page form.
|
|
40
|
-
*/
|
|
41
|
-
title?: string;
|
|
42
|
-
/** Badge text in the title pill. Defaults from `variant` (New / Edit / View). */
|
|
43
|
-
badge?: string;
|
|
44
|
-
/** Colored badge variant, matching the page form's header. Default `"new"`. */
|
|
45
|
-
variant?: HeaderVariant;
|
|
46
|
-
/** Action buttons shown on the right of the drawer header (e.g. a Save submit). */
|
|
47
|
-
actions?: ReactNode;
|
|
48
|
-
/**
|
|
49
|
-
* Shows an "Open in new tab" pill in the notch when provided.
|
|
50
|
-
*
|
|
51
|
-
* Prefer `notchActions` (a `FormRenderer.NotchAction` child): the caller owns the label
|
|
52
|
-
* there, so it needs no second prop to be translatable. Kept for callers that only want
|
|
53
|
-
* upstream's single built-in action.
|
|
54
|
-
*/
|
|
55
|
-
onOpenInNewTab?: () => void;
|
|
56
|
-
/**
|
|
57
|
-
* Buttons rendered in the notch, authored by the caller.
|
|
58
|
-
*
|
|
59
|
-
* LOCAL PATCH (Contact Center): upstream offers only `onOpenInNewTab` with a hardcoded
|
|
60
|
-
* English label, so a localized app cannot translate it and cannot add a second action.
|
|
61
|
-
* Passing the button itself solves both. Written as `FormRenderer.NotchAction` children
|
|
62
|
-
* and lifted here — see `notch-action.tsx`.
|
|
63
|
-
*/
|
|
64
|
-
notchActions?: ReactNode;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* LOCAL PATCH (Contact Center): the layout knobs `DrawerContent` already has.
|
|
68
|
-
*
|
|
69
|
-
* Upstream swallowed every one of them, which is why each non-default drawer in this app was
|
|
70
|
-
* hand-rolled instead: a two-field form does not want 1048px, a widget gallery is a bottom
|
|
71
|
-
* sheet, and a detail view brings its own header and scroll container. All optional and all
|
|
72
|
-
* defaulting to the original behaviour, so existing callers are untouched.
|
|
73
|
-
*/
|
|
74
|
-
|
|
75
|
-
/** Which edge it slides from. `"bottom"` is a sheet; the default follows document direction. */
|
|
76
|
-
side?: "inline-end" | "bottom";
|
|
77
|
-
/**
|
|
78
|
-
* vaul `NestedRoot` — REQUIRED when this drawer opens inside another one, or the two Roots
|
|
79
|
-
* fight over the overlay and the scroll lock. Throws without a parent Drawer in the tree.
|
|
80
|
-
*/
|
|
81
|
-
nested?: boolean;
|
|
82
|
-
/** The dark tray frame and the panel's border/inset shadow. Default `true`. */
|
|
83
|
-
framed?: boolean;
|
|
84
|
-
/** Skip the `FormHeaderBar` — for a child that draws its own header. */
|
|
85
|
-
hideHeader?: boolean;
|
|
86
|
-
/** Skip the padded scroll wrapper — for a child that owns its own padding and scrolling. */
|
|
87
|
-
bareBody?: boolean;
|
|
88
|
-
/** sr-only description. vaul warns when a drawer has none. */
|
|
89
|
-
description?: string;
|
|
90
|
-
/** Lands on the positioner: width, height, insets. Replaces the default sizing. */
|
|
91
|
-
wrapperClassName?: string;
|
|
92
|
-
/** Lands on the tray. */
|
|
93
|
-
className?: string;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* A right-anchored Glare drawer for hosting a form. This is a **FormRenderer**
|
|
98
|
-
* concern — `FormBuilder` itself is drawer-unaware (it only displays inputs).
|
|
99
|
-
* Wrap a `<FormBuilder>` in `<FormDrawer>` (and pass `fieldDirection="vertical"`
|
|
100
|
-
* to the form) to show it in a drawer, or let `FormRenderer` do it via
|
|
101
|
-
* `display: "drawer"`.
|
|
102
|
-
*
|
|
103
|
-
* The `wrapperClassName` includes `mt-0 h-auto` to cancel `DrawerContent`'s base
|
|
104
|
-
* bottom-sheet offset (the Glare right-side form-drawer recipe).
|
|
105
|
-
*
|
|
106
|
-
* It owns the arrangement of its two slots: the form goes in a `DrawerPanel` (the light
|
|
107
|
-
* surface), and `summary` sits beside it in the tray with a 6px gutter. The tray itself
|
|
108
|
-
* paints nothing, so each panel brings its own background.
|
|
109
|
-
*/
|
|
110
|
-
export function FormDrawer({
|
|
111
|
-
open,
|
|
112
|
-
onOpenChange,
|
|
113
|
-
children,
|
|
114
|
-
summary,
|
|
115
|
-
childrenOutside,
|
|
116
|
-
title = "Form",
|
|
117
|
-
badge,
|
|
118
|
-
variant,
|
|
119
|
-
actions,
|
|
120
|
-
onOpenInNewTab,
|
|
121
|
-
notchActions,
|
|
122
|
-
// LOCAL PATCH (Contact Center) — see the props above.
|
|
123
|
-
side = "inline-end",
|
|
124
|
-
nested = false,
|
|
125
|
-
framed = true,
|
|
126
|
-
hideHeader = false,
|
|
127
|
-
bareBody = false,
|
|
128
|
-
description,
|
|
129
|
-
wrapperClassName,
|
|
130
|
-
className,
|
|
131
|
-
}: FormDrawerProps) {
|
|
132
|
-
const conclusion = summary ?? childrenOutside;
|
|
133
|
-
const isBottom = side === "bottom";
|
|
134
|
-
// A drawer inside a drawer must be vaul's NestedRoot, which scales the parent behind it.
|
|
135
|
-
const Root = nested ? DrawerNested : Drawer;
|
|
136
|
-
|
|
137
|
-
// The ONLY thing that still has to know the direction in JS. Everything visual below is
|
|
138
|
-
// expressed in logical CSS and mirrors itself; but vaul (1.1.2) has no RTL support at all —
|
|
139
|
-
// it computes an inline `transform: translate3d(±Npx,0,0)` from `direction` and keys its drag
|
|
140
|
-
// physics off it. An inline transform cannot be overridden from a stylesheet mid-drag, so this
|
|
141
|
-
// one value must be passed, not styled. Read from <html dir>, so it still follows the document.
|
|
142
|
-
const slideFrom = useHtmlDir() === "rtl" ? "left" : "right";
|
|
143
|
-
|
|
144
|
-
return (
|
|
145
|
-
<Root open={open} onOpenChange={onOpenChange} direction={isBottom ? "bottom" : slideFrom}>
|
|
146
|
-
{/* The panel fills the available width (minus the 8px insets), capped at 1048px.
|
|
147
|
-
`gap-[6px]` is the gutter between the form panel and the conclusion beside it. */}
|
|
148
|
-
<DrawerContent
|
|
149
|
-
// Logical: the notch attaches to the inline-start edge, which the browser resolves
|
|
150
|
-
// to left under LTR and right under RTL. No direction check here.
|
|
151
|
-
notchSide="start"
|
|
152
|
-
framed={framed}
|
|
153
|
-
// `end-2` / `start-auto` are logical insets (inset-inline-*), so the panel parks
|
|
154
|
-
// against the inline-end edge in either direction — this used to be two hand-written
|
|
155
|
-
// physical class strings picked by JS.
|
|
156
|
-
//
|
|
157
|
-
// LOCAL PATCH (Contact Center): `inset-x-auto` is load-bearing. `DrawerContent` hardcodes
|
|
158
|
-
// `inset-x-0`, and tailwind-merge's `inset-x` conflict group covers `left`/`right` but NOT
|
|
159
|
-
// `start`/`end` — so `inset-x-0` survives into the class list and was only losing because
|
|
160
|
-
// Tailwind v4 happens to emit `start`/`end` later in the cascade. Every caller inherited
|
|
161
|
-
// that; this stops depending on emit order.
|
|
162
|
-
wrapperClassName={
|
|
163
|
-
wrapperClassName ??
|
|
164
|
-
(isBottom
|
|
165
|
-
? "inset-x-0 bottom-0 top-auto mt-0 h-auto w-full"
|
|
166
|
-
: "top-2 end-2 bottom-2 inset-x-auto start-auto mt-0 h-auto w-[calc(100vw-1rem)] max-w-[1048px]")
|
|
167
|
-
}
|
|
168
|
-
className={cn("gap-[6px]", className)}
|
|
169
|
-
// LOCAL PATCH (Contact Center): a bottom sheet has no notch. The notch is a tab on the
|
|
170
|
-
// panel's inline-start edge — on a sheet that slides up from below there is no such edge
|
|
171
|
-
// to hang it from, and it renders as a stray pill floating above the corner.
|
|
172
|
-
notch={
|
|
173
|
-
isBottom ? undefined : (
|
|
174
|
-
<DrawerNotch>
|
|
175
|
-
<DrawerNotchClose onClick={() => onOpenChange(false)} />
|
|
176
|
-
{/* Caller-authored notch buttons win; `onOpenInNewTab` is upstream's built-in
|
|
177
|
-
single action, kept as a fallback for callers that pass no children. */}
|
|
178
|
-
{notchActions ? (
|
|
179
|
-
<>
|
|
180
|
-
<DrawerNotchDivider />
|
|
181
|
-
{notchActions}
|
|
182
|
-
</>
|
|
183
|
-
) : (
|
|
184
|
-
onOpenInNewTab && (
|
|
185
|
-
<>
|
|
186
|
-
<DrawerNotchDivider />
|
|
187
|
-
<DrawerNotchPill color="Yellow" onClick={onOpenInNewTab}>
|
|
188
|
-
Open in new tab
|
|
189
|
-
<i className="ri-arrow-right-up-line text-[12px]" />
|
|
190
|
-
</DrawerNotchPill>
|
|
191
|
-
</>
|
|
192
|
-
)
|
|
193
|
-
)}
|
|
194
|
-
</DrawerNotch>
|
|
195
|
-
)
|
|
196
|
-
}
|
|
197
|
-
>
|
|
198
|
-
{/* `rounded-se-*` is the logical top-inline-end corner: rounded away from the notch,
|
|
199
|
-
square beneath it, mirrored by the browser rather than by a ternary. */}
|
|
200
|
-
<DrawerPanel
|
|
201
|
-
framed={framed}
|
|
202
|
-
className={cn(
|
|
203
|
-
"p-0",
|
|
204
|
-
isBottom ? "rounded-t-[16px]" : "rounded-se-[16px] rounded-b-[16px]",
|
|
205
|
-
)}
|
|
206
|
-
>
|
|
207
|
-
<div className="relative flex min-h-0 flex-1 flex-col">
|
|
208
|
-
{/* Vaul requires a Drawer.Title for the a11y name; the visible title is the
|
|
209
|
-
HeaderBar below, so this one is for screen readers only. */}
|
|
210
|
-
<DrawerTitle className="sr-only">{title}</DrawerTitle>
|
|
211
|
-
{description && (
|
|
212
|
-
<DrawerDescription className="sr-only">{description}</DrawerDescription>
|
|
213
|
-
)}
|
|
214
|
-
|
|
215
|
-
{/* The SAME floating header the page form uses, so a form's title looks
|
|
216
|
-
identical in either surface. */}
|
|
217
|
-
{!hideHeader && (
|
|
218
|
-
<FormHeaderBar title={title} label={badge} variant={variant}>
|
|
219
|
-
{actions}
|
|
220
|
-
</FormHeaderBar>
|
|
221
|
-
)}
|
|
222
|
-
|
|
223
|
-
{/* pt-[72px] clears the 44px header pill (inset 4px) — same as the page shell. The
|
|
224
|
-
48px bottom breathing-room goes on an inner wrapper, not the scroll container:
|
|
225
|
-
FormRenderer's outer element is `h-full`, which would pin it to the content box and
|
|
226
|
-
swallow the container's own `pb`. On a plain wrapper that `h-full` resolves to the
|
|
227
|
-
content height, so the padding actually lengthens the scroll. The conclusion panel
|
|
228
|
-
is a separate sibling, so it keeps its own spacing. */}
|
|
229
|
-
{/* LOCAL PATCH (Contact Center): `bareBody` hands the body to the child untouched.
|
|
230
|
-
Without it, a child that already scrolls and already offsets for its own header
|
|
231
|
-
(a detail view does both) gets a second scroll container and a second 72px of
|
|
232
|
-
dead space stacked on top of its own. */}
|
|
233
|
-
{bareBody ? (
|
|
234
|
-
children
|
|
235
|
-
) : (
|
|
236
|
-
<div className={cn("h-full overflow-y-auto px-3", !hideHeader && "pt-[72px]")}>
|
|
237
|
-
<div className="pb-[48px]">{children}</div>
|
|
238
|
-
</div>
|
|
239
|
-
)}
|
|
240
|
-
</div>
|
|
241
|
-
</DrawerPanel>
|
|
242
|
-
|
|
243
|
-
{/* `flex min-h-0` so the conclusion stretches to the tray's full height and can
|
|
244
|
-
still shrink — without `min-h-0` it would grow past the tray instead of
|
|
245
|
-
scrolling inside it. No `flex-1`: the panel sizes itself. */}
|
|
246
|
-
{conclusion && <div className="flex min-h-0">{conclusion}</div>}
|
|
247
|
-
</DrawerContent>
|
|
248
|
-
</Root>
|
|
249
|
-
);
|
|
250
|
-
}
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
5
|
-
|
|
6
|
-
import { cn } from "../../utils/cn";
|
|
7
|
-
import { formBarItemStyles } from "../TabFormItem";
|
|
8
|
-
import { useHtmlDir } from "../../hooks/useHtmlDir";
|
|
9
|
-
import { FormHeaderBar, type HeaderVariant } from "./header";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Detail-tabs — a display-only view where a left **sidebar** switches the main area between
|
|
13
|
-
* **`FormRenderer.Section` panels** (a detail page, not a form). It lives on `FormRenderer`
|
|
14
|
-
* (`FormRenderer.Sidebar` / `.Sidebar.Item` / `.Tab`) so `FormBuilder` stays form-only. Built on
|
|
15
|
-
* the same Radix Tabs primitive shadcn uses: the sidebar is the `Tabs.List`, each `Sidebar.Item` a
|
|
16
|
-
* `Tabs.Trigger`, each `Tab` a `Tabs.Content` — so the fixed rail and the panels share tab state.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
export interface DetailSidebarProps {
|
|
20
|
-
children: React.ReactNode;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* `FormRenderer.Sidebar` — the tab rail, sitting where a `FormRenderer.Stepper`'s nav would.
|
|
25
|
-
* Renders **nothing itself**: the FormRenderer root detects it and places its `Sidebar.Item`
|
|
26
|
-
* children (the tab triggers) into the fixed rail.
|
|
27
|
-
*/
|
|
28
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- children are read by the FormRenderer root
|
|
29
|
-
function DetailSidebarRoot(_props: DetailSidebarProps) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
(DetailSidebarRoot as unknown as { __isDetailSidebar: boolean }).__isDetailSidebar = true;
|
|
33
|
-
|
|
34
|
-
export interface DetailSidebarItemProps {
|
|
35
|
-
/** Ties this row to the `FormRenderer.Tab` of the same `value` — clicking it shows that panel. */
|
|
36
|
-
value: string;
|
|
37
|
-
/** Leading icon (e.g. a Remix `<i className="ri-…" />`). */
|
|
38
|
-
icon?: React.ReactNode;
|
|
39
|
-
children: React.ReactNode;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* `FormRenderer.Sidebar.Item` — a rail nav row, rendered as a Radix `Tabs.Trigger` styled with the
|
|
44
|
-
* `TabFormItem` `tree` look. Radix drives the active state (`data-state="active"` → black pill).
|
|
45
|
-
*/
|
|
46
|
-
function DetailSidebarItem({ value, icon, children }: DetailSidebarItemProps) {
|
|
47
|
-
return (
|
|
48
|
-
<TabsPrimitive.Trigger
|
|
49
|
-
value={value}
|
|
50
|
-
className={cn(
|
|
51
|
-
formBarItemStyles({ componentType: "tree" }),
|
|
52
|
-
"h-[32px] w-full justify-start gap-2 rounded-[10px] px-[6px] [&_i]:text-[16px]",
|
|
53
|
-
// Radix sets `data-state` on the trigger; the active tab is the filled (black) pill.
|
|
54
|
-
"data-[state=active]:bg-background-presentation-tab-topbar-selected data-[state=active]:text-content-presentation-tab-action-selected",
|
|
55
|
-
"data-[state=active]:hover:bg-background-presentation-tab-topbar-selected data-[state=active]:hover:px-[6px]",
|
|
56
|
-
)}
|
|
57
|
-
>
|
|
58
|
-
{icon}
|
|
59
|
-
{/* LOCAL PATCH (Contact Center): `text-start`, not `text-left` — otherwise an Arabic label
|
|
60
|
-
left-aligns inside a right-aligned rail, and `truncate` clips the wrong end. */}
|
|
61
|
-
<span className="flex-1 truncate text-start typography-body-medium-medium">{children}</span>
|
|
62
|
-
</TabsPrimitive.Trigger>
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export const DetailSidebar = Object.assign(DetailSidebarRoot, {
|
|
67
|
-
Item: DetailSidebarItem,
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
export function isDetailSidebarElement(
|
|
71
|
-
node: React.ReactNode,
|
|
72
|
-
): node is React.ReactElement<DetailSidebarProps> {
|
|
73
|
-
return (
|
|
74
|
-
React.isValidElement(node) &&
|
|
75
|
-
(node.type as { __isDetailSidebar?: boolean })?.__isDetailSidebar === true
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface DetailRowProps {
|
|
80
|
-
label: React.ReactNode;
|
|
81
|
-
value: React.ReactNode;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* `FormRenderer.Row` — a read-only label/value cell for detail content (the display counterpart of a
|
|
86
|
-
* form field). Drop several inside a `FormRenderer.Grid` within a `FormRenderer.Section`.
|
|
87
|
-
*/
|
|
88
|
-
export function DetailRow({ label, value }: DetailRowProps) {
|
|
89
|
-
return (
|
|
90
|
-
<div className="flex flex-col gap-1">
|
|
91
|
-
<span className="typography-body-small-regular text-content-presentation-global-secondary">
|
|
92
|
-
{label}
|
|
93
|
-
</span>
|
|
94
|
-
<span className="typography-body-medium-medium text-content-presentation-global-primary">
|
|
95
|
-
{value}
|
|
96
|
-
</span>
|
|
97
|
-
</div>
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export interface DetailGridProps {
|
|
102
|
-
/** Column count (default 2). */
|
|
103
|
-
columns?: 1 | 2 | 3;
|
|
104
|
-
children: React.ReactNode;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const GRID_COLS: Record<NonNullable<DetailGridProps["columns"]>, string> = {
|
|
108
|
-
1: "grid-cols-1",
|
|
109
|
-
2: "grid-cols-2",
|
|
110
|
-
3: "grid-cols-3",
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* `FormRenderer.Grid` — arranges `FormRenderer.Row`s in an equal-column grid spanning the **full
|
|
115
|
-
* section width** (default 2 columns, so cells split in half). Padded so the rows breathe inside a
|
|
116
|
-
* `FormRenderer.Section` (clear of the title badge, roomy row + column spacing).
|
|
117
|
-
*/
|
|
118
|
-
export function DetailGrid({ columns = 2, children }: DetailGridProps) {
|
|
119
|
-
return (
|
|
120
|
-
<div className={cn("grid w-full gap-x-12 gap-y-5 py-3", GRID_COLS[columns])}>{children}</div>
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export interface DetailTabProps {
|
|
125
|
-
/** Ties this panel to the `Sidebar.Item` of the same `value`. */
|
|
126
|
-
value: string;
|
|
127
|
-
/** The panel body — typically `FormRenderer.Section` display blocks. */
|
|
128
|
-
children: React.ReactNode;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* `FormRenderer.Tab` — a content panel shown when its `value` is the active tab. Renders
|
|
133
|
-
* **nothing itself**: the FormRenderer root detects it and mounts it as a Radix `Tabs.Content`
|
|
134
|
-
* (kept mounted, inactive ones hidden).
|
|
135
|
-
*/
|
|
136
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- read by the FormRenderer root
|
|
137
|
-
export function DetailTab(_props: DetailTabProps) {
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
(DetailTab as unknown as { __isDetailTab: boolean }).__isDetailTab = true;
|
|
141
|
-
|
|
142
|
-
export function isDetailTabElement(
|
|
143
|
-
node: React.ReactNode,
|
|
144
|
-
): node is React.ReactElement<DetailTabProps> {
|
|
145
|
-
return (
|
|
146
|
-
React.isValidElement(node) && (node.type as { __isDetailTab?: boolean })?.__isDetailTab === true
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export interface DetailTabsViewProps {
|
|
151
|
-
header?: { title: string; label?: string; variant?: HeaderVariant };
|
|
152
|
-
/** Header action buttons (Print / Approve / …). */
|
|
153
|
-
actions?: React.ReactNode;
|
|
154
|
-
/** The `FormRenderer.Sidebar` element — its children are the tab triggers. */
|
|
155
|
-
sidebar: React.ReactElement<DetailSidebarProps>;
|
|
156
|
-
/** The `FormRenderer.Tab` elements — the content panels. */
|
|
157
|
-
tabs: React.ReactElement<DetailTabProps>[];
|
|
158
|
-
className?: string;
|
|
159
|
-
/**
|
|
160
|
-
* LOCAL PATCH (Contact Center): the active tab, when the caller owns it. Omit both this and
|
|
161
|
-
* `onValueChange` to keep the original uncontrolled behaviour (defaults to the first tab).
|
|
162
|
-
*
|
|
163
|
-
* Upstream offered no way in, so a detail view could not put its tab in the URL — no
|
|
164
|
-
* `?tab=audit` deep link, no correct back-navigation, and a reload always bounced the user to
|
|
165
|
-
* the first tab. That is what this app's `useTabPersistence` provides.
|
|
166
|
-
*/
|
|
167
|
-
value?: string;
|
|
168
|
-
/** LOCAL PATCH (Contact Center): fires when a rail item is clicked. See `value`. */
|
|
169
|
-
onValueChange?: (value: string) => void;
|
|
170
|
-
/**
|
|
171
|
-
* LOCAL PATCH (Contact Center): rendered inside a surface that already draws its own card —
|
|
172
|
-
* a drawer, a panel. Drops the rounded body background so it doesn't double up, and lets the
|
|
173
|
-
* host own the height instead of filling the viewport.
|
|
174
|
-
*/
|
|
175
|
-
embedded?: boolean;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* The detail-tabs surface: the floating header over a fixed left rail (the sidebar) + a scrolling
|
|
180
|
-
* content column showing the active tab. Radix `Tabs.Root` owns the state — uncontrolled and
|
|
181
|
-
* defaulting to the first tab, unless the caller passes `value`/`onValueChange`. The rail matches
|
|
182
|
-
* the stepper's rail position; only the content column scrolls.
|
|
183
|
-
*/
|
|
184
|
-
export function DetailTabsView({
|
|
185
|
-
header,
|
|
186
|
-
actions,
|
|
187
|
-
sidebar,
|
|
188
|
-
tabs,
|
|
189
|
-
className,
|
|
190
|
-
value,
|
|
191
|
-
onValueChange,
|
|
192
|
-
embedded,
|
|
193
|
-
}: DetailTabsViewProps) {
|
|
194
|
-
const defaultValue = tabs[0]?.props.value;
|
|
195
|
-
// Radix treats a defined `value` as controlled, so only pass one of the two — handing it both
|
|
196
|
-
// logs a warning and pins the tab.
|
|
197
|
-
const controlled = value !== undefined;
|
|
198
|
-
// LOCAL PATCH (Contact Center): Radix Tabs defaults to `dir="ltr"` when given neither a `dir`
|
|
199
|
-
// prop nor a `DirectionProvider`, and it stamps that onto the subtree — which left this whole
|
|
200
|
-
// detail surface rendering left-to-right on an Arabic page, no matter what `<html dir>` said.
|
|
201
|
-
// Same fix already applied to `Tabs.tsx` and `TabPage.tsx`.
|
|
202
|
-
const htmlDir = useHtmlDir();
|
|
203
|
-
|
|
204
|
-
return (
|
|
205
|
-
<TabsPrimitive.Root
|
|
206
|
-
orientation="vertical"
|
|
207
|
-
dir={htmlDir}
|
|
208
|
-
{...(controlled ? { value, onValueChange } : { defaultValue, onValueChange })}
|
|
209
|
-
className={cn("h-full w-full @container", className)}
|
|
210
|
-
>
|
|
211
|
-
{/* Scroll shell — mirrors FormBuilder's: the absolute header floats over the body. */}
|
|
212
|
-
<div
|
|
213
|
-
className={cn(
|
|
214
|
-
"relative isolate flex h-full w-full flex-col overflow-hidden",
|
|
215
|
-
!embedded && "rounded-2xl bg-background-presentation-body-primary",
|
|
216
|
-
)}
|
|
217
|
-
>
|
|
218
|
-
{header && (
|
|
219
|
-
<FormHeaderBar title={header.title} label={header.label} variant={header.variant}>
|
|
220
|
-
{actions}
|
|
221
|
-
</FormHeaderBar>
|
|
222
|
-
)}
|
|
223
|
-
|
|
224
|
-
<div className="relative z-[1] flex min-h-0 w-full flex-1 flex-row">
|
|
225
|
-
{/* The fixed rail — the tab list. `pt-[72px]` clears the floating header.
|
|
226
|
-
|
|
227
|
-
LOCAL PATCH (Contact Center): `border-e`, not `border-r`. The row is `flex-row`, which
|
|
228
|
-
is direction-aware, so under `dir="rtl"` the rail moves to the right — a physical
|
|
229
|
-
right border then lands on the outer screen edge instead of between rail and content,
|
|
230
|
-
leaving the rail visually detached. */}
|
|
231
|
-
<TabsPrimitive.List asChild>
|
|
232
|
-
<aside className="flex h-full w-[216px] shrink-0 flex-col gap-1 overflow-y-auto border-e border-border-presentation-global-primary bg-black-alpha-5 px-2 pb-6 pt-[72px] scrollbar-hide">
|
|
233
|
-
{sidebar.props.children}
|
|
234
|
-
</aside>
|
|
235
|
-
</TabsPrimitive.List>
|
|
236
|
-
|
|
237
|
-
{/* The only scrolling region — the active tab's Sections. */}
|
|
238
|
-
<div className="flex min-h-0 w-full flex-1 flex-col overflow-y-auto px-6 py-6 pt-[72px] scrollbar-hide">
|
|
239
|
-
<div className="mx-auto flex w-full max-w-[1100px] flex-col gap-4">
|
|
240
|
-
{tabs.map((panel) => (
|
|
241
|
-
<TabsPrimitive.Content
|
|
242
|
-
key={panel.props.value}
|
|
243
|
-
value={panel.props.value}
|
|
244
|
-
forceMount
|
|
245
|
-
className="flex flex-col gap-4 outline-none data-[state=inactive]:hidden"
|
|
246
|
-
>
|
|
247
|
-
{panel.props.children}
|
|
248
|
-
</TabsPrimitive.Content>
|
|
249
|
-
))}
|
|
250
|
-
</div>
|
|
251
|
-
</div>
|
|
252
|
-
</div>
|
|
253
|
-
</div>
|
|
254
|
-
</TabsPrimitive.Root>
|
|
255
|
-
);
|
|
256
|
-
}
|