maz-ui 5.0.0 → 5.1.0-beta.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 (186) hide show
  1. package/dist/assets/{MazDropzone.DJ8au25t.css → MazDropzone.BW2grpTi.css} +1 -1
  2. package/dist/chunks/{MazDrawer.DANxKYxJ.js → MazDrawer.CC8zomfx.js} +2 -2
  3. package/dist/chunks/{MazDropzone.POH3pmfi.js → MazDropzone.Dez5j0WP.js} +2 -2
  4. package/dist/components/MazDrawer.js +1 -1
  5. package/dist/components/MazDropzone.js +1 -1
  6. package/dist/components/MazDropzone.vue.d.ts +2 -2
  7. package/dist/components/MazInputPrice.vue.d.ts +1 -1
  8. package/dist/components/index.js +2 -2
  9. package/docs/README.md +207 -0
  10. package/docs/agents/agents-md.md +52 -0
  11. package/docs/agents/claude-rule.md +52 -0
  12. package/docs/components/maz-accordion.md +76 -0
  13. package/docs/components/maz-alert.md +241 -0
  14. package/docs/components/maz-animated-counter.md +87 -0
  15. package/docs/components/maz-animated-element.md +46 -0
  16. package/docs/components/maz-animated-text.md +53 -0
  17. package/docs/components/maz-avatar.md +193 -0
  18. package/docs/components/maz-backdrop.md +178 -0
  19. package/docs/components/maz-badge.md +167 -0
  20. package/docs/components/maz-bottom-sheet.md +257 -0
  21. package/docs/components/maz-btn-group.md +316 -0
  22. package/docs/components/maz-btn.md +423 -0
  23. package/docs/components/maz-card-spotlight.md +84 -0
  24. package/docs/components/maz-card.md +321 -0
  25. package/docs/components/maz-carousel.md +153 -0
  26. package/docs/components/maz-chart.md +206 -0
  27. package/docs/components/maz-checkbox.md +138 -0
  28. package/docs/components/maz-checklist.md +251 -0
  29. package/docs/components/maz-circular-progress-bar.md +109 -0
  30. package/docs/components/maz-code-highlight.md +155 -0
  31. package/docs/components/maz-container.md +241 -0
  32. package/docs/components/maz-date-picker.md +791 -0
  33. package/docs/components/maz-dialog-confirm.md +215 -0
  34. package/docs/components/maz-dialog.md +143 -0
  35. package/docs/components/maz-drawer.md +106 -0
  36. package/docs/components/maz-dropdown.md +419 -0
  37. package/docs/components/maz-dropzone.md +387 -0
  38. package/docs/components/maz-expand-animation.md +82 -0
  39. package/docs/components/maz-fullscreen-loader.md +58 -0
  40. package/docs/components/maz-gallery.md +79 -0
  41. package/docs/components/maz-icon.md +203 -0
  42. package/docs/components/maz-input-code.md +73 -0
  43. package/docs/components/maz-input-number.md +79 -0
  44. package/docs/components/maz-input-phone-number.md +536 -0
  45. package/docs/components/maz-input-price.md +68 -0
  46. package/docs/components/maz-input-tags.md +112 -0
  47. package/docs/components/maz-input.md +334 -0
  48. package/docs/components/maz-lazy-img.md +113 -0
  49. package/docs/components/maz-link.md +146 -0
  50. package/docs/components/maz-loading-bar.md +38 -0
  51. package/docs/components/maz-markdown-editor.md +320 -0
  52. package/docs/components/maz-pagination.md +82 -0
  53. package/docs/components/maz-popover.md +794 -0
  54. package/docs/components/maz-pull-to-refresh.md +222 -0
  55. package/docs/components/maz-radio-buttons.md +313 -0
  56. package/docs/components/maz-radio.md +119 -0
  57. package/docs/components/maz-read-more.md +209 -0
  58. package/docs/components/maz-reading-progress-bar.md +96 -0
  59. package/docs/components/maz-select-country.md +513 -0
  60. package/docs/components/maz-select.md +318 -0
  61. package/docs/components/maz-sidebar-content.md +25 -0
  62. package/docs/components/maz-sidebar-footer.md +25 -0
  63. package/docs/components/maz-sidebar-group.md +27 -0
  64. package/docs/components/maz-sidebar-header.md +25 -0
  65. package/docs/components/maz-sidebar-menu-button.md +41 -0
  66. package/docs/components/maz-sidebar-menu-item.md +25 -0
  67. package/docs/components/maz-sidebar-menu-sub.md +32 -0
  68. package/docs/components/maz-sidebar-menu.md +25 -0
  69. package/docs/components/maz-sidebar-separator.md +21 -0
  70. package/docs/components/maz-sidebar-trigger.md +25 -0
  71. package/docs/components/maz-sidebar.md +507 -0
  72. package/docs/components/maz-skeleton.md +226 -0
  73. package/docs/components/maz-slider.md +165 -0
  74. package/docs/components/maz-spinner.md +84 -0
  75. package/docs/components/maz-stepper.md +301 -0
  76. package/docs/components/maz-switch.md +86 -0
  77. package/docs/components/maz-table-cell.md +27 -0
  78. package/docs/components/maz-table-row.md +28 -0
  79. package/docs/components/maz-table-title.md +27 -0
  80. package/docs/components/maz-table-virtualizer.md +31 -0
  81. package/docs/components/maz-table.md +426 -0
  82. package/docs/components/maz-tabs-bar.md +43 -0
  83. package/docs/components/maz-tabs-content-item.md +27 -0
  84. package/docs/components/maz-tabs-content.md +27 -0
  85. package/docs/components/maz-tabs.md +308 -0
  86. package/docs/components/maz-textarea.md +255 -0
  87. package/docs/components/maz-ticker.md +427 -0
  88. package/docs/components/maz-timeline.md +304 -0
  89. package/docs/components/maz-ui-provider.md +26 -0
  90. package/docs/components/maz-window-mockup.md +182 -0
  91. package/docs/composables/use-aos.md +41 -0
  92. package/docs/composables/use-breakpoints.md +42 -0
  93. package/docs/composables/use-dialog.md +58 -0
  94. package/docs/composables/use-display-names.md +130 -0
  95. package/docs/composables/use-drag.md +185 -0
  96. package/docs/composables/use-form-validator.md +1123 -0
  97. package/docs/composables/use-idle-timeout.md +172 -0
  98. package/docs/composables/use-pull-to-refresh.md +86 -0
  99. package/docs/composables/use-reading-time.md +132 -0
  100. package/docs/composables/use-string-matching.md +41 -0
  101. package/docs/composables/use-swipe.md +171 -0
  102. package/docs/composables/use-timer.md +104 -0
  103. package/docs/composables/use-toast.md +50 -0
  104. package/docs/composables/use-user-visibility.md +127 -0
  105. package/docs/composables/use-wait.md +50 -0
  106. package/docs/composables/use-window-size.md +25 -0
  107. package/docs/directives/click-outside.md +182 -0
  108. package/docs/directives/fullscreen-img.md +83 -0
  109. package/docs/directives/lazy-img.md +182 -0
  110. package/docs/directives/tooltip.md +298 -0
  111. package/docs/directives/zoom-img.md +100 -0
  112. package/docs/ecosystem/eslint-config.md +289 -0
  113. package/docs/ecosystem/icons/icon-set.md +25 -0
  114. package/docs/ecosystem/icons/index.md +584 -0
  115. package/docs/ecosystem/mcp.md +165 -0
  116. package/docs/ecosystem/node/exec-promise.md +93 -0
  117. package/docs/ecosystem/node/index.md +53 -0
  118. package/docs/ecosystem/node/logger.md +152 -0
  119. package/docs/ecosystem/node/print-banner.md +101 -0
  120. package/docs/ecosystem/node/setup-agents.md +102 -0
  121. package/docs/ecosystem/nuxt.md +551 -0
  122. package/docs/ecosystem/stylelint-config.md +310 -0
  123. package/docs/ecosystem/themes.md +966 -0
  124. package/docs/ecosystem/translations.md +1173 -0
  125. package/docs/ecosystem/utils/camel-case.md +37 -0
  126. package/docs/ecosystem/utils/capitalize.md +37 -0
  127. package/docs/ecosystem/utils/check-availability.md +85 -0
  128. package/docs/ecosystem/utils/cookie.md +86 -0
  129. package/docs/ecosystem/utils/country-code-to-unicode-flag.md +128 -0
  130. package/docs/ecosystem/utils/currency.md +53 -0
  131. package/docs/ecosystem/utils/date.md +53 -0
  132. package/docs/ecosystem/utils/debounce-callback.md +44 -0
  133. package/docs/ecosystem/utils/debounce-id.md +75 -0
  134. package/docs/ecosystem/utils/debounce.md +71 -0
  135. package/docs/ecosystem/utils/fetch-locale-ip.md +39 -0
  136. package/docs/ecosystem/utils/format-json.md +39 -0
  137. package/docs/ecosystem/utils/format-phone-number.md +43 -0
  138. package/docs/ecosystem/utils/get-browser-locale.md +35 -0
  139. package/docs/ecosystem/utils/get-country-flag-url.md +67 -0
  140. package/docs/ecosystem/utils/get-error-message.md +45 -0
  141. package/docs/ecosystem/utils/idle-timeout.md +96 -0
  142. package/docs/ecosystem/utils/index.md +57 -0
  143. package/docs/ecosystem/utils/is-client.md +38 -0
  144. package/docs/ecosystem/utils/is-equal.md +44 -0
  145. package/docs/ecosystem/utils/is-ios.md +43 -0
  146. package/docs/ecosystem/utils/is-server.md +37 -0
  147. package/docs/ecosystem/utils/is-standalone-mode.md +49 -0
  148. package/docs/ecosystem/utils/kebab-case.md +42 -0
  149. package/docs/ecosystem/utils/normalize-string.md +83 -0
  150. package/docs/ecosystem/utils/number.md +51 -0
  151. package/docs/ecosystem/utils/pascal-case.md +41 -0
  152. package/docs/ecosystem/utils/prevent-ios-input-zoom.md +72 -0
  153. package/docs/ecosystem/utils/script-loader.md +85 -0
  154. package/docs/ecosystem/utils/sleep.md +65 -0
  155. package/docs/ecosystem/utils/snake-case.md +42 -0
  156. package/docs/ecosystem/utils/swipe-handler.md +97 -0
  157. package/docs/ecosystem/utils/textarea-autogrow.md +47 -0
  158. package/docs/ecosystem/utils/throttle-id.md +54 -0
  159. package/docs/ecosystem/utils/throttle.md +63 -0
  160. package/docs/ecosystem/utils/truthy-filter.md +37 -0
  161. package/docs/ecosystem/utils/types/deep-key-of.md +54 -0
  162. package/docs/ecosystem/utils/types/deep-partial.md +48 -0
  163. package/docs/ecosystem/utils/types/deep-required.md +45 -0
  164. package/docs/ecosystem/utils/types/flatten-object-keys.md +50 -0
  165. package/docs/ecosystem/utils/types/generic-instance-type.md +48 -0
  166. package/docs/ecosystem/utils/types/infer-maybe-ref.md +41 -0
  167. package/docs/ecosystem/utils/upper-first.md +38 -0
  168. package/docs/ecosystem/utils/user-visibility.md +75 -0
  169. package/docs/guide/ai-agents.md +237 -0
  170. package/docs/guide/browser-support.md +88 -0
  171. package/docs/guide/getting-started.md +191 -0
  172. package/docs/guide/global-defaults.md +103 -0
  173. package/docs/guide/maz-ui-provider.md +231 -0
  174. package/docs/guide/migration-v5.md +871 -0
  175. package/docs/guide/resolvers.md +650 -0
  176. package/docs/guide/tailwind.md +483 -0
  177. package/docs/guide/vue.md +286 -0
  178. package/docs/manifest.json +1 -0
  179. package/docs/plugins/aos.md +312 -0
  180. package/docs/plugins/dialog.md +269 -0
  181. package/docs/plugins/toast.md +221 -0
  182. package/docs/plugins/wait.md +78 -0
  183. package/docs/reference/icons.md +46 -0
  184. package/docs/reference/tailwind-tokens.md +191 -0
  185. package/docs/rules.md +57 -0
  186. package/package.json +31 -4
@@ -0,0 +1,507 @@
1
+ ---
2
+ title: "MazSidebar"
3
+ description: "MazSidebar is a composable sidebar system for dashboard, admin, and SaaS applications. It provides a fully accessible, collapsible navigation with multiple display modes."
4
+ package: "maz-ui"
5
+ url: "https://maz-ui.com/components/maz-sidebar"
6
+ ---
7
+
8
+ # MazSidebar
9
+
10
+ > MazSidebar is a composable sidebar system for dashboard, admin, and SaaS applications. It provides a fully accessible, collapsible navigation with multiple display modes.
11
+
12
+ - Package: `maz-ui`
13
+ - Import: `import MazSidebar from 'maz-ui/components/MazSidebar'` or `import MazSidebarMenuButton from 'maz-ui/components/MazSidebarMenuButton'` or `import MazSidebarMenuSub from 'maz-ui/components/MazSidebarMenuSub'` or `import MazSidebarGroup from 'maz-ui/components/MazSidebarGroup'`
14
+ - Nuxt: auto-imported by `@maz-ui/nuxt`, no import needed in a Nuxt app
15
+ - Web: https://maz-ui.com/components/maz-sidebar
16
+
17
+ > Before use it, you should install the MazUi plugin in your project, follow instructions in [Getting Started](../guide/getting-started.md)
18
+
19
+ **Tip:**
20
+
21
+ `MazSidebar` shares its state with all sub-components via Vue's `provide`/`inject`. No separate Provider component is needed. All sub-components must be descendants of `MazSidebar`.
22
+
23
+ **Warning: Deferred features (v1.1)**
24
+
25
+ The following features are planned for a future release and are **not yet available**:
26
+ - `localStorage` state persistence
27
+ - `Cmd/Ctrl+B` keyboard shortcut
28
+ - Automatic mobile drawer under a breakpoint
29
+
30
+ ## Sub-components
31
+
32
+ | Component | Role |
33
+ | ---------------------- | --------------------------------------------------------------------- |
34
+ | `MazSidebar` | Root container - provides state context |
35
+ | `MazSidebarHeader` | Fixed top area |
36
+ | `MazSidebarContent` | Scrollable central area |
37
+ | `MazSidebarFooter` | Fixed bottom area |
38
+ | `MazSidebarGroup` | Item grouping with optional label |
39
+ | `MazSidebarSeparator` | Visual divider (`<hr>`) |
40
+ | `MazSidebarMenu` | `<ul>` wrapper with `role="menu"` |
41
+ | `MazSidebarMenuItem` | `<li>` item wrapper |
42
+ | `MazSidebarMenuButton` | Clickable item (link or button), supports icon, label, badge, tooltip |
43
+ | `MazSidebarMenuSub` | Collapsible sub-menu |
44
+ | `MazSidebarTrigger` | Toggle button (must be a descendant of `MazSidebar`) |
45
+
46
+ ## Basic usage
47
+
48
+ ```html
49
+ <div class="flex h-screen">
50
+ <MazSidebar v-model:open="isOpen">
51
+ <MazSidebarHeader>
52
+ <div class="p-4 font-bold">My App</div>
53
+ </MazSidebarHeader>
54
+ <MazSidebarContent>
55
+ <MazSidebarMenu>
56
+ <MazSidebarMenuItem>
57
+ <MazSidebarMenuButton label="Dashboard" :active="true" />
58
+ </MazSidebarMenuItem>
59
+ <MazSidebarMenuItem>
60
+ <MazSidebarMenuButton label="Settings" />
61
+ </MazSidebarMenuItem>
62
+ </MazSidebarMenu>
63
+ </MazSidebarContent>
64
+ <MazSidebarFooter>
65
+ <div class="p-4">Footer</div>
66
+ </MazSidebarFooter>
67
+ </MazSidebar>
68
+ <main class="flex-1 p-4">Main content</main>
69
+ </div>
70
+
71
+ <script setup>
72
+ const isOpen = ref(true)
73
+ </script>
74
+ ```
75
+
76
+ ## Groups & dividers
77
+
78
+ ```html
79
+ <MazSidebar v-model:open="isOpen">
80
+ <MazSidebarContent>
81
+ <MazSidebarGroup label="Navigation">
82
+ <MazSidebarMenu>
83
+ <MazSidebarMenuItem>
84
+ <MazSidebarMenuButton label="Dashboard" :active="true" />
85
+ </MazSidebarMenuItem>
86
+ <MazSidebarMenuItem>
87
+ <MazSidebarMenuButton label="Projects" />
88
+ </MazSidebarMenuItem>
89
+ </MazSidebarMenu>
90
+ </MazSidebarGroup>
91
+ <MazSidebarSeparator />
92
+ <MazSidebarGroup label="Settings">
93
+ <MazSidebarMenu>
94
+ <MazSidebarMenuItem>
95
+ <MazSidebarMenuButton label="Profile" />
96
+ </MazSidebarMenuItem>
97
+ </MazSidebarMenu>
98
+ </MazSidebarGroup>
99
+ </MazSidebarContent>
100
+ </MazSidebar>
101
+ ```
102
+
103
+ ## Sub-menus
104
+
105
+ ```html
106
+ <MazSidebar v-model:open="isOpen">
107
+ <MazSidebarContent>
108
+ <MazSidebarMenu>
109
+ <MazSidebarMenuItem>
110
+ <MazSidebarMenuSub label="Products" :default-open="true">
111
+ <MazSidebarMenuItem>
112
+ <MazSidebarMenuButton label="All Products" />
113
+ </MazSidebarMenuItem>
114
+ <MazSidebarMenuItem>
115
+ <MazSidebarMenuButton label="Add Product" />
116
+ </MazSidebarMenuItem>
117
+ </MazSidebarMenuSub>
118
+ </MazSidebarMenuItem>
119
+ </MazSidebarMenu>
120
+ </MazSidebarContent>
121
+ </MazSidebar>
122
+ ```
123
+
124
+ ## Icon mode with tooltips
125
+
126
+ When `collapsible="icon"` and the sidebar is collapsed, labels fade out and only the icons stay visible. To help users identify items in collapsed state, provide a `tooltip` prop on each `MazSidebarMenuButton`: it uses the `v-tooltip` directive and is only shown on hover when the sidebar is collapsed by default.
127
+
128
+ ### Controlling when the tooltip appears
129
+
130
+ Both `MazSidebar` and `MazSidebarMenuButton` accept a `tooltip-mode` prop:
131
+
132
+ - `closed` (default on the sidebar) - tooltip only shows on hover when the sidebar is collapsed
133
+ - `always` - tooltip shows on hover regardless of the sidebar state
134
+
135
+ Set it on the sidebar to apply to every descendant button, or override per-button:
136
+
137
+ ```html
138
+ <!-- Every button: tooltip visible only when collapsed -->
139
+ <MazSidebar tooltip-mode="closed">
140
+ <MazSidebarMenuButton :icon="MazHome" label="Dashboard" tooltip="Go to Dashboard" />
141
+ </MazSidebar>
142
+
143
+ <!-- This button overrides: tooltip always shown -->
144
+ <MazSidebar tooltip-mode="closed">
145
+ <MazSidebarMenuButton
146
+ :icon="MazCog6Tooth"
147
+ label="Settings"
148
+ tooltip="Open Settings"
149
+ tooltip-mode="always"
150
+ />
151
+ </MazSidebar>
152
+ ```
153
+
154
+ **Tip: Performance**
155
+
156
+ When no `tooltip` prop is provided on a button, the `v-tooltip` directive is not attached at all - no listeners, no popover instance.
157
+
158
+ ```html
159
+ <script setup>
160
+ import { MazHome } from '@maz-ui/icons/lazy/MazHome'
161
+ import { MazCog6Tooth } from '@maz-ui/icons/lazy/MazCog6Tooth'
162
+
163
+ const isOpen = ref(true)
164
+ </script>
165
+
166
+ <template>
167
+ <MazSidebar v-model:open="isOpen" collapsible="icon">
168
+ <MazSidebarContent>
169
+ <MazSidebarMenu>
170
+ <MazSidebarMenuItem>
171
+ <MazSidebarMenuButton :icon="MazHome" label="Dashboard" tooltip="Go to Dashboard" />
172
+ </MazSidebarMenuItem>
173
+ </MazSidebarMenu>
174
+ </MazSidebarContent>
175
+ <MazSidebarFooter>
176
+ <MazSidebarTrigger />
177
+ </MazSidebarFooter>
178
+ </MazSidebar>
179
+ </template>
180
+ ```
181
+
182
+ ## Hover mode
183
+
184
+ `collapsible="hover"` displays the sidebar in icon-only mode and **automatically expands it when the mouse enters the sidebar (or any descendant) and collapses it when the mouse leaves**. Keyboard focus also expands the sidebar, so users navigating with `Tab` see the full labels.
185
+
186
+ **Tip:**
187
+
188
+ This is a **purely visual** state. The `v-model:open` value is not updated and the persistence cookie is not written when the sidebar expands or collapses through hover. Use this mode when you want the rail-style sidebar of `collapsible="icon"` without exposing a toggle.
189
+
190
+ ```html
191
+ <MazSidebar collapsible="hover">
192
+ <MazSidebarContent>
193
+ <MazSidebarMenu>
194
+ <MazSidebarMenuItem>
195
+ <MazSidebarMenuButton :icon="MazHome" label="Dashboard" />
196
+ </MazSidebarMenuItem>
197
+ <MazSidebarMenuItem>
198
+ <MazSidebarMenuButton :icon="MazCog6Tooth" label="Settings" />
199
+ </MazSidebarMenuItem>
200
+ </MazSidebarMenu>
201
+ </MazSidebarContent>
202
+ </MazSidebar>
203
+ ```
204
+
205
+ ## Offcanvas mode
206
+
207
+ ```html
208
+ <MazSidebar v-model:open="isOpen" collapsible="offcanvas">
209
+ <!-- content -->
210
+ </MazSidebar>
211
+ ```
212
+
213
+ ## Overlay vs push mode
214
+
215
+ In `mode="push"` (default), the sidebar is part of the document flow and pushes the main content.
216
+ In `mode="overlay"`, the sidebar floats over the content with a backdrop, escape key support and focus trapping.
217
+
218
+ ```html
219
+ <!-- Overlay mode: sidebar floats over content -->
220
+ <MazSidebar v-model:open="isOpen" mode="overlay">
221
+ <!-- content -->
222
+ </MazSidebar>
223
+ ```
224
+
225
+ ## Side end (right)
226
+
227
+ ```html
228
+ <div class="flex h-screen">
229
+ <main class="flex-1">Main content</main>
230
+ <MazSidebar v-model:open="isOpen" side="end">
231
+ <!-- content -->
232
+ </MazSidebar>
233
+ </div>
234
+ ```
235
+
236
+ ## Badges
237
+
238
+ `badge` accepts a `string`, a `number`, or a full `MazBadgeProps` object (with an optional `text`) to fine-tune color, size, outlined, etc.
239
+
240
+ ```html
241
+ <!-- Simple: pass a string or number -->
242
+ <MazSidebarMenuButton label="Inbox" :badge="12" />
243
+
244
+ <!-- Full customisation: pass a MazBadgeProps object -->
245
+ <MazSidebarMenuButton
246
+ label="Errors"
247
+ :badge="{ text: 3, color: 'destructive' }"
248
+ />
249
+ <MazSidebarMenuButton
250
+ label="Beta"
251
+ :badge="{ text: 'NEW', color: 'success', outlined: true }"
252
+ />
253
+ ```
254
+
255
+ ## User menu in footer
256
+
257
+ ```html
258
+ <MazSidebar v-model:open="isOpen">
259
+ <MazSidebarContent><!-- ... --></MazSidebarContent>
260
+ <MazSidebarFooter>
261
+ <div class="flex items-center gap-3 p-3">
262
+ <MazAvatar src="..." size="0.8rem" />
263
+ <div class="flex-1 min-w-0">
264
+ <p class="m-0 text-md font-semibold">Jane Doe</p>
265
+ <p class="m-0 text-xs text-muted">jane@example.com</p>
266
+ </div>
267
+ </div>
268
+ </MazSidebarFooter>
269
+ </MazSidebar>
270
+ ```
271
+
272
+ ## Mobile (static rendering)
273
+
274
+ **Note:**
275
+
276
+ Automatic mobile drawer (drawer auto under a breakpoint with backdrop) is a **deferred v1.1 feature**. For now, control the sidebar visibility programmatically based on viewport.
277
+
278
+ ```html
279
+ <script setup>
280
+ import { useWindowSize } from 'maz-ui'
281
+
282
+ const { width } = useWindowSize()
283
+ const isMobile = computed(() => width.value < 768)
284
+ const isOpen = ref(!isMobile.value)
285
+
286
+ watch(isMobile, (mobile) => {
287
+ isOpen.value = !mobile
288
+ })
289
+ </script>
290
+
291
+ <template>
292
+ <div class="flex h-screen">
293
+ <MazSidebar v-model:open="isOpen" :mode="isMobile ? 'overlay' : 'push'">
294
+ <!-- content -->
295
+ </MazSidebar>
296
+ <main class="flex-1">
297
+ <MazSidebarTrigger />
298
+ <!-- page content -->
299
+ </main>
300
+ </div>
301
+ </template>
302
+ ```
303
+
304
+ ## Programmatic control (v-model + composable)
305
+
306
+ Use `v-model:open` for two-way binding, or `useSidebar()` inside any descendant component.
307
+
308
+ ```html
309
+ <script setup>
310
+ import { useSidebar } from 'maz-ui'
311
+
312
+ // Inside a child component that is a descendant of MazSidebar:
313
+ const sidebar = useSidebar()
314
+
315
+ // sidebar.open.value → boolean
316
+ // sidebar.state.value → 'expanded' | 'collapsed'
317
+ // sidebar.toggle() → toggle open state
318
+ // sidebar.setOpen(true/false) → set explicitly
319
+ </script>
320
+
321
+ <template>
322
+ <MazSidebar v-model:open="isOpen">
323
+ <MazSidebarContent>
324
+ <MazSidebarMenu>
325
+ <MazSidebarMenuItem>
326
+ <MazSidebarMenuButton label="Dashboard" />
327
+ </MazSidebarMenuItem>
328
+ </MazSidebarMenu>
329
+ </MazSidebarContent>
330
+ <!-- MazSidebarTrigger uses useSidebar() internally -->
331
+ <MazSidebarTrigger />
332
+ </MazSidebar>
333
+ </template>
334
+ ```
335
+
336
+ ## Persistent open state
337
+
338
+ The sidebar persists its open/collapsed state in a cookie (`maz-sidebar-open`) so it survives page reloads. This is **enabled by default**.
339
+
340
+ ```html
341
+ <!-- Default: persistence enabled, cookie name "maz-sidebar-open" -->
342
+ <MazSidebar v-model:open="isOpen" />
343
+
344
+ <!-- Disable persistence -->
345
+ <MazSidebar v-model:open="isOpen" :persist="false" />
346
+
347
+ <!-- Custom cookie key (useful when multiple sidebars coexist) -->
348
+ <MazSidebar v-model:open="isOpen" persist-key="admin-sidebar-open" />
349
+ ```
350
+
351
+ ### How it works
352
+
353
+ - **In setup (server + client)**: the cookie is read and used to initialize the open state. On the server, the value is taken from the request `Cookie` header via Vue's `useSSRContext()`; on the client it comes from `document.cookie`.
354
+ - **On client mount**: `update:open` is emitted if the persisted value differs from the `:open` prop, so your parent `v-model` stays in sync.
355
+ - **On state change**: every transition between expanded/collapsed writes the new value to the cookie (1-year expiry, `SameSite=Lax`).
356
+
357
+ ### SSR considerations
358
+
359
+ Persistence is **SSR-native** - the server reads the request cookie and renders the sidebar in its persisted state immediately, so there is no expand → collapse flash on hydration. This works out of the box in Nuxt and any Vue 3 SSR runtime that exposes the request headers through `useSSRContext()`.
360
+
361
+ If you prefer to manage the state yourself (e.g. to share it with other parts of your app), disable persistence and feed the cookie via your own ref:
362
+
363
+ ```html
364
+ <script setup>
365
+ const sidebarOpen = useCookie<boolean>('maz-sidebar-open', { default: () => true })
366
+ </script>
367
+
368
+ <template>
369
+ <MazSidebar v-model:open="sidebarOpen" :persist="false">
370
+ <!-- ... -->
371
+ </MazSidebar>
372
+ </template>
373
+ ```
374
+
375
+ `:persist="false"` prevents the sidebar from also writing the cookie, leaving full control to your `useCookie` ref.
376
+
377
+ ## With router (vue-router / NuxtLink)
378
+
379
+ `MazSidebarMenuButton` uses `resolveLinkComponent()` internally - it detects `RouterLink` (vue-router) or a provided `NuxtLink`. Pass the `to` prop for router navigation, `href` for plain anchor links.
380
+
381
+ ```html
382
+ <!-- With vue-router -->
383
+ <MazSidebarMenuButton :to="{ name: 'home' }" label="Home" />
384
+ <MazSidebarMenuButton to="/about" label="About" />
385
+
386
+ <!-- With plain href -->
387
+ <MazSidebarMenuButton href="https://maz-ui.com" label="Docs" />
388
+
389
+ <!-- Mark as active manually (useful when router is not available) -->
390
+ <MazSidebarMenuButton label="Dashboard" :active="$route.name === 'dashboard'" />
391
+ ```
392
+
393
+ ## CSS Variables
394
+
395
+ Customize the sidebar width using these CSS custom properties (also settable via `width` / `iconWidth` props):
396
+
397
+ ```css
398
+ :root {
399
+ --maz-sidebar-width: 16rem; /* expanded width */
400
+ --maz-sidebar-icon-width: 3rem; /* icon-mode collapsed width */
401
+ }
402
+ ```
403
+
404
+ ## Accessibility
405
+
406
+ - The sidebar root element renders as `<aside aria-label="Sidebar">`
407
+ - `MazSidebarMenu` renders as `<ul role="menu">`
408
+ - `MazSidebarMenuItem` renders as `<li role="none">`
409
+ - `MazSidebarTrigger` has `aria-expanded` and `aria-controls` referencing the sidebar `id`
410
+ - `MazSidebarMenuButton` applies `aria-current="page"` on active items and exposes the label via `aria-label`
411
+ - `MazSidebarMenuSub` trigger has `aria-expanded` and `aria-controls`
412
+ - In `mode="overlay"`, pressing `Escape` closes the sidebar and focus is restored to the trigger element
413
+ - In `mode="overlay"`, `Tab`/`Shift+Tab` are trapped within the sidebar
414
+ - All transitions respect `prefers-reduced-motion`
415
+
416
+ ## MazSidebar
417
+
418
+ ## MazSidebar API
419
+
420
+ `import MazSidebar from 'maz-ui/components/MazSidebar'`
421
+
422
+ ### Props
423
+
424
+ - `id` (`string`): Unique identifier for the sidebar (auto-generated if not provided).
425
+ - `open` (`boolean`, default: `true`, `v-model:open`): Whether the sidebar is open.
426
+ - `side` (`"end" | "start"`, default: `"start"`): Side of the sidebar.
427
+ - `collapsible` (`"icon" | "none" | "hover" | "offcanvas"`, default: `"offcanvas"`): How the sidebar collapses - offcanvas: completely hidden - icon: only icons visible - hover: only icons visible by default, expands on mouse hover or keyboard focus (transient visual state - does not update `v-model:open` nor the persistence cookie) - none: always fully visible.
428
+ - `mode` (`"push" | "overlay"`, default: `"push"`): How the sidebar affects layout - push: sidebar is in document flow - overlay: sidebar floats over content with a backdrop.
429
+ - `width` (`string`, default: `"16rem"`): Width of the expanded sidebar.
430
+ - `icon-width` (`string`, default: `"3rem"`): Width of the collapsed sidebar in icon mode.
431
+ - `tooltip-mode` (`MazSidebarTooltipMode`, default: `"closed"`): When descendant `MazSidebarMenuButton` components should display their tooltip. - `always`: tooltip shows on hover regardless of the sidebar state - `closed`: tooltip only shows on hover when the sidebar is collapsed Individual buttons can override this via their own `tooltipMode` prop.
432
+ - `persist` (`boolean`, default: `true`): Persist the open/collapsed state in a cookie so it survives reloads. Restoration happens on client mount (SSR-safe). For zero-flash SSR, read the cookie server-side and forward it via `v-model:open`.
433
+ - `persist-key` (`string`, default: `"maz-sidebar-open"`): Cookie key used when `persist` is enabled. Set a unique key per sidebar instance if you mount several sidebars on the same site.
434
+
435
+ ### Events
436
+
437
+ - `@update:open` (payload: `value: boolean`): Emitted when open state changes
438
+
439
+ ### Slots
440
+
441
+ - `#default`
442
+
443
+ ### Exposed (template ref)
444
+
445
+ - `toggle`
446
+ - `setOpen`
447
+
448
+ ## MazSidebarMenuButton
449
+
450
+ ## MazSidebarMenuButton API
451
+
452
+ `import MazSidebarMenuButton from 'maz-ui/components/MazSidebarMenuButton'`
453
+
454
+ ### Props
455
+
456
+ - `to` (`string | Record<string, unknown>`): Route for router-link navigation.
457
+ - `href` (`string`): URL for anchor navigation.
458
+ - `icon` (`MazIconLike`): Icon to display before the label. Accepts a bare icon value (Vue component, raw SVG string, URL) or a full `MazIconProps` object for fine-grained control (size, title, fallback, …).
459
+ - `label` (`string`): Label text.
460
+ - `badge` (`MazSidebarMenuButtonBadge`): Badge content. Pass a `string`/`number` for a simple primary badge, or a full `MazBadgeProps` object (with optional `text`) to customise color, size, outlined, ….
461
+ - `tooltip` (`string`): Tooltip text. When provided, shows a tooltip on hover via the `v-tooltip` directive.
462
+ - `tooltip-mode` (`MazSidebarTooltipMode`): Controls when the tooltip should be displayed. - `always`: tooltip shows on hover regardless of the sidebar state - `closed`: tooltip only shows on hover when the sidebar is collapsed Overrides the parent `MazSidebar`'s `tooltipMode`. Falls back to the sidebar value (which defaults to `always`) when not provided.
463
+ - `active` (`boolean`): Whether the item is active (highlights with `aria-current="page"`).
464
+ - `disabled` (`boolean`): Whether the item is disabled.
465
+ - `size` (`"sm" | "md" | "lg"`, default: `"md"`): Size of the button.
466
+
467
+ ### Events
468
+
469
+ - `@click` (payload: `event: MouseEvent`)
470
+
471
+ ### Slots
472
+
473
+ - `#icon`
474
+ - `#default`
475
+
476
+ ## MazSidebarMenuSub
477
+
478
+ ## MazSidebarMenuSub API
479
+
480
+ `import MazSidebarMenuSub from 'maz-ui/components/MazSidebarMenuSub'`
481
+
482
+ ### Props
483
+
484
+ - `label` (`string`): Label for the sub-menu trigger button.
485
+ - `icon` (`MazIconLike`): Icon to display before the label. Accepts a bare icon value (Vue component, raw SVG string, URL) or a full `MazIconProps` object for fine-grained control.
486
+ - `default-open` (`boolean`, default: `false`): Whether the sub-menu is open by default.
487
+
488
+ ### Slots
489
+
490
+ - `#icon`
491
+ - `#label`
492
+ - `#chevron`
493
+ - `#default`
494
+
495
+ ## MazSidebarGroup
496
+
497
+ ## MazSidebarGroup API
498
+
499
+ `import MazSidebarGroup from 'maz-ui/components/MazSidebarGroup'`
500
+
501
+ ### Props
502
+
503
+ - `label` (`string`): Optional label for the group.
504
+
505
+ ### Slots
506
+
507
+ - `#default`