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,854 +0,0 @@
1
- ---
2
- title: CNLayout
3
- description: Comprehensive dashboard layout system with sidebar navigation, header, and content areas.
4
- component: true
5
- group: Layout & Containers
6
- keywords: [layout, dashboard, sidebar, navigation, admin, panel]
7
- ---
8
-
9
- # CNLayout
10
-
11
- A complete layout system for building dashboard and admin panel interfaces. Features a flexible sidebar with icon buttons, navigation items, and footer, plus a styled content body with gradient effects.
12
-
13
- ## Installation
14
-
15
- TORCH Glare is a copy-in library: the CLI copies this component's source into your project
16
- (you do **not** install it from the npm package). Run `init` once, then `add`:
17
-
18
- ```bash
19
- npx torch-glare@latest init
20
- npx torch-glare@latest add CnLayout
21
- ```
22
-
23
- `add` also copies any components, hooks, and utilities that `CnLayout` depends on.
24
-
25
- ## Imports
26
-
27
- ```typescript
28
- import {
29
- Layout,
30
- Body,
31
- SideBar,
32
- SideBarItem,
33
- SideBarIconButton,
34
- SideBarFooterItem,
35
- SideBarChildContainer
36
- } from '@/layouts/CNLayout'
37
- ```
38
-
39
- ## Basic Usage
40
-
41
- ```tsx
42
- import { Layout, Body, SideBar, SideBarItem } from '@/layouts/CNLayout'
43
-
44
- export function BasicLayout() {
45
- return (
46
- <Layout>
47
- <SideBar
48
- headerChild={<Logo />}
49
- icon Buttons={
50
- <>
51
- <SideBarIconButton>
52
- <i className="ri-home-line"></i>
53
- </SideBarIconButton>
54
- </>
55
- }
56
- navigationChildren={[
57
- <SideBarItem>Dashboard</SideBarItem>,
58
- <SideBarItem>Settings</SideBarItem>,
59
- ]}
60
- />
61
-
62
- <Body>
63
- {/* Your page content */}
64
- </Body>
65
- </Layout>
66
- )
67
- }
68
- ```
69
-
70
- ## Examples
71
-
72
- ### Complete Dashboard Layout
73
-
74
- Full-featured dashboard with navigation and content.
75
-
76
- ```tsx
77
- export function DashboardLayout() {
78
- const [activeTab, setActiveTab] = useState('dashboard')
79
- const [activeSection, setActiveSection] = useState('overview')
80
-
81
- return (
82
- <Layout>
83
- <SideBar
84
- headerChild={
85
- <div className="text-xl font-bold">
86
- MyApp
87
- </div>
88
- }
89
- iconButtons={
90
- <>
91
- <SideBarIconButton
92
- active={activeTab === 'dashboard'}
93
- onClick={() => setActiveTab('dashboard')}
94
- message="Dashboard"
95
- >
96
- <i className="ri-dashboard-3-line"></i>
97
- </SideBarIconButton>
98
-
99
- <SideBarIconButton
100
- active={activeTab === 'projects'}
101
- onClick={() => setActiveTab('projects')}
102
- message="Projects"
103
- count={5}
104
- >
105
- <i className="ri-folder-line"></i>
106
- </SideBarIconButton>
107
-
108
- <SideBarIconButton
109
- active={activeTab === 'tasks'}
110
- onClick={() => setActiveTab('tasks')}
111
- message="Tasks"
112
- count={12}
113
- >
114
- <i className="ri-task-line"></i>
115
- </SideBarIconButton>
116
-
117
- <SideBarIconButton
118
- active={activeTab === 'messages'}
119
- onClick={() => setActiveTab('messages')}
120
- message="Messages"
121
- count={3}
122
- >
123
- <i className="ri-message-3-line"></i>
124
- </SideBarIconButton>
125
- </>
126
- }
127
- navigationChildren={[
128
- <SideBarItem
129
- active={activeSection === 'overview'}
130
- onClick={() => setActiveSection('overview')}
131
- >
132
- <i className="ri-pie-chart-line mr-2"></i>
133
- Overview
134
- </SideBarItem>,
135
-
136
- <SideBarItem
137
- active={activeSection === 'analytics'}
138
- onClick={() => setActiveSection('analytics')}
139
- >
140
- <i className="ri-line-chart-line mr-2"></i>
141
- Analytics
142
- </SideBarItem>,
143
-
144
- <SideBarItem
145
- active={activeSection === 'reports'}
146
- onClick={() => setActiveSection('reports')}
147
- >
148
- <i className="ri-file-chart-line mr-2"></i>
149
- Reports
150
- </SideBarItem>,
151
-
152
- <SideBarItem
153
- active={activeSection === 'team'}
154
- onClick={() => setActiveSection('team')}
155
- >
156
- <i className="ri-team-line mr-2"></i>
157
- Team
158
- </SideBarItem>,
159
- ]}
160
- footerChildren={
161
- <>
162
- <SideBarFooterItem>
163
- <i className="ri-settings-3-line mr-2"></i>
164
- Settings
165
- </SideBarFooterItem>
166
-
167
- <SideBarFooterItem>
168
- <i className="ri-question-line mr-2"></i>
169
- Help
170
- </SideBarFooterItem>
171
- </>
172
- }
173
- />
174
-
175
- <Body>
176
- <div className="p-6">
177
- {/* Dashboard content */}
178
- <h1 className="text-2xl font-bold mb-4">Dashboard</h1>
179
- {/* Content based on active section */}
180
- </div>
181
- </Body>
182
- </Layout>
183
- )
184
- }
185
- ```
186
-
187
- ### Admin Panel with Multi-Level Navigation
188
-
189
- Admin interface with grouped navigation sections.
190
-
191
- ```tsx
192
- export function AdminPanel() {
193
- const [activeModule, setActiveModule] = useState('users')
194
-
195
- const navigationSections = [
196
- {
197
- title: 'User Management',
198
- items: [
199
- { id: 'users', label: 'Users', icon: 'ri-user-line' },
200
- { id: 'roles', label: 'Roles', icon: 'ri-shield-user-line' },
201
- { id: 'permissions', label: 'Permissions', icon: 'ri-lock-line' },
202
- ]
203
- },
204
- {
205
- title: 'Content',
206
- items: [
207
- { id: 'posts', label: 'Posts', icon: 'ri-article-line' },
208
- { id: 'media', label: 'Media', icon: 'ri-image-line' },
209
- { id: 'categories', label: 'Categories', icon: 'ri-folder-line' },
210
- ]
211
- },
212
- {
213
- title: 'System',
214
- items: [
215
- { id: 'settings', label: 'Settings', icon: 'ri-settings-3-line' },
216
- { id: 'logs', label: 'Logs', icon: 'ri-file-list-line' },
217
- { id: 'backups', label: 'Backups', icon: 'ri-save-line' },
218
- ]
219
- },
220
- ]
221
-
222
- return (
223
- <Layout>
224
- <SideBar
225
- headerChild={
226
- <div className="flex items-center gap-2">
227
- <i className="ri-admin-line text-2xl"></i>
228
- <span className="font-bold">Admin</span>
229
- </div>
230
- }
231
- iconButtons={<></>}
232
- navigationChildren={navigationSections.flatMap(section => [
233
- <SideBarChildContainer key={section.title}>
234
- <div className="text-xs uppercase text-content-system-global-secondary px-2 mb-1">
235
- {section.title}
236
- </div>
237
- </SideBarChildContainer>,
238
- ...section.items.map(item => (
239
- <SideBarItem
240
- key={item.id}
241
- active={activeModule === item.id}
242
- onClick={() => setActiveModule(item.id)}
243
- >
244
- <i className={`${item.icon} mr-2`}></i>
245
- {item.label}
246
- </SideBarItem>
247
- ))
248
- ])}
249
- footerChildren={
250
- <SideBarFooterItem>
251
- <i className="ri-logout-box-line mr-2"></i>
252
- Sign Out
253
- </SideBarFooterItem>
254
- }
255
- />
256
-
257
- <Body>
258
- {/* Admin panel content */}
259
- </Body>
260
- </Layout>
261
- )
262
- }
263
- ```
264
-
265
- ### Custom Sidebar Content
266
-
267
- Using children prop for completely custom sidebar layout.
268
-
269
- ```tsx
270
- export function CustomSidebarLayout() {
271
- return (
272
- <Layout>
273
- <SideBar>
274
- <div className="w-full h-full flex flex-col">
275
- {/* Custom header */}
276
- <div className="h-[56px] bg-background-system-body-base flex items-center justify-center border-b">
277
- <img src="/logo.svg" alt="Logo" className="h-8" />
278
- </div>
279
-
280
- {/* Custom navigation */}
281
- <div className="flex-1 p-4 bg-background-system-body-base">
282
- <nav className="space-y-2">
283
- {/* Custom navigation structure */}
284
- <div className="font-semibold mb-2">Main Menu</div>
285
- <button className="w-full text-left p-2 rounded hover:bg-gray-100">
286
- Dashboard
287
- </button>
288
- <button className="w-full text-left p-2 rounded hover:bg-gray-100">
289
- Projects
290
- </button>
291
- </nav>
292
- </div>
293
-
294
- {/* Custom footer */}
295
- <div className="p-4 bg-background-system-body-base border-t">
296
- <div className="flex items-center gap-2">
297
- <img src="/avatar.jpg" className="w-8 h-8 rounded-full" />
298
- <div className="text-sm">
299
- <div className="font-medium">John Doe</div>
300
- <div className="text-gray-500">john@example.com</div>
301
- </div>
302
- </div>
303
- </div>
304
- </div>
305
- </SideBar>
306
-
307
- <Body>
308
- {/* Content */}
309
- </Body>
310
- </Layout>
311
- )
312
- }
313
- ```
314
-
315
- ### Icon-Only Sidebar
316
-
317
- Compact sidebar showing only icons.
318
-
319
- ```tsx
320
- export function CompactSidebar() {
321
- const [activeIcon, setActiveIcon] = useState('home')
322
-
323
- const icons = [
324
- { id: 'home', icon: 'ri-home-3-line', tooltip: 'Home' },
325
- { id: 'search', icon: 'ri-search-line', tooltip: 'Search' },
326
- { id: 'notifications', icon: 'ri-notification-3-line', tooltip: 'Notifications', count: 5 },
327
- { id: 'messages', icon: 'ri-message-3-line', tooltip: 'Messages', count: 2 },
328
- { id: 'settings', icon: 'ri-settings-3-line', tooltip: 'Settings' },
329
- ]
330
-
331
- return (
332
- <Layout>
333
- <SideBar
334
- className="!w-[58px]"
335
- iconButtons={
336
- <>
337
- {icons.map(item => (
338
- <SideBarIconButton
339
- key={item.id}
340
- active={activeIcon === item.id}
341
- onClick={() => setActiveIcon(item.id)}
342
- message={item.tooltip}
343
- count={item.count}
344
- >
345
- <i className={item.icon}></i>
346
- </SideBarIconButton>
347
- ))}
348
- </>
349
- }
350
- navigationChildren={[
351
- <SideBarItem iconOnly>
352
- <i className="ri-user-line"></i>
353
- </SideBarItem>,
354
- <SideBarItem iconOnly>
355
- <i className="ri-folder-line"></i>
356
- </SideBarItem>,
357
- ]}
358
- />
359
-
360
- <Body>
361
- {/* Content */}
362
- </Body>
363
- </Layout>
364
- )
365
- }
366
- ```
367
-
368
- ### Multi-Tab Application
369
-
370
- Application with tab switching and persistent sidebar.
371
-
372
- ```tsx
373
- export function MultiTabApp() {
374
- const [activeWorkspace, setActiveWorkspace] = useState('work')
375
- const [activeView, setActiveView] = useState('list')
376
-
377
- const workspaces = [
378
- { id: 'work', icon: 'ri-briefcase-line', label: 'Work', count: 12 },
379
- { id: 'personal', icon: 'ri-user-line', label: 'Personal', count: 5 },
380
- { id: 'shared', icon: 'ri-group-line', label: 'Shared', count: 3 },
381
- ]
382
-
383
- return (
384
- <Layout>
385
- <SideBar
386
- headerChild={
387
- <select
388
- value={activeWorkspace}
389
- onChange={(e) => setActiveWorkspace(e.target.value)}
390
- className="w-full px-2 py-1 rounded border"
391
- >
392
- {workspaces.map(ws => (
393
- <option key={ws.id} value={ws.id}>
394
- {ws.label} ({ws.count})
395
- </option>
396
- ))}
397
- </select>
398
- }
399
- iconButtons={
400
- <>
401
- <SideBarIconButton
402
- active={activeView === 'list'}
403
- onClick={() => setActiveView('list')}
404
- message="List View"
405
- >
406
- <i className="ri-list-check"></i>
407
- </SideBarIconButton>
408
-
409
- <SideBarIconButton
410
- active={activeView === 'board'}
411
- onClick={() => setActiveView('board')}
412
- message="Board View"
413
- >
414
- <i className="ri-layout-grid-line"></i>
415
- </SideBarIconButton>
416
-
417
- <SideBarIconButton
418
- active={activeView === 'calendar'}
419
- onClick={() => setActiveView('calendar')}
420
- message="Calendar View"
421
- >
422
- <i className="ri-calendar-line"></i>
423
- </SideBarIconButton>
424
- </>
425
- }
426
- navigationChildren={[
427
- <SideBarItem>All Tasks</SideBarItem>,
428
- <SideBarItem>In Progress</SideBarItem>,
429
- <SideBarItem>Completed</SideBarItem>,
430
- ]}
431
- footerChildren={
432
- <SideBarFooterItem>
433
- <i className="ri-add-line mr-2"></i>
434
- New Task
435
- </SideBarFooterItem>
436
- }
437
- />
438
-
439
- <Body>
440
- {/* Render view based on activeView */}
441
- </Body>
442
- </Layout>
443
- )
444
- }
445
- ```
446
-
447
- ### Sidebar with Variants
448
-
449
- Using variant prop for different color schemes.
450
-
451
- ```tsx
452
- export function VariantSidebar() {
453
- return (
454
- <Layout>
455
- <SideBar
456
- iconButtons={
457
- <>
458
- <SideBarIconButton variant="secondary">
459
- <i className="ri-home-line"></i>
460
- </SideBarIconButton>
461
- </>
462
- }
463
- navigationChildren={[
464
- <SideBarItem variant="secondary">
465
- Dashboard
466
- </SideBarItem>,
467
- <SideBarItem variant="secondary" active>
468
- Analytics
469
- </SideBarItem>,
470
- ]}
471
- footerChildren={
472
- <SideBarFooterItem variant="secondary">
473
- Settings
474
- </SideBarFooterItem>
475
- }
476
- />
477
-
478
- <Body>
479
- {/* Content */}
480
- </Body>
481
- </Layout>
482
- )
483
- }
484
- ```
485
-
486
- ### Disabled Items
487
-
488
- Showing disabled navigation items.
489
-
490
- ```tsx
491
- export function DisabledItems() {
492
- return (
493
- <Layout>
494
- <SideBar
495
- iconButtons={<></>}
496
- navigationChildren={[
497
- <SideBarItem>Available Feature</SideBarItem>,
498
- <SideBarItem disabled>
499
- <i className="ri-lock-line mr-2"></i>
500
- Premium Feature
501
- </SideBarItem>,
502
- <SideBarItem disabled>
503
- <i className="ri-lock-line mr-2"></i>
504
- Coming Soon
505
- </SideBarItem>,
506
- ]}
507
- />
508
-
509
- <Body>
510
- {/* Content */}
511
- </Body>
512
- </Layout>
513
- )
514
- }
515
- ```
516
-
517
- ### With Router Integration
518
-
519
- Using CNLayout with React Router.
520
-
521
- ```tsx
522
- import { NavLink } from 'react-router-dom'
523
-
524
- export function RouterLayout() {
525
- return (
526
- <Layout>
527
- <SideBar
528
- headerChild={<Logo />}
529
- iconButtons={<></>}
530
- navigationChildren={[
531
- <NavLink to="/" style={{ textDecoration: 'none' }}>
532
- {({ isActive }) => (
533
- <SideBarItem active={isActive}>
534
- <i className="ri-home-line mr-2"></i>
535
- Home
536
- </SideBarItem>
537
- )}
538
- </NavLink>,
539
-
540
- <NavLink to="/dashboard" style={{ textDecoration: 'none' }}>
541
- {({ isActive }) => (
542
- <SideBarItem active={isActive}>
543
- <i className="ri-dashboard-line mr-2"></i>
544
- Dashboard
545
- </SideBarItem>
546
- )}
547
- </NavLink>,
548
-
549
- <NavLink to="/settings" style={{ textDecoration: 'none' }}>
550
- {({ isActive }) => (
551
- <SideBarItem active={isActive}>
552
- <i className="ri-settings-line mr-2"></i>
553
- Settings
554
- </SideBarItem>
555
- )}
556
- </NavLink>,
557
- ]}
558
- />
559
-
560
- <Body>
561
- <Outlet /> {/* React Router outlet */}
562
- </Body>
563
- </Layout>
564
- )
565
- }
566
- ```
567
-
568
- ## API Reference
569
-
570
- ### Layout Props
571
-
572
- | Prop | Type | Default | Description |
573
- |------|------|---------|-------------|
574
- | children | `ReactNode` | - | Sidebar and Body components |
575
- | className | `string` | - | Additional CSS classes |
576
-
577
- ### Body Props
578
-
579
- | Prop | Type | Default | Description |
580
- |------|------|---------|-------------|
581
- | children | `ReactNode` | - | Page content |
582
- | className | `string` | - | Additional CSS classes |
583
-
584
- ### SideBar Props
585
-
586
- | Prop | Type | Default | Description |
587
- |------|------|---------|-------------|
588
- | headerChild | `ReactNode` | - | Header content (logo, title) |
589
- | iconButtons | `ReactNode` | - | Icon buttons column |
590
- | navigationChildren | `ReactNode \| ReactNode[]` | - | Navigation items |
591
- | footerChildren | `ReactNode` | - | Footer content |
592
- | children | `ReactNode` | - | Custom sidebar content (overrides other props) |
593
- | className | `string` | - | Additional CSS classes |
594
-
595
- ### SideBarItem Props
596
-
597
- | Prop | Type | Default | Description |
598
- |------|------|---------|-------------|
599
- | active | `boolean` | `false` | Active/selected state |
600
- | disabled | `boolean` | `false` | Disabled state |
601
- | iconOnly | `boolean` | `false` | Icon-only display mode |
602
- | variant | `'default' \| 'secondary'` | `'default'` | Visual variant |
603
- | theme | `Themes` | - | Theme override |
604
- | asChild | `boolean` | `false` | Merge props with child |
605
- | as | `React.ElementType` | `'span'` | Element type |
606
- | className | `string` | - | Additional CSS classes |
607
- | children | `ReactNode` | - | Item content |
608
- | onClick | `() => void` | - | Click handler |
609
-
610
- ### SideBarIconButton Props
611
-
612
- | Prop | Type | Default | Description |
613
- |------|------|---------|-------------|
614
- | active | `boolean` | `false` | Active state |
615
- | count | `number` | - | Badge count |
616
- | message | `ReactNode` | - | Tooltip message |
617
- | disabled | `boolean` | `false` | Disabled state |
618
- | variant | `'default' \| 'secondary'` | `'default'` | Visual variant |
619
- | theme | `Themes` | - | Theme override |
620
- | asChild | `boolean` | `false` | Merge props with child |
621
- | as | `React.ElementType` | `'button'` | Element type |
622
- | className | `string` | - | Additional CSS classes |
623
- | children | `ReactNode` | - | Icon content |
624
- | onClick | `() => void` | - | Click handler |
625
-
626
- ### SideBarFooterItem Props
627
-
628
- | Prop | Type | Default | Description |
629
- |------|------|---------|-------------|
630
- | variant | `'primary' \| 'secondary'` | `'primary'` | Visual variant |
631
- | theme | `Themes` | - | Theme override |
632
- | asChild | `boolean` | `false` | Merge props with child |
633
- | as | `React.ElementType` | `'button'` | Element type |
634
- | className | `string` | - | Additional CSS classes |
635
- | children | `ReactNode` | - | Footer item content |
636
- | onClick | `() => void` | - | Click handler |
637
-
638
- ### SideBarChildContainer Props
639
-
640
- | Prop | Type | Default | Description |
641
- |------|------|---------|-------------|
642
- | theme | `Themes` | - | Theme override |
643
- | className | `string` | - | Additional CSS classes |
644
- | children | `ReactNode` | - | Container content |
645
-
646
- ## Styling
647
-
648
- ### Layout Structure
649
-
650
- - **Full Height**: 100dvh viewport height
651
- - **Responsive Gap**: 10px gap on large screens
652
- - **Base Background**: System body base color
653
- - **Padding**: 16px on large screens
654
-
655
- ### Body Styling
656
-
657
- - **Gradient Border**: Blue sparkle gradient effect
658
- - **Shadow**: Pronounced shadow for depth
659
- - **Rounded Corners**: 12px border radius
660
- - **Top Accent**: Decorative gradient at top-left
661
- - **Scrollable**: Hidden scrollbar with overflow
662
-
663
- ### Sidebar Dimensions
664
-
665
- - **Default Width**: 265px
666
- - **Header Height**: 56px
667
- - **Icon Column**: 46px width
668
- - **Hidden on Mobile**: Only visible on lg breakpoint
669
-
670
- ### Navigation Item Animations
671
-
672
- - **Padding Transition**: Animates from 8px to 14px on hover
673
- - **Border**: 2px left border (or right in RTL)
674
- - **Duration**: 150ms ease-in-out
675
-
676
- ## TypeScript Types
677
-
678
- ```typescript
679
- interface LayoutProps extends HTMLAttributes<HTMLDivElement> {}
680
-
681
- interface ContentProps extends HTMLAttributes<HTMLDivElement> {}
682
-
683
- interface SideBarProps extends HTMLAttributes<HTMLDivElement> {
684
- iconButtons?: ReactNode
685
- headerChild?: ReactNode
686
- navigationChildren?: ReactNode | ReactNode[]
687
- footerChildren?: ReactNode
688
- children?: ReactNode
689
- }
690
-
691
- interface SideBarItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {
692
- asChild?: boolean
693
- as?: React.ElementType
694
- theme?: Themes
695
- variant?: 'default' | 'secondary'
696
- iconOnly?: boolean
697
- active?: boolean
698
- disabled?: boolean
699
- }
700
-
701
- interface SideBarIconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
702
- asChild?: boolean
703
- as?: React.ElementType
704
- theme?: Themes
705
- variant?: 'default' | 'secondary'
706
- active?: boolean
707
- count?: number
708
- message?: ReactNode
709
- disabled?: boolean
710
- }
711
-
712
- interface SideBarFooterItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {
713
- theme?: Themes
714
- as?: React.ElementType
715
- asChild?: boolean
716
- variant?: 'primary' | 'secondary'
717
- }
718
-
719
- interface SideBarChildContainerProps extends HTMLAttributes<HTMLDivElement> {
720
- theme?: Themes
721
- }
722
- ```
723
-
724
- ## Common Patterns
725
-
726
- ### Collapsible Sidebar
727
-
728
- ```tsx
729
- function CollapsibleLayout() {
730
- const [collapsed, setCollapsed] = useState(false)
731
-
732
- return (
733
- <Layout>
734
- <SideBar className={cn(collapsed && "!w-[58px]")}>
735
- {/* Collapsed sidebar content */}
736
- </SideBar>
737
-
738
- <Body>
739
- <button onClick={() => setCollapsed(!collapsed)}>
740
- <i className={`ri-arrow-${collapsed ? 'right' : 'left'}-s-line`}></i>
741
- </button>
742
- {/* Content */}
743
- </Body>
744
- </Layout>
745
- )
746
- }
747
- ```
748
-
749
- ### Dynamic Navigation
750
-
751
- ```tsx
752
- function DynamicNavigation({ items, activeId, onSelect }) {
753
- return (
754
- <SideBar
755
- navigationChildren={items.map(item => (
756
- <SideBarItem
757
- key={item.id}
758
- active={activeId === item.id}
759
- onClick={() => onSelect(item.id)}
760
- disabled={item.disabled}
761
- >
762
- {item.icon && <i className={`${item.icon} mr-2`}></i>}
763
- {item.label}
764
- {item.badge && (
765
- <span className="ml-auto">{item.badge}</span>
766
- )}
767
- </SideBarItem>
768
- ))}
769
- />
770
- )
771
- }
772
- ```
773
-
774
- ## Testing
775
-
776
- ```typescript
777
- import { render, screen, fireEvent } from '@testing-library/react'
778
- import { Layout, Body, SideBar, SideBarItem } from '@/layouts/CNLayout'
779
-
780
- describe('CNLayout', () => {
781
- it('renders layout structure', () => {
782
- render(
783
- <Layout>
784
- <SideBar navigationChildren={[]} />
785
- <Body>Content</Body>
786
- </Layout>
787
- )
788
-
789
- expect(screen.getByText('Content')).toBeInTheDocument()
790
- })
791
-
792
- it('handles navigation clicks', () => {
793
- const handleClick = jest.fn()
794
-
795
- render(
796
- <SideBar
797
- navigationChildren={[
798
- <SideBarItem onClick={handleClick}>
799
- Dashboard
800
- </SideBarItem>
801
- ]}
802
- />
803
- )
804
-
805
- fireEvent.click(screen.getByText('Dashboard'))
806
- expect(handleClick).toHaveBeenCalled()
807
- })
808
-
809
- it('shows active state', () => {
810
- render(
811
- <SideBarItem active>Active Item</SideBarItem>
812
- )
813
-
814
- const item = screen.getByText('Active Item')
815
- expect(item).toHaveClass('bg-background-system-action-primary-hover')
816
- })
817
-
818
- it('displays badge count', () => {
819
- render(
820
- <SideBarIconButton count={5}>
821
- <i className="ri-notification-line"></i>
822
- </SideBarIconButton>
823
- )
824
-
825
- expect(screen.getByText('5')).toBeInTheDocument()
826
- })
827
- })
828
- ```
829
-
830
- ## Accessibility
831
-
832
- - **Semantic HTML**: Uses aside, main, nav elements
833
- - **Keyboard Navigation**: Full keyboard support
834
- - **Focus Management**: Proper focus indicators
835
- - **Screen Reader Support**: Meaningful labels and structure
836
- - **ARIA Attributes**: Supports all standard ARIA props
837
- - **Tooltips**: Icon buttons include tooltips via message prop
838
-
839
- ## Performance
840
-
841
- - **CSS Grid**: Efficient layout with CSS Grid
842
- - **Hardware Acceleration**: GPU-accelerated transitions
843
- - **Minimal Re-renders**: Optimized component structure
844
- - **Hidden Scrollbars**: Custom scrollbar styling
845
-
846
- ## Best Practices
847
-
848
- 1. **Consistent Navigation**: Keep navigation structure predictable
849
- 2. **Active States**: Always indicate the current location
850
- 3. **Icon Consistency**: Use consistent icon sizes and styles
851
- 4. **Mobile Responsive**: Consider mobile layout alternatives
852
- 5. **Loading States**: Show loading indicators for async navigation
853
- 6. **Error Boundaries**: Wrap layout in error boundaries
854
- 7. **Badge Counts**: Use badges sparingly for important notifications