@cocoar/vue-ui 3.1.0 → 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 (179) hide show
  1. package/dist/components/checkbox/CoarCheckbox.vue.d.ts +1 -1
  2. package/dist/components/checkbox/CoarCheckbox.vue.d.ts.map +1 -1
  3. package/dist/components/code-block/CoarCodeBlock.vue.d.ts +1 -1
  4. package/dist/components/code-block/CoarCodeBlock.vue.d.ts.map +1 -1
  5. package/dist/components/data-list/CoarDataList.vue.d.ts +158 -0
  6. package/dist/components/data-list/CoarDataList.vue.d.ts.map +1 -0
  7. package/dist/components/data-list/CoarDataListToolbar.vue.d.ts +30 -0
  8. package/dist/components/data-list/CoarDataListToolbar.vue.d.ts.map +1 -0
  9. package/dist/components/data-list/data-list-builder.d.ts +288 -0
  10. package/dist/components/data-list/data-list-builder.d.ts.map +1 -0
  11. package/dist/components/data-list/index.d.ts +12 -0
  12. package/dist/components/data-list/index.d.ts.map +1 -0
  13. package/dist/components/data-list/internal/compare.d.ts +14 -0
  14. package/dist/components/data-list/internal/compare.d.ts.map +1 -0
  15. package/dist/components/data-list/internal/reorder-core.d.ts +46 -0
  16. package/dist/components/data-list/internal/reorder-core.d.ts.map +1 -0
  17. package/dist/components/data-list/internal/search.d.ts +16 -0
  18. package/dist/components/data-list/internal/search.d.ts.map +1 -0
  19. package/dist/components/data-list/internal/useDataListLines.d.ts +92 -0
  20. package/dist/components/data-list/internal/useDataListLines.d.ts.map +1 -0
  21. package/dist/components/data-list/internal/useDataListReorder.d.ts +68 -0
  22. package/dist/components/data-list/internal/useDataListReorder.d.ts.map +1 -0
  23. package/dist/components/data-list/internal/useSearchHighlight.d.ts +19 -0
  24. package/dist/components/data-list/internal/useSearchHighlight.d.ts.map +1 -0
  25. package/dist/components/data-list/types.d.ts +185 -0
  26. package/dist/components/data-list/types.d.ts.map +1 -0
  27. package/dist/components/data-list/useDataListModel.d.ts +79 -0
  28. package/dist/components/data-list/useDataListModel.d.ts.map +1 -0
  29. package/dist/components/date-time/_shared/maskito-config.d.ts +7 -2
  30. package/dist/components/date-time/_shared/maskito-config.d.ts.map +1 -1
  31. package/dist/components/date-time/_shared/time-helpers.d.ts +11 -4
  32. package/dist/components/date-time/_shared/time-helpers.d.ts.map +1 -1
  33. package/dist/components/date-time/_shared/use-date-picker-base.d.ts +1 -1
  34. package/dist/components/date-time/plain-date-picker/CoarPlainDatePicker.vue.d.ts +1 -1
  35. package/dist/components/date-time/plain-date-picker/CoarPlainDatePicker.vue.d.ts.map +1 -1
  36. package/dist/components/date-time/plain-date-time-picker/CoarPlainDateTimePicker.vue.d.ts +1 -1
  37. package/dist/components/date-time/plain-date-time-picker/CoarPlainDateTimePicker.vue.d.ts.map +1 -1
  38. package/dist/components/date-time/zoned-date-time-picker/CoarZonedDateTimePicker.vue.d.ts +1 -1
  39. package/dist/components/date-time/zoned-date-time-picker/CoarZonedDateTimePicker.vue.d.ts.map +1 -1
  40. package/dist/components/dual-listbox/CoarDualListbox.vue.d.ts +3 -0
  41. package/dist/components/dual-listbox/CoarDualListbox.vue.d.ts.map +1 -1
  42. package/dist/components/form-field/CoarFormField.vue.d.ts +1 -1
  43. package/dist/components/form-field/CoarFormField.vue.d.ts.map +1 -1
  44. package/dist/components/icon/CoarIcon.vue.d.ts +2 -2
  45. package/dist/components/icon/CoarIcon.vue.d.ts.map +1 -1
  46. package/dist/components/listbox/CoarListbox.vue.d.ts +7 -0
  47. package/dist/components/listbox/CoarListbox.vue.d.ts.map +1 -1
  48. package/dist/components/number-input/CoarNumberInput.vue.d.ts +1 -1
  49. package/dist/components/number-input/CoarNumberInput.vue.d.ts.map +1 -1
  50. package/dist/components/otp-input/CoarOtpInput.vue.d.ts +1 -1
  51. package/dist/components/otp-input/CoarOtpInput.vue.d.ts.map +1 -1
  52. package/dist/components/password-input/CoarPasswordInput.vue.d.ts +1 -1
  53. package/dist/components/password-input/CoarPasswordInput.vue.d.ts.map +1 -1
  54. package/dist/components/switch/CoarSwitch.vue.d.ts +1 -1
  55. package/dist/components/switch/CoarSwitch.vue.d.ts.map +1 -1
  56. package/dist/components/text-input/CoarTextInput.vue.d.ts +1 -1
  57. package/dist/components/text-input/CoarTextInput.vue.d.ts.map +1 -1
  58. package/dist/composables/dragRegistry.d.ts +12 -0
  59. package/dist/composables/dragRegistry.d.ts.map +1 -1
  60. package/dist/composables/index.d.ts +2 -2
  61. package/dist/composables/index.d.ts.map +1 -1
  62. package/dist/composables/useDragDrop.d.ts +62 -6
  63. package/dist/composables/useDragDrop.d.ts.map +1 -1
  64. package/dist/composables/useVirtualList.d.ts +21 -1
  65. package/dist/composables/useVirtualList.d.ts.map +1 -1
  66. package/dist/index.css +1 -1
  67. package/dist/index.d.ts +4 -2
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +4508 -2039
  70. package/package.json +5 -3
  71. package/skills/cocoar-vue-ui/SKILL.md +244 -0
  72. package/skills/cocoar-vue-ui/references/components/avatar.md +178 -0
  73. package/skills/cocoar-vue-ui/references/components/badge.md +290 -0
  74. package/skills/cocoar-vue-ui/references/components/breadcrumb.md +238 -0
  75. package/skills/cocoar-vue-ui/references/components/button.md +252 -0
  76. package/skills/cocoar-vue-ui/references/components/calendar/agenda-view.md +353 -0
  77. package/skills/cocoar-vue-ui/references/components/calendar/coar-calendar.md +1645 -0
  78. package/skills/cocoar-vue-ui/references/components/calendar/day-view.md +361 -0
  79. package/skills/cocoar-vue-ui/references/components/calendar/index.md +312 -0
  80. package/skills/cocoar-vue-ui/references/components/calendar/month-view.md +475 -0
  81. package/skills/cocoar-vue-ui/references/components/calendar/performance.md +186 -0
  82. package/skills/cocoar-vue-ui/references/components/calendar/timeline-view.md +301 -0
  83. package/skills/cocoar-vue-ui/references/components/calendar/week-view.md +382 -0
  84. package/skills/cocoar-vue-ui/references/components/calendar/work-week-view.md +145 -0
  85. package/skills/cocoar-vue-ui/references/components/calendar/year-view.md +63 -0
  86. package/skills/cocoar-vue-ui/references/components/card.md +151 -0
  87. package/skills/cocoar-vue-ui/references/components/checkbox-group.md +103 -0
  88. package/skills/cocoar-vue-ui/references/components/checkbox.md +279 -0
  89. package/skills/cocoar-vue-ui/references/components/code-block.md +241 -0
  90. package/skills/cocoar-vue-ui/references/components/context-menu.md +355 -0
  91. package/skills/cocoar-vue-ui/references/components/data-grid/checkbox.md +213 -0
  92. package/skills/cocoar-vue-ui/references/components/data-grid/date-columns.md +272 -0
  93. package/skills/cocoar-vue-ui/references/components/data-grid/editing.md +236 -0
  94. package/skills/cocoar-vue-ui/references/components/data-grid/multi-select.md +193 -0
  95. package/skills/cocoar-vue-ui/references/components/data-grid/number.md +147 -0
  96. package/skills/cocoar-vue-ui/references/components/data-grid/select.md +202 -0
  97. package/skills/cocoar-vue-ui/references/components/data-grid/text.md +127 -0
  98. package/skills/cocoar-vue-ui/references/components/data-grid.md +1225 -0
  99. package/skills/cocoar-vue-ui/references/components/data-list.md +2121 -0
  100. package/skills/cocoar-vue-ui/references/components/date-or-time-picker.md +200 -0
  101. package/skills/cocoar-vue-ui/references/components/date-picker.md +203 -0
  102. package/skills/cocoar-vue-ui/references/components/date-time-picker.md +154 -0
  103. package/skills/cocoar-vue-ui/references/components/date-views.md +212 -0
  104. package/skills/cocoar-vue-ui/references/components/dialog.md +148 -0
  105. package/skills/cocoar-vue-ui/references/components/divider.md +157 -0
  106. package/skills/cocoar-vue-ui/references/components/document-viewer/annotations.md +400 -0
  107. package/skills/cocoar-vue-ui/references/components/document-viewer/coar-document-viewer.md +327 -0
  108. package/skills/cocoar-vue-ui/references/components/document-viewer/index.md +234 -0
  109. package/skills/cocoar-vue-ui/references/components/document-viewer/toolbar.md +221 -0
  110. package/skills/cocoar-vue-ui/references/components/drag-drop.md +267 -0
  111. package/skills/cocoar-vue-ui/references/components/dual-listbox.md +449 -0
  112. package/skills/cocoar-vue-ui/references/components/file-explorer/asset-store.md +327 -0
  113. package/skills/cocoar-vue-ui/references/components/file-explorer/in-memory-store.md +176 -0
  114. package/skills/cocoar-vue-ui/references/components/file-explorer/index.md +311 -0
  115. package/skills/cocoar-vue-ui/references/components/file-explorer/use-file-explorer.md +300 -0
  116. package/skills/cocoar-vue-ui/references/components/form-field.md +1025 -0
  117. package/skills/cocoar-vue-ui/references/components/fragment-parser.md +298 -0
  118. package/skills/cocoar-vue-ui/references/components/link.md +235 -0
  119. package/skills/cocoar-vue-ui/references/components/listbox.md +575 -0
  120. package/skills/cocoar-vue-ui/references/components/map/editor.md +448 -0
  121. package/skills/cocoar-vue-ui/references/components/map/index.md +351 -0
  122. package/skills/cocoar-vue-ui/references/components/markdown-diagrams.md +210 -0
  123. package/skills/cocoar-vue-ui/references/components/markdown-editor.md +1478 -0
  124. package/skills/cocoar-vue-ui/references/components/markdown-embeds.md +387 -0
  125. package/skills/cocoar-vue-ui/references/components/markdown-form.md +447 -0
  126. package/skills/cocoar-vue-ui/references/components/markdown.md +276 -0
  127. package/skills/cocoar-vue-ui/references/components/menu.md +380 -0
  128. package/skills/cocoar-vue-ui/references/components/mermaid.md +172 -0
  129. package/skills/cocoar-vue-ui/references/components/navbar.md +147 -0
  130. package/skills/cocoar-vue-ui/references/components/note.md +96 -0
  131. package/skills/cocoar-vue-ui/references/components/notice.md +131 -0
  132. package/skills/cocoar-vue-ui/references/components/number-input.md +215 -0
  133. package/skills/cocoar-vue-ui/references/components/otp-input.md +324 -0
  134. package/skills/cocoar-vue-ui/references/components/page-builder/authoring-contract.md +271 -0
  135. package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-builder.md +476 -0
  136. package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-renderer.md +677 -0
  137. package/skills/cocoar-vue-ui/references/components/page-builder/custom-elements.md +441 -0
  138. package/skills/cocoar-vue-ui/references/components/page-builder/idp-integration.md +122 -0
  139. package/skills/cocoar-vue-ui/references/components/page-builder/index.md +573 -0
  140. package/skills/cocoar-vue-ui/references/components/pagination.md +150 -0
  141. package/skills/cocoar-vue-ui/references/components/panel-layout.md +372 -0
  142. package/skills/cocoar-vue-ui/references/components/password-input.md +175 -0
  143. package/skills/cocoar-vue-ui/references/components/popconfirm.md +186 -0
  144. package/skills/cocoar-vue-ui/references/components/popover.md +173 -0
  145. package/skills/cocoar-vue-ui/references/components/progress-bar.md +178 -0
  146. package/skills/cocoar-vue-ui/references/components/radio-group.md +225 -0
  147. package/skills/cocoar-vue-ui/references/components/script-editor.md +1271 -0
  148. package/skills/cocoar-vue-ui/references/components/segmented-control.md +238 -0
  149. package/skills/cocoar-vue-ui/references/components/select.md +463 -0
  150. package/skills/cocoar-vue-ui/references/components/sidebar.md +421 -0
  151. package/skills/cocoar-vue-ui/references/components/spinner.md +132 -0
  152. package/skills/cocoar-vue-ui/references/components/switch.md +195 -0
  153. package/skills/cocoar-vue-ui/references/components/table.md +170 -0
  154. package/skills/cocoar-vue-ui/references/components/tabs.md +382 -0
  155. package/skills/cocoar-vue-ui/references/components/tag.md +178 -0
  156. package/skills/cocoar-vue-ui/references/components/text-input.md +256 -0
  157. package/skills/cocoar-vue-ui/references/components/toast.md +160 -0
  158. package/skills/cocoar-vue-ui/references/components/tooltip.md +121 -0
  159. package/skills/cocoar-vue-ui/references/components/transitions.md +193 -0
  160. package/skills/cocoar-vue-ui/references/components/tree.md +2388 -0
  161. package/skills/cocoar-vue-ui/references/components/virtual-list.md +212 -0
  162. package/skills/cocoar-vue-ui/references/components/wizard.md +251 -0
  163. package/skills/cocoar-vue-ui/references/components/zoned-date-time-picker.md +177 -0
  164. package/skills/cocoar-vue-ui/references/foundations/colors.md +708 -0
  165. package/skills/cocoar-vue-ui/references/foundations/design-principles.md +115 -0
  166. package/skills/cocoar-vue-ui/references/foundations/icons.md +381 -0
  167. package/skills/cocoar-vue-ui/references/foundations/localization/formatting.md +530 -0
  168. package/skills/cocoar-vue-ui/references/foundations/localization/setup.md +86 -0
  169. package/skills/cocoar-vue-ui/references/foundations/localization/timezones.md +182 -0
  170. package/skills/cocoar-vue-ui/references/foundations/localization/translations.md +305 -0
  171. package/skills/cocoar-vue-ui/references/foundations/motion.md +549 -0
  172. package/skills/cocoar-vue-ui/references/foundations/spacing.md +330 -0
  173. package/skills/cocoar-vue-ui/references/foundations/theming.md +140 -0
  174. package/skills/cocoar-vue-ui/references/foundations/typography.md +206 -0
  175. package/skills/cocoar-vue-ui/references/guide/error-handling.md +162 -0
  176. package/skills/cocoar-vue-ui/references/guide/getting-started.md +119 -0
  177. package/skills/cocoar-vue-ui/references/guide/migration-page-builder-3.md +207 -0
  178. package/skills/cocoar-vue-ui/references/guide/migration.md +140 -0
  179. package/skills/cocoar-vue-ui/references/guide/theming.md +98 -0
@@ -0,0 +1,115 @@
1
+ <!-- Generated from apps/docs/foundations/design-principles.md by apps/docs/scripts/sync-skill.mjs. Do not edit; edit the docs page. -->
2
+
3
+ # Design Principles
4
+
5
+ The foundation of the Cocoar Design System — six principles that guide every design decision across our Vue 3 component library.
6
+
7
+ ---
8
+
9
+ ### Clarity
10
+
11
+ Every element has a clear purpose. Reduce visual noise and make the important thing obvious.
12
+
13
+ - Consistent spacing creates visual rhythm that guides scanning
14
+ - Typography hierarchy directs attention to what matters most
15
+ - Limit each view to one primary action to reduce decision fatigue
16
+ - Use whitespace generously — empty space is not wasted space
17
+
18
+ ---
19
+
20
+ ### Consistency
21
+
22
+ Use the same patterns, tokens, and components everywhere. Predictability reduces cognitive load and builds trust.
23
+
24
+ - Shared token vocabulary across colors, spacing, radius, and motion
25
+ - Uniform component API patterns — props, events, and slots follow conventions
26
+ - Consistent interaction models — similar controls behave identically
27
+ - One way to do things, not many — fewer choices lead to better outcomes
28
+
29
+ ---
30
+
31
+ ### Accessibility
32
+
33
+ Design for everyone. Meet WCAG AA standards at minimum. Keyboard navigation is not optional — it is a core feature.
34
+
35
+ - **4.5 : 1** minimum contrast ratio for all text content
36
+ - Full keyboard navigation built into every interactive component
37
+ - Screen reader support with proper ARIA attributes
38
+ - Focus indicators that are visible and consistent
39
+ - Respect `prefers-reduced-motion` for users who need it
40
+
41
+ ---
42
+
43
+ ### Touch-First
44
+
45
+ All components work with **touch and focus** — hover is an enhancement, not a requirement. This is **tablet-first** design: touch interaction with desktop-appropriate information density. Not mobile-first — mobile phones have different constraints (small screens, portrait orientation, one-handed use). Tablets have similar screen real estate to laptops but use touch instead of mouse.
46
+
47
+ - Minimum **44 x 44 px** touch targets on all interactive elements
48
+ - Appropriate tap spacing to prevent accidental activation
49
+ - No hover-only interactions — every feature is reachable via tap or keyboard
50
+ - Use dimmed states instead of hiding; on focus/hover elements become prominent
51
+ - Desktop gets additional polish (hover states) as progressive enhancement
52
+
53
+ ---
54
+
55
+ ### Performance
56
+
57
+ Ship less, load faster. Icons are inlined SVGs. Components are tree-shakeable. CSS theming uses custom properties for zero runtime cost.
58
+
59
+ - Inline SVG icons eliminate icon font overhead
60
+ - Individual component imports enable dead-code elimination
61
+ - CSS custom property theming — no JavaScript at render time
62
+ - Lightweight component architecture with minimal dependencies
63
+
64
+ ---
65
+
66
+ ### Developer Experience
67
+
68
+ Strong TypeScript types. Composable APIs. Predictable naming. The system should be a joy to use, not a chore to learn.
69
+
70
+ - Full TypeScript support with exported types for every component
71
+ - Consistent `v-model` patterns across all form controls
72
+ - Self-documenting prop names — no guessing what `mode="3"` means
73
+ - Composable utilities (`useDialog`, `useToast`) for programmatic control
74
+
75
+ ---
76
+
77
+ ## Design Token Architecture
78
+
79
+ Cocoar uses a **two-layer token system**: raw primitives are referenced by semantic tokens. Always use semantic tokens in your components — they adapt automatically to light and dark mode.
80
+
81
+ | Category | Token Prefix | Description |
82
+ |---|---|---|
83
+ | **Color** | `--coar-color-*` | Raw color primitives (gray, slate, accent, green, red, amber) |
84
+ | **Background** | `--coar-background-*` | Semantic surface tokens for accent, brand, neutral, and status |
85
+ | **Text** | `--coar-text-*` | Text color tokens for all states and emphasis levels |
86
+ | **Border** | `--coar-border-*` | Border color tokens for interactive and structural elements |
87
+ | **Spacing** | `--coar-spacing-*` | Space scale from `xxs` (2 px) to `xxxl` (64 px) on a 4 px grid |
88
+ | **Radius** | `--coar-radius-*` | Border radius from `xxs` (1 px) to `full` (999 px) |
89
+ | **Shadow** | `--coar-shadow-*` | Elevation shadows `xs`–`xl` plus a focus ring |
90
+ | **Typography** | `--coar-titles-*` / `--coar-headings-*` / `--coar-body-*` | Font family, size, and weight tokens for each text role |
91
+ | **Motion** | `--coar-duration-*` / `--coar-ease-*` / `--coar-transition-*` | Duration, easing, and pre-composed transition tokens |
92
+
93
+ ## Do's and Don'ts
94
+
95
+ > **Tip: Do**
96
+ >
97
+ > - Use semantic tokens — `--coar-text-neutral-primary`, not a raw hex value
98
+ > - Follow the **4 px spacing grid** for all layout dimensions
99
+ > - Use `v-model` for two-way binding on form controls
100
+ > - Import components individually for tree-shaking: `import { CoarButton } from '@cocoar/vue-ui'`
101
+ > - Test keyboard navigation for every interactive flow
102
+ > - Provide `aria-label` for icon-only buttons
103
+
104
+ > **Danger: Don't**
105
+ >
106
+ > - Hardcode colors or spacing values in component styles
107
+ > - Use primitive tokens directly in components (`--coar-color-gray-500`)
108
+ > - Override component internals with `:deep()` selectors
109
+ > - Create hover-only interactions that exclude touch and keyboard users
110
+ > - Mix spacing values that are not on the 4 px grid
111
+ > - Ignore `prefers-reduced-motion` in custom animations
112
+
113
+ > **Info: Dark Mode**
114
+ >
115
+ > Toggle dark mode by adding the `.dark-mode` class to `document.documentElement`. All tokens and components update automatically — no JavaScript required at render time.
@@ -0,0 +1,381 @@
1
+ <!-- Generated from apps/docs/foundations/icons.md by apps/docs/scripts/sync-skill.mjs. Do not edit; edit the docs page. -->
2
+
3
+ # Icons
4
+
5
+ A flexible icon system with built-in SVG icons. Icons support multiple sizes, colors, rotation, and animations.
6
+
7
+ ```ts
8
+ import { CoarIcon } from '@cocoar/vue-ui';
9
+ ```
10
+
11
+ ## Icon Gallery
12
+
13
+ **Demo — `icons/demos/IconGallery.vue`**
14
+
15
+ ```vue
16
+ <template>
17
+ <div>
18
+ <p style="margin: 0 0 8px; font-size: 14px; color: var(--coar-text-neutral-secondary);">
19
+ Browse all {{ allIcons.length }} available icons. Click an icon to copy its name.
20
+ </p>
21
+ <div class="search-wrapper">
22
+ <CoarTextInput v-model="search" placeholder="Search icons..." :clearable="true" />
23
+ </div>
24
+
25
+ <div v-if="filteredIcons.length > 0" class="icons-grid">
26
+ <button
27
+ v-for="icon in filteredIcons"
28
+ :key="icon"
29
+ class="icon-item"
30
+ :class="{ 'icon-item--copied': copiedIcon === icon }"
31
+ :title="`Click to copy: ${icon}`"
32
+ @click="copyIconName(icon)"
33
+ >
34
+ <CoarIcon :name="icon" size="l" />
35
+ <span class="icon-name">{{ icon }}</span>
36
+ <span v-if="copiedIcon === icon" class="icon-copied">Copied!</span>
37
+ </button>
38
+ </div>
39
+ <p v-else style="color: var(--coar-text-neutral-secondary); font-size: 14px; margin-top: 16px;">
40
+ No icons match "{{ search }}"
41
+ </p>
42
+ </div>
43
+ </template>
44
+
45
+ <script setup lang="ts">
46
+ import { ref, computed } from 'vue';
47
+ import { CoarTextInput, CoarIcon, CORE_ICONS } from '@cocoar/vue-ui';
48
+
49
+ const search = ref('');
50
+ const copiedIcon = ref<string | null>(null);
51
+
52
+ const allIcons = Object.keys(CORE_ICONS);
53
+
54
+ const filteredIcons = computed(() => {
55
+ const q = search.value.toLowerCase().trim();
56
+ return q ? allIcons.filter(name => name.includes(q)) : allIcons;
57
+ });
58
+
59
+ function copyIconName(name: string) {
60
+ navigator.clipboard.writeText(name).catch(() => {});
61
+ copiedIcon.value = name;
62
+ setTimeout(() => { copiedIcon.value = null; }, 1500);
63
+ }
64
+ </script>
65
+
66
+ <style scoped>
67
+ .search-wrapper {
68
+ margin-bottom: 16px;
69
+ }
70
+
71
+ .icons-grid {
72
+ display: grid;
73
+ grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
74
+ gap: 4px;
75
+ max-height: 480px;
76
+ overflow-y: auto;
77
+ }
78
+
79
+ .icon-item {
80
+ display: flex;
81
+ flex-direction: column;
82
+ align-items: center;
83
+ gap: 4px;
84
+ padding: 8px;
85
+ background: transparent;
86
+ border: 1px solid transparent;
87
+ border-radius: var(--coar-radius-s);
88
+ cursor: pointer;
89
+ transition: background 100ms ease-out;
90
+ color: var(--coar-text-neutral-primary);
91
+ position: relative;
92
+ }
93
+
94
+ .icon-item:hover {
95
+ background: var(--coar-background-neutral-tertiary);
96
+ border-color: var(--coar-border-neutral-secondary);
97
+ }
98
+
99
+ .icon-item--copied {
100
+ background: var(--coar-background-semantic-success-subtle);
101
+ border-color: var(--coar-background-semantic-success-bold);
102
+ }
103
+
104
+ .icon-name {
105
+ font-size: 10px;
106
+ color: var(--coar-text-neutral-tertiary);
107
+ text-align: center;
108
+ word-break: break-all;
109
+ font-family: 'Consolas', 'Monaco', monospace;
110
+ }
111
+
112
+ .icon-copied {
113
+ position: absolute;
114
+ bottom: 2px;
115
+ font-size: 9px;
116
+ color: var(--coar-text-neutral-secondary);
117
+ font-weight: 600;
118
+ }
119
+ </style>
120
+ ```
121
+
122
+ ## Sizes
123
+
124
+ Icons come in 5 preset sizes and can use any valid CSS value.
125
+
126
+ **Demo — `icons/demos/IconSizes.vue`**
127
+
128
+ ```vue
129
+ <template>
130
+ <div style="display: flex; flex-wrap: wrap; gap: 24px; align-items: flex-end;">
131
+ <div v-for="size in sizes" :key="size" class="size-item">
132
+ <CoarIcon name="settings" :size="size" />
133
+ <span class="size-label">{{ size }} ({{ sizeLabels[size] }})</span>
134
+ </div>
135
+ <div class="size-item">
136
+ <CoarIcon name="settings" size="48px" />
137
+ <span class="size-label">custom (48px)</span>
138
+ </div>
139
+ </div>
140
+ </template>
141
+
142
+ <script setup lang="ts">
143
+ import { CoarIcon } from '@cocoar/vue-ui';
144
+
145
+ const sizes = ['xs', 's', 'm', 'l', 'xl'] as const;
146
+ const sizeLabels: Record<string, string> = { xs: '12px', s: '16px', m: '20px', l: '24px', xl: '32px' };
147
+ </script>
148
+
149
+ <style scoped>
150
+ .size-item {
151
+ display: flex;
152
+ flex-direction: column;
153
+ align-items: center;
154
+ gap: 4px;
155
+ }
156
+
157
+ .size-label {
158
+ font-size: 11px;
159
+ color: var(--coar-text-neutral-tertiary);
160
+ font-family: monospace;
161
+ white-space: nowrap;
162
+ }
163
+ </style>
164
+ ```
165
+
166
+ ## Colors
167
+
168
+ Icons inherit color by default. Override with any valid CSS color value.
169
+
170
+ **Demo — `icons/demos/IconColors.vue`**
171
+
172
+ ```vue
173
+ <template>
174
+ <div style="display: flex; flex-wrap: wrap; gap: 24px; align-items: center;">
175
+ <div class="color-item"><CoarIcon name="check" size="l" color="green" /><span class="color-label">green</span></div>
176
+ <div class="color-item"><CoarIcon name="x" size="l" color="red" /><span class="color-label">red</span></div>
177
+ <div class="color-item"><CoarIcon name="triangle-alert" size="l" color="orange" /><span class="color-label">orange</span></div>
178
+ <div class="color-item"><CoarIcon name="circle-help" size="l" color="blue" /><span class="color-label">blue</span></div>
179
+ <div class="color-item"><CoarIcon name="settings" size="l" color="#888" /><span class="color-label">#888</span></div>
180
+ <div class="color-item"><CoarIcon name="user" size="l" color="var(--coar-text-accent-primary)" /><span class="color-label">accent</span></div>
181
+ </div>
182
+ </template>
183
+
184
+ <script setup lang="ts">
185
+ import { CoarIcon } from '@cocoar/vue-ui';
186
+ </script>
187
+
188
+ <style scoped>
189
+ .color-item {
190
+ display: flex;
191
+ flex-direction: column;
192
+ align-items: center;
193
+ gap: 4px;
194
+ }
195
+
196
+ .color-label {
197
+ font-size: 11px;
198
+ color: var(--coar-text-neutral-tertiary);
199
+ font-family: monospace;
200
+ white-space: nowrap;
201
+ }
202
+ </style>
203
+ ```
204
+
205
+ ## Rotation
206
+
207
+ Rotate icons to any angle using the `rotate` prop.
208
+
209
+ **Demo — `icons/demos/IconRotation.vue`**
210
+
211
+ ```vue
212
+ <template>
213
+ <div style="display: flex; flex-wrap: wrap; gap: 24px; align-items: center;">
214
+ <div class="rotation-item"><CoarIcon name="chevron-right" size="l" :rotate="0" /><span class="rotation-label">0&deg;</span></div>
215
+ <div class="rotation-item"><CoarIcon name="chevron-right" size="l" :rotate="90" /><span class="rotation-label">90&deg;</span></div>
216
+ <div class="rotation-item"><CoarIcon name="chevron-right" size="l" :rotate="180" /><span class="rotation-label">180&deg;</span></div>
217
+ <div class="rotation-item"><CoarIcon name="chevron-right" size="l" :rotate="270" /><span class="rotation-label">270&deg;</span></div>
218
+ </div>
219
+ </template>
220
+
221
+ <script setup lang="ts">
222
+ import { CoarIcon } from '@cocoar/vue-ui';
223
+ </script>
224
+
225
+ <style scoped>
226
+ .rotation-item {
227
+ display: flex;
228
+ flex-direction: column;
229
+ align-items: center;
230
+ gap: 4px;
231
+ }
232
+
233
+ .rotation-label {
234
+ font-size: 11px;
235
+ color: var(--coar-text-neutral-tertiary);
236
+ font-family: monospace;
237
+ white-space: nowrap;
238
+ }
239
+ </style>
240
+ ```
241
+
242
+ ## Spin Animation
243
+
244
+ Enable continuous spinning for loading indicators.
245
+
246
+ **Demo — `icons/demos/IconSpin.vue`**
247
+
248
+ ```vue
249
+ <template>
250
+ <div style="display: flex; flex-wrap: wrap; gap: 32px; align-items: flex-start;">
251
+ <div class="spin-item">
252
+ <CoarIcon name="loader-circle" size="xl" :spin="true" />
253
+ <span style="font-size: 14px;">Loading...</span>
254
+ </div>
255
+ <div class="spin-item">
256
+ <CoarIcon name="settings" size="l" :spin="true" />
257
+ <span style="font-size: 14px;">Processing</span>
258
+ </div>
259
+ </div>
260
+ </template>
261
+
262
+ <script setup lang="ts">
263
+ import { CoarIcon } from '@cocoar/vue-ui';
264
+ </script>
265
+
266
+ <style scoped>
267
+ .spin-item {
268
+ display: flex;
269
+ flex-direction: column;
270
+ align-items: center;
271
+ gap: 8px;
272
+ }
273
+ </style>
274
+ ```
275
+
276
+ ## Custom Icon Sources
277
+
278
+ Register your own icons alongside the built-in set. Cocoar supports multiple icon sources with automatic fallback.
279
+
280
+ ### SVG Map (Inline Icons)
281
+
282
+ Register a set of SVG strings — resolved synchronously, no network requests.
283
+
284
+ ```ts
285
+ // main.ts
286
+ import { CoarIconPlugin, CoarIconMapSource } from '@cocoar/vue-ui';
287
+
288
+ app.use(CoarIconPlugin, {
289
+ sources: [
290
+ {
291
+ key: 'app',
292
+ source: new CoarIconMapSource({
293
+ 'logo': '<svg viewBox="0 0 24 24">...</svg>',
294
+ 'dashboard': '<svg viewBox="0 0 24 24">...</svg>',
295
+ }),
296
+ },
297
+ ],
298
+ defaultSource: 'app', // check custom icons first
299
+ });
300
+ ```
301
+
302
+ ```vue
303
+ <template>
304
+ <!-- Resolves from 'app' source first, then built-in -->
305
+ <CoarIcon name="logo" size="xl" />
306
+
307
+ <!-- Explicitly target a source -->
308
+ <CoarIcon name="settings" source="coar-builtin" />
309
+ </template>
310
+ ```
311
+
312
+ ### HTTP Source (Remote Icons)
313
+
314
+ Load icons on demand from a URL. Responses are cached automatically.
315
+
316
+ ```ts
317
+ import { CoarIconPlugin, CoarHttpIconSource } from '@cocoar/vue-ui';
318
+
319
+ app.use(CoarIconPlugin, {
320
+ sources: [
321
+ {
322
+ key: 'cdn',
323
+ source: new CoarHttpIconSource(
324
+ (name) => `https://cdn.example.com/icons/${name}.svg`,
325
+ ),
326
+ },
327
+ ],
328
+ });
329
+ ```
330
+
331
+ ```vue
332
+ <!-- Fetched async, shows nothing while loading -->
333
+ <CoarIcon name="custom-icon" source="cdn" />
334
+ ```
335
+
336
+ ### Override Built-in Icons
337
+
338
+ Replace specific built-in icons without creating a full source:
339
+
340
+ ```ts
341
+ app.use(CoarIconPlugin, {
342
+ builtInOverrides: {
343
+ 'settings': '<svg viewBox="0 0 24 24"><!-- your custom settings icon --></svg>',
344
+ },
345
+ });
346
+ ```
347
+
348
+ ### Resolution Order
349
+
350
+ When no `source` prop is specified, icons are resolved in this order:
351
+ 1. **Default source** (set via `defaultSource` option)
352
+ 2. **Additional sources** (in registration order)
353
+ 3. **Built-in icons** (`coar-builtin`)
354
+
355
+ The first source that returns a match wins. Use the `source` prop to bypass fallback and target a specific source directly.
356
+
357
+ ## API
358
+
359
+ ### Props
360
+
361
+ | Prop | Type | Default | Description |
362
+ |------|------|---------|-------------|
363
+ | `name` | `string` | `—` | Icon name from the registered icon set |
364
+ | `source` | `string` | — | Target a specific icon source (bypasses fallback) |
365
+ | `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl' \| string` | `'m'` | Icon size (preset or custom CSS value) |
366
+ | `color` | `string` | `'inherit'` | Icon color (any valid CSS color) |
367
+ | `strokeWidth` | `number` | — | Override stroke width for stroke-based icons |
368
+ | `rotate` | `number` | `0` | Rotation angle in degrees |
369
+ | `rotateTransition` | `number \| string` | — | Rotation animation (ms or CSS transition) |
370
+ | `spin` | `boolean` | `false` | Enable continuous spinning animation |
371
+ | `label` | `string \| number` | — | Text label displayed next to the icon |
372
+
373
+ ### Size Reference
374
+
375
+ | Size | Pixels |
376
+ |------|--------|
377
+ | `xs` | 12px |
378
+ | `s` | 16px |
379
+ | `m` | 20px |
380
+ | `l` | 24px |
381
+ | `xl` | 32px |