@cocoar/vue-ui 3.2.0-beta.5 → 3.2.0-beta.6

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 (110) hide show
  1. package/package.json +5 -3
  2. package/skills/cocoar-vue-ui/SKILL.md +244 -0
  3. package/skills/cocoar-vue-ui/references/components/avatar.md +178 -0
  4. package/skills/cocoar-vue-ui/references/components/badge.md +290 -0
  5. package/skills/cocoar-vue-ui/references/components/breadcrumb.md +238 -0
  6. package/skills/cocoar-vue-ui/references/components/button.md +252 -0
  7. package/skills/cocoar-vue-ui/references/components/calendar/agenda-view.md +353 -0
  8. package/skills/cocoar-vue-ui/references/components/calendar/coar-calendar.md +1645 -0
  9. package/skills/cocoar-vue-ui/references/components/calendar/day-view.md +361 -0
  10. package/skills/cocoar-vue-ui/references/components/calendar/index.md +312 -0
  11. package/skills/cocoar-vue-ui/references/components/calendar/month-view.md +475 -0
  12. package/skills/cocoar-vue-ui/references/components/calendar/performance.md +186 -0
  13. package/skills/cocoar-vue-ui/references/components/calendar/timeline-view.md +301 -0
  14. package/skills/cocoar-vue-ui/references/components/calendar/week-view.md +382 -0
  15. package/skills/cocoar-vue-ui/references/components/calendar/work-week-view.md +145 -0
  16. package/skills/cocoar-vue-ui/references/components/calendar/year-view.md +63 -0
  17. package/skills/cocoar-vue-ui/references/components/card.md +151 -0
  18. package/skills/cocoar-vue-ui/references/components/checkbox-group.md +103 -0
  19. package/skills/cocoar-vue-ui/references/components/checkbox.md +279 -0
  20. package/skills/cocoar-vue-ui/references/components/code-block.md +241 -0
  21. package/skills/cocoar-vue-ui/references/components/context-menu.md +355 -0
  22. package/skills/cocoar-vue-ui/references/components/data-grid/checkbox.md +213 -0
  23. package/skills/cocoar-vue-ui/references/components/data-grid/date-columns.md +272 -0
  24. package/skills/cocoar-vue-ui/references/components/data-grid/editing.md +236 -0
  25. package/skills/cocoar-vue-ui/references/components/data-grid/multi-select.md +193 -0
  26. package/skills/cocoar-vue-ui/references/components/data-grid/number.md +147 -0
  27. package/skills/cocoar-vue-ui/references/components/data-grid/select.md +202 -0
  28. package/skills/cocoar-vue-ui/references/components/data-grid/text.md +127 -0
  29. package/skills/cocoar-vue-ui/references/components/data-grid.md +1225 -0
  30. package/skills/cocoar-vue-ui/references/components/data-list.md +2121 -0
  31. package/skills/cocoar-vue-ui/references/components/date-or-time-picker.md +200 -0
  32. package/skills/cocoar-vue-ui/references/components/date-picker.md +203 -0
  33. package/skills/cocoar-vue-ui/references/components/date-time-picker.md +154 -0
  34. package/skills/cocoar-vue-ui/references/components/date-views.md +212 -0
  35. package/skills/cocoar-vue-ui/references/components/dialog.md +148 -0
  36. package/skills/cocoar-vue-ui/references/components/divider.md +157 -0
  37. package/skills/cocoar-vue-ui/references/components/document-viewer/annotations.md +400 -0
  38. package/skills/cocoar-vue-ui/references/components/document-viewer/coar-document-viewer.md +327 -0
  39. package/skills/cocoar-vue-ui/references/components/document-viewer/index.md +234 -0
  40. package/skills/cocoar-vue-ui/references/components/document-viewer/toolbar.md +221 -0
  41. package/skills/cocoar-vue-ui/references/components/drag-drop.md +267 -0
  42. package/skills/cocoar-vue-ui/references/components/dual-listbox.md +449 -0
  43. package/skills/cocoar-vue-ui/references/components/file-explorer/asset-store.md +327 -0
  44. package/skills/cocoar-vue-ui/references/components/file-explorer/in-memory-store.md +176 -0
  45. package/skills/cocoar-vue-ui/references/components/file-explorer/index.md +311 -0
  46. package/skills/cocoar-vue-ui/references/components/file-explorer/use-file-explorer.md +300 -0
  47. package/skills/cocoar-vue-ui/references/components/form-field.md +1025 -0
  48. package/skills/cocoar-vue-ui/references/components/fragment-parser.md +298 -0
  49. package/skills/cocoar-vue-ui/references/components/link.md +235 -0
  50. package/skills/cocoar-vue-ui/references/components/listbox.md +575 -0
  51. package/skills/cocoar-vue-ui/references/components/map/editor.md +448 -0
  52. package/skills/cocoar-vue-ui/references/components/map/index.md +351 -0
  53. package/skills/cocoar-vue-ui/references/components/markdown-diagrams.md +210 -0
  54. package/skills/cocoar-vue-ui/references/components/markdown-editor.md +1478 -0
  55. package/skills/cocoar-vue-ui/references/components/markdown-embeds.md +387 -0
  56. package/skills/cocoar-vue-ui/references/components/markdown-form.md +447 -0
  57. package/skills/cocoar-vue-ui/references/components/markdown.md +276 -0
  58. package/skills/cocoar-vue-ui/references/components/menu.md +380 -0
  59. package/skills/cocoar-vue-ui/references/components/mermaid.md +172 -0
  60. package/skills/cocoar-vue-ui/references/components/navbar.md +147 -0
  61. package/skills/cocoar-vue-ui/references/components/note.md +96 -0
  62. package/skills/cocoar-vue-ui/references/components/notice.md +131 -0
  63. package/skills/cocoar-vue-ui/references/components/number-input.md +215 -0
  64. package/skills/cocoar-vue-ui/references/components/otp-input.md +324 -0
  65. package/skills/cocoar-vue-ui/references/components/page-builder/authoring-contract.md +271 -0
  66. package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-builder.md +476 -0
  67. package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-renderer.md +677 -0
  68. package/skills/cocoar-vue-ui/references/components/page-builder/custom-elements.md +441 -0
  69. package/skills/cocoar-vue-ui/references/components/page-builder/idp-integration.md +122 -0
  70. package/skills/cocoar-vue-ui/references/components/page-builder/index.md +573 -0
  71. package/skills/cocoar-vue-ui/references/components/pagination.md +150 -0
  72. package/skills/cocoar-vue-ui/references/components/panel-layout.md +372 -0
  73. package/skills/cocoar-vue-ui/references/components/password-input.md +175 -0
  74. package/skills/cocoar-vue-ui/references/components/popconfirm.md +186 -0
  75. package/skills/cocoar-vue-ui/references/components/popover.md +173 -0
  76. package/skills/cocoar-vue-ui/references/components/progress-bar.md +178 -0
  77. package/skills/cocoar-vue-ui/references/components/radio-group.md +225 -0
  78. package/skills/cocoar-vue-ui/references/components/script-editor.md +1271 -0
  79. package/skills/cocoar-vue-ui/references/components/segmented-control.md +238 -0
  80. package/skills/cocoar-vue-ui/references/components/select.md +463 -0
  81. package/skills/cocoar-vue-ui/references/components/sidebar.md +421 -0
  82. package/skills/cocoar-vue-ui/references/components/spinner.md +132 -0
  83. package/skills/cocoar-vue-ui/references/components/switch.md +195 -0
  84. package/skills/cocoar-vue-ui/references/components/table.md +170 -0
  85. package/skills/cocoar-vue-ui/references/components/tabs.md +382 -0
  86. package/skills/cocoar-vue-ui/references/components/tag.md +178 -0
  87. package/skills/cocoar-vue-ui/references/components/text-input.md +256 -0
  88. package/skills/cocoar-vue-ui/references/components/toast.md +160 -0
  89. package/skills/cocoar-vue-ui/references/components/tooltip.md +121 -0
  90. package/skills/cocoar-vue-ui/references/components/transitions.md +193 -0
  91. package/skills/cocoar-vue-ui/references/components/tree.md +2388 -0
  92. package/skills/cocoar-vue-ui/references/components/virtual-list.md +212 -0
  93. package/skills/cocoar-vue-ui/references/components/wizard.md +251 -0
  94. package/skills/cocoar-vue-ui/references/components/zoned-date-time-picker.md +177 -0
  95. package/skills/cocoar-vue-ui/references/foundations/colors.md +708 -0
  96. package/skills/cocoar-vue-ui/references/foundations/design-principles.md +115 -0
  97. package/skills/cocoar-vue-ui/references/foundations/icons.md +381 -0
  98. package/skills/cocoar-vue-ui/references/foundations/localization/formatting.md +530 -0
  99. package/skills/cocoar-vue-ui/references/foundations/localization/setup.md +86 -0
  100. package/skills/cocoar-vue-ui/references/foundations/localization/timezones.md +182 -0
  101. package/skills/cocoar-vue-ui/references/foundations/localization/translations.md +305 -0
  102. package/skills/cocoar-vue-ui/references/foundations/motion.md +549 -0
  103. package/skills/cocoar-vue-ui/references/foundations/spacing.md +330 -0
  104. package/skills/cocoar-vue-ui/references/foundations/theming.md +140 -0
  105. package/skills/cocoar-vue-ui/references/foundations/typography.md +206 -0
  106. package/skills/cocoar-vue-ui/references/guide/error-handling.md +162 -0
  107. package/skills/cocoar-vue-ui/references/guide/getting-started.md +119 -0
  108. package/skills/cocoar-vue-ui/references/guide/migration-page-builder-3.md +207 -0
  109. package/skills/cocoar-vue-ui/references/guide/migration.md +140 -0
  110. package/skills/cocoar-vue-ui/references/guide/theming.md +98 -0
@@ -0,0 +1,421 @@
1
+ <!-- Generated from apps/docs/components/sidebar.md by apps/docs/scripts/sync-skill.mjs. Do not edit; edit the docs page. -->
2
+
3
+ # Sidebar
4
+
5
+ A structured navigation sidebar with three distinct sections: a header for branding, a scrollable content area for navigation, and a footer for secondary actions. Use the dedicated sidebar components (`CoarSidebarItem`, `CoarSidebarGroup`, `CoarSidebarHeading`, `CoarSidebarDivider`, `CoarSidebarSpacer`) for full collapsed/expanded support with automatic tooltips.
6
+
7
+ ```ts
8
+ import {
9
+ CoarSidebar,
10
+ CoarSidebarItem,
11
+ CoarSidebarGroup,
12
+ CoarSidebarHeading,
13
+ CoarSidebarDivider,
14
+ CoarSidebarSpacer,
15
+ } from '@cocoar/vue-ui';
16
+ ```
17
+
18
+ ## Sidebar Items
19
+
20
+ Use `CoarSidebarItem` for navigation, `CoarSidebarGroup` for expandable or flyout sections, and `CoarSidebarHeading` for section labels. Items go directly into the sidebar — no `CoarMenu` wrapper needed.
21
+
22
+ Toggle `collapsed` for icon-only mode with automatic tooltips. Groups support two modes: `expand` (inline panel with plus/minus indicator) and `flyout` (floating panel with chevron indicator). Use the controls to explore all options.
23
+
24
+ **Demo — `sidebar/demos/SidebarItems.vue`**
25
+
26
+ ```vue
27
+ <template>
28
+ <div style="display: flex; flex-direction: column; gap: 16px;">
29
+ <div style="display: flex; flex-wrap: wrap; gap: 12px; align-items: center;">
30
+ <CoarCheckbox v-model="collapsed" label="collapsed" />
31
+ <CoarSelect v-model="size" :options="sizeOptions" label="size" size="s" style="width: 100px;" />
32
+ <CoarSelect v-model="variant" :options="variantOptions" label="variant" size="s" style="width: 140px;" />
33
+ <CoarCheckbox v-model="elevated" label="elevated" />
34
+ <CoarCheckbox v-model="borderless" label="borderless" />
35
+ </div>
36
+
37
+ <div style="height: 560px; border: 1px solid var(--coar-border-neutral-secondary); border-radius: 8px; overflow: hidden; display: flex;">
38
+ <CoarSidebar
39
+ v-model:collapsed="collapsed"
40
+ :size="size"
41
+ :variant="variant"
42
+ :elevated="elevated"
43
+ :borderless="borderless"
44
+ >
45
+ <template #header="{ collapsed: isCollapsed }">
46
+ <div style="display: flex; align-items: center; gap: 8px; padding: 4px;">
47
+ <div style="width: 28px; height: 28px; background: var(--coar-background-accent-primary); color: white; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 14px; flex-shrink: 0;">C</div>
48
+ <strong v-if="!isCollapsed" style="white-space: nowrap;">cocoar</strong>
49
+ </div>
50
+ </template>
51
+
52
+ <CoarSidebarItem icon="home" label="Dashboard" active />
53
+ <CoarSidebarItem icon="user" label="Profile" />
54
+ <CoarSidebarItem icon="list" label="Projects" />
55
+ <CoarSidebarItem label="No Icon Item" />
56
+
57
+ <CoarSidebarHeading label="Management" />
58
+ <CoarSidebarGroup icon="users" label="Users" v-model:open="usersOpen">
59
+ <CoarSidebarItem icon="user-plus" label="All Users" />
60
+ <CoarSidebarItem icon="shield" label="Roles" />
61
+ <CoarSidebarItem icon="lock" label="Permissions" />
62
+ </CoarSidebarGroup>
63
+ <CoarSidebarGroup icon="list" label="Reports (hover)" mode="flyout" open-on-hover>
64
+ <CoarSidebarItem icon="globe" label="Sales" />
65
+ <CoarSidebarItem icon="bell" label="Alerts" />
66
+ <CoarSidebarGroup icon="settings" label="Nested flyout" mode="flyout">
67
+ <CoarSidebarItem icon="lock" label="Audit Log" />
68
+ <CoarSidebarItem icon="shield" label="Compliance" />
69
+ </CoarSidebarGroup>
70
+ <CoarSidebarGroup icon="list" label="Nested expand" v-model:open="expandInFlyout">
71
+ <CoarSidebarItem icon="user-plus" label="Create" />
72
+ <CoarSidebarItem icon="settings" label="Configure" />
73
+ </CoarSidebarGroup>
74
+ </CoarSidebarGroup>
75
+ <CoarSidebarGroup icon="settings" label="Quick Actions (icons)" mode="flyout" icon-only>
76
+ <CoarSidebarItem icon="user-plus" label="Add User" />
77
+ <CoarSidebarItem icon="lock" label="Lock" />
78
+ <CoarSidebarGroup icon="bell" label="Nested icons" mode="flyout">
79
+ <CoarSidebarItem icon="bell" label="Notify" />
80
+ <CoarSidebarItem icon="shield" label="Security" />
81
+ </CoarSidebarGroup>
82
+ <CoarSidebarGroup icon="list" label="Expand" v-model:open="expandInIconOnly">
83
+ <CoarSidebarItem icon="user-plus" label="Create" />
84
+ <CoarSidebarItem icon="settings" label="Configure" />
85
+ </CoarSidebarGroup>
86
+ </CoarSidebarGroup>
87
+
88
+ <CoarSidebarHeading label="System" />
89
+ <CoarSidebarItem icon="settings" label="Settings" />
90
+ <CoarSidebarItem icon="globe" label="Localization" />
91
+
92
+ <template #footer>
93
+ <CoarSidebarDivider />
94
+ <CoarSidebarItem icon="log-out" label="Logout" />
95
+ <CoarSidebarSpacer height="4px" />
96
+ </template>
97
+ </CoarSidebar>
98
+
99
+ <div style="flex: 1; padding: 24px; display: flex; align-items: center; justify-content: center; color: var(--coar-text-neutral-tertiary);">
100
+ Main content area
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </template>
105
+
106
+ <script setup lang="ts">
107
+ import { ref } from 'vue';
108
+ import {
109
+ CoarSidebar,
110
+ CoarSidebarItem,
111
+ CoarSidebarGroup,
112
+ CoarSidebarHeading,
113
+ CoarSidebarDivider,
114
+ CoarSidebarSpacer,
115
+ CoarCheckbox,
116
+ CoarSelect,
117
+ } from '@cocoar/vue-ui';
118
+ import type { CoarSelectOption } from '@cocoar/vue-ui';
119
+
120
+ const collapsed = ref(false);
121
+ const size = ref<'s' | 'm' | 'l'>('m');
122
+ const variant = ref<'primary' | 'secondary'>('primary');
123
+ const elevated = ref(false);
124
+ const borderless = ref(false);
125
+ const usersOpen = ref(false);
126
+ const reportsOpen = ref(false);
127
+ const expandInFlyout = ref(false);
128
+ const expandInIconOnly = ref(false);
129
+
130
+ const sizeOptions: CoarSelectOption<string>[] = [
131
+ { value: 's', label: 's (16px)' },
132
+ { value: 'm', label: 'm (20px)' },
133
+ { value: 'l', label: 'l (24px)' },
134
+ ];
135
+
136
+ const variantOptions: CoarSelectOption<string>[] = [
137
+ { value: 'primary', label: 'primary' },
138
+ { value: 'secondary', label: 'secondary' },
139
+ ];
140
+ </script>
141
+ ```
142
+
143
+ ## Side / Orientation
144
+
145
+ The `side` prop attaches the sidebar to any of the four edges. `left` and `right` give a vertical column (the classic navigation rail); `top` and `bottom` switch the layout to a horizontal toolbar. Tooltip placement, flyout direction, the active-state indicator border, and the collapsed dimension (width vs. height) all adapt automatically.
146
+
147
+ Use the `side` selector below to flip between all four orientations on the same content.
148
+
149
+ **Demo — `sidebar/demos/SidebarSides.vue`**
150
+
151
+ ```vue
152
+ <template>
153
+ <div style="display: flex; flex-direction: column; gap: 16px;">
154
+ <div style="display: flex; flex-wrap: wrap; gap: 12px; align-items: center;">
155
+ <CoarSelect
156
+ v-model="side"
157
+ :options="sideOptions"
158
+ label="side"
159
+ size="s"
160
+ style="width: 140px;"
161
+ />
162
+ <CoarCheckbox v-model="collapsed" label="collapsed" />
163
+ <CoarCheckbox v-model="elevated" label="elevated" />
164
+ <CoarCheckbox v-model="borderless" label="borderless" />
165
+ <span style="color: var(--coar-text-neutral-tertiary); font-size: 13px;">
166
+ Note: in horizontal sidebars `mode="expand"` opens to the right; `mode="flyout"` opens downward (top) or upward (bottom).
167
+ </span>
168
+ </div>
169
+
170
+ <div
171
+ :style="containerStyle"
172
+ style="height: 480px; border: 1px solid var(--coar-border-neutral-secondary); border-radius: 8px; overflow: hidden;"
173
+ >
174
+ <CoarSidebar
175
+ v-model:collapsed="collapsed"
176
+ :side="side"
177
+ :elevated="elevated"
178
+ :borderless="borderless"
179
+ >
180
+ <CoarSidebarItem icon="home" label="Home" active @click="lastClicked = 'Home'" />
181
+ <CoarSidebarItem icon="user" label="Profile" @click="lastClicked = 'Profile'" />
182
+ <CoarSidebarItem icon="list" label="Projects" @click="lastClicked = 'Projects'" />
183
+
184
+ <CoarSidebarGroup icon="users" label="Team" v-model:open="teamOpen">
185
+ <CoarSidebarItem icon="user-plus" label="Members" @click="lastClicked = 'Members'" />
186
+ <CoarSidebarItem icon="shield" label="Roles" @click="lastClicked = 'Roles'" />
187
+ </CoarSidebarGroup>
188
+
189
+ <CoarSidebarGroup icon="settings" label="Tools" mode="flyout">
190
+ <CoarSidebarItem icon="bell" label="Notifications" @click="lastClicked = 'Notifications'" />
191
+ <CoarSidebarItem icon="lock" label="Security" @click="lastClicked = 'Security'" />
192
+ <CoarSidebarItem icon="globe" label="Localization" @click="lastClicked = 'Localization'" />
193
+ </CoarSidebarGroup>
194
+
195
+ <CoarSidebarItem icon="settings" label="Settings" @click="lastClicked = 'Settings'" />
196
+ </CoarSidebar>
197
+
198
+ <div
199
+ style="flex: 1; padding: 24px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; color: var(--coar-text-neutral-tertiary); text-align: center;"
200
+ >
201
+ <div>Main content area</div>
202
+ <div style="font-size: 13px;">Last clicked: <strong>{{ lastClicked }}</strong></div>
203
+ </div>
204
+ </div>
205
+ </div>
206
+ </template>
207
+
208
+ <script setup lang="ts">
209
+ import { computed, ref } from 'vue';
210
+ import {
211
+ CoarSidebar,
212
+ CoarSidebarItem,
213
+ CoarSidebarGroup,
214
+ CoarCheckbox,
215
+ CoarSelect,
216
+ } from '@cocoar/vue-ui';
217
+ import type { CoarSelectOption } from '@cocoar/vue-ui';
218
+
219
+ type Side = 'left' | 'right' | 'top' | 'bottom';
220
+
221
+ const side = ref<Side>('left');
222
+ const collapsed = ref(false);
223
+ const elevated = ref(false);
224
+ const borderless = ref(false);
225
+ const teamOpen = ref(false);
226
+ const lastClicked = ref('—');
227
+
228
+ const sideOptions: CoarSelectOption<Side>[] = [
229
+ { value: 'left', label: 'left' },
230
+ { value: 'right', label: 'right' },
231
+ { value: 'top', label: 'top' },
232
+ { value: 'bottom', label: 'bottom' },
233
+ ];
234
+
235
+ // Container layout flips based on side:
236
+ // - left/right: flex-row, sidebar at start or end
237
+ // - top/bottom: flex-column, sidebar at start or end
238
+ const containerStyle = computed(() => {
239
+ switch (side.value) {
240
+ case 'right':
241
+ return { display: 'flex', flexDirection: 'row-reverse' as const };
242
+ case 'top':
243
+ return { display: 'flex', flexDirection: 'column' as const };
244
+ case 'bottom':
245
+ return { display: 'flex', flexDirection: 'column-reverse' as const };
246
+ default:
247
+ return { display: 'flex', flexDirection: 'row' as const };
248
+ }
249
+ });
250
+ </script>
251
+ ```
252
+
253
+ ## Router-aware navigation
254
+
255
+ Pass `to` to `CoarSidebarItem` to render it as a real `<a href>` link instead of `<div role="menuitem">`. The item keeps its full visual styling — collapsed mode, tooltips, side-aware indicator border, all sidebar tokens — but the user gains native browser link behaviour: right-click → "Open in new tab" / "Copy link address", middle-click + Ctrl/Cmd-click open a new tab, and screenreaders announce "link" instead of "menuitem".
256
+
257
+ ```vue
258
+ <!-- Before — modifier-clicks silently did nothing -->
259
+ <CoarSidebarItem
260
+ icon="layout-dashboard"
261
+ label="Dashboard"
262
+ :active="route.path === '/dashboard'"
263
+ @click="router.push('/dashboard')"
264
+ />
265
+
266
+ <!-- After — full browser link affordances + auto isActive -->
267
+ <CoarSidebarItem
268
+ icon="layout-dashboard"
269
+ label="Dashboard"
270
+ to="/dashboard"
271
+ />
272
+ ```
273
+
274
+ When `to` is set and `active` is omitted, the highlighted state and `aria-current="page"` attribute follow `<RouterLink>`'s internal `isActive` automatically — no more `route.path === '/x'` drift. Setting `active` explicitly still wins:
275
+
276
+ ```vue
277
+ <!-- Manual override — keep "Settings" highlighted while a child modal is open -->
278
+ <CoarSidebarItem
279
+ icon="settings"
280
+ label="Settings"
281
+ to="/settings"
282
+ :active="modal.isOpen || undefined"
283
+ />
284
+ ```
285
+
286
+ Items without `to` keep the original `<div role="menuitem">` rendering and the `@click` emit pathway — use this for action items that don't map to a route (logout, drawer-toggle, external help link):
287
+
288
+ ```vue
289
+ <CoarSidebarItem icon="log-out" label="Logout" @click="auth.signOut()" />
290
+ ```
291
+
292
+ > **Info**
293
+ >
294
+ > `vue-router` is declared as an **optional `peerDependenciesMeta`** entry of `@cocoar/vue-ui` — install it for SPA routing, omit it for click-emit-only / external-URL use. Apps without a router can still use `<CoarSidebarItem>` with `@click` exactly as before. Setting `to` to a string URL (`to="https://docs.example.com"`) falls back to a plain `<a href>` that works without a router.
295
+
296
+ > **Warning: Object `to` without router**
297
+ >
298
+ > Passing an object literal (`:to="{ name: 'dashboard' }"`) when no router is installed falls back to `String(to)`, producing `href="[object Object]"` — a broken link. The component logs a DEV-only `console.warn` once per component instance to make this loud at dev-time. Pass a string path for the no-router case.
299
+
300
+ ## Migrating from Menu-based Sidebar
301
+
302
+ If you are using `CoarMenu` and `CoarMenuItem` inside `CoarSidebar`, we recommend migrating to the new sidebar-specific components. The new components support collapsed mode with automatic tooltips, flyout panels, icon-only mode, and nested groups — none of which work with the menu-based approach.
303
+
304
+ **Before (menu-based):**
305
+
306
+ ```vue
307
+ <CoarSidebar v-model:collapsed="collapsed">
308
+ <CoarMenu>
309
+ <CoarMenuItem icon="home" label="Dashboard" />
310
+ <CoarMenuItem icon="user" label="Profile" />
311
+ <CoarSubExpand icon="users" label="Users">
312
+ <CoarMenuItem icon="user-plus" label="All Users" />
313
+ <CoarMenuItem icon="shield" label="Roles" />
314
+ </CoarSubExpand>
315
+ </CoarMenu>
316
+ </CoarSidebar>
317
+ ```
318
+
319
+ **After (sidebar components):**
320
+
321
+ ```vue
322
+ <CoarSidebar v-model:collapsed="collapsed">
323
+ <CoarSidebarItem icon="home" label="Dashboard" active />
324
+ <CoarSidebarItem icon="user" label="Profile" />
325
+ <CoarSidebarGroup icon="users" label="Users" v-model:open="usersOpen">
326
+ <CoarSidebarItem icon="user-plus" label="All Users" />
327
+ <CoarSidebarItem icon="shield" label="Roles" />
328
+ </CoarSidebarGroup>
329
+ </CoarSidebar>
330
+ ```
331
+
332
+ **Key differences:**
333
+ - No `CoarMenu` wrapper — items go directly into the sidebar
334
+ - `CoarSidebarItem` replaces `CoarMenuItem` (same props: `icon`, `label`, `active`, `disabled`)
335
+ - `CoarSidebarGroup` replaces `CoarSubExpand` — add `mode="flyout"` for flyout behavior
336
+ - Headings use `CoarSidebarHeading` instead of custom markup
337
+ - Footer items use `<template #footer>` slot — they stretch to full width automatically
338
+
339
+ ## API
340
+
341
+ ### CoarSidebar
342
+
343
+ #### Props
344
+
345
+ | Prop | Type | Default | Description |
346
+ |------|------|---------|-------------|
347
+ | `side` | `'left' \| 'right' \| 'top' \| 'bottom'` | `'left'` | Which edge the sidebar attaches to. `top`/`bottom` switch the layout to horizontal (items in a row, scrolls horizontally). Flyout submenus and tooltip placements adapt automatically. |
348
+ | `position` | `'left' \| 'right'` | — | **Deprecated.** Use `side` instead. Still accepted as an alias for backwards compatibility. |
349
+ | `collapsed` | `boolean` | `false` | Narrow/icon-only collapsed state. Supports `v-model:collapsed`. In horizontal sidebars this collapses height instead of width. |
350
+ | `size` | `'s' \| 'm' \| 'l'` | `'m'` | Icon size: s (16px), m (20px), l (24px) |
351
+ | `variant` | `'primary' \| 'secondary'` | `'primary'` | Background color variant |
352
+ | `elevated` | `boolean` | `false` | Show elevation shadow |
353
+ | `borderless` | `boolean` | `false` | Hide the border |
354
+ | `ariaLabel` | `string` | `'Sidebar'` | Accessible label for the nav landmark |
355
+
356
+ #### Slots
357
+
358
+ All slots receive `{ collapsed: boolean }` as scoped slot props.
359
+
360
+ | Slot | Description |
361
+ |------|-------------|
362
+ | `#header` | Start of the main axis — top in vertical sidebars, left in horizontal. Use for logo, brand, workspace switcher |
363
+ | `default` | Scrollable content area — sidebar items. Scrolls vertically in vertical sidebars, horizontally in horizontal ones |
364
+ | `#footer` | End of the main axis — bottom in vertical sidebars, right in horizontal. Use for user profile, logout, secondary actions |
365
+
366
+ ### CoarSidebarItem
367
+
368
+ | Prop | Type | Default | Description |
369
+ |------|------|---------|-------------|
370
+ | `label` | `string` | *(required)* | Item label text |
371
+ | `icon` | `string` | — | Icon name (recommended for collapsed mode) |
372
+ | `to` | `RouteLocationRaw \| string` | `undefined` | Vue Router target. When set, renders as `<a href>` via `<RouterLink>` (or plain `<a>` if no router is installed). Enables native browser link behaviour (new-tab, copy address). See [Router-aware navigation](#router-aware-navigation). |
373
+ | `active` | `boolean` | `undefined` | Highlight as current page. Defaults to `<RouterLink>`'s `isActive` when `to` is set; explicit value always wins. |
374
+ | `disabled` | `boolean` | `false` | Disabled state |
375
+
376
+ **Events:** `@click` — standard `MouseEvent` (emitted on both the `<div>` and `<a>` branches for telemetry / side-effects)
377
+
378
+ ### CoarSidebarGroup
379
+
380
+ | Prop | Type | Default | Description |
381
+ |------|------|---------|-------------|
382
+ | `label` | `string` | *(required)* | Group label text |
383
+ | `icon` | `string` | — | Icon name (recommended for collapsed mode) |
384
+ | `disabled` | `boolean` | `false` | Disabled state |
385
+ | `mode` | `'expand' \| 'flyout'` | `'expand'` | `expand`: inline animated panel (plus/minus icon). `flyout`: floating panel next to the sidebar (chevron icon). |
386
+ | `open` | `boolean` | `false` | Expanded state (expand mode). Supports `v-model:open`. |
387
+ | `icon-only` | `boolean` | `false` | Flyout shows icon-only items with tooltips (no labels). Inherited by nested groups. Use `:icon-only="collapsed"` for dynamic behavior. |
388
+ | `open-on-hover` | `boolean` | `false` | Open flyout on hover (200ms delay) instead of click. Only applies to `mode="flyout"`. |
389
+
390
+ ### CoarSidebarHeading
391
+
392
+ | Prop | Type | Default | Description |
393
+ |------|------|---------|-------------|
394
+ | `label` | `string` | *(required)* | Section heading text. Hidden when sidebar is collapsed (small spacer remains). |
395
+
396
+ ### CoarSidebarDivider
397
+
398
+ No props. Renders a horizontal separator line.
399
+
400
+ ### CoarSidebarSpacer
401
+
402
+ | Prop | Type | Default | Description |
403
+ |------|------|---------|-------------|
404
+ | `height` | `string` | `var(--coar-spacing-m)` | CSS height value (e.g. `'8px'`, `'1rem'`) |
405
+ | `grow` | `boolean` | `false` | If true, fills available space (`flex: 1`) |
406
+
407
+ ## CSS Tokens
408
+
409
+ | Token | Default | Description |
410
+ |-------|---------|-------------|
411
+ | `--coar-sidebar-width` | `16rem` | Default width (vertical sidebars) |
412
+ | `--coar-sidebar-collapsed-width` | *size-aware* — s: `2.25rem`, m: `2.75rem`, l: `3.25rem` | Width in collapsed mode. Auto-scales with `size`; set this token to override. |
413
+ | `--coar-sidebar-height` | `auto` | Default height (horizontal sidebars) |
414
+ | `--coar-sidebar-collapsed-height` | *size-aware* — same scale as collapsed-width | Height in collapsed mode. Auto-scales with `size`; set this token to override. |
415
+ | `--coar-sidebar-item-padding` | `0.5rem 0.75rem` | Item padding |
416
+ | `--coar-sidebar-item-gap` | `0.75rem` | Gap between icon and label |
417
+ | `--coar-sidebar-item-margin-horizontal` | `0 2px` | Item margin in horizontal sidebars |
418
+ | `--coar-sidebar-item-hover` | neutral tertiary | Hover background |
419
+ | `--coar-sidebar-item-active-color` | accent primary | Active text color |
420
+ | `--coar-sidebar-item-active-bg` | accent tertiary | Active background |
421
+ | `--coar-sidebar-group-indent` | `16px` | Child indent for `mode="expand"` (vertical only) |
@@ -0,0 +1,132 @@
1
+ <!-- Generated from apps/docs/components/spinner.md by apps/docs/scripts/sync-skill.mjs. Do not edit; edit the docs page. -->
2
+
3
+ # Spinner
4
+
5
+ Spinners signal that something is loading when you can't show a progress bar. They tell users "we're working on it" for network requests, lazy-loaded content, or any asynchronous operation with an unpredictable duration.
6
+
7
+ ```ts
8
+ import { CoarSpinner } from '@cocoar/vue-ui';
9
+ ```
10
+
11
+ ## Basic Spinner
12
+
13
+ Drop in a spinner wherever content is still loading. It animates continuously until you remove it or swap in the real content.
14
+
15
+ **Demo — `spinner/demos/SpinnerBasic.vue`**
16
+
17
+ ```vue
18
+ <template>
19
+ <div style="display: flex; justify-content: center; padding: 24px;">
20
+ <CoarSpinner />
21
+ </div>
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ import { CoarSpinner } from '@cocoar/vue-ui';
26
+ </script>
27
+ ```
28
+
29
+ ## Sizes
30
+
31
+ Four sizes to fit any context -- `xs` for inline loading indicators next to text, up to `l` for full-page or overlay states.
32
+
33
+ **Demo — `spinner/demos/SpinnerSizes.vue`**
34
+
35
+ ```vue
36
+ <template>
37
+ <div style="display: flex; flex-wrap: wrap; gap: 32px; align-items: flex-end; justify-content: center;">
38
+ <div style="display: flex; flex-direction: column; align-items: center; gap: 8px;">
39
+ <CoarSpinner size="xs" />
40
+ <span style="font-size: 11px; color: #64748b; font-family: monospace;">xs</span>
41
+ </div>
42
+ <div style="display: flex; flex-direction: column; align-items: center; gap: 8px;">
43
+ <CoarSpinner size="s" />
44
+ <span style="font-size: 11px; color: #64748b; font-family: monospace;">s</span>
45
+ </div>
46
+ <div style="display: flex; flex-direction: column; align-items: center; gap: 8px;">
47
+ <CoarSpinner size="m" />
48
+ <span style="font-size: 11px; color: #64748b; font-family: monospace;">m</span>
49
+ </div>
50
+ <div style="display: flex; flex-direction: column; align-items: center; gap: 8px;">
51
+ <CoarSpinner size="l" />
52
+ <span style="font-size: 11px; color: #64748b; font-family: monospace;">l</span>
53
+ </div>
54
+ </div>
55
+ </template>
56
+
57
+ <script setup lang="ts">
58
+ import { CoarSpinner } from '@cocoar/vue-ui';
59
+ </script>
60
+ ```
61
+
62
+ ## With Loading Text
63
+
64
+ Pair a spinner with a descriptive message so users know what's being loaded, not just that something is happening.
65
+
66
+ **Demo — `spinner/demos/SpinnerWithText.vue`**
67
+
68
+ ```vue
69
+ <template>
70
+ <div style="display: flex; flex-direction: column; gap: 12px;">
71
+ <div style="display: flex; align-items: center; gap: 8px;">
72
+ <CoarSpinner size="s" />
73
+ <span style="font-size: 14px;">Loading data...</span>
74
+ </div>
75
+ <div style="display: flex; align-items: center; gap: 8px;">
76
+ <CoarSpinner size="m" />
77
+ <span style="font-size: 14px;">Saving changes...</span>
78
+ </div>
79
+ <div style="display: flex; align-items: center; gap: 8px;">
80
+ <CoarSpinner size="l" />
81
+ <span>Processing request...</span>
82
+ </div>
83
+ </div>
84
+ </template>
85
+
86
+ <script setup lang="ts">
87
+ import { CoarSpinner } from '@cocoar/vue-ui';
88
+ </script>
89
+ ```
90
+
91
+ ## Full Page Overlay
92
+
93
+ Center a spinner in a container overlay to block interaction while critical data loads. This pattern works well for initial page loads and modal content.
94
+
95
+ **Demo — `spinner/demos/SpinnerOverlay.vue`**
96
+
97
+ ```vue
98
+ <template>
99
+ <div class="loading-overlay">
100
+ <CoarSpinner size="l" />
101
+ <span style="font-size: 14px;">Loading application...</span>
102
+ </div>
103
+ </template>
104
+
105
+ <script setup lang="ts">
106
+ import { CoarSpinner } from '@cocoar/vue-ui';
107
+ </script>
108
+
109
+ <style scoped>
110
+ .loading-overlay {
111
+ background: var(--coar-background-neutral-primary);
112
+ border-radius: 8px;
113
+ border: 1px solid var(--coar-border-neutral-secondary);
114
+ padding: 48px;
115
+ display: flex;
116
+ flex-direction: column;
117
+ align-items: center;
118
+ gap: 12px;
119
+ min-height: 160px;
120
+ justify-content: center;
121
+ }
122
+ </style>
123
+ ```
124
+
125
+ ## API
126
+
127
+ ### Props
128
+
129
+ | Prop | Type | Default | Description |
130
+ |------|------|---------|-------------|
131
+ | `size` | `'xs' \| 's' \| 'm' \| 'l'` | `'m'` | Spinner size |
132
+ | `label` | `string` | `'Loading'` | Accessible label for screen readers |