@maz-ui/mcp 5.0.0-beta.1 → 5.0.0-beta.17

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 (63) hide show
  1. package/dist/mcp.mjs +1 -1
  2. package/docs/generated-docs/maz-checkbox.doc.md +16 -17
  3. package/docs/generated-docs/maz-circular-progress-bar.doc.md +1 -1
  4. package/docs/generated-docs/maz-code-highlight.doc.md +11 -0
  5. package/docs/generated-docs/maz-date-picker.doc.md +41 -41
  6. package/docs/generated-docs/maz-drawer.doc.md +7 -8
  7. package/docs/generated-docs/maz-expand-animation.doc.md +4 -4
  8. package/docs/generated-docs/maz-fullscreen-loader.doc.md +5 -5
  9. package/docs/generated-docs/maz-gallery.doc.md +15 -15
  10. package/docs/generated-docs/maz-input-code.doc.md +16 -16
  11. package/docs/generated-docs/maz-input-phone-number.doc.md +42 -38
  12. package/docs/generated-docs/maz-input-price.doc.md +14 -14
  13. package/docs/generated-docs/maz-input-tags.doc.md +16 -16
  14. package/docs/generated-docs/maz-input.doc.md +14 -14
  15. package/docs/generated-docs/maz-lazy-img.doc.md +14 -14
  16. package/docs/generated-docs/maz-loading-bar.doc.md +4 -4
  17. package/docs/generated-docs/maz-pull-to-refresh.doc.md +10 -10
  18. package/docs/generated-docs/maz-radio-buttons.doc.md +17 -17
  19. package/docs/generated-docs/maz-radio.doc.md +16 -16
  20. package/docs/generated-docs/maz-reading-progress-bar.doc.md +4 -4
  21. package/docs/generated-docs/maz-sidebar-content.doc.md +5 -0
  22. package/docs/generated-docs/maz-sidebar-footer.doc.md +5 -0
  23. package/docs/generated-docs/maz-sidebar-group.doc.md +11 -0
  24. package/docs/generated-docs/maz-sidebar-header.doc.md +5 -0
  25. package/docs/generated-docs/maz-sidebar-menu-button.doc.md +27 -0
  26. package/docs/generated-docs/maz-sidebar-menu-item.doc.md +5 -0
  27. package/docs/generated-docs/maz-sidebar-menu-sub.doc.md +16 -0
  28. package/docs/generated-docs/maz-sidebar-menu.doc.md +5 -0
  29. package/docs/generated-docs/maz-sidebar-separator.doc.md +0 -0
  30. package/docs/generated-docs/maz-sidebar-trigger.doc.md +5 -0
  31. package/docs/generated-docs/maz-sidebar.doc.md +36 -0
  32. package/docs/generated-docs/maz-slider.doc.md +1 -1
  33. package/docs/generated-docs/maz-spinner.doc.md +4 -4
  34. package/docs/generated-docs/maz-switch.doc.md +14 -14
  35. package/docs/generated-docs/maz-table.doc.md +5 -5
  36. package/docs/generated-docs/maz-textarea.doc.md +25 -24
  37. package/docs/generated-docs/maz-ticker.doc.md +1 -1
  38. package/docs/generated-docs/maz-window-mockup.doc.md +23 -0
  39. package/docs/src/blog/v5.md +1 -3
  40. package/docs/src/components/maz-code-highlight.md +233 -0
  41. package/docs/src/components/maz-container.md +2 -2
  42. package/docs/src/components/maz-input-phone-number.md +106 -103
  43. package/docs/src/components/maz-sidebar.md +674 -0
  44. package/docs/src/components/maz-textarea.md +27 -1
  45. package/docs/src/components/maz-timeline.md +60 -0
  46. package/docs/src/components/maz-window-mockup.md +249 -0
  47. package/docs/src/directives/click-outside.md +7 -14
  48. package/docs/src/directives/lazy-img.md +4 -4
  49. package/docs/src/directives/tooltip.md +23 -0
  50. package/docs/src/ecosystem/eslint-config.md +95 -1
  51. package/docs/src/guide/getting-started.md +13 -11
  52. package/docs/src/guide/maz-ui-provider.md +6 -3
  53. package/docs/src/guide/migration-v4.md +7 -3
  54. package/docs/src/guide/migration-v5.md +67 -12
  55. package/docs/src/guide/nuxt.md +53 -46
  56. package/docs/src/guide/tailwind.md +4 -0
  57. package/docs/src/guide/themes.md +127 -69
  58. package/docs/src/helpers/capitalize.md +2 -3
  59. package/docs/src/helpers/currency.md +2 -2
  60. package/docs/src/helpers/date.md +2 -2
  61. package/docs/src/helpers/number.md +2 -2
  62. package/docs/src/plugins/wait.md +1 -1
  63. package/package.json +4 -4
@@ -0,0 +1,674 @@
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
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ <!--@include: ./../../.vitepress/mixins/getting-started.md-->
11
+
12
+ ::: tip
13
+ `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`.
14
+ :::
15
+
16
+ ::: warning Deferred features (v1.1)
17
+ The following features are planned for a future release and are **not yet available**:
18
+ - `localStorage` state persistence
19
+ - `Cmd/Ctrl+B` keyboard shortcut
20
+ - Automatic mobile drawer under a breakpoint
21
+ :::
22
+
23
+ ## Sub-components
24
+
25
+ | Component | Role |
26
+ |---|---|
27
+ | `MazSidebar` | Root container — provides state context |
28
+ | `MazSidebarHeader` | Fixed top area |
29
+ | `MazSidebarContent` | Scrollable central area |
30
+ | `MazSidebarFooter` | Fixed bottom area |
31
+ | `MazSidebarGroup` | Item grouping with optional label |
32
+ | `MazSidebarSeparator` | Visual divider (`<hr>`) |
33
+ | `MazSidebarMenu` | `<ul>` wrapper with `role="menu"` |
34
+ | `MazSidebarMenuItem` | `<li>` item wrapper |
35
+ | `MazSidebarMenuButton` | Clickable item (link or button), supports icon, label, badge, tooltip |
36
+ | `MazSidebarMenuSub` | Collapsible sub-menu |
37
+ | `MazSidebarTrigger` | Toggle button (must be a descendant of `MazSidebar`) |
38
+
39
+ ## Basic usage
40
+
41
+ <ComponentDemo>
42
+ <div class="maz:border maz:border-divider maz:overflow-hidden maz:rounded-md maz:h-[25rem] maz:flex">
43
+ <MazSidebar v-model:open="basicOpen" class="maz:h-full">
44
+ <MazSidebarHeader>
45
+ <div class="maz:p-4 maz:font-bold">My App</div>
46
+ </MazSidebarHeader>
47
+ <MazSidebarContent>
48
+ <MazSidebarMenu>
49
+ <MazSidebarMenuItem>
50
+ <MazSidebarMenuButton label="Dashboard" :active="true" />
51
+ </MazSidebarMenuItem>
52
+ <MazSidebarMenuItem>
53
+ <MazSidebarMenuButton label="Settings" />
54
+ </MazSidebarMenuItem>
55
+ </MazSidebarMenu>
56
+ </MazSidebarContent>
57
+ <MazSidebarFooter>
58
+ <div class="maz:p-4">Footer</div>
59
+ </MazSidebarFooter>
60
+ </MazSidebar>
61
+ <main class="maz:flex-1 maz:p-4">Main content</main>
62
+ </div>
63
+
64
+ <template #code>
65
+
66
+ ```html
67
+ <div class="maz:flex maz:h-screen">
68
+ <MazSidebar v-model:open="isOpen">
69
+ <MazSidebarHeader>
70
+ <div class="maz:p-4 maz:font-bold">My App</div>
71
+ </MazSidebarHeader>
72
+ <MazSidebarContent>
73
+ <MazSidebarMenu>
74
+ <MazSidebarMenuItem>
75
+ <MazSidebarMenuButton label="Dashboard" :active="true" />
76
+ </MazSidebarMenuItem>
77
+ <MazSidebarMenuItem>
78
+ <MazSidebarMenuButton label="Settings" />
79
+ </MazSidebarMenuItem>
80
+ </MazSidebarMenu>
81
+ </MazSidebarContent>
82
+ <MazSidebarFooter>
83
+ <div class="maz:p-4">Footer</div>
84
+ </MazSidebarFooter>
85
+ </MazSidebar>
86
+ <main class="maz:flex-1 maz:p-4">Main content</main>
87
+ </div>
88
+
89
+ <script setup>
90
+ const isOpen = ref(true)
91
+ </script>
92
+ ```
93
+
94
+ </template>
95
+ </ComponentDemo>
96
+
97
+ ## Groups & dividers
98
+
99
+ <ComponentDemo>
100
+ <div class="maz:border maz:border-divider maz:overflow-hidden maz:rounded-md maz:h-[25rem] maz:flex">
101
+ <MazSidebar v-model:open="groupsOpen" class="maz:h-full">
102
+ <MazSidebarContent>
103
+ <MazSidebarGroup label="Navigation">
104
+ <MazSidebarMenu>
105
+ <MazSidebarMenuItem>
106
+ <MazSidebarMenuButton label="Dashboard" :active="true" />
107
+ </MazSidebarMenuItem>
108
+ <MazSidebarMenuItem>
109
+ <MazSidebarMenuButton label="Projects" />
110
+ </MazSidebarMenuItem>
111
+ </MazSidebarMenu>
112
+ </MazSidebarGroup>
113
+ <MazSidebarSeparator />
114
+ <MazSidebarGroup label="Settings">
115
+ <MazSidebarMenu>
116
+ <MazSidebarMenuItem>
117
+ <MazSidebarMenuButton label="Profile" />
118
+ </MazSidebarMenuItem>
119
+ <MazSidebarMenuItem>
120
+ <MazSidebarMenuButton label="Billing" />
121
+ </MazSidebarMenuItem>
122
+ </MazSidebarMenu>
123
+ </MazSidebarGroup>
124
+ </MazSidebarContent>
125
+ </MazSidebar>
126
+ <main class="maz:flex-1 maz:p-4">Main content</main>
127
+ </div>
128
+
129
+ <template #code>
130
+
131
+ ```html
132
+ <MazSidebar v-model:open="isOpen">
133
+ <MazSidebarContent>
134
+ <MazSidebarGroup label="Navigation">
135
+ <MazSidebarMenu>
136
+ <MazSidebarMenuItem>
137
+ <MazSidebarMenuButton label="Dashboard" :active="true" />
138
+ </MazSidebarMenuItem>
139
+ <MazSidebarMenuItem>
140
+ <MazSidebarMenuButton label="Projects" />
141
+ </MazSidebarMenuItem>
142
+ </MazSidebarMenu>
143
+ </MazSidebarGroup>
144
+ <MazSidebarSeparator />
145
+ <MazSidebarGroup label="Settings">
146
+ <MazSidebarMenu>
147
+ <MazSidebarMenuItem>
148
+ <MazSidebarMenuButton label="Profile" />
149
+ </MazSidebarMenuItem>
150
+ </MazSidebarMenu>
151
+ </MazSidebarGroup>
152
+ </MazSidebarContent>
153
+ </MazSidebar>
154
+ ```
155
+
156
+ </template>
157
+ </ComponentDemo>
158
+
159
+ ## Sub-menus
160
+
161
+ <ComponentDemo>
162
+ <div class="maz:border maz:border-divider maz:overflow-hidden maz:rounded-md maz:h-[25rem] maz:flex">
163
+ <MazSidebar v-model:open="submenusOpen" class="maz:h-full">
164
+ <MazSidebarContent>
165
+ <MazSidebarMenu>
166
+ <MazSidebarMenuItem>
167
+ <MazSidebarMenuButton label="Dashboard" :active="true" />
168
+ </MazSidebarMenuItem>
169
+ <MazSidebarMenuItem>
170
+ <MazSidebarMenuSub label="Products" :default-open="true">
171
+ <MazSidebarMenuItem>
172
+ <MazSidebarMenuButton label="All Products" />
173
+ </MazSidebarMenuItem>
174
+ <MazSidebarMenuItem>
175
+ <MazSidebarMenuButton label="Add Product" />
176
+ </MazSidebarMenuItem>
177
+ </MazSidebarMenuSub>
178
+ </MazSidebarMenuItem>
179
+ <MazSidebarMenuItem>
180
+ <MazSidebarMenuSub label="Reports">
181
+ <MazSidebarMenuItem>
182
+ <MazSidebarMenuButton label="Sales" />
183
+ </MazSidebarMenuItem>
184
+ </MazSidebarMenuSub>
185
+ </MazSidebarMenuItem>
186
+ </MazSidebarMenu>
187
+ </MazSidebarContent>
188
+ </MazSidebar>
189
+ <main class="maz:flex-1 maz:p-4">Main content</main>
190
+ </div>
191
+
192
+ <template #code>
193
+
194
+ ```html
195
+ <MazSidebar v-model:open="isOpen">
196
+ <MazSidebarContent>
197
+ <MazSidebarMenu>
198
+ <MazSidebarMenuItem>
199
+ <MazSidebarMenuSub label="Products" :default-open="true">
200
+ <MazSidebarMenuItem>
201
+ <MazSidebarMenuButton label="All Products" />
202
+ </MazSidebarMenuItem>
203
+ <MazSidebarMenuItem>
204
+ <MazSidebarMenuButton label="Add Product" />
205
+ </MazSidebarMenuItem>
206
+ </MazSidebarMenuSub>
207
+ </MazSidebarMenuItem>
208
+ </MazSidebarMenu>
209
+ </MazSidebarContent>
210
+ </MazSidebar>
211
+ ```
212
+
213
+ </template>
214
+ </ComponentDemo>
215
+
216
+ ## Icon mode with tooltips
217
+
218
+ 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.
219
+
220
+ ### Controlling when the tooltip appears
221
+
222
+ Both `MazSidebar` and `MazSidebarMenuButton` accept a `tooltip-mode` prop:
223
+
224
+ - `closed` (default on the sidebar) — tooltip only shows on hover when the sidebar is collapsed
225
+ - `always` — tooltip shows on hover regardless of the sidebar state
226
+
227
+ Set it on the sidebar to apply to every descendant button, or override per-button:
228
+
229
+ ```html
230
+ <!-- Every button: tooltip visible only when collapsed -->
231
+ <MazSidebar tooltip-mode="closed">
232
+ <MazSidebarMenuButton :icon="MazHome" label="Dashboard" tooltip="Go to Dashboard" />
233
+ </MazSidebar>
234
+
235
+ <!-- This button overrides: tooltip always shown -->
236
+ <MazSidebar tooltip-mode="closed">
237
+ <MazSidebarMenuButton
238
+ :icon="MazCog6Tooth"
239
+ label="Settings"
240
+ tooltip="Open Settings"
241
+ tooltip-mode="always"
242
+ />
243
+ </MazSidebar>
244
+ ```
245
+
246
+ ::: tip Performance
247
+ When no `tooltip` prop is provided on a button, the `v-tooltip` directive is not attached at all — no listeners, no popover instance.
248
+ :::
249
+
250
+ <ComponentDemo>
251
+ <div class="maz:border maz:border-divider maz:overflow-hidden maz:rounded-md maz:h-[25rem] maz:flex">
252
+ <MazSidebar v-model:open="iconModeOpen" collapsible="icon" class="maz:h-full">
253
+ <MazSidebarContent>
254
+ <MazSidebarMenu>
255
+ <MazSidebarMenuItem>
256
+ <MazSidebarMenuButton :icon="MazHome" label="Dashboard" tooltip="Go to Dashboard" :active="true" />
257
+ </MazSidebarMenuItem>
258
+ <MazSidebarMenuItem>
259
+ <MazSidebarMenuButton :icon="MazCog6Tooth" label="Settings" tooltip="Open Settings" />
260
+ </MazSidebarMenuItem>
261
+ </MazSidebarMenu>
262
+ </MazSidebarContent>
263
+ <MazSidebarFooter>
264
+ <MazSidebarTrigger />
265
+ </MazSidebarFooter>
266
+ </MazSidebar>
267
+ <main class="maz:flex-1 maz:flex maz:flex-col maz:gap-4 maz:p-4">
268
+ Click the trigger to collapse/expand
269
+ <MazBtn @click="iconModeOpen = !iconModeOpen">Toggle sidebar</MazBtn>
270
+ </main>
271
+ </div>
272
+
273
+ <template #code>
274
+
275
+ ```html
276
+ <script setup>
277
+ import { MazHome } from '@maz-ui/icons/lazy/MazHome'
278
+ import { MazCog6Tooth } from '@maz-ui/icons/lazy/MazCog6Tooth'
279
+
280
+ const isOpen = ref(true)
281
+ </script>
282
+
283
+ <template>
284
+ <MazSidebar v-model:open="isOpen" collapsible="icon">
285
+ <MazSidebarContent>
286
+ <MazSidebarMenu>
287
+ <MazSidebarMenuItem>
288
+ <MazSidebarMenuButton :icon="MazHome" label="Dashboard" tooltip="Go to Dashboard" />
289
+ </MazSidebarMenuItem>
290
+ </MazSidebarMenu>
291
+ </MazSidebarContent>
292
+ <MazSidebarFooter>
293
+ <MazSidebarTrigger />
294
+ </MazSidebarFooter>
295
+ </MazSidebar>
296
+ </template>
297
+ ```
298
+
299
+ </template>
300
+ </ComponentDemo>
301
+
302
+ ## Offcanvas mode
303
+
304
+ <ComponentDemo>
305
+ <div class="maz:border maz:border-divider maz:overflow-hidden maz:rounded-md maz:h-[20rem] maz:flex">
306
+ <MazSidebar v-model:open="offcanvasOpen" collapsible="offcanvas" class="maz:h-full">
307
+ <MazSidebarContent>
308
+ <MazSidebarMenu>
309
+ <MazSidebarMenuItem>
310
+ <MazSidebarMenuButton label="Home" :active="true" />
311
+ </MazSidebarMenuItem>
312
+ <MazSidebarMenuItem>
313
+ <MazSidebarMenuButton label="About" />
314
+ </MazSidebarMenuItem>
315
+ </MazSidebarMenu>
316
+ </MazSidebarContent>
317
+ </MazSidebar>
318
+ <main class="maz:flex-1 maz:flex maz:flex-col maz:gap-4 maz:p-4">
319
+ <MazBtn @click="offcanvasOpen = !offcanvasOpen">Toggle sidebar</MazBtn>
320
+ Main content — sidebar disappears completely when closed
321
+ </main>
322
+ </div>
323
+
324
+ <template #code>
325
+
326
+ ```html
327
+ <MazSidebar v-model:open="isOpen" collapsible="offcanvas">
328
+ <!-- content -->
329
+ </MazSidebar>
330
+ ```
331
+
332
+ </template>
333
+ </ComponentDemo>
334
+
335
+ ## Overlay vs push mode
336
+
337
+ In `mode="push"` (default), the sidebar is part of the document flow and pushes the main content.
338
+ In `mode="overlay"`, the sidebar floats over the content with a backdrop, escape key support and focus trapping.
339
+
340
+ <ComponentDemo>
341
+ <div class="maz:border maz:border-divider maz:overflow-hidden maz:rounded-md maz:h-[20rem] maz:relative">
342
+ <MazBtn class="maz:absolute maz:top-4 maz:left-4 maz:z-1" @click="overlayOpen = !overlayOpen">
343
+ Toggle overlay sidebar
344
+ </MazBtn>
345
+ <MazSidebar v-model:open="overlayOpen" mode="overlay">
346
+ <MazSidebarHeader>
347
+ <div class="maz:p-4 maz:font-bold">Overlay Sidebar</div>
348
+ </MazSidebarHeader>
349
+ <MazSidebarContent>
350
+ <MazSidebarMenu>
351
+ <MazSidebarMenuItem>
352
+ <MazSidebarMenuButton label="Home" :active="true" />
353
+ </MazSidebarMenuItem>
354
+ </MazSidebarMenu>
355
+ </MazSidebarContent>
356
+ <MazSidebarFooter>
357
+ <MazSidebarTrigger />
358
+ </MazSidebarFooter>
359
+ </MazSidebar>
360
+ </div>
361
+
362
+ <template #code>
363
+
364
+ ```html
365
+ <!-- Overlay mode: sidebar floats over content -->
366
+ <MazSidebar v-model:open="isOpen" mode="overlay">
367
+ <!-- content -->
368
+ </MazSidebar>
369
+ ```
370
+
371
+ </template>
372
+ </ComponentDemo>
373
+
374
+ ## Side end (right)
375
+
376
+ <ComponentDemo>
377
+ <div class="maz:border maz:border-divider maz:overflow-hidden maz:rounded-md maz:h-[20rem] maz:flex">
378
+ <main class="maz:flex-1 maz:p-4">Main content</main>
379
+ <MazSidebar v-model:open="sideEndOpen" side="end" class="maz:h-full">
380
+ <MazSidebarContent>
381
+ <MazSidebarMenu>
382
+ <MazSidebarMenuItem>
383
+ <MazSidebarMenuButton label="Right panel item" />
384
+ </MazSidebarMenuItem>
385
+ </MazSidebarMenu>
386
+ </MazSidebarContent>
387
+ </MazSidebar>
388
+ </div>
389
+
390
+ <template #code>
391
+
392
+ ```html
393
+ <div class="maz:flex maz:h-screen">
394
+ <main class="maz:flex-1">Main content</main>
395
+ <MazSidebar v-model:open="isOpen" side="end">
396
+ <!-- content -->
397
+ </MazSidebar>
398
+ </div>
399
+ ```
400
+
401
+ </template>
402
+ </ComponentDemo>
403
+
404
+ ## Badges
405
+
406
+ `badge` accepts a `string`, a `number`, or a full `MazBadgeProps` object (with an optional `text`) to fine-tune color, size, outlined, etc.
407
+
408
+ <ComponentDemo>
409
+ <div class="maz:border maz:border-divider maz:overflow-hidden maz:rounded-md maz:h-[22rem] maz:flex">
410
+ <MazSidebar v-model:open="badgesOpen" class="maz:h-full">
411
+ <MazSidebarContent>
412
+ <MazSidebarMenu>
413
+ <MazSidebarMenuItem>
414
+ <MazSidebarMenuButton label="Inbox" :badge="12" :active="true" />
415
+ </MazSidebarMenuItem>
416
+ <MazSidebarMenuItem>
417
+ <MazSidebarMenuButton label="Errors" :badge="{ text: 3, color: 'destructive' }" />
418
+ </MazSidebarMenuItem>
419
+ <MazSidebarMenuItem>
420
+ <MazSidebarMenuButton label="Beta" :badge="{ text: 'NEW', color: 'success', outlined: true }" />
421
+ </MazSidebarMenuItem>
422
+ <MazSidebarMenuItem>
423
+ <MazSidebarMenuButton label="Settings" />
424
+ </MazSidebarMenuItem>
425
+ </MazSidebarMenu>
426
+ </MazSidebarContent>
427
+ </MazSidebar>
428
+ <main class="maz:flex-1 maz:flex maz:flex-col maz:gap-4 maz:p-4">
429
+ Badges are hidden in icon-collapsed mode.
430
+ <MazBtn @click="badgesOpen = !badgesOpen">Toggle sidebar</MazBtn>
431
+ </main>
432
+ </div>
433
+
434
+ <template #code>
435
+
436
+ ```html
437
+ <!-- Simple: pass a string or number -->
438
+ <MazSidebarMenuButton label="Inbox" :badge="12" />
439
+
440
+ <!-- Full customisation: pass a MazBadgeProps object -->
441
+ <MazSidebarMenuButton
442
+ label="Errors"
443
+ :badge="{ text: 3, color: 'destructive' }"
444
+ />
445
+ <MazSidebarMenuButton
446
+ label="Beta"
447
+ :badge="{ text: 'NEW', color: 'success', outlined: true }"
448
+ />
449
+ ```
450
+
451
+ </template>
452
+ </ComponentDemo>
453
+
454
+ ## User menu in footer
455
+
456
+ <ComponentDemo>
457
+ <div class="maz:border maz:border-divider maz:overflow-hidden maz:rounded-md maz:h-[22rem] maz:flex">
458
+ <MazSidebar v-model:open="userMenuOpen" class="maz:h-full">
459
+ <MazSidebarContent>
460
+ <MazSidebarMenu>
461
+ <MazSidebarMenuItem>
462
+ <MazSidebarMenuButton label="Dashboard" :active="true" />
463
+ </MazSidebarMenuItem>
464
+ </MazSidebarMenu>
465
+ </MazSidebarContent>
466
+ <MazSidebarFooter>
467
+ <div class="maz:flex maz:items-center maz:gap-3 maz:p-3">
468
+ <MazAvatar src="https://placedog.net/100/100" size="0.8rem" />
469
+ <div class="maz:flex-1 maz:min-w-0">
470
+ <p class="maz:m-0 maz:text-md maz:font-semibold">Jane Doe</p>
471
+ <p class="maz:m-0 maz:text-xs maz:text-muted">jane@example.com</p>
472
+ </div>
473
+ </div>
474
+ </MazSidebarFooter>
475
+ </MazSidebar>
476
+ <main class="maz:flex-1 maz:p-4">Main content</main>
477
+ </div>
478
+
479
+ <template #code>
480
+
481
+ ```html
482
+ <MazSidebar v-model:open="isOpen">
483
+ <MazSidebarContent><!-- ... --></MazSidebarContent>
484
+ <MazSidebarFooter>
485
+ <div class="maz:flex maz:items-center maz:gap-3 maz:p-3">
486
+ <MazAvatar src="..." size="0.8rem" />
487
+ <div class="maz:flex-1 maz:min-w-0">
488
+ <p class="maz:m-0 maz:text-md maz:font-semibold">Jane Doe</p>
489
+ <p class="maz:m-0 maz:text-xs maz:text-muted">jane@example.com</p>
490
+ </div>
491
+ </div>
492
+ </MazSidebarFooter>
493
+ </MazSidebar>
494
+ ```
495
+
496
+ </template>
497
+ </ComponentDemo>
498
+
499
+ ## Mobile (static rendering)
500
+
501
+ ::: info
502
+ 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.
503
+ :::
504
+
505
+ ```html
506
+ <script setup>
507
+ import { useWindowSize } from 'maz-ui'
508
+
509
+ const { width } = useWindowSize()
510
+ const isMobile = computed(() => width.value < 768)
511
+ const isOpen = ref(!isMobile.value)
512
+
513
+ watch(isMobile, (mobile) => {
514
+ isOpen.value = !mobile
515
+ })
516
+ </script>
517
+
518
+ <template>
519
+ <div class="maz:flex maz:h-screen">
520
+ <MazSidebar v-model:open="isOpen" :mode="isMobile ? 'overlay' : 'push'">
521
+ <!-- content -->
522
+ </MazSidebar>
523
+ <main class="maz:flex-1">
524
+ <MazSidebarTrigger />
525
+ <!-- page content -->
526
+ </main>
527
+ </div>
528
+ </template>
529
+ ```
530
+
531
+ ## Programmatic control (v-model + composable)
532
+
533
+ Use `v-model:open` for two-way binding, or `useSidebar()` inside any descendant component.
534
+
535
+ ```html
536
+ <script setup>
537
+ import { useSidebar } from 'maz-ui'
538
+
539
+ // Inside a child component that is a descendant of MazSidebar:
540
+ const sidebar = useSidebar()
541
+
542
+ // sidebar.open.value → boolean
543
+ // sidebar.state.value → 'expanded' | 'collapsed'
544
+ // sidebar.toggle() → toggle open state
545
+ // sidebar.setOpen(true/false) → set explicitly
546
+ </script>
547
+
548
+ <template>
549
+ <MazSidebar v-model:open="isOpen">
550
+ <MazSidebarContent>
551
+ <MazSidebarMenu>
552
+ <MazSidebarMenuItem>
553
+ <MazSidebarMenuButton label="Dashboard" />
554
+ </MazSidebarMenuItem>
555
+ </MazSidebarMenu>
556
+ </MazSidebarContent>
557
+ <!-- MazSidebarTrigger uses useSidebar() internally -->
558
+ <MazSidebarTrigger />
559
+ </MazSidebar>
560
+ </template>
561
+ ```
562
+
563
+ ## Persistent open state
564
+
565
+ The sidebar persists its open/collapsed state in a cookie (`maz-sidebar-open`) so it survives page reloads. This is **enabled by default**.
566
+
567
+ ```html
568
+ <!-- Default: persistence enabled, cookie name "maz-sidebar-open" -->
569
+ <MazSidebar v-model:open="isOpen" />
570
+
571
+ <!-- Disable persistence -->
572
+ <MazSidebar v-model:open="isOpen" :persist="false" />
573
+
574
+ <!-- Custom cookie key (useful when multiple sidebars coexist) -->
575
+ <MazSidebar v-model:open="isOpen" persist-key="admin-sidebar-open" />
576
+ ```
577
+
578
+ ### How it works
579
+
580
+ - **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`.
581
+ - **On client mount**: `update:open` is emitted if the persisted value differs from the `:open` prop, so your parent `v-model` stays in sync.
582
+ - **On state change**: every transition between expanded/collapsed writes the new value to the cookie (1-year expiry, `SameSite=Lax`).
583
+
584
+ ### SSR considerations
585
+
586
+ 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()`.
587
+
588
+ 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:
589
+
590
+ ```html
591
+ <script setup>
592
+ const sidebarOpen = useCookie<boolean>('maz-sidebar-open', { default: () => true })
593
+ </script>
594
+
595
+ <template>
596
+ <MazSidebar v-model:open="sidebarOpen" :persist="false">
597
+ <!-- ... -->
598
+ </MazSidebar>
599
+ </template>
600
+ ```
601
+
602
+ `:persist="false"` prevents the sidebar from also writing the cookie, leaving full control to your `useCookie` ref.
603
+
604
+ ## With router (vue-router / NuxtLink)
605
+
606
+ `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.
607
+
608
+ ```html
609
+ <!-- With vue-router -->
610
+ <MazSidebarMenuButton :to="{ name: 'home' }" label="Home" />
611
+ <MazSidebarMenuButton to="/about" label="About" />
612
+
613
+ <!-- With plain href -->
614
+ <MazSidebarMenuButton href="https://maz-ui.com" label="Docs" />
615
+
616
+ <!-- Mark as active manually (useful when router is not available) -->
617
+ <MazSidebarMenuButton label="Dashboard" :active="$route.name === 'dashboard'" />
618
+ ```
619
+
620
+ ## CSS Variables
621
+
622
+ Customize the sidebar width using these CSS custom properties (also settable via `width` / `iconWidth` props):
623
+
624
+ ```css
625
+ :root {
626
+ --maz-sidebar-width: 16rem; /* expanded width */
627
+ --maz-sidebar-icon-width: 3rem; /* icon-mode collapsed width */
628
+ }
629
+ ```
630
+
631
+ ## Accessibility
632
+
633
+ - The sidebar root element renders as `<aside aria-label="Sidebar">`
634
+ - `MazSidebarMenu` renders as `<ul role="menu">`
635
+ - `MazSidebarMenuItem` renders as `<li role="none">`
636
+ - `MazSidebarTrigger` has `aria-expanded` and `aria-controls` referencing the sidebar `id`
637
+ - `MazSidebarMenuButton` applies `aria-current="page"` on active items and exposes the label via `aria-label`
638
+ - `MazSidebarMenuSub` trigger has `aria-expanded` and `aria-controls`
639
+ - In `mode="overlay"`, pressing `Escape` closes the sidebar and focus is restored to the trigger element
640
+ - In `mode="overlay"`, `Tab`/`Shift+Tab` are trapped within the sidebar
641
+ - All transitions respect `prefers-reduced-motion`
642
+
643
+ ## MazSidebar
644
+
645
+ <!--@include: ./../../.vitepress/generated-docs/maz-sidebar.doc.md-->
646
+
647
+ ## MazSidebarMenuButton
648
+
649
+ <!--@include: ./../../.vitepress/generated-docs/maz-sidebar-menu-button.doc.md-->
650
+
651
+ ## MazSidebarMenuSub
652
+
653
+ <!--@include: ./../../.vitepress/generated-docs/maz-sidebar-menu-sub.doc.md-->
654
+
655
+ ## MazSidebarGroup
656
+
657
+ <!--@include: ./../../.vitepress/generated-docs/maz-sidebar-group.doc.md-->
658
+
659
+ <script setup>
660
+ import { ref } from 'vue'
661
+
662
+ import { MazHome } from '@maz-ui/icons/lazy/MazHome'
663
+ import { MazCog6Tooth } from '@maz-ui/icons/lazy/MazCog6Tooth'
664
+
665
+ const overlayOpen = ref(false)
666
+ const offcanvasOpen = ref(true)
667
+ const userMenuOpen = ref(true)
668
+ const badgesOpen = ref(true)
669
+ const sideEndOpen = ref(true)
670
+ const iconModeOpen = ref(true)
671
+ const submenusOpen = ref(true)
672
+ const groupsOpen = ref(true)
673
+ const basicOpen = ref(true)
674
+ </script>