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,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