torch-glare 2.5.5 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/README.md +4 -3
  2. package/dist/bin/index.js +9 -24
  3. package/dist/bin/index.js.map +1 -1
  4. package/dist/src/commands/add.d.ts +2 -2
  5. package/dist/src/commands/add.d.ts.map +1 -1
  6. package/dist/src/commands/add.js +4 -70
  7. package/dist/src/commands/add.js.map +1 -1
  8. package/dist/src/commands/hook.d.ts +5 -4
  9. package/dist/src/commands/hook.d.ts.map +1 -1
  10. package/dist/src/commands/hook.js +7 -75
  11. package/dist/src/commands/hook.js.map +1 -1
  12. package/dist/src/commands/init.js +1 -1
  13. package/dist/src/commands/init.js.map +1 -1
  14. package/dist/src/commands/layout.d.ts +5 -4
  15. package/dist/src/commands/layout.d.ts.map +1 -1
  16. package/dist/src/commands/layout.js +7 -75
  17. package/dist/src/commands/layout.js.map +1 -1
  18. package/dist/src/commands/provider.d.ts +5 -4
  19. package/dist/src/commands/provider.d.ts.map +1 -1
  20. package/dist/src/commands/provider.js +7 -75
  21. package/dist/src/commands/provider.js.map +1 -1
  22. package/dist/src/commands/update.d.ts.map +1 -1
  23. package/dist/src/commands/update.js +78 -43
  24. package/dist/src/commands/update.js.map +1 -1
  25. package/dist/src/commands/utils.d.ts +5 -4
  26. package/dist/src/commands/utils.d.ts.map +1 -1
  27. package/dist/src/commands/utils.js +7 -80
  28. package/dist/src/commands/utils.js.map +1 -1
  29. package/dist/src/shared/addFromRegistry.d.ts +16 -0
  30. package/dist/src/shared/addFromRegistry.d.ts.map +1 -0
  31. package/dist/src/shared/addFromRegistry.js +88 -0
  32. package/dist/src/shared/addFromRegistry.js.map +1 -0
  33. package/dist/src/shared/getInstallCommand.d.ts.map +1 -1
  34. package/dist/src/shared/getInstallCommand.js +5 -0
  35. package/dist/src/shared/getInstallCommand.js.map +1 -1
  36. package/dist/src/shared/installDependencies.d.ts +0 -10
  37. package/dist/src/shared/installDependencies.d.ts.map +1 -1
  38. package/dist/src/shared/installDependencies.js +0 -17
  39. package/dist/src/shared/installDependencies.js.map +1 -1
  40. package/dist/src/shared/installFromPlan.d.ts +7 -5
  41. package/dist/src/shared/installFromPlan.d.ts.map +1 -1
  42. package/dist/src/shared/installFromPlan.js +103 -36
  43. package/dist/src/shared/installFromPlan.js.map +1 -1
  44. package/dist/src/shared/loadRegistry.d.ts +12 -3
  45. package/dist/src/shared/loadRegistry.d.ts.map +1 -1
  46. package/dist/src/shared/loadRegistry.js +19 -20
  47. package/dist/src/shared/loadRegistry.js.map +1 -1
  48. package/dist/src/shared/registryClient.d.ts +19 -0
  49. package/dist/src/shared/registryClient.d.ts.map +1 -0
  50. package/dist/src/shared/registryClient.js +128 -0
  51. package/dist/src/shared/registryClient.js.map +1 -0
  52. package/dist/src/shared/resolveEntry.d.ts +10 -7
  53. package/dist/src/shared/resolveEntry.d.ts.map +1 -1
  54. package/dist/src/shared/resolveEntry.js +18 -13
  55. package/dist/src/shared/resolveEntry.js.map +1 -1
  56. package/dist/src/shared/suggestOtherCommand.d.ts +7 -1
  57. package/dist/src/shared/suggestOtherCommand.d.ts.map +1 -1
  58. package/dist/src/shared/suggestOtherCommand.js +29 -23
  59. package/dist/src/shared/suggestOtherCommand.js.map +1 -1
  60. package/dist/src/types/main.d.ts +31 -2
  61. package/dist/src/types/main.d.ts.map +1 -1
  62. package/package.json +6 -11
  63. package/apps/lib/components/ActionButton.tsx +0 -93
  64. package/apps/lib/components/ActionsGroup.tsx +0 -27
  65. package/apps/lib/components/AlertDialog.tsx +0 -204
  66. package/apps/lib/components/Avatar.tsx +0 -46
  67. package/apps/lib/components/Badge.tsx +0 -250
  68. package/apps/lib/components/BadgeField.tsx +0 -338
  69. package/apps/lib/components/Breadcrumb.tsx +0 -280
  70. package/apps/lib/components/Button.tsx +0 -317
  71. package/apps/lib/components/ButtonGroup.tsx +0 -190
  72. package/apps/lib/components/Calendar.tsx +0 -115
  73. package/apps/lib/components/Card.tsx +0 -95
  74. package/apps/lib/components/Checkbox.tsx +0 -42
  75. package/apps/lib/components/ColorPicker.tsx +0 -441
  76. package/apps/lib/components/ConclusionHeader.tsx +0 -148
  77. package/apps/lib/components/ContextMenu.tsx +0 -571
  78. package/apps/lib/components/CountBadge.tsx +0 -52
  79. package/apps/lib/components/DataTable.tsx +0 -213
  80. package/apps/lib/components/DataViews/badge.ts +0 -49
  81. package/apps/lib/components/DataViews/cell.tsx +0 -324
  82. package/apps/lib/components/DataViews/context.ts +0 -144
  83. package/apps/lib/components/DataViews/data-views.tsx +0 -383
  84. package/apps/lib/components/DataViews/filters/children.tsx +0 -98
  85. package/apps/lib/components/DataViews/filters/custom.tsx +0 -34
  86. package/apps/lib/components/DataViews/filters/filters.tsx +0 -157
  87. package/apps/lib/components/DataViews/filters/index.ts +0 -4
  88. package/apps/lib/components/DataViews/filters/labelled.tsx +0 -20
  89. package/apps/lib/components/DataViews/filters/presets.tsx +0 -65
  90. package/apps/lib/components/DataViews/filters/sync.tsx +0 -35
  91. package/apps/lib/components/DataViews/filters/values.ts +0 -173
  92. package/apps/lib/components/DataViews/header.tsx +0 -220
  93. package/apps/lib/components/DataViews/hooks/index.ts +0 -5
  94. package/apps/lib/components/DataViews/hooks/useActiveRow.ts +0 -22
  95. package/apps/lib/components/DataViews/hooks/useControllable.ts +0 -52
  96. package/apps/lib/components/DataViews/index.ts +0 -84
  97. package/apps/lib/components/DataViews/panel/columns.tsx +0 -153
  98. package/apps/lib/components/DataViews/panel/controls.tsx +0 -106
  99. package/apps/lib/components/DataViews/panel/index.ts +0 -3
  100. package/apps/lib/components/DataViews/panel/panel.tsx +0 -164
  101. package/apps/lib/components/DataViews/panel/saved-views.tsx +0 -67
  102. package/apps/lib/components/DataViews/panel/section.tsx +0 -81
  103. package/apps/lib/components/DataViews/panel/sort.tsx +0 -42
  104. package/apps/lib/components/DataViews/panel/tab.tsx +0 -31
  105. package/apps/lib/components/DataViews/slots.ts +0 -63
  106. package/apps/lib/components/DataViews/states.tsx +0 -38
  107. package/apps/lib/components/DataViews/types.ts +0 -510
  108. package/apps/lib/components/DataViews/views/board-view.tsx +0 -381
  109. package/apps/lib/components/DataViews/views/card-rows.tsx +0 -36
  110. package/apps/lib/components/DataViews/views/inbox-view.tsx +0 -260
  111. package/apps/lib/components/DataViews/views/pane-views.tsx +0 -196
  112. package/apps/lib/components/DataViews/views/table-view.tsx +0 -493
  113. package/apps/lib/components/DataViews/views/tree-view.tsx +0 -367
  114. package/apps/lib/components/DatePicker.tsx +0 -232
  115. package/apps/lib/components/Dialog.tsx +0 -116
  116. package/apps/lib/components/Divider.tsx +0 -28
  117. package/apps/lib/components/Drawer.tsx +0 -420
  118. package/apps/lib/components/DropdownMenu.tsx +0 -540
  119. package/apps/lib/components/FieldHint.tsx +0 -69
  120. package/apps/lib/components/Form.tsx +0 -182
  121. package/apps/lib/components/FormBuilder/context.ts +0 -73
  122. package/apps/lib/components/FormBuilder/field-kind.ts +0 -28
  123. package/apps/lib/components/FormBuilder/fields/ChoiceFields.tsx +0 -60
  124. package/apps/lib/components/FormBuilder/fields/ColorField.tsx +0 -59
  125. package/apps/lib/components/FormBuilder/fields/CustomField.tsx +0 -11
  126. package/apps/lib/components/FormBuilder/fields/DateField.tsx +0 -32
  127. package/apps/lib/components/FormBuilder/fields/FieldArray.tsx +0 -74
  128. package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +0 -163
  129. package/apps/lib/components/FormBuilder/fields/FileField.tsx +0 -39
  130. package/apps/lib/components/FormBuilder/fields/OptionListFields.tsx +0 -132
  131. package/apps/lib/components/FormBuilder/fields/OtpField.tsx +0 -31
  132. package/apps/lib/components/FormBuilder/fields/PhoneField.tsx +0 -109
  133. package/apps/lib/components/FormBuilder/fields/RichTextEditorField.tsx +0 -31
  134. package/apps/lib/components/FormBuilder/fields/SelectField.tsx +0 -91
  135. package/apps/lib/components/FormBuilder/fields/SignatureField.tsx +0 -157
  136. package/apps/lib/components/FormBuilder/fields/SliderField.tsx +0 -67
  137. package/apps/lib/components/FormBuilder/fields/SwitchBoxField.tsx +0 -41
  138. package/apps/lib/components/FormBuilder/fields/TableField.tsx +0 -336
  139. package/apps/lib/components/FormBuilder/fields/TextField.tsx +0 -213
  140. package/apps/lib/components/FormBuilder/fields/TreeSelectField.tsx +0 -43
  141. package/apps/lib/components/FormBuilder/fields/countries.ts +0 -303
  142. package/apps/lib/components/FormBuilder/fields/index.ts +0 -25
  143. package/apps/lib/components/FormBuilder/form-builder.tsx +0 -198
  144. package/apps/lib/components/FormBuilder/index.ts +0 -31
  145. package/apps/lib/components/FormBuilder/numberFormat.ts +0 -16
  146. package/apps/lib/components/FormBuilder/submit.tsx +0 -47
  147. package/apps/lib/components/FormBuilder/types.ts +0 -311
  148. package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -128
  149. package/apps/lib/components/FormRenderer/detail.tsx +0 -207
  150. package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -297
  151. package/apps/lib/components/FormRenderer/header.tsx +0 -88
  152. package/apps/lib/components/FormRenderer/index.ts +0 -15
  153. package/apps/lib/components/FormRenderer/section.tsx +0 -39
  154. package/apps/lib/components/FormRenderer/stepper.tsx +0 -339
  155. package/apps/lib/components/FormRenderer/types.ts +0 -78
  156. package/apps/lib/components/FormSummary.tsx +0 -282
  157. package/apps/lib/components/HeaderBar.tsx +0 -117
  158. package/apps/lib/components/ImageAttachment.tsx +0 -209
  159. package/apps/lib/components/InnerLabelField.tsx +0 -154
  160. package/apps/lib/components/Input.tsx +0 -224
  161. package/apps/lib/components/InputField.tsx +0 -147
  162. package/apps/lib/components/InputOTP.tsx +0 -84
  163. package/apps/lib/components/Label.tsx +0 -129
  164. package/apps/lib/components/LabelField.tsx +0 -76
  165. package/apps/lib/components/LabeledCheckBox.tsx +0 -51
  166. package/apps/lib/components/LabeledRadio.tsx +0 -51
  167. package/apps/lib/components/LinkButton.tsx +0 -94
  168. package/apps/lib/components/LoginButton.tsx +0 -51
  169. package/apps/lib/components/PasswordLevel.tsx +0 -58
  170. package/apps/lib/components/Popover.tsx +0 -312
  171. package/apps/lib/components/ProfileMenu.tsx +0 -85
  172. package/apps/lib/components/Radio.tsx +0 -59
  173. package/apps/lib/components/RadioCard.tsx +0 -50
  174. package/apps/lib/components/ScrollArea.tsx +0 -54
  175. package/apps/lib/components/SearchField.tsx +0 -62
  176. package/apps/lib/components/SearchableSelect.tsx +0 -318
  177. package/apps/lib/components/SearchableTable.tsx +0 -344
  178. package/apps/lib/components/SearchableTree.tsx +0 -485
  179. package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
  180. package/apps/lib/components/SectionBlock.tsx +0 -147
  181. package/apps/lib/components/Select.tsx +0 -347
  182. package/apps/lib/components/SimpleSelect.tsx +0 -225
  183. package/apps/lib/components/Skeleton.tsx +0 -12
  184. package/apps/lib/components/SlideDatePicker.tsx +0 -253
  185. package/apps/lib/components/SpinLoading.tsx +0 -174
  186. package/apps/lib/components/Stepper.tsx +0 -480
  187. package/apps/lib/components/Switch.tsx +0 -82
  188. package/apps/lib/components/TabFormItem.tsx +0 -153
  189. package/apps/lib/components/TabSwitch.tsx +0 -172
  190. package/apps/lib/components/Table.tsx +0 -610
  191. package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
  192. package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
  193. package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
  194. package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
  195. package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
  196. package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
  197. package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
  198. package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
  199. package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
  200. package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
  201. package/apps/lib/components/TextEditor/index.ts +0 -7
  202. package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
  203. package/apps/lib/components/Textarea.tsx +0 -117
  204. package/apps/lib/components/Timeline.tsx +0 -263
  205. package/apps/lib/components/Toast.tsx +0 -87
  206. package/apps/lib/components/Toggle.tsx +0 -125
  207. package/apps/lib/components/ToggleButton.tsx +0 -140
  208. package/apps/lib/components/Tooltip.tsx +0 -116
  209. package/apps/lib/components/TransparentLabel.tsx +0 -71
  210. package/apps/lib/components/TreeDropDown.tsx +0 -115
  211. package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
  212. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
  213. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
  214. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
  215. package/apps/lib/components/TreeFolder/icons.tsx +0 -60
  216. package/apps/lib/components/TreeFolder/index.ts +0 -24
  217. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
  218. package/apps/lib/components/TreeFolder/types.ts +0 -77
  219. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
  220. package/apps/lib/hooks/useActiveTreeItem.ts +0 -58
  221. package/apps/lib/hooks/useClickOutside.ts +0 -27
  222. package/apps/lib/hooks/useDragDrop.tsx +0 -365
  223. package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
  224. package/apps/lib/hooks/useIsMobile.ts +0 -21
  225. package/apps/lib/hooks/useResize.ts +0 -67
  226. package/apps/lib/hooks/useTagSelection.ts +0 -214
  227. package/apps/lib/layouts/CNLayout.tsx +0 -372
  228. package/apps/lib/layouts/DataViewCard.tsx +0 -62
  229. package/apps/lib/layouts/FieldSection.tsx +0 -91
  230. package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
  231. package/apps/lib/providers/ThemeProvider.tsx +0 -84
  232. package/apps/lib/registry.json +0 -1201
  233. package/apps/lib/tsconfig.json +0 -9
  234. package/apps/lib/tsconfig.tsbuildinfo +0 -1
  235. package/apps/lib/utils/cn.ts +0 -6
  236. package/apps/lib/utils/color.ts +0 -175
  237. package/apps/lib/utils/dataViews/path.ts +0 -67
  238. package/apps/lib/utils/dataViews/query.ts +0 -73
  239. package/apps/lib/utils/dataViews/types.ts +0 -187
  240. package/apps/lib/utils/dateFormat.ts +0 -108
  241. package/apps/lib/utils/resize.ts +0 -31
  242. package/apps/lib/utils/types.ts +0 -16
  243. package/docs/BLOCKS.md +0 -129
  244. package/docs/CHANGELOG-1.1.16.md +0 -108
  245. package/docs/Cover.png +0 -0
  246. package/docs/README.md +0 -215
  247. package/docs/components/action-button.md +0 -638
  248. package/docs/components/actions-group.md +0 -708
  249. package/docs/components/alert-dialog.md +0 -920
  250. package/docs/components/avatar.md +0 -709
  251. package/docs/components/badge-field.md +0 -712
  252. package/docs/components/badge.md +0 -301
  253. package/docs/components/breadcrumb.md +0 -930
  254. package/docs/components/button-group.md +0 -650
  255. package/docs/components/button.md +0 -639
  256. package/docs/components/calendar.md +0 -555
  257. package/docs/components/card.md +0 -622
  258. package/docs/components/chart-block-tool.md +0 -129
  259. package/docs/components/checkbox.md +0 -699
  260. package/docs/components/cn-layout.md +0 -854
  261. package/docs/components/color-picker.md +0 -101
  262. package/docs/components/conclusion-header.md +0 -80
  263. package/docs/components/context-menu.md +0 -483
  264. package/docs/components/count-badge.md +0 -560
  265. package/docs/components/data-table.md +0 -854
  266. package/docs/components/data-views/backend-response.md +0 -324
  267. package/docs/components/data-views/examples/a11y-rtl.md +0 -250
  268. package/docs/components/data-views/examples/api-orders-route.md +0 -130
  269. package/docs/components/data-views/examples/fields.md +0 -362
  270. package/docs/components/data-views/examples/filters.md +0 -307
  271. package/docs/components/data-views/examples/inbox-routing.md +0 -218
  272. package/docs/components/data-views/examples/index.md +0 -29
  273. package/docs/components/data-views/examples/overview.md +0 -244
  274. package/docs/components/data-views/examples/panel.md +0 -212
  275. package/docs/components/data-views/examples/scale.md +0 -231
  276. package/docs/components/data-views/examples/server-side.md +0 -210
  277. package/docs/components/data-views/examples/state.md +0 -250
  278. package/docs/components/data-views/examples/tree-custom.md +0 -388
  279. package/docs/components/data-views/examples/view-registry.md +0 -313
  280. package/docs/components/data-views/examples/views.md +0 -534
  281. package/docs/components/data-views/guide.md +0 -405
  282. package/docs/components/data-views/index.md +0 -1495
  283. package/docs/components/data-views/migration.md +0 -79
  284. package/docs/components/date-picker.md +0 -857
  285. package/docs/components/dialog.md +0 -929
  286. package/docs/components/divider.md +0 -766
  287. package/docs/components/drawer.md +0 -654
  288. package/docs/components/dropdown-menu.md +0 -668
  289. package/docs/components/field-hint.md +0 -898
  290. package/docs/components/field-section.md +0 -781
  291. package/docs/components/form-builder.md +0 -276
  292. package/docs/components/form-renderer.md +0 -326
  293. package/docs/components/form-summary.md +0 -138
  294. package/docs/components/form.md +0 -785
  295. package/docs/components/header-bar.md +0 -188
  296. package/docs/components/image-attachment.md +0 -906
  297. package/docs/components/inner-label-field.md +0 -819
  298. package/docs/components/input-field.md +0 -623
  299. package/docs/components/input-otp.md +0 -756
  300. package/docs/components/input.md +0 -634
  301. package/docs/components/label-field.md +0 -770
  302. package/docs/components/label.md +0 -761
  303. package/docs/components/labeled-check-box.md +0 -642
  304. package/docs/components/labeled-radio.md +0 -796
  305. package/docs/components/link-button.md +0 -685
  306. package/docs/components/login-button.md +0 -872
  307. package/docs/components/password-level.md +0 -803
  308. package/docs/components/popover.md +0 -649
  309. package/docs/components/profile-menu.md +0 -656
  310. package/docs/components/radio-card.md +0 -801
  311. package/docs/components/radio.md +0 -735
  312. package/docs/components/scroll-area.md +0 -691
  313. package/docs/components/search-field.md +0 -702
  314. package/docs/components/searchable-select.md +0 -368
  315. package/docs/components/searchable-table.md +0 -438
  316. package/docs/components/searchable-tree-dialog.md +0 -190
  317. package/docs/components/searchable-tree.md +0 -200
  318. package/docs/components/section-block.md +0 -477
  319. package/docs/components/select.md +0 -709
  320. package/docs/components/simple-select.md +0 -741
  321. package/docs/components/skeleton.md +0 -706
  322. package/docs/components/slide-date-picker.md +0 -837
  323. package/docs/components/spin-loading.md +0 -696
  324. package/docs/components/stepper.md +0 -316
  325. package/docs/components/switch.md +0 -770
  326. package/docs/components/tab-form-item.md +0 -773
  327. package/docs/components/tab-switch.md +0 -170
  328. package/docs/components/table-dnd-wrapper.md +0 -107
  329. package/docs/components/table.md +0 -1088
  330. package/docs/components/text-editor.md +0 -735
  331. package/docs/components/textarea.md +0 -681
  332. package/docs/components/timeline.md +0 -254
  333. package/docs/components/toast.md +0 -773
  334. package/docs/components/toggle-button.md +0 -643
  335. package/docs/components/toggle.md +0 -882
  336. package/docs/components/tooltip.md +0 -513
  337. package/docs/components/transparent-label.md +0 -721
  338. package/docs/components/tree-drop-down.md +0 -740
  339. package/docs/components/tree-folder.md +0 -110
  340. package/docs/components/tree-sub-layout.md +0 -707
  341. package/docs/explanation/architecture.md +0 -54
  342. package/docs/explanation/design-system.md +0 -52
  343. package/docs/how-to/form-and-list-recipes.md +0 -386
  344. package/docs/how-to/forms-with-form-builder.md +0 -472
  345. package/docs/how-to/guides.md +0 -1027
  346. package/docs/migration/changelog.md +0 -54
  347. package/docs/migration/form-builder-2.5.2.md +0 -113
  348. package/docs/reference/cli.md +0 -112
  349. package/docs/reference/components.md +0 -572
  350. package/docs/reference/hooks.md +0 -1500
  351. package/docs/reference/providers.md +0 -866
  352. package/docs/reference/tailwind-plugins.md +0 -942
  353. package/docs/reference/theme.md +0 -85
  354. package/docs/reference/types.md +0 -1016
  355. package/docs/reference/utilities.md +0 -704
  356. package/docs/tutorials/building-first-form.md +0 -846
  357. package/docs/tutorials/component-composition.md +0 -882
  358. package/docs/tutorials/getting-started.md +0 -302
  359. 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