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,101 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: ColorPicker
|
|
3
|
-
description: A full Figma-style color picker with a saturation/value area, hue and opacity sliders, an eyedropper, switchable HEX/RGB/HSL inputs, and preset swatches
|
|
4
|
-
group: Forms
|
|
5
|
-
keywords: [color-picker, color, palette, hex, rgb, hsl, hsv, opacity, alpha, eyedropper, swatch]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# ColorPicker
|
|
9
|
-
|
|
10
|
-
> A full Figma-style color palette opened from **a trigger you supply**: a draggable
|
|
11
|
-
> saturation/value area, a hue slider, an optional opacity slider, an eyedropper (where the
|
|
12
|
-
> browser supports it), switchable **HEX / RGB / HSL** numeric inputs, and preset swatches.
|
|
13
|
-
> The value is always a hex string.
|
|
14
|
-
|
|
15
|
-
## Installation
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npx torch-glare@latest init
|
|
19
|
-
npx torch-glare@latest add ColorPicker
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
`add` also copies its dependencies — `utils/color` (the pure hex/RGB/HSV/HSL math), plus the
|
|
23
|
-
`Popover` and `Input` components.
|
|
24
|
-
|
|
25
|
-
## Import
|
|
26
|
-
|
|
27
|
-
```tsx
|
|
28
|
-
import { ColorPicker } from "@/components/ColorPicker";
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Usage
|
|
32
|
-
|
|
33
|
-
ColorPicker renders **no trigger of its own** — you pass one as its child (rendered via `asChild`,
|
|
34
|
-
so it must forward ref/props to a DOM node). The current color is handed to that child based on
|
|
35
|
-
what it is:
|
|
36
|
-
|
|
37
|
-
| Child | Receives |
|
|
38
|
-
|---|---|
|
|
39
|
-
| an **input** — native `<input>`/`<textarea>`, or any element already given a `value` prop | the hex as **`value`** (plus an `onChange` that commits a typed hex, if you didn't supply one) |
|
|
40
|
-
| **anything else** | the hex as **`children`** — unless it already has children, which are left untouched |
|
|
41
|
-
|
|
42
|
-
```tsx
|
|
43
|
-
const [color, setColor] = useState("#3B82F6");
|
|
44
|
-
|
|
45
|
-
// input child → gets `value={color}`
|
|
46
|
-
<ColorPicker value={color} onChange={setColor}>
|
|
47
|
-
<input className="…" />
|
|
48
|
-
</ColorPicker>
|
|
49
|
-
|
|
50
|
-
// non-input child → gets the hex as its content
|
|
51
|
-
<ColorPicker value={color} onChange={setColor}>
|
|
52
|
-
<Button variant="BorderStyle" />
|
|
53
|
-
</ColorPicker>
|
|
54
|
-
|
|
55
|
-
// a child with its own content keeps it — render the value yourself
|
|
56
|
-
<ColorPicker value={color} onChange={setColor}>
|
|
57
|
-
<button type="button">
|
|
58
|
-
<span style={{ backgroundColor: color }} />
|
|
59
|
-
{color}
|
|
60
|
-
</button>
|
|
61
|
-
</ColorPicker>
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
With presets and opacity disabled (always emits `#rrggbb`):
|
|
65
|
-
|
|
66
|
-
```tsx
|
|
67
|
-
<ColorPicker
|
|
68
|
-
value={color}
|
|
69
|
-
onChange={setColor}
|
|
70
|
-
alpha={false}
|
|
71
|
-
presets={["#005ECC", "#047854", "#E30C30", "#F5A623"]}
|
|
72
|
-
>
|
|
73
|
-
<Button variant="BorderStyle" />
|
|
74
|
-
</ColorPicker>
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Props
|
|
78
|
-
|
|
79
|
-
| Prop | Type | Default | Description |
|
|
80
|
-
| ----------- | -------------------------- | ------------- | --------------------------------------------------------------------------- |
|
|
81
|
-
| `children` | `ReactElement` | — (required) | The trigger. Gets the hex as `value` if it's an input, else as `children`. |
|
|
82
|
-
| `value` | `string` | `"#000000"` | Current color as a hex string (`#rrggbb` or `#rrggbbaa`). |
|
|
83
|
-
| `onChange` | `(hex: string) => void` | — | Called on every change. Emits `#rrggbbaa` only when opacity < 100%. |
|
|
84
|
-
| `presets` | `string[]` | — | Quick-pick swatches shown at the bottom of the panel. |
|
|
85
|
-
| `alpha` | `boolean` | `true` | Show the opacity slider + input and allow 8-digit output. |
|
|
86
|
-
| `disabled` | `boolean` | `false` | Disable the trigger and all controls. |
|
|
87
|
-
| `theme` | `"dark" \| "light" \| "default"` | — | Applied as `data-theme`. |
|
|
88
|
-
|
|
89
|
-
## Value format
|
|
90
|
-
|
|
91
|
-
The value stays `#rrggbb` while fully opaque (backward-compatible with plain hex fields) and is
|
|
92
|
-
promoted to `#rrggbbaa` only when opacity drops below 100%. Feeding a 3-, 6-, or 8-digit hex
|
|
93
|
-
(with or without `#`) back in via `value` is always accepted.
|
|
94
|
-
|
|
95
|
-
## Notes
|
|
96
|
-
|
|
97
|
-
- The **eyedropper** button appears only where the native [`EyeDropper` API](https://developer.mozilla.org/docs/Web/API/EyeDropper)
|
|
98
|
-
is available (Chromium/Edge); it is hidden on Firefox/Safari.
|
|
99
|
-
- Used by `FormBuilder.Color` — see [form-builder.md](./form-builder.md).
|
|
100
|
-
- Color math lives in `utils/color` (`parseHex`, `formatHex`, `rgbToHsv`, `hsvToRgb`,
|
|
101
|
-
`rgbToHsl`, `hslToRgb`) and is reusable on its own.
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: ConclusionHeader
|
|
3
|
-
description: A clickable section header with a chevron toggle — white-alpha hover surfaces, chevron down when open and sideways when closed, and a "Disabled" badge when disabled. Direction-aware (LTR/RTL). Used for each FormSummary group title.
|
|
4
|
-
component: true
|
|
5
|
-
group: Layout & Containers
|
|
6
|
-
keywords: [conclusion-header, collapsible, header, disclosure, accordion, toggle, chevron, expand, collapse, section]
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# ConclusionHeader
|
|
10
|
-
|
|
11
|
-
A clickable **section header** that toggles a collapsible region, per the
|
|
12
|
-
*Conclusion-Header-2.0* design. Its surfaces are **button overlays** (not an input field): at
|
|
13
|
-
rest the label stands alone, and on hover it gains a `Button/ContStyle-Hover` pill while the
|
|
14
|
-
chevron gains a `Button/Secondary` box. The chevron is hidden at rest while open, shows
|
|
15
|
-
**sideways** when closed (left in LTR, right in RTL), and flips to **down** on hover. When
|
|
16
|
-
`disabled` the label greys out, truncates at 120px, and a gray-subtle `Badge` replaces the
|
|
17
|
-
chevron.
|
|
18
|
-
|
|
19
|
-
It renders only the header — you own the collapsible body. It works **uncontrolled**
|
|
20
|
-
(manages its own open state) or **controlled** (pass `open` + `onOpenChange`):
|
|
21
|
-
|
|
22
|
-
```tsx
|
|
23
|
-
// Uncontrolled — reflect the state with onOpenChange
|
|
24
|
-
const [open, setOpen] = useState(true)
|
|
25
|
-
|
|
26
|
-
<ConclusionHeader label="Invoice" defaultOpen onOpenChange={setOpen} />
|
|
27
|
-
{open && <section>…body…</section>}
|
|
28
|
-
|
|
29
|
-
// Controlled — you drive `open`
|
|
30
|
-
<ConclusionHeader label="Invoice" open={open} onOpenChange={setOpen} />
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Installation
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
npx torch-glare@latest init
|
|
37
|
-
npx torch-glare@latest add ConclusionHeader
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Imports
|
|
41
|
-
|
|
42
|
-
```tsx
|
|
43
|
-
import { ConclusionHeader } from '@/components/ConclusionHeader'
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Props
|
|
47
|
-
|
|
48
|
-
| Prop | Type | Default | Notes |
|
|
49
|
-
|---|---|---|---|
|
|
50
|
-
| `label` | `ReactNode` | — | The header text. |
|
|
51
|
-
| `open` | `boolean` | — | **Controlled** open state. Omit to let the header manage its own. |
|
|
52
|
-
| `defaultOpen` | `boolean` | `true` | Initial open state when **uncontrolled**. |
|
|
53
|
-
| `onOpenChange` | `(open: boolean) => void` | — | Called with the next open state on click. |
|
|
54
|
-
| `disabled` | `boolean` | `false` | Greys the label and shows a `Badge` instead of the chevron. |
|
|
55
|
-
| `disabledLabel` | `string` | `"Disabled"` | Badge text when `disabled`. |
|
|
56
|
-
| `theme` | `'dark' \| 'light' \| 'default'` | — | Theme override; otherwise inherits the nearest `data-theme`. |
|
|
57
|
-
|
|
58
|
-
Extra props spread to the underlying `<button>`, which is what the header renders — so it is
|
|
59
|
-
focusable, toggles on <kbd>Enter</kbd>/<kbd>Space</kbd>, and exposes `aria-expanded` for
|
|
60
|
-
free. A `ref` is forwarded to that `HTMLButtonElement`.
|
|
61
|
-
|
|
62
|
-
## Behaviour
|
|
63
|
-
|
|
64
|
-
- **Open** (rest): label only — no surface, no chevron.
|
|
65
|
-
- **Open hover**: `Button/ContStyle-Hover` pill (label inset 4px) + `Button/Secondary`
|
|
66
|
-
chevron box with a **down** chevron.
|
|
67
|
-
- **Closed** (rest): label + a bare **sideways** chevron (`<` LTR / `>` RTL), no box.
|
|
68
|
-
- **Closed hover**: same surfaces as open hover; the chevron flips to down.
|
|
69
|
-
- **Disabled**: greyed label truncated at 120px + a `● Disabled` badge sitting beside it
|
|
70
|
-
(not at the row's end); not clickable.
|
|
71
|
-
|
|
72
|
-
Direction is inherited from the ambient `dir` — the design's RTL variants are the LTR ones
|
|
73
|
-
mirrored, which the component's logical properties produce automatically.
|
|
74
|
-
|
|
75
|
-
## Composition
|
|
76
|
-
|
|
77
|
-
Uses the design-system tokens directly (`Button/Secondary`, `Button/ContStyle-Hover`) rather
|
|
78
|
-
than the input/button components, and reuses [Badge](./badge.md) for the disabled state.
|
|
79
|
-
[FormSummary](./form-summary.md) uses it as each **group** title, so every group of totals
|
|
80
|
-
collapses independently.
|
|
@@ -1,483 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: ContextMenu
|
|
3
|
-
description: Right-click (or long-press) menu that opens at the pointer, with submenus, checkboxes, radio groups, and keyboard navigation
|
|
4
|
-
group: Overlays & Dialogs
|
|
5
|
-
keywords: [context-menu, right-click, menu, radix-ui, submenu, checkbox, contextmenu]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# ContextMenu
|
|
9
|
-
|
|
10
|
-
> A right-click / long-press menu that opens at the pointer. Wrap any zone in a `ContextMenuTrigger` and the menu appears where the user clicks — same surface as DropdownMenu (items, groups, the boxed look, auto-grouping), built on `@radix-ui/react-context-menu`.
|
|
11
|
-
|
|
12
|
-
## Installation
|
|
13
|
-
|
|
14
|
-
TORCH Glare is a copy-in library: the CLI copies this component's source into your project
|
|
15
|
-
(you do **not** install it from the npm package). Run `init` once, then `add`:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npx torch-glare@latest init
|
|
19
|
-
npx torch-glare@latest add ContextMenu
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
`add` also copies any components, hooks, and utilities that `ContextMenu` depends on.
|
|
23
|
-
|
|
24
|
-
## Import
|
|
25
|
-
|
|
26
|
-
Import from your project's local path — the alias configured in `glare.json` (e.g. `@/*`):
|
|
27
|
-
|
|
28
|
-
```tsx
|
|
29
|
-
import { ContextMenu } from "@/components/ContextMenu";
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Quick Examples
|
|
33
|
-
|
|
34
|
-
### Basic Menu
|
|
35
|
-
|
|
36
|
-
Wrap the right-click zone in `ContextMenuTrigger`. The menu opens at the pointer.
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem } from "@/components/ContextMenu";
|
|
40
|
-
|
|
41
|
-
function Example() {
|
|
42
|
-
return (
|
|
43
|
-
<ContextMenu>
|
|
44
|
-
<ContextMenuTrigger asChild>
|
|
45
|
-
<div className="flex h-40 w-72 items-center justify-center rounded-md border border-dashed">
|
|
46
|
-
Right-click here
|
|
47
|
-
</div>
|
|
48
|
-
</ContextMenuTrigger>
|
|
49
|
-
<ContextMenuContent>
|
|
50
|
-
<ContextMenuItem>Profile</ContextMenuItem>
|
|
51
|
-
<ContextMenuItem>Settings</ContextMenuItem>
|
|
52
|
-
<ContextMenuItem>Logout</ContextMenuItem>
|
|
53
|
-
</ContextMenuContent>
|
|
54
|
-
</ContextMenu>
|
|
55
|
-
)
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### With Icons, Shortcuts, and a Negative Item
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuShortcut } from "@/components/ContextMenu";
|
|
63
|
-
|
|
64
|
-
function ActionsMenu() {
|
|
65
|
-
return (
|
|
66
|
-
<ContextMenu>
|
|
67
|
-
<ContextMenuTrigger asChild>
|
|
68
|
-
<div className="flex h-40 w-72 items-center justify-center rounded-md border border-dashed">
|
|
69
|
-
Right-click the canvas
|
|
70
|
-
</div>
|
|
71
|
-
</ContextMenuTrigger>
|
|
72
|
-
<ContextMenuContent>
|
|
73
|
-
<ContextMenuItem>
|
|
74
|
-
<i className="ri-edit-line" />
|
|
75
|
-
<span>Edit</span>
|
|
76
|
-
<ContextMenuShortcut>⌘E</ContextMenuShortcut>
|
|
77
|
-
</ContextMenuItem>
|
|
78
|
-
<ContextMenuItem>
|
|
79
|
-
<i className="ri-share-line" />
|
|
80
|
-
<span>Share</span>
|
|
81
|
-
<ContextMenuShortcut>⌘⇧S</ContextMenuShortcut>
|
|
82
|
-
</ContextMenuItem>
|
|
83
|
-
<ContextMenuItem variant="Negative">
|
|
84
|
-
<i className="ri-delete-bin-line" />
|
|
85
|
-
<span>Delete</span>
|
|
86
|
-
<ContextMenuShortcut>⌫</ContextMenuShortcut>
|
|
87
|
-
</ContextMenuItem>
|
|
88
|
-
</ContextMenuContent>
|
|
89
|
-
</ContextMenu>
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### With Checkboxes
|
|
95
|
-
|
|
96
|
-
> Clicking a checkbox item keeps the menu open — `onSelect` calls `preventDefault()` internally so Radix does not auto-close. Toggle several options without the menu dismissing.
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuCheckboxItem } from "@/components/ContextMenu";
|
|
100
|
-
import { useState } from 'react'
|
|
101
|
-
|
|
102
|
-
function CheckboxMenu() {
|
|
103
|
-
const [showStatusBar, setShowStatusBar] = useState(true)
|
|
104
|
-
const [showActivityBar, setShowActivityBar] = useState(false)
|
|
105
|
-
const [showPanel, setShowPanel] = useState(false)
|
|
106
|
-
|
|
107
|
-
return (
|
|
108
|
-
<ContextMenu>
|
|
109
|
-
<ContextMenuTrigger asChild>
|
|
110
|
-
<div className="flex h-40 w-72 items-center justify-center rounded-md border border-dashed">
|
|
111
|
-
Right-click to toggle view
|
|
112
|
-
</div>
|
|
113
|
-
</ContextMenuTrigger>
|
|
114
|
-
<ContextMenuContent>
|
|
115
|
-
<ContextMenuCheckboxItem
|
|
116
|
-
checked={showStatusBar}
|
|
117
|
-
onCheckedChange={setShowStatusBar}
|
|
118
|
-
>
|
|
119
|
-
Status Bar
|
|
120
|
-
</ContextMenuCheckboxItem>
|
|
121
|
-
<ContextMenuCheckboxItem
|
|
122
|
-
checked={showActivityBar}
|
|
123
|
-
onCheckedChange={setShowActivityBar}
|
|
124
|
-
>
|
|
125
|
-
Activity Bar
|
|
126
|
-
</ContextMenuCheckboxItem>
|
|
127
|
-
<ContextMenuCheckboxItem
|
|
128
|
-
checked={showPanel}
|
|
129
|
-
onCheckedChange={setShowPanel}
|
|
130
|
-
>
|
|
131
|
-
Panel
|
|
132
|
-
</ContextMenuCheckboxItem>
|
|
133
|
-
</ContextMenuContent>
|
|
134
|
-
</ContextMenu>
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### With Radio Group
|
|
140
|
-
|
|
141
|
-
> Like checkboxes, selecting a radio item keeps the menu open (`onSelect` `preventDefault` is built in).
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuRadioGroup, ContextMenuRadioItem } from "@/components/ContextMenu";
|
|
145
|
-
import { useState } from 'react'
|
|
146
|
-
|
|
147
|
-
function RadioMenu() {
|
|
148
|
-
const [position, setPosition] = useState('bottom')
|
|
149
|
-
|
|
150
|
-
return (
|
|
151
|
-
<ContextMenu>
|
|
152
|
-
<ContextMenuTrigger asChild>
|
|
153
|
-
<div className="flex h-40 w-72 items-center justify-center rounded-md border border-dashed">
|
|
154
|
-
Right-click to pick a position
|
|
155
|
-
</div>
|
|
156
|
-
</ContextMenuTrigger>
|
|
157
|
-
<ContextMenuContent>
|
|
158
|
-
<ContextMenuRadioGroup value={position} onValueChange={setPosition}>
|
|
159
|
-
<ContextMenuRadioItem value="top">Top</ContextMenuRadioItem>
|
|
160
|
-
<ContextMenuRadioItem value="bottom">Bottom</ContextMenuRadioItem>
|
|
161
|
-
<ContextMenuRadioItem value="right">Right</ContextMenuRadioItem>
|
|
162
|
-
</ContextMenuRadioGroup>
|
|
163
|
-
</ContextMenuContent>
|
|
164
|
-
</ContextMenu>
|
|
165
|
-
)
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### With Submenu
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent } from "@/components/ContextMenu";
|
|
173
|
-
|
|
174
|
-
function SubmenuExample() {
|
|
175
|
-
return (
|
|
176
|
-
<ContextMenu>
|
|
177
|
-
<ContextMenuTrigger asChild>
|
|
178
|
-
<div className="flex h-40 w-72 items-center justify-center rounded-md border border-dashed">
|
|
179
|
-
Right-click for more
|
|
180
|
-
</div>
|
|
181
|
-
</ContextMenuTrigger>
|
|
182
|
-
<ContextMenuContent>
|
|
183
|
-
<ContextMenuItem>New Tab</ContextMenuItem>
|
|
184
|
-
<ContextMenuItem>New Window</ContextMenuItem>
|
|
185
|
-
|
|
186
|
-
<ContextMenuSub>
|
|
187
|
-
<ContextMenuSubTrigger>More Tools</ContextMenuSubTrigger>
|
|
188
|
-
<ContextMenuSubContent>
|
|
189
|
-
<ContextMenuItem>Developer Tools</ContextMenuItem>
|
|
190
|
-
<ContextMenuItem>Task Manager</ContextMenuItem>
|
|
191
|
-
<ContextMenuItem>Extensions</ContextMenuItem>
|
|
192
|
-
</ContextMenuSubContent>
|
|
193
|
-
</ContextMenuSub>
|
|
194
|
-
|
|
195
|
-
<ContextMenuItem>Print</ContextMenuItem>
|
|
196
|
-
</ContextMenuContent>
|
|
197
|
-
</ContextMenu>
|
|
198
|
-
)
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### RTL
|
|
203
|
-
|
|
204
|
-
Set `dir="rtl"` on the Root and the menu, items, and submenu arrows mirror automatically.
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuShortcut } from "@/components/ContextMenu";
|
|
208
|
-
|
|
209
|
-
function RtlMenu() {
|
|
210
|
-
return (
|
|
211
|
-
<ContextMenu dir="rtl">
|
|
212
|
-
<ContextMenuTrigger asChild>
|
|
213
|
-
<div className="flex h-40 w-72 items-center justify-center rounded-md border border-dashed">
|
|
214
|
-
انقر بزر الفأرة الأيمن
|
|
215
|
-
</div>
|
|
216
|
-
</ContextMenuTrigger>
|
|
217
|
-
<ContextMenuContent>
|
|
218
|
-
<ContextMenuItem>
|
|
219
|
-
تحرير
|
|
220
|
-
<ContextMenuShortcut>⌘E</ContextMenuShortcut>
|
|
221
|
-
</ContextMenuItem>
|
|
222
|
-
<ContextMenuItem variant="Negative">حذف</ContextMenuItem>
|
|
223
|
-
</ContextMenuContent>
|
|
224
|
-
</ContextMenu>
|
|
225
|
-
)
|
|
226
|
-
}
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### Long Menu (max height + scroll)
|
|
230
|
-
|
|
231
|
-
Tall menus scroll instead of overflowing off-screen. The surface caps at `maxHeight` (default `320`px) and never exceeds the space available after collision handling. Pass `maxHeight` to change the cap.
|
|
232
|
-
|
|
233
|
-
The panel itself does not scroll — it clips, and an inner viewport inside it does the scrolling. That keeps the panel's 4px frosted gutter fixed instead of scrolling away with the rows. Submenus behave identically and take their own `maxHeight` (same `320`px default).
|
|
234
|
-
|
|
235
|
-
```typescript
|
|
236
|
-
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuLabel } from "@/components/ContextMenu";
|
|
237
|
-
|
|
238
|
-
function LongMenu() {
|
|
239
|
-
return (
|
|
240
|
-
<ContextMenu>
|
|
241
|
-
<ContextMenuTrigger asChild>
|
|
242
|
-
<div className="flex h-40 w-72 items-center justify-center rounded-md border border-dashed">
|
|
243
|
-
Right-click here
|
|
244
|
-
</div>
|
|
245
|
-
</ContextMenuTrigger>
|
|
246
|
-
{/* Cap the surface at 220px — the rest scrolls. */}
|
|
247
|
-
<ContextMenuContent maxHeight={220}>
|
|
248
|
-
<ContextMenuLabel>Jump to section</ContextMenuLabel>
|
|
249
|
-
{Array.from({ length: 20 }, (_, i) => (
|
|
250
|
-
<ContextMenuItem key={i}>Section {i + 1}</ContextMenuItem>
|
|
251
|
-
))}
|
|
252
|
-
</ContextMenuContent>
|
|
253
|
-
</ContextMenu>
|
|
254
|
-
)
|
|
255
|
-
}
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
## API Reference
|
|
259
|
-
|
|
260
|
-
### ContextMenu (Root)
|
|
261
|
-
|
|
262
|
-
A controlled wrapper around the Radix root. It tracks the open state internally (so a second right-click can dismiss the menu) while still forwarding `open` / `onOpenChange` when you control it.
|
|
263
|
-
|
|
264
|
-
| Prop | Type | Default | Description |
|
|
265
|
-
|------|------|---------|-------------|
|
|
266
|
-
| `open` | `boolean` | - | Controlled open state |
|
|
267
|
-
| `onOpenChange` | `(open: boolean) => void` | - | Callback when state changes |
|
|
268
|
-
| `dir` | `'ltr' \| 'rtl'` | - | Reading direction; mirrors layout and arrows |
|
|
269
|
-
| `modal` | `boolean` | `true` | Whether to block outside interactions |
|
|
270
|
-
| `children` | `React.ReactNode` | - | Trigger and content |
|
|
271
|
-
|
|
272
|
-
### ContextMenuTrigger
|
|
273
|
-
|
|
274
|
-
The right-click zone. Wrap it around the element the menu should open from.
|
|
275
|
-
|
|
276
|
-
| Prop | Type | Default | Description |
|
|
277
|
-
|------|------|---------|-------------|
|
|
278
|
-
| `asChild` | `boolean` | `false` | Merge props onto the child element instead of rendering a wrapper |
|
|
279
|
-
| `disabled` | `boolean` | `false` | Disables opening on right-click |
|
|
280
|
-
|
|
281
|
-
### ContextMenuContent
|
|
282
|
-
|
|
283
|
-
| Prop | Type | Default | Description |
|
|
284
|
-
|------|------|---------|-------------|
|
|
285
|
-
| `variant` | `'PresentationStyle'` | `'PresentationStyle'` | Visual style variant |
|
|
286
|
-
| `theme` | `'dark' \| 'light' \| 'default'` | - | Theme variant (applied as `data-theme`) |
|
|
287
|
-
| `className` | `string` | - | Additional CSS classes |
|
|
288
|
-
| `collisionPadding` | `number` | `8` | Min distance kept from the viewport edge |
|
|
289
|
-
| `maxHeight` | `number` | `320` | Max height (px) of the surface before it scrolls. Capped at `min(maxHeight, available-height)` so the menu never overflows off-screen |
|
|
290
|
-
| `autoGroup` | `boolean` | `true` | Auto-wrap loose items in a Boxed group (see Behavior notes) |
|
|
291
|
-
|
|
292
|
-
### ContextMenuItem
|
|
293
|
-
|
|
294
|
-
| Prop | Type | Default | Description |
|
|
295
|
-
|------|------|---------|-------------|
|
|
296
|
-
| `variant` | `'Default' \| 'info' \| 'Negative'` | `'Default'` | Item style variant |
|
|
297
|
-
| `size` | `'S' \| 'M'` | `'M'` | Item size |
|
|
298
|
-
| `inset` | `boolean` | `false` | Add left padding to align with items that have icons |
|
|
299
|
-
| `active` | `boolean` | `false` | Active (selected) state |
|
|
300
|
-
| `disabled` | `boolean` | `false` | Disabled state (still shows but is not selectable) |
|
|
301
|
-
| `onSelect` | `(event: Event) => void` | - | Select handler; closes the menu by default |
|
|
302
|
-
|
|
303
|
-
### ContextMenuCheckboxItem
|
|
304
|
-
|
|
305
|
-
| Prop | Type | Default | Description |
|
|
306
|
-
|------|------|---------|-------------|
|
|
307
|
-
| `checked` | `boolean \| 'indeterminate'` | `false` | Checked state |
|
|
308
|
-
| `onCheckedChange` | `(checked: boolean) => void` | - | Change handler |
|
|
309
|
-
| `variant` | `'Default' \| 'info' \| 'Negative'` | `'Default'` | Style variant |
|
|
310
|
-
| `size` | `'S' \| 'M'` | `'M'` | Item size |
|
|
311
|
-
|
|
312
|
-
> Selecting a checkbox item keeps the menu open — `onSelect` `preventDefault` is built in.
|
|
313
|
-
|
|
314
|
-
### ContextMenuRadioGroup
|
|
315
|
-
|
|
316
|
-
| Prop | Type | Default | Description |
|
|
317
|
-
|------|------|---------|-------------|
|
|
318
|
-
| `value` | `string` | - | Selected radio value |
|
|
319
|
-
| `onValueChange` | `(value: string) => void` | - | Change handler |
|
|
320
|
-
| `variant` | `'Boxed' \| 'Plain'` | `'Boxed'` | `Boxed` renders a bordered container; `Plain` is semantic grouping only |
|
|
321
|
-
|
|
322
|
-
### ContextMenuRadioItem
|
|
323
|
-
|
|
324
|
-
| Prop | Type | Default | Description |
|
|
325
|
-
|------|------|---------|-------------|
|
|
326
|
-
| `value` | `string` | Required | Radio option value |
|
|
327
|
-
| `variant` | `'Default' \| 'info' \| 'Negative'` | `'Default'` | Style variant |
|
|
328
|
-
| `size` | `'S' \| 'M'` | `'M'` | Item size |
|
|
329
|
-
|
|
330
|
-
> Selecting a radio item keeps the menu open — `onSelect` `preventDefault` is built in.
|
|
331
|
-
|
|
332
|
-
### ContextMenuSubTrigger
|
|
333
|
-
|
|
334
|
-
| Prop | Type | Default | Description |
|
|
335
|
-
|------|------|---------|-------------|
|
|
336
|
-
| `variant` | `'Default' \| 'info' \| 'Negative'` | `'Default'` | Style variant |
|
|
337
|
-
| `size` | `'S' \| 'M'` | `'M'` | Item size |
|
|
338
|
-
| `inset` | `boolean` | `false` | Add left padding to align with items that have icons |
|
|
339
|
-
| `className` | `string` | - | Additional CSS classes |
|
|
340
|
-
|
|
341
|
-
Renders a trailing chevron (`ri-arrow-right-s-line`) that mirrors in RTL.
|
|
342
|
-
|
|
343
|
-
### ContextMenuLabel
|
|
344
|
-
|
|
345
|
-
| Prop | Type | Default | Description |
|
|
346
|
-
|------|------|---------|-------------|
|
|
347
|
-
| `inset` | `boolean` | `false` | Add left padding to align with items that have icons |
|
|
348
|
-
| `className` | `string` | - | Additional CSS classes |
|
|
349
|
-
|
|
350
|
-
A non-interactive section heading. Acts as a boundary for auto-grouping.
|
|
351
|
-
|
|
352
|
-
### ContextMenuShortcut
|
|
353
|
-
|
|
354
|
-
| Prop | Type | Default | Description |
|
|
355
|
-
|------|------|---------|-------------|
|
|
356
|
-
| `className` | `string` | - | Additional CSS classes |
|
|
357
|
-
|
|
358
|
-
A right-aligned (RTL-aware) span for keyboard hints inside an item.
|
|
359
|
-
|
|
360
|
-
## TypeScript
|
|
361
|
-
|
|
362
|
-
### Key Interfaces
|
|
363
|
-
|
|
364
|
-
```typescript
|
|
365
|
-
import * as ContextMenuPrimitive from '@radix-ui/react-context-menu'
|
|
366
|
-
|
|
367
|
-
// Root — controlled wrapper
|
|
368
|
-
type ContextMenuProps = React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Root>
|
|
369
|
-
// { open?, onOpenChange?, dir?, modal?, children, ... }
|
|
370
|
-
|
|
371
|
-
export const ContextMenu: React.FC<ContextMenuProps>
|
|
372
|
-
|
|
373
|
-
// Content
|
|
374
|
-
interface ContextMenuContentProps {
|
|
375
|
-
variant?: 'PresentationStyle'
|
|
376
|
-
theme?: 'dark' | 'light' | 'default'
|
|
377
|
-
className?: string
|
|
378
|
-
collisionPadding?: number // default 8
|
|
379
|
-
maxHeight?: number // default 320 — surface scrolls past this
|
|
380
|
-
autoGroup?: boolean // default true
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
export const ContextMenuContent: React.ForwardRefExoticComponent<ContextMenuContentProps>
|
|
384
|
-
|
|
385
|
-
// Item
|
|
386
|
-
interface ContextMenuItemProps {
|
|
387
|
-
variant?: 'Default' | 'info' | 'Negative'
|
|
388
|
-
size?: 'S' | 'M'
|
|
389
|
-
active?: boolean
|
|
390
|
-
disabled?: boolean
|
|
391
|
-
onSelect?: (event: Event) => void
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
export const ContextMenuItem: React.ForwardRefExoticComponent<ContextMenuItemProps>
|
|
395
|
-
|
|
396
|
-
// CheckboxItem
|
|
397
|
-
interface ContextMenuCheckboxItemProps {
|
|
398
|
-
checked?: boolean | 'indeterminate'
|
|
399
|
-
onCheckedChange?: (checked: boolean) => void
|
|
400
|
-
variant?: 'Default' | 'info' | 'Negative'
|
|
401
|
-
size?: 'S' | 'M'
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
export const ContextMenuCheckboxItem: React.ForwardRefExoticComponent<ContextMenuCheckboxItemProps>
|
|
405
|
-
|
|
406
|
-
// RadioGroup
|
|
407
|
-
interface ContextMenuRadioGroupProps {
|
|
408
|
-
value?: string
|
|
409
|
-
onValueChange?: (value: string) => void
|
|
410
|
-
variant?: 'Boxed' | 'Plain'
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
export const ContextMenuRadioGroup: React.ForwardRefExoticComponent<ContextMenuRadioGroupProps>
|
|
414
|
-
|
|
415
|
-
// RadioItem
|
|
416
|
-
interface ContextMenuRadioItemProps {
|
|
417
|
-
value: string
|
|
418
|
-
variant?: 'Default' | 'info' | 'Negative'
|
|
419
|
-
size?: 'S' | 'M'
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
export const ContextMenuRadioItem: React.ForwardRefExoticComponent<ContextMenuRadioItemProps>
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
## Behavior Notes
|
|
426
|
-
|
|
427
|
-
- **Opens at the pointer**: the menu opens on right-click (`contextmenu`) at the exact cursor position, not anchored to a fixed trigger button.
|
|
428
|
-
- **Second right-click closes it**: the Root is made controlled and tracks `open` in context. The Trigger listens in the capture phase, and when the menu is already open it `preventDefault()` / `stopPropagation()` and closes — so a second right-click dismisses instead of re-anchoring (which Radix handles unreliably).
|
|
429
|
-
- **Auto-grouping**: by default (`autoGroup` on `ContextMenuContent`, default `true`) consecutive loose items (`ContextMenuItem`, `ContextMenuCheckboxItem`, `ContextMenuRadioItem`, and `ContextMenuSub`) are automatically wrapped in a `Boxed` `ContextMenuGroup`, so they render inside a boxed container like DropdownMenu even when you do not write a group. Labels and explicit groups act as boundaries and pass through unchanged. Set `autoGroup={false}` to render children verbatim.
|
|
430
|
-
- **Max height & scrolling**: the surface caps its height at `min(maxHeight, available-height)` (where `maxHeight` defaults to `320`px and `available-height` is the space Radix has after collision handling). A taller menu scrolls vertically instead of overflowing off-screen — items and groups keep their full height rather than squishing. The panel clips and an inner viewport scrolls, so the panel's frosted gutter stays put. Pass `maxHeight={N}` to change the cap; `ContextMenuSubContent` accepts it too.
|
|
431
|
-
- **Checkbox / radio keep the menu open**: `ContextMenuCheckboxItem` and `ContextMenuRadioItem` call `event.preventDefault()` inside `onSelect`, stopping Radix's default auto-close so users can toggle multiple options in one pass.
|
|
432
|
-
- **Open-only animation**: only the open (enter) state animates (`fade-in`). There is intentionally no exit animation — holding the old DOM node during close breaks close/reposition on a second right-click, so it is omitted to keep repositioning reliable.
|
|
433
|
-
- **Submenus and RTL**: nested `ContextMenuSub` / `ContextMenuSubTrigger` / `ContextMenuSubContent` are supported, and `dir="rtl"` on the Root mirrors the layout (including the submenu chevron).
|
|
434
|
-
|
|
435
|
-
## Accessibility
|
|
436
|
-
|
|
437
|
-
- **Keyboard Support**:
|
|
438
|
-
- Shift+F10 or the Menu (context) key: open the menu from the focused trigger
|
|
439
|
-
- Arrow Down / Arrow Up: move between items
|
|
440
|
-
- Arrow Right: open submenu (Arrow Left to close) — mirrored in RTL
|
|
441
|
-
- Enter / Space: select item
|
|
442
|
-
- Escape: close menu
|
|
443
|
-
- **Touch**: long-press on the trigger opens the menu on touch devices.
|
|
444
|
-
- **ARIA Attributes**: roles and states are applied automatically by Radix UI.
|
|
445
|
-
- **Focus Management**: focus is trapped within the open menu and restored on close.
|
|
446
|
-
- **Screen Readers**: menu structure, checked/selected states, and submenus are announced.
|
|
447
|
-
|
|
448
|
-
## Best Practices
|
|
449
|
-
|
|
450
|
-
1. **Use a clear right-click zone**
|
|
451
|
-
```typescript
|
|
452
|
-
<ContextMenuTrigger asChild>
|
|
453
|
-
<div className="rounded-md border border-dashed">Right-click here</div>
|
|
454
|
-
</ContextMenuTrigger>
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
2. **Use labels to separate sections** — they also break auto-grouping into distinct boxed runs
|
|
458
|
-
```typescript
|
|
459
|
-
<ContextMenuLabel>Edit</ContextMenuLabel>
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
3. **Show keyboard shortcuts**
|
|
463
|
-
```typescript
|
|
464
|
-
<ContextMenuItem>
|
|
465
|
-
Save
|
|
466
|
-
<ContextMenuShortcut>⌘S</ContextMenuShortcut>
|
|
467
|
-
</ContextMenuItem>
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
4. **Use the Negative variant for destructive actions**
|
|
471
|
-
```typescript
|
|
472
|
-
<ContextMenuItem variant="Negative">Delete</ContextMenuItem>
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
5. **Let checkbox/radio toggles stay open**: rely on the built-in behavior so users can adjust several settings without reopening.
|
|
476
|
-
6. **Avoid deeply nested submenus**: 2 levels max.
|
|
477
|
-
7. **Keep item labels concise**: short, action-oriented text.
|
|
478
|
-
|
|
479
|
-
## Related Components
|
|
480
|
-
|
|
481
|
-
- [DropdownMenu](./dropdown-menu.md) - Button-anchored menu
|
|
482
|
-
- [Popover](./popover.md) - Non-menu popover
|
|
483
|
-
- [Select](./select.md) - Form select field
|