torch-glare 2.5.6 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/bin/index.js +9 -24
- package/dist/bin/index.js.map +1 -1
- package/dist/src/commands/add.d.ts +2 -2
- package/dist/src/commands/add.d.ts.map +1 -1
- package/dist/src/commands/add.js +4 -70
- package/dist/src/commands/add.js.map +1 -1
- package/dist/src/commands/hook.d.ts +5 -4
- package/dist/src/commands/hook.d.ts.map +1 -1
- package/dist/src/commands/hook.js +7 -75
- package/dist/src/commands/hook.js.map +1 -1
- package/dist/src/commands/init.js +1 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/layout.d.ts +5 -4
- package/dist/src/commands/layout.d.ts.map +1 -1
- package/dist/src/commands/layout.js +7 -75
- package/dist/src/commands/layout.js.map +1 -1
- package/dist/src/commands/provider.d.ts +5 -4
- package/dist/src/commands/provider.d.ts.map +1 -1
- package/dist/src/commands/provider.js +7 -75
- package/dist/src/commands/provider.js.map +1 -1
- package/dist/src/commands/update.d.ts.map +1 -1
- package/dist/src/commands/update.js +78 -43
- package/dist/src/commands/update.js.map +1 -1
- package/dist/src/commands/utils.d.ts +5 -4
- package/dist/src/commands/utils.d.ts.map +1 -1
- package/dist/src/commands/utils.js +7 -80
- package/dist/src/commands/utils.js.map +1 -1
- package/dist/src/shared/addFromRegistry.d.ts +16 -0
- package/dist/src/shared/addFromRegistry.d.ts.map +1 -0
- package/dist/src/shared/addFromRegistry.js +88 -0
- package/dist/src/shared/addFromRegistry.js.map +1 -0
- package/dist/src/shared/getInstallCommand.d.ts.map +1 -1
- package/dist/src/shared/getInstallCommand.js +5 -0
- package/dist/src/shared/getInstallCommand.js.map +1 -1
- package/dist/src/shared/installDependencies.d.ts +0 -10
- package/dist/src/shared/installDependencies.d.ts.map +1 -1
- package/dist/src/shared/installDependencies.js +0 -17
- package/dist/src/shared/installDependencies.js.map +1 -1
- package/dist/src/shared/installFromPlan.d.ts +7 -5
- package/dist/src/shared/installFromPlan.d.ts.map +1 -1
- package/dist/src/shared/installFromPlan.js +103 -36
- package/dist/src/shared/installFromPlan.js.map +1 -1
- package/dist/src/shared/loadRegistry.d.ts +12 -3
- package/dist/src/shared/loadRegistry.d.ts.map +1 -1
- package/dist/src/shared/loadRegistry.js +19 -20
- package/dist/src/shared/loadRegistry.js.map +1 -1
- package/dist/src/shared/registryClient.d.ts +19 -0
- package/dist/src/shared/registryClient.d.ts.map +1 -0
- package/dist/src/shared/registryClient.js +128 -0
- package/dist/src/shared/registryClient.js.map +1 -0
- package/dist/src/shared/resolveEntry.d.ts +10 -7
- package/dist/src/shared/resolveEntry.d.ts.map +1 -1
- package/dist/src/shared/resolveEntry.js +18 -13
- package/dist/src/shared/resolveEntry.js.map +1 -1
- package/dist/src/shared/suggestOtherCommand.d.ts +7 -1
- package/dist/src/shared/suggestOtherCommand.d.ts.map +1 -1
- package/dist/src/shared/suggestOtherCommand.js +29 -23
- package/dist/src/shared/suggestOtherCommand.js.map +1 -1
- package/dist/src/types/main.d.ts +31 -2
- package/dist/src/types/main.d.ts.map +1 -1
- package/package.json +6 -11
- package/apps/lib/components/ActionButton.tsx +0 -93
- package/apps/lib/components/ActionsGroup.tsx +0 -27
- package/apps/lib/components/AlertDialog.tsx +0 -204
- package/apps/lib/components/Avatar.tsx +0 -46
- package/apps/lib/components/Badge.tsx +0 -250
- package/apps/lib/components/BadgeField.tsx +0 -403
- package/apps/lib/components/Breadcrumb.tsx +0 -280
- package/apps/lib/components/Button.tsx +0 -325
- package/apps/lib/components/ButtonGroup.tsx +0 -190
- package/apps/lib/components/Calendar.tsx +0 -115
- package/apps/lib/components/Card.tsx +0 -95
- package/apps/lib/components/Checkbox.tsx +0 -42
- package/apps/lib/components/ColorPicker.tsx +0 -441
- package/apps/lib/components/ConclusionHeader.tsx +0 -148
- package/apps/lib/components/ContextMenu.tsx +0 -571
- package/apps/lib/components/CountBadge.tsx +0 -52
- package/apps/lib/components/DataTable.tsx +0 -213
- package/apps/lib/components/DataViews/badge.ts +0 -49
- package/apps/lib/components/DataViews/cell.tsx +0 -324
- package/apps/lib/components/DataViews/context.ts +0 -144
- package/apps/lib/components/DataViews/data-views.tsx +0 -395
- package/apps/lib/components/DataViews/filters/children.tsx +0 -98
- package/apps/lib/components/DataViews/filters/custom.tsx +0 -34
- package/apps/lib/components/DataViews/filters/filters.tsx +0 -157
- package/apps/lib/components/DataViews/filters/index.ts +0 -4
- package/apps/lib/components/DataViews/filters/labelled.tsx +0 -20
- package/apps/lib/components/DataViews/filters/presets.tsx +0 -65
- package/apps/lib/components/DataViews/filters/sync.tsx +0 -35
- package/apps/lib/components/DataViews/filters/values.ts +0 -173
- package/apps/lib/components/DataViews/header.tsx +0 -220
- package/apps/lib/components/DataViews/hooks/index.ts +0 -5
- package/apps/lib/components/DataViews/hooks/useActiveRow.ts +0 -22
- package/apps/lib/components/DataViews/hooks/useControllable.ts +0 -52
- package/apps/lib/components/DataViews/index.ts +0 -88
- package/apps/lib/components/DataViews/panel/columns.tsx +0 -153
- package/apps/lib/components/DataViews/panel/controls.tsx +0 -106
- package/apps/lib/components/DataViews/panel/index.ts +0 -3
- package/apps/lib/components/DataViews/panel/panel.tsx +0 -164
- package/apps/lib/components/DataViews/panel/saved-views.tsx +0 -67
- package/apps/lib/components/DataViews/panel/section.tsx +0 -81
- package/apps/lib/components/DataViews/panel/sort.tsx +0 -42
- package/apps/lib/components/DataViews/panel/tab.tsx +0 -31
- package/apps/lib/components/DataViews/slots.ts +0 -72
- package/apps/lib/components/DataViews/states.tsx +0 -73
- package/apps/lib/components/DataViews/types.ts +0 -510
- package/apps/lib/components/DataViews/views/board-view.tsx +0 -381
- package/apps/lib/components/DataViews/views/card-rows.tsx +0 -36
- package/apps/lib/components/DataViews/views/inbox-view.tsx +0 -260
- package/apps/lib/components/DataViews/views/pane-views.tsx +0 -196
- package/apps/lib/components/DataViews/views/table-view.tsx +0 -493
- package/apps/lib/components/DataViews/views/tree-view.tsx +0 -367
- package/apps/lib/components/DatePicker.tsx +0 -232
- package/apps/lib/components/Dialog.tsx +0 -116
- package/apps/lib/components/Divider.tsx +0 -28
- package/apps/lib/components/Drawer.tsx +0 -451
- package/apps/lib/components/DropdownMenu.tsx +0 -554
- package/apps/lib/components/FieldHint.tsx +0 -69
- package/apps/lib/components/Form.tsx +0 -182
- package/apps/lib/components/FormBuilder/context.ts +0 -85
- package/apps/lib/components/FormBuilder/field-kind.ts +0 -28
- package/apps/lib/components/FormBuilder/fields/ChoiceFields.tsx +0 -60
- package/apps/lib/components/FormBuilder/fields/ColorField.tsx +0 -59
- package/apps/lib/components/FormBuilder/fields/CustomField.tsx +0 -11
- package/apps/lib/components/FormBuilder/fields/DateField.tsx +0 -32
- package/apps/lib/components/FormBuilder/fields/FieldArray.tsx +0 -74
- package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +0 -168
- package/apps/lib/components/FormBuilder/fields/FileField.tsx +0 -39
- package/apps/lib/components/FormBuilder/fields/OptionListFields.tsx +0 -132
- package/apps/lib/components/FormBuilder/fields/OtpField.tsx +0 -31
- package/apps/lib/components/FormBuilder/fields/PhoneField.tsx +0 -109
- package/apps/lib/components/FormBuilder/fields/RichTextEditorField.tsx +0 -31
- package/apps/lib/components/FormBuilder/fields/SelectField.tsx +0 -114
- package/apps/lib/components/FormBuilder/fields/SignatureField.tsx +0 -157
- package/apps/lib/components/FormBuilder/fields/SliderField.tsx +0 -67
- package/apps/lib/components/FormBuilder/fields/SwitchBoxField.tsx +0 -41
- package/apps/lib/components/FormBuilder/fields/TableField.tsx +0 -336
- package/apps/lib/components/FormBuilder/fields/TextField.tsx +0 -213
- package/apps/lib/components/FormBuilder/fields/TreeSelectField.tsx +0 -43
- package/apps/lib/components/FormBuilder/fields/countries.ts +0 -303
- package/apps/lib/components/FormBuilder/fields/index.ts +0 -25
- package/apps/lib/components/FormBuilder/form-builder.tsx +0 -198
- package/apps/lib/components/FormBuilder/index.ts +0 -31
- package/apps/lib/components/FormBuilder/numberFormat.ts +0 -16
- package/apps/lib/components/FormBuilder/submit.tsx +0 -67
- package/apps/lib/components/FormBuilder/types.ts +0 -316
- package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -250
- package/apps/lib/components/FormRenderer/detail.tsx +0 -256
- package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -358
- package/apps/lib/components/FormRenderer/header.tsx +0 -88
- package/apps/lib/components/FormRenderer/index.ts +0 -17
- package/apps/lib/components/FormRenderer/notch-action.tsx +0 -64
- package/apps/lib/components/FormRenderer/section.tsx +0 -39
- package/apps/lib/components/FormRenderer/stepper.tsx +0 -393
- package/apps/lib/components/FormRenderer/types.ts +0 -115
- package/apps/lib/components/FormSummary.tsx +0 -282
- package/apps/lib/components/HeaderBar.tsx +0 -117
- package/apps/lib/components/ImageAttachment.tsx +0 -209
- package/apps/lib/components/InnerLabelField.tsx +0 -154
- package/apps/lib/components/Input.tsx +0 -224
- package/apps/lib/components/InputField.tsx +0 -147
- package/apps/lib/components/InputOTP.tsx +0 -84
- package/apps/lib/components/Label.tsx +0 -129
- package/apps/lib/components/LabelField.tsx +0 -76
- package/apps/lib/components/LabeledCheckBox.tsx +0 -51
- package/apps/lib/components/LabeledRadio.tsx +0 -51
- package/apps/lib/components/LinkButton.tsx +0 -94
- package/apps/lib/components/LoginButton.tsx +0 -51
- package/apps/lib/components/PasswordLevel.tsx +0 -58
- package/apps/lib/components/Popover.tsx +0 -312
- package/apps/lib/components/ProfileMenu.tsx +0 -85
- package/apps/lib/components/Radio.tsx +0 -59
- package/apps/lib/components/RadioCard.tsx +0 -50
- package/apps/lib/components/ScrollArea.tsx +0 -54
- package/apps/lib/components/SearchField.tsx +0 -62
- package/apps/lib/components/SearchableSelect.tsx +0 -318
- package/apps/lib/components/SearchableTable.tsx +0 -344
- package/apps/lib/components/SearchableTree.tsx +0 -485
- package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
- package/apps/lib/components/SectionBlock.tsx +0 -168
- package/apps/lib/components/Select.tsx +0 -347
- package/apps/lib/components/SimpleSelect.tsx +0 -225
- package/apps/lib/components/Skeleton.tsx +0 -12
- package/apps/lib/components/SlideDatePicker.tsx +0 -255
- package/apps/lib/components/SpinLoading.tsx +0 -174
- package/apps/lib/components/Stepper.tsx +0 -480
- package/apps/lib/components/Switch.tsx +0 -82
- package/apps/lib/components/TabFormItem.tsx +0 -153
- package/apps/lib/components/TabSwitch.tsx +0 -172
- package/apps/lib/components/Table.tsx +0 -597
- package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
- package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
- package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
- package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
- package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
- package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
- package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
- package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
- package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
- package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
- package/apps/lib/components/TextEditor/index.ts +0 -7
- package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
- package/apps/lib/components/Textarea.tsx +0 -117
- package/apps/lib/components/Timeline.tsx +0 -263
- package/apps/lib/components/Toast.tsx +0 -87
- package/apps/lib/components/Toggle.tsx +0 -125
- package/apps/lib/components/ToggleButton.tsx +0 -140
- package/apps/lib/components/Tooltip.tsx +0 -116
- package/apps/lib/components/TransparentLabel.tsx +0 -71
- package/apps/lib/components/TreeDropDown.tsx +0 -115
- package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
- package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
- package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
- package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
- package/apps/lib/components/TreeFolder/icons.tsx +0 -60
- package/apps/lib/components/TreeFolder/index.ts +0 -24
- package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
- package/apps/lib/components/TreeFolder/types.ts +0 -77
- package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
- package/apps/lib/hooks/useActiveTreeItem.ts +0 -61
- package/apps/lib/hooks/useClickOutside.ts +0 -27
- package/apps/lib/hooks/useDragDrop.tsx +0 -365
- package/apps/lib/hooks/useHtmlDir.ts +0 -31
- package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
- package/apps/lib/hooks/useIsMobile.ts +0 -21
- package/apps/lib/hooks/useResize.ts +0 -67
- package/apps/lib/hooks/useTagSelection.ts +0 -300
- package/apps/lib/layouts/CNLayout.tsx +0 -372
- package/apps/lib/layouts/DataViewCard.tsx +0 -62
- package/apps/lib/layouts/FieldSection.tsx +0 -91
- package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
- package/apps/lib/providers/ThemeProvider.tsx +0 -84
- package/apps/lib/registry.json +0 -1217
- package/apps/lib/tsconfig.json +0 -9
- package/apps/lib/tsconfig.tsbuildinfo +0 -1
- package/apps/lib/utils/cn.ts +0 -6
- package/apps/lib/utils/color.ts +0 -175
- package/apps/lib/utils/dataViews/path.ts +0 -67
- package/apps/lib/utils/dataViews/query.ts +0 -73
- package/apps/lib/utils/dataViews/types.ts +0 -187
- package/apps/lib/utils/dateFormat.ts +0 -108
- package/apps/lib/utils/resize.ts +0 -31
- package/apps/lib/utils/scroller.ts +0 -26
- package/apps/lib/utils/types.ts +0 -16
- package/docs/BLOCKS.md +0 -129
- package/docs/CHANGELOG-1.1.16.md +0 -108
- package/docs/Cover.png +0 -0
- package/docs/README.md +0 -215
- package/docs/components/action-button.md +0 -638
- package/docs/components/actions-group.md +0 -708
- package/docs/components/alert-dialog.md +0 -920
- package/docs/components/avatar.md +0 -709
- package/docs/components/badge-field.md +0 -738
- package/docs/components/badge.md +0 -301
- package/docs/components/breadcrumb.md +0 -930
- package/docs/components/button-group.md +0 -650
- package/docs/components/button.md +0 -639
- package/docs/components/calendar.md +0 -555
- package/docs/components/card.md +0 -622
- package/docs/components/chart-block-tool.md +0 -129
- package/docs/components/checkbox.md +0 -699
- package/docs/components/cn-layout.md +0 -854
- package/docs/components/color-picker.md +0 -101
- package/docs/components/conclusion-header.md +0 -80
- package/docs/components/context-menu.md +0 -483
- package/docs/components/count-badge.md +0 -560
- package/docs/components/data-table.md +0 -854
- package/docs/components/data-views/backend-response.md +0 -324
- package/docs/components/data-views/examples/a11y-rtl.md +0 -250
- package/docs/components/data-views/examples/api-orders-route.md +0 -130
- package/docs/components/data-views/examples/fields.md +0 -362
- package/docs/components/data-views/examples/filters.md +0 -307
- package/docs/components/data-views/examples/inbox-routing.md +0 -218
- package/docs/components/data-views/examples/index.md +0 -29
- package/docs/components/data-views/examples/overview.md +0 -244
- package/docs/components/data-views/examples/panel.md +0 -212
- package/docs/components/data-views/examples/scale.md +0 -231
- package/docs/components/data-views/examples/server-side.md +0 -210
- package/docs/components/data-views/examples/state.md +0 -250
- package/docs/components/data-views/examples/tree-custom.md +0 -388
- package/docs/components/data-views/examples/view-registry.md +0 -313
- package/docs/components/data-views/examples/views.md +0 -534
- package/docs/components/data-views/guide.md +0 -405
- package/docs/components/data-views/index.md +0 -1521
- package/docs/components/data-views/migration.md +0 -81
- package/docs/components/date-picker.md +0 -857
- package/docs/components/dialog.md +0 -929
- package/docs/components/divider.md +0 -766
- package/docs/components/drawer.md +0 -654
- package/docs/components/dropdown-menu.md +0 -668
- package/docs/components/field-hint.md +0 -898
- package/docs/components/field-section.md +0 -781
- package/docs/components/form-builder.md +0 -284
- package/docs/components/form-renderer.md +0 -396
- package/docs/components/form-summary.md +0 -138
- package/docs/components/form.md +0 -785
- package/docs/components/header-bar.md +0 -188
- package/docs/components/image-attachment.md +0 -906
- package/docs/components/inner-label-field.md +0 -819
- package/docs/components/input-field.md +0 -623
- package/docs/components/input-otp.md +0 -756
- package/docs/components/input.md +0 -634
- package/docs/components/label-field.md +0 -770
- package/docs/components/label.md +0 -761
- package/docs/components/labeled-check-box.md +0 -642
- package/docs/components/labeled-radio.md +0 -796
- package/docs/components/link-button.md +0 -685
- package/docs/components/login-button.md +0 -872
- package/docs/components/password-level.md +0 -803
- package/docs/components/popover.md +0 -649
- package/docs/components/profile-menu.md +0 -656
- package/docs/components/radio-card.md +0 -801
- package/docs/components/radio.md +0 -735
- package/docs/components/scroll-area.md +0 -691
- package/docs/components/search-field.md +0 -702
- package/docs/components/searchable-select.md +0 -368
- package/docs/components/searchable-table.md +0 -438
- package/docs/components/searchable-tree-dialog.md +0 -190
- package/docs/components/searchable-tree.md +0 -200
- package/docs/components/section-block.md +0 -483
- package/docs/components/select.md +0 -709
- package/docs/components/simple-select.md +0 -741
- package/docs/components/skeleton.md +0 -706
- package/docs/components/slide-date-picker.md +0 -837
- package/docs/components/spin-loading.md +0 -696
- package/docs/components/stepper.md +0 -316
- package/docs/components/switch.md +0 -770
- package/docs/components/tab-form-item.md +0 -773
- package/docs/components/tab-switch.md +0 -170
- package/docs/components/table-dnd-wrapper.md +0 -107
- package/docs/components/table.md +0 -1088
- package/docs/components/text-editor.md +0 -735
- package/docs/components/textarea.md +0 -681
- package/docs/components/timeline.md +0 -254
- package/docs/components/toast.md +0 -773
- package/docs/components/toggle-button.md +0 -643
- package/docs/components/toggle.md +0 -882
- package/docs/components/tooltip.md +0 -513
- package/docs/components/transparent-label.md +0 -721
- package/docs/components/tree-drop-down.md +0 -740
- package/docs/components/tree-folder.md +0 -110
- package/docs/components/tree-sub-layout.md +0 -707
- package/docs/explanation/architecture.md +0 -54
- package/docs/explanation/design-system.md +0 -52
- package/docs/how-to/form-and-list-recipes.md +0 -386
- package/docs/how-to/forms-with-form-builder.md +0 -472
- package/docs/how-to/guides.md +0 -1027
- package/docs/migration/changelog.md +0 -60
- package/docs/migration/form-builder-2.5.2.md +0 -113
- package/docs/reference/cli.md +0 -112
- package/docs/reference/components.md +0 -572
- package/docs/reference/hooks.md +0 -1523
- package/docs/reference/providers.md +0 -866
- package/docs/reference/tailwind-plugins.md +0 -942
- package/docs/reference/theme.md +0 -85
- package/docs/reference/types.md +0 -1016
- package/docs/reference/utilities.md +0 -726
- package/docs/tutorials/building-first-form.md +0 -846
- package/docs/tutorials/component-composition.md +0 -882
- package/docs/tutorials/getting-started.md +0 -302
- package/docs/tutorials/theming-basics.md +0 -785
|
@@ -1,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
|