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.
Files changed (362) 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 -403
  69. package/apps/lib/components/Breadcrumb.tsx +0 -280
  70. package/apps/lib/components/Button.tsx +0 -325
  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 -395
  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 -88
  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 -72
  106. package/apps/lib/components/DataViews/states.tsx +0 -73
  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 -451
  118. package/apps/lib/components/DropdownMenu.tsx +0 -554
  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 -85
  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 -168
  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 -114
  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 -67
  147. package/apps/lib/components/FormBuilder/types.ts +0 -316
  148. package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -250
  149. package/apps/lib/components/FormRenderer/detail.tsx +0 -256
  150. package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -358
  151. package/apps/lib/components/FormRenderer/header.tsx +0 -88
  152. package/apps/lib/components/FormRenderer/index.ts +0 -17
  153. package/apps/lib/components/FormRenderer/notch-action.tsx +0 -64
  154. package/apps/lib/components/FormRenderer/section.tsx +0 -39
  155. package/apps/lib/components/FormRenderer/stepper.tsx +0 -393
  156. package/apps/lib/components/FormRenderer/types.ts +0 -115
  157. package/apps/lib/components/FormSummary.tsx +0 -282
  158. package/apps/lib/components/HeaderBar.tsx +0 -117
  159. package/apps/lib/components/ImageAttachment.tsx +0 -209
  160. package/apps/lib/components/InnerLabelField.tsx +0 -154
  161. package/apps/lib/components/Input.tsx +0 -224
  162. package/apps/lib/components/InputField.tsx +0 -147
  163. package/apps/lib/components/InputOTP.tsx +0 -84
  164. package/apps/lib/components/Label.tsx +0 -129
  165. package/apps/lib/components/LabelField.tsx +0 -76
  166. package/apps/lib/components/LabeledCheckBox.tsx +0 -51
  167. package/apps/lib/components/LabeledRadio.tsx +0 -51
  168. package/apps/lib/components/LinkButton.tsx +0 -94
  169. package/apps/lib/components/LoginButton.tsx +0 -51
  170. package/apps/lib/components/PasswordLevel.tsx +0 -58
  171. package/apps/lib/components/Popover.tsx +0 -312
  172. package/apps/lib/components/ProfileMenu.tsx +0 -85
  173. package/apps/lib/components/Radio.tsx +0 -59
  174. package/apps/lib/components/RadioCard.tsx +0 -50
  175. package/apps/lib/components/ScrollArea.tsx +0 -54
  176. package/apps/lib/components/SearchField.tsx +0 -62
  177. package/apps/lib/components/SearchableSelect.tsx +0 -318
  178. package/apps/lib/components/SearchableTable.tsx +0 -344
  179. package/apps/lib/components/SearchableTree.tsx +0 -485
  180. package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
  181. package/apps/lib/components/SectionBlock.tsx +0 -168
  182. package/apps/lib/components/Select.tsx +0 -347
  183. package/apps/lib/components/SimpleSelect.tsx +0 -225
  184. package/apps/lib/components/Skeleton.tsx +0 -12
  185. package/apps/lib/components/SlideDatePicker.tsx +0 -255
  186. package/apps/lib/components/SpinLoading.tsx +0 -174
  187. package/apps/lib/components/Stepper.tsx +0 -480
  188. package/apps/lib/components/Switch.tsx +0 -82
  189. package/apps/lib/components/TabFormItem.tsx +0 -153
  190. package/apps/lib/components/TabSwitch.tsx +0 -172
  191. package/apps/lib/components/Table.tsx +0 -597
  192. package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
  193. package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
  194. package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
  195. package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
  196. package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
  197. package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
  198. package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
  199. package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
  200. package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
  201. package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
  202. package/apps/lib/components/TextEditor/index.ts +0 -7
  203. package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
  204. package/apps/lib/components/Textarea.tsx +0 -117
  205. package/apps/lib/components/Timeline.tsx +0 -263
  206. package/apps/lib/components/Toast.tsx +0 -87
  207. package/apps/lib/components/Toggle.tsx +0 -125
  208. package/apps/lib/components/ToggleButton.tsx +0 -140
  209. package/apps/lib/components/Tooltip.tsx +0 -116
  210. package/apps/lib/components/TransparentLabel.tsx +0 -71
  211. package/apps/lib/components/TreeDropDown.tsx +0 -115
  212. package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
  213. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
  214. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
  215. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
  216. package/apps/lib/components/TreeFolder/icons.tsx +0 -60
  217. package/apps/lib/components/TreeFolder/index.ts +0 -24
  218. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
  219. package/apps/lib/components/TreeFolder/types.ts +0 -77
  220. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
  221. package/apps/lib/hooks/useActiveTreeItem.ts +0 -61
  222. package/apps/lib/hooks/useClickOutside.ts +0 -27
  223. package/apps/lib/hooks/useDragDrop.tsx +0 -365
  224. package/apps/lib/hooks/useHtmlDir.ts +0 -31
  225. package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
  226. package/apps/lib/hooks/useIsMobile.ts +0 -21
  227. package/apps/lib/hooks/useResize.ts +0 -67
  228. package/apps/lib/hooks/useTagSelection.ts +0 -300
  229. package/apps/lib/layouts/CNLayout.tsx +0 -372
  230. package/apps/lib/layouts/DataViewCard.tsx +0 -62
  231. package/apps/lib/layouts/FieldSection.tsx +0 -91
  232. package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
  233. package/apps/lib/providers/ThemeProvider.tsx +0 -84
  234. package/apps/lib/registry.json +0 -1217
  235. package/apps/lib/tsconfig.json +0 -9
  236. package/apps/lib/tsconfig.tsbuildinfo +0 -1
  237. package/apps/lib/utils/cn.ts +0 -6
  238. package/apps/lib/utils/color.ts +0 -175
  239. package/apps/lib/utils/dataViews/path.ts +0 -67
  240. package/apps/lib/utils/dataViews/query.ts +0 -73
  241. package/apps/lib/utils/dataViews/types.ts +0 -187
  242. package/apps/lib/utils/dateFormat.ts +0 -108
  243. package/apps/lib/utils/resize.ts +0 -31
  244. package/apps/lib/utils/scroller.ts +0 -26
  245. package/apps/lib/utils/types.ts +0 -16
  246. package/docs/BLOCKS.md +0 -129
  247. package/docs/CHANGELOG-1.1.16.md +0 -108
  248. package/docs/Cover.png +0 -0
  249. package/docs/README.md +0 -215
  250. package/docs/components/action-button.md +0 -638
  251. package/docs/components/actions-group.md +0 -708
  252. package/docs/components/alert-dialog.md +0 -920
  253. package/docs/components/avatar.md +0 -709
  254. package/docs/components/badge-field.md +0 -738
  255. package/docs/components/badge.md +0 -301
  256. package/docs/components/breadcrumb.md +0 -930
  257. package/docs/components/button-group.md +0 -650
  258. package/docs/components/button.md +0 -639
  259. package/docs/components/calendar.md +0 -555
  260. package/docs/components/card.md +0 -622
  261. package/docs/components/chart-block-tool.md +0 -129
  262. package/docs/components/checkbox.md +0 -699
  263. package/docs/components/cn-layout.md +0 -854
  264. package/docs/components/color-picker.md +0 -101
  265. package/docs/components/conclusion-header.md +0 -80
  266. package/docs/components/context-menu.md +0 -483
  267. package/docs/components/count-badge.md +0 -560
  268. package/docs/components/data-table.md +0 -854
  269. package/docs/components/data-views/backend-response.md +0 -324
  270. package/docs/components/data-views/examples/a11y-rtl.md +0 -250
  271. package/docs/components/data-views/examples/api-orders-route.md +0 -130
  272. package/docs/components/data-views/examples/fields.md +0 -362
  273. package/docs/components/data-views/examples/filters.md +0 -307
  274. package/docs/components/data-views/examples/inbox-routing.md +0 -218
  275. package/docs/components/data-views/examples/index.md +0 -29
  276. package/docs/components/data-views/examples/overview.md +0 -244
  277. package/docs/components/data-views/examples/panel.md +0 -212
  278. package/docs/components/data-views/examples/scale.md +0 -231
  279. package/docs/components/data-views/examples/server-side.md +0 -210
  280. package/docs/components/data-views/examples/state.md +0 -250
  281. package/docs/components/data-views/examples/tree-custom.md +0 -388
  282. package/docs/components/data-views/examples/view-registry.md +0 -313
  283. package/docs/components/data-views/examples/views.md +0 -534
  284. package/docs/components/data-views/guide.md +0 -405
  285. package/docs/components/data-views/index.md +0 -1521
  286. package/docs/components/data-views/migration.md +0 -81
  287. package/docs/components/date-picker.md +0 -857
  288. package/docs/components/dialog.md +0 -929
  289. package/docs/components/divider.md +0 -766
  290. package/docs/components/drawer.md +0 -654
  291. package/docs/components/dropdown-menu.md +0 -668
  292. package/docs/components/field-hint.md +0 -898
  293. package/docs/components/field-section.md +0 -781
  294. package/docs/components/form-builder.md +0 -284
  295. package/docs/components/form-renderer.md +0 -396
  296. package/docs/components/form-summary.md +0 -138
  297. package/docs/components/form.md +0 -785
  298. package/docs/components/header-bar.md +0 -188
  299. package/docs/components/image-attachment.md +0 -906
  300. package/docs/components/inner-label-field.md +0 -819
  301. package/docs/components/input-field.md +0 -623
  302. package/docs/components/input-otp.md +0 -756
  303. package/docs/components/input.md +0 -634
  304. package/docs/components/label-field.md +0 -770
  305. package/docs/components/label.md +0 -761
  306. package/docs/components/labeled-check-box.md +0 -642
  307. package/docs/components/labeled-radio.md +0 -796
  308. package/docs/components/link-button.md +0 -685
  309. package/docs/components/login-button.md +0 -872
  310. package/docs/components/password-level.md +0 -803
  311. package/docs/components/popover.md +0 -649
  312. package/docs/components/profile-menu.md +0 -656
  313. package/docs/components/radio-card.md +0 -801
  314. package/docs/components/radio.md +0 -735
  315. package/docs/components/scroll-area.md +0 -691
  316. package/docs/components/search-field.md +0 -702
  317. package/docs/components/searchable-select.md +0 -368
  318. package/docs/components/searchable-table.md +0 -438
  319. package/docs/components/searchable-tree-dialog.md +0 -190
  320. package/docs/components/searchable-tree.md +0 -200
  321. package/docs/components/section-block.md +0 -483
  322. package/docs/components/select.md +0 -709
  323. package/docs/components/simple-select.md +0 -741
  324. package/docs/components/skeleton.md +0 -706
  325. package/docs/components/slide-date-picker.md +0 -837
  326. package/docs/components/spin-loading.md +0 -696
  327. package/docs/components/stepper.md +0 -316
  328. package/docs/components/switch.md +0 -770
  329. package/docs/components/tab-form-item.md +0 -773
  330. package/docs/components/tab-switch.md +0 -170
  331. package/docs/components/table-dnd-wrapper.md +0 -107
  332. package/docs/components/table.md +0 -1088
  333. package/docs/components/text-editor.md +0 -735
  334. package/docs/components/textarea.md +0 -681
  335. package/docs/components/timeline.md +0 -254
  336. package/docs/components/toast.md +0 -773
  337. package/docs/components/toggle-button.md +0 -643
  338. package/docs/components/toggle.md +0 -882
  339. package/docs/components/tooltip.md +0 -513
  340. package/docs/components/transparent-label.md +0 -721
  341. package/docs/components/tree-drop-down.md +0 -740
  342. package/docs/components/tree-folder.md +0 -110
  343. package/docs/components/tree-sub-layout.md +0 -707
  344. package/docs/explanation/architecture.md +0 -54
  345. package/docs/explanation/design-system.md +0 -52
  346. package/docs/how-to/form-and-list-recipes.md +0 -386
  347. package/docs/how-to/forms-with-form-builder.md +0 -472
  348. package/docs/how-to/guides.md +0 -1027
  349. package/docs/migration/changelog.md +0 -60
  350. package/docs/migration/form-builder-2.5.2.md +0 -113
  351. package/docs/reference/cli.md +0 -112
  352. package/docs/reference/components.md +0 -572
  353. package/docs/reference/hooks.md +0 -1523
  354. package/docs/reference/providers.md +0 -866
  355. package/docs/reference/tailwind-plugins.md +0 -942
  356. package/docs/reference/theme.md +0 -85
  357. package/docs/reference/types.md +0 -1016
  358. package/docs/reference/utilities.md +0 -726
  359. package/docs/tutorials/building-first-form.md +0 -846
  360. package/docs/tutorials/component-composition.md +0 -882
  361. package/docs/tutorials/getting-started.md +0 -302
  362. package/docs/tutorials/theming-basics.md +0 -785
@@ -1,441 +0,0 @@
1
- "use client";
2
-
3
- import React, {
4
- cloneElement,
5
- forwardRef,
6
- useCallback,
7
- useEffect,
8
- useMemo,
9
- useRef,
10
- useState,
11
- type ReactElement,
12
- } from "react";
13
- import * as Slider from "@radix-ui/react-slider";
14
-
15
- import { cn } from "../utils/cn";
16
- import { Themes } from "../utils/types";
17
- import { Popover, PopoverContent, PopoverTrigger } from "./Popover";
18
- import { Group, Input } from "./Input";
19
- import {
20
- clamp,
21
- formatHex,
22
- hslToRgb,
23
- hsvToRgb,
24
- parseHex,
25
- rgbToHsl,
26
- rgbToHsv,
27
- round,
28
- type HSV,
29
- } from "../utils/color";
30
-
31
- export interface ColorPickerProps {
32
- /**
33
- * The trigger — a single element that opens the picker (rendered via `asChild`, so it must
34
- * forward its ref/props to a DOM node). ColorPicker renders **no trigger of its own**; it
35
- * hands the current color to whatever you pass:
36
- *
37
- * - an **input** (native `<input>`/`<textarea>`, or any element already given a `value` prop)
38
- * receives the hex as its `value`;
39
- * - **anything else** receives the hex as its `children` — unless it already has children of
40
- * its own, which are left untouched.
41
- */
42
- children: ReactElement;
43
- /** Current color as a hex string (`#rrggbb` or `#rrggbbaa`). Defaults to `#000000`. */
44
- value?: string;
45
- /** Called with the new hex string on every change. */
46
- onChange?: (hex: string) => void;
47
- /** Quick-pick swatches shown at the bottom of the panel. */
48
- presets?: string[];
49
- /** Show the opacity slider + opacity input and emit `#rrggbbaa` when < 100%. Default true. */
50
- alpha?: boolean;
51
- disabled?: boolean;
52
- theme?: Themes;
53
- }
54
-
55
- /** Native form controls, or any element already driven by a `value` prop, take the hex as `value`. */
56
- function isInputLike(el: ReactElement): boolean {
57
- if (typeof el.type === "string") return el.type === "input" || el.type === "textarea";
58
- return "value" in ((el.props ?? {}) as Record<string, unknown>);
59
- }
60
-
61
- type Mode = "hex" | "rgb" | "hsl";
62
-
63
- const HUE_GRADIENT =
64
- "linear-gradient(to right,#f00 0%,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,#f00 100%)";
65
-
66
- /** Small 8px checkerboard so transparency reads clearly behind swatches / the alpha track. */
67
- export const CHECKERBOARD: React.CSSProperties = {
68
- backgroundColor: "#fff",
69
- backgroundImage:
70
- "linear-gradient(45deg,#c8c8c8 25%,transparent 25%),linear-gradient(-45deg,#c8c8c8 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#c8c8c8 75%),linear-gradient(-45deg,transparent 75%,#c8c8c8 75%)",
71
- backgroundSize: "8px 8px",
72
- backgroundPosition: "0 0,0 4px,4px -4px,-4px 0",
73
- };
74
-
75
- const THUMB_CLS =
76
- "block h-[16px] w-[16px] rounded-full border-2 border-white bg-transparent shadow-[0_1px_4px_0_rgba(0,0,0,0.45)] outline-none transition-transform hover:scale-110 focus:ring-2 focus:ring-white/70";
77
-
78
- // Compact numeric inputs: allow shrinking below the base `min-w-[30px]` and drop the native
79
- // number spinners so a full row (3 channels + opacity) never overflows the fixed-width panel.
80
- const NUM_INPUT_CLS =
81
- "min-w-0 px-0 text-center [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none";
82
-
83
- /**
84
- * A full Figma-style color picker: a draggable saturation/value area, hue slider,
85
- * optional opacity slider, an eyedropper (where supported), switchable HEX/RGB/HSL
86
- * inputs, and preset swatches — all opened from a field-styled swatch trigger.
87
- *
88
- * The value is always a hex string, kept `#rrggbb` while fully opaque and promoted to
89
- * `#rrggbbaa` only when opacity drops below 100%.
90
- */
91
- export const ColorPicker = forwardRef<HTMLElement, ColorPickerProps>(
92
- ({ children, value, onChange, presets, alpha = true, disabled, theme }, ref) => {
93
- // Internal source of truth is HSV + alpha: keeping HSV (not RGB/hex) means dragging in the
94
- // grey column or the black row doesn't discard the chosen hue.
95
- const [hsv, setHsv] = useState<HSV>({ h: 0, s: 0, v: 0 });
96
- const [a, setA] = useState(1);
97
- const [mode, setMode] = useState<Mode>("hex");
98
- const lastHexRef = useRef<string | null>(null);
99
-
100
- const rgb = useMemo(() => hsvToRgb(hsv), [hsv]);
101
- const hsl = useMemo(() => rgbToHsl(rgb), [rgb]);
102
- const hex = useMemo(() => formatHex({ ...rgb, a }), [rgb, a]);
103
- const hex6 = useMemo(() => formatHex({ ...rgb, a: 1 }), [rgb]);
104
-
105
- // Sync FROM the controlled value — but skip the echo of our own last emit to avoid loops.
106
- useEffect(() => {
107
- if (!value) return;
108
- if (value === lastHexRef.current) return;
109
- const parsed = parseHex(value);
110
- if (!parsed) return;
111
- setHsv(rgbToHsv(parsed));
112
- setA(parsed.a);
113
- lastHexRef.current = value;
114
- }, [value]);
115
-
116
- const emit = useCallback(
117
- (nextHsv: HSV, nextA: number) => {
118
- setHsv(nextHsv);
119
- setA(nextA);
120
- const out = formatHex({ ...hsvToRgb(nextHsv), a: nextA });
121
- lastHexRef.current = out;
122
- onChange?.(out);
123
- },
124
- [onChange],
125
- );
126
-
127
- const applyHsv = useCallback((next: HSV, nextA = a) => emit(next, nextA), [emit, a]);
128
- const applyRgba = useCallback(
129
- (r: number, g: number, b: number, nextA = a) =>
130
- emit(rgbToHsv({ r, g, b }), clamp(nextA, 0, 1)),
131
- [emit, a],
132
- );
133
-
134
- // ── Saturation / value area ─────────────────────────────────────────────
135
- const svRef = useRef<HTMLDivElement>(null);
136
- const readSV = useCallback(
137
- (clientX: number, clientY: number) => {
138
- const el = svRef.current;
139
- if (!el) return;
140
- const rect = el.getBoundingClientRect();
141
- const x = clamp((clientX - rect.left) / rect.width, 0, 1);
142
- const y = clamp((clientY - rect.top) / rect.height, 0, 1);
143
- applyHsv({ h: hsv.h, s: round(x * 100), v: round((1 - y) * 100) });
144
- },
145
- [applyHsv, hsv.h],
146
- );
147
-
148
- const onSVPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
149
- if (disabled) return;
150
- e.currentTarget.setPointerCapture(e.pointerId);
151
- readSV(e.clientX, e.clientY);
152
- };
153
- const onSVPointerMove = (e: React.PointerEvent<HTMLDivElement>) => {
154
- if (disabled || e.buttons !== 1) return;
155
- readSV(e.clientX, e.clientY);
156
- };
157
-
158
- // ── Eyedropper (Chromium/Edge only) ─────────────────────────────────────
159
- const hasEyeDropper = typeof window !== "undefined" && "EyeDropper" in window;
160
- const pickWithEyeDropper = async () => {
161
- try {
162
- const ED = (
163
- window as unknown as {
164
- EyeDropper: new () => { open: () => Promise<{ sRGBHex: string }> };
165
- }
166
- ).EyeDropper;
167
- const res = await new ED().open();
168
- const parsed = parseHex(res.sRGBHex);
169
- if (parsed) applyRgba(parsed.r, parsed.g, parsed.b, parsed.a);
170
- } catch {
171
- /* user cancelled — ignore */
172
- }
173
- };
174
-
175
- // ── HEX input draft (free typing, commit on blur / Enter) ────────────────
176
- const [hexDraft, setHexDraft] = useState(hex6);
177
- const hexFocused = useRef(false);
178
- useEffect(() => {
179
- if (!hexFocused.current) setHexDraft(hex6);
180
- }, [hex6]);
181
- const commitHex = () => {
182
- const parsed = parseHex(hexDraft);
183
- if (parsed) applyRgba(parsed.r, parsed.g, parsed.b, a);
184
- else setHexDraft(hex6);
185
- };
186
-
187
- const opacityPct = round(a * 100);
188
-
189
- // The trigger is the caller's child — ColorPicker renders none of its own. An input gets the
190
- // hex as `value`; anything else gets it as `children` (unless it already has its own).
191
- const trigger = useMemo(() => {
192
- const childProps = (children.props ?? {}) as Record<string, unknown>;
193
-
194
- if (isInputLike(children)) {
195
- return cloneElement(children as ReactElement<Record<string, unknown>>, {
196
- value: hex,
197
- // A controlled input with no `onChange` warns in React — commit typed hex instead.
198
- ...(childProps.onChange
199
- ? {}
200
- : {
201
- onChange: (e: React.ChangeEvent<HTMLInputElement>) => {
202
- const parsed = parseHex(e.target.value);
203
- if (parsed) applyRgba(parsed.r, parsed.g, parsed.b, parsed.a);
204
- },
205
- }),
206
- });
207
- }
208
-
209
- if (childProps.children == null) {
210
- return cloneElement(children as ReactElement<Record<string, unknown>>, {}, hex);
211
- }
212
- return children;
213
- }, [children, hex, applyRgba]);
214
-
215
- return (
216
- <Popover>
217
- <PopoverTrigger asChild disabled={disabled} ref={ref as React.Ref<HTMLButtonElement>}>
218
- {trigger}
219
- </PopoverTrigger>
220
-
221
- <PopoverContent
222
- variant="PresentationStyle"
223
- theme={theme}
224
- align="start"
225
- onOpenAutoFocus={(e) => e.preventDefault()}
226
- className="w-[300px] max-h-fit overflow-visible p-0"
227
- >
228
- <div className="flex flex-col gap-3 p-3">
229
- {/* Saturation / value */}
230
- <div
231
- ref={svRef}
232
- onPointerDown={onSVPointerDown}
233
- onPointerMove={onSVPointerMove}
234
- className="relative h-[150px] w-full cursor-crosshair touch-none rounded-[6px]"
235
- style={{ backgroundColor: `hsl(${hsv.h},100%,50%)` }}
236
- >
237
- <div
238
- className="absolute inset-0 rounded-[6px]"
239
- style={{ backgroundImage: "linear-gradient(to right,#fff,rgba(255,255,255,0))" }}
240
- />
241
- <div
242
- className="absolute inset-0 rounded-[6px]"
243
- style={{ backgroundImage: "linear-gradient(to top,#000,rgba(0,0,0,0))" }}
244
- />
245
- <span
246
- className="absolute h-[14px] w-[14px] -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white shadow-[0_1px_4px_0_rgba(0,0,0,0.45)]"
247
- style={{
248
- left: `${hsv.s}%`,
249
- top: `${100 - hsv.v}%`,
250
- backgroundColor: hex6,
251
- }}
252
- />
253
- </div>
254
-
255
- {/* Eyedropper + hue (+ alpha) sliders */}
256
- <div className="flex items-center gap-2">
257
- {hasEyeDropper && (
258
- <button
259
- type="button"
260
- aria-label="Pick color from screen"
261
- onClick={pickWithEyeDropper}
262
- disabled={disabled}
263
- className="flex h-[28px] w-[28px] shrink-0 items-center justify-center rounded-[6px] border border-border-presentation-action-primary text-content-presentation-action-light-secondary transition-colors hover:bg-background-presentation-form-field-hover"
264
- >
265
- <i className="ri-sip-line text-[16px]" />
266
- </button>
267
- )}
268
-
269
- <div className="flex flex-1 flex-col gap-2">
270
- <Slider.Root
271
- className="relative flex h-[14px] w-full touch-none select-none items-center"
272
- min={0}
273
- max={360}
274
- step={1}
275
- value={[hsv.h]}
276
- onValueChange={([h]) => applyHsv({ ...hsv, h })}
277
- disabled={disabled}
278
- >
279
- <Slider.Track
280
- className="relative h-[10px] grow rounded-full"
281
- style={{ backgroundImage: HUE_GRADIENT }}
282
- >
283
- <Slider.Range className="absolute h-full rounded-full bg-transparent" />
284
- </Slider.Track>
285
- <Slider.Thumb
286
- className={THUMB_CLS}
287
- style={{ backgroundColor: `hsl(${hsv.h},100%,50%)` }}
288
- />
289
- </Slider.Root>
290
-
291
- {alpha && (
292
- <Slider.Root
293
- className="relative flex h-[14px] w-full touch-none select-none items-center"
294
- min={0}
295
- max={1}
296
- step={0.01}
297
- value={[a]}
298
- onValueChange={([na]) => applyHsv(hsv, na)}
299
- disabled={disabled}
300
- >
301
- <Slider.Track
302
- className="relative h-[10px] grow overflow-hidden rounded-full"
303
- style={CHECKERBOARD}
304
- >
305
- <div
306
- className="absolute inset-0"
307
- style={{
308
- backgroundImage: `linear-gradient(to right,rgba(${rgb.r},${rgb.g},${rgb.b},0),rgb(${rgb.r},${rgb.g},${rgb.b}))`,
309
- }}
310
- />
311
- <Slider.Range className="absolute h-full rounded-full bg-transparent" />
312
- </Slider.Track>
313
- <Slider.Thumb className={THUMB_CLS} style={{ backgroundColor: hex }} />
314
- </Slider.Root>
315
- )}
316
- </div>
317
- </div>
318
-
319
- {/* Model switch + numeric inputs */}
320
- <div className="flex items-start gap-2">
321
- <select
322
- value={mode}
323
- disabled={disabled}
324
- onChange={(e) => setMode(e.target.value as Mode)}
325
- className="h-[30px] w-[54px] shrink-0 rounded-[6px] border border-border-presentation-action-primary bg-background-presentation-form-field-primary px-1 typography-body-small-regular text-content-presentation-action-light-primary outline-none"
326
- >
327
- <option value="hex">HEX</option>
328
- <option value="rgb">RGB</option>
329
- <option value="hsl">HSL</option>
330
- </select>
331
-
332
- <div className="flex min-w-0 flex-1 items-center gap-1">
333
- {mode === "hex" && (
334
- <Group size="S" className="min-w-0 flex-1">
335
- <Input
336
- value={hexDraft}
337
- disabled={disabled}
338
- onFocus={() => (hexFocused.current = true)}
339
- onChange={(e) => setHexDraft(e.target.value)}
340
- onBlur={() => {
341
- hexFocused.current = false;
342
- commitHex();
343
- }}
344
- onKeyDown={(e) => e.key === "Enter" && (e.target as HTMLInputElement).blur()}
345
- className="min-w-0 text-center"
346
- />
347
- </Group>
348
- )}
349
-
350
- {mode === "rgb" &&
351
- (["r", "g", "b"] as const).map((ch) => (
352
- <Group key={ch} size="S" className="min-w-0 flex-1 px-0">
353
- <Input
354
- type="number"
355
- min={0}
356
- max={255}
357
- disabled={disabled}
358
- value={rgb[ch]}
359
- onChange={(e) => {
360
- const n = clamp(Number(e.target.value) || 0, 0, 255);
361
- applyRgba(
362
- ch === "r" ? n : rgb.r,
363
- ch === "g" ? n : rgb.g,
364
- ch === "b" ? n : rgb.b,
365
- a,
366
- );
367
- }}
368
- className={NUM_INPUT_CLS}
369
- />
370
- </Group>
371
- ))}
372
-
373
- {mode === "hsl" &&
374
- (["h", "s", "l"] as const).map((ch) => (
375
- <Group key={ch} size="S" className="min-w-0 flex-1 px-0">
376
- <Input
377
- type="number"
378
- min={0}
379
- max={ch === "h" ? 360 : 100}
380
- disabled={disabled}
381
- value={hsl[ch]}
382
- onChange={(e) => {
383
- const n = clamp(Number(e.target.value) || 0, 0, ch === "h" ? 360 : 100);
384
- const next = { ...hsl, [ch]: n };
385
- const r = hslToRgb(next);
386
- applyRgba(r.r, r.g, r.b, a);
387
- }}
388
- className={NUM_INPUT_CLS}
389
- />
390
- </Group>
391
- ))}
392
-
393
- {alpha && (
394
- <Group size="S" className="w-[48px] shrink-0 gap-0 px-0">
395
- <Input
396
- type="number"
397
- min={0}
398
- max={100}
399
- disabled={disabled}
400
- value={opacityPct}
401
- onChange={(e) => {
402
- const n = clamp(Number(e.target.value) || 0, 0, 100);
403
- applyHsv(hsv, n / 100);
404
- }}
405
- className={NUM_INPUT_CLS}
406
- />
407
- <span className="pe-1 typography-body-small-regular text-content-presentation-action-light-secondary">
408
- %
409
- </span>
410
- </Group>
411
- )}
412
- </div>
413
- </div>
414
-
415
- {/* Presets */}
416
- {presets && presets.length > 0 && (
417
- <div className="flex flex-wrap items-center gap-1.5 border-t border-border-presentation-global-primary pt-3">
418
- {presets.map((c) => (
419
- <button
420
- key={c}
421
- type="button"
422
- aria-label={c}
423
- disabled={disabled}
424
- onClick={() => {
425
- const parsed = parseHex(c);
426
- if (parsed) applyRgba(parsed.r, parsed.g, parsed.b, parsed.a);
427
- }}
428
- style={{ backgroundColor: c }}
429
- className="h-[20px] w-[20px] rounded-[4px] border border-border-presentation-action-primary transition-transform hover:scale-110"
430
- />
431
- ))}
432
- </div>
433
- )}
434
- </div>
435
- </PopoverContent>
436
- </Popover>
437
- );
438
- },
439
- );
440
-
441
- ColorPicker.displayName = "ColorPicker";
@@ -1,148 +0,0 @@
1
- "use client";
2
-
3
- import React, { forwardRef, useState, ButtonHTMLAttributes, ReactNode } from "react";
4
- import { Badge } from "./Badge";
5
- import { cn } from "../utils/cn";
6
- import { Themes } from "../utils/types";
7
-
8
- export interface ConclusionHeaderProps extends Omit<
9
- ButtonHTMLAttributes<HTMLButtonElement>,
10
- "onClick"
11
- > {
12
- /** The header text. */
13
- label: ReactNode;
14
- /** Controlled open state. Omit to let the header manage its own (uncontrolled). */
15
- open?: boolean;
16
- /** Initial open state when uncontrolled (default `true`). */
17
- defaultOpen?: boolean;
18
- /** Called with the next open state when the header is clicked. */
19
- onOpenChange?: (open: boolean) => void;
20
- /** Disabled — greys the label and shows a "Disabled" badge instead of the chevron. */
21
- disabled?: boolean;
22
- /** Badge text shown when `disabled` (default `"Disabled"`). */
23
- disabledLabel?: string;
24
- theme?: Themes;
25
- className?: string;
26
- }
27
-
28
- /**
29
- * `ConclusionHeader` — a clickable section header, per the "Conclusion-Header-2.0" design.
30
- *
31
- * The surfaces are **button overlays**, not an input field: at rest the label stands alone;
32
- * on hover the row gains a `Button/ContStyle-Hover` pill and the chevron a `Button/Secondary`
33
- * box. The chevron is hidden at rest while open, shows sideways when closed (left in LTR,
34
- * right in RTL), and flips to down on hover. When `disabled` the label greys out, truncates
35
- * at 120px, and a gray-subtle `Badge` replaces the chevron.
36
- *
37
- * Direction is inherited from the ambient `dir` — the RTL design variants are the LTR ones
38
- * mirrored, which the logical properties here produce automatically.
39
- *
40
- * Works controlled (`open` + `onOpenChange`) or uncontrolled.
41
- *
42
- * ```tsx
43
- * <ConclusionHeader label="Total" defaultOpen onOpenChange={setOpen} />
44
- * {open && <section>…</section>}
45
- * ```
46
- */
47
- export const ConclusionHeader = forwardRef<HTMLButtonElement, ConclusionHeaderProps>(
48
- (
49
- {
50
- label,
51
- open: openProp,
52
- defaultOpen = true,
53
- onOpenChange,
54
- disabled = false,
55
- disabledLabel = "Disabled",
56
- theme,
57
- className,
58
- ...props
59
- },
60
- ref,
61
- ) => {
62
- // Controlled when `open` is passed; otherwise manage state internally.
63
- const [internalOpen, setInternalOpen] = useState(defaultOpen);
64
- const open = openProp ?? internalOpen;
65
-
66
- const toggle = () => {
67
- if (disabled) return;
68
- if (openProp === undefined) setInternalOpen((o) => !o);
69
- onOpenChange?.(!open);
70
- };
71
-
72
- return (
73
- <button
74
- {...props}
75
- ref={ref}
76
- type="button"
77
- disabled={disabled}
78
- aria-expanded={disabled ? undefined : open}
79
- data-theme={theme}
80
- data-state={open ? "open" : "closed"}
81
- onClick={toggle}
82
- className={cn(
83
- // The hover surface is ONE full-width pill (design: 216×28, r6); the chevron box
84
- // sits flush inside its trailing end, 6px off the label.
85
- "group/collapsible flex h-[28px] w-full items-center gap-[6px] overflow-hidden rounded-[6px]",
86
- "transition-all duration-200 ease-in-out",
87
- "outline-none focus-visible:ring-1 focus-visible:ring-border-presentation-state-focus",
88
- disabled
89
- ? "cursor-not-allowed"
90
- : // Design insets the label by 4px once the pill appears.
91
- "cursor-pointer hover:bg-background-presentation-button-contstyle-hover hover:ps-[4px]",
92
- className,
93
- )}
94
- >
95
- {disabled ? (
96
- <>
97
- {/* Design: label shrinks to 120px and the badge sits right beside it, not at the end. */}
98
- <span
99
- className={cn(
100
- "max-w-[120px] shrink-0 truncate text-start",
101
- "typography-headers-medium-medium",
102
- "text-content-presentation-global-secondary",
103
- )}
104
- >
105
- {label}
106
- </span>
107
- <Badge label={disabledLabel} badgeStyle="subtle" color="gray" size="S" />
108
- </>
109
- ) : (
110
- <>
111
- <span
112
- className={cn(
113
- "min-w-0 flex-1 truncate text-start",
114
- // Design: En/Header/Medium/Medium — 18px / 510 / 132% / -0.18px.
115
- "typography-headers-medium-medium",
116
- "text-content-presentation-global-primary",
117
- )}
118
- >
119
- {label}
120
- </span>
121
-
122
- {/* Chevron — bare when closed at rest; gains a Button/Secondary box on hover. */}
123
- <span
124
- className={cn(
125
- "flex size-[28px] shrink-0 items-center justify-center rounded-[6px] p-[5px]",
126
- "text-content-presentation-global-primary",
127
- "transition-all duration-200 ease-in-out",
128
- "group-hover/collapsible:bg-background-presentation-button-secondary",
129
- // Hidden at rest while open; always visible when closed; hover reveals.
130
- open ? "opacity-0 group-hover/collapsible:opacity-100" : "opacity-100",
131
- )}
132
- >
133
- <i
134
- className={cn(
135
- "ri-arrow-down-s-line text-[18px] transition-transform duration-200 ease-in-out",
136
- // Down when open; sideways when closed (left LTR / right RTL); hover → down.
137
- !open && "ltr:rotate-90 rtl:-rotate-90 group-hover/collapsible:!rotate-0",
138
- )}
139
- />
140
- </span>
141
- </>
142
- )}
143
- </button>
144
- );
145
- },
146
- );
147
-
148
- ConclusionHeader.displayName = "ConclusionHeader";