@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.
- package/dist/components/checkbox/CoarCheckbox.vue.d.ts +1 -1
- package/dist/components/checkbox/CoarCheckbox.vue.d.ts.map +1 -1
- package/dist/components/code-block/CoarCodeBlock.vue.d.ts +1 -1
- package/dist/components/code-block/CoarCodeBlock.vue.d.ts.map +1 -1
- package/dist/components/data-list/CoarDataList.vue.d.ts +158 -0
- package/dist/components/data-list/CoarDataList.vue.d.ts.map +1 -0
- package/dist/components/data-list/CoarDataListToolbar.vue.d.ts +30 -0
- package/dist/components/data-list/CoarDataListToolbar.vue.d.ts.map +1 -0
- package/dist/components/data-list/data-list-builder.d.ts +288 -0
- package/dist/components/data-list/data-list-builder.d.ts.map +1 -0
- package/dist/components/data-list/index.d.ts +12 -0
- package/dist/components/data-list/index.d.ts.map +1 -0
- package/dist/components/data-list/internal/compare.d.ts +14 -0
- package/dist/components/data-list/internal/compare.d.ts.map +1 -0
- package/dist/components/data-list/internal/reorder-core.d.ts +46 -0
- package/dist/components/data-list/internal/reorder-core.d.ts.map +1 -0
- package/dist/components/data-list/internal/search.d.ts +16 -0
- package/dist/components/data-list/internal/search.d.ts.map +1 -0
- package/dist/components/data-list/internal/useDataListLines.d.ts +92 -0
- package/dist/components/data-list/internal/useDataListLines.d.ts.map +1 -0
- package/dist/components/data-list/internal/useDataListReorder.d.ts +68 -0
- package/dist/components/data-list/internal/useDataListReorder.d.ts.map +1 -0
- package/dist/components/data-list/internal/useSearchHighlight.d.ts +19 -0
- package/dist/components/data-list/internal/useSearchHighlight.d.ts.map +1 -0
- package/dist/components/data-list/types.d.ts +185 -0
- package/dist/components/data-list/types.d.ts.map +1 -0
- package/dist/components/data-list/useDataListModel.d.ts +79 -0
- package/dist/components/data-list/useDataListModel.d.ts.map +1 -0
- package/dist/components/date-time/_shared/maskito-config.d.ts +7 -2
- package/dist/components/date-time/_shared/maskito-config.d.ts.map +1 -1
- package/dist/components/date-time/_shared/time-helpers.d.ts +11 -4
- package/dist/components/date-time/_shared/time-helpers.d.ts.map +1 -1
- package/dist/components/date-time/_shared/use-date-picker-base.d.ts +1 -1
- package/dist/components/date-time/plain-date-picker/CoarPlainDatePicker.vue.d.ts +1 -1
- package/dist/components/date-time/plain-date-picker/CoarPlainDatePicker.vue.d.ts.map +1 -1
- package/dist/components/date-time/plain-date-time-picker/CoarPlainDateTimePicker.vue.d.ts +1 -1
- package/dist/components/date-time/plain-date-time-picker/CoarPlainDateTimePicker.vue.d.ts.map +1 -1
- package/dist/components/date-time/zoned-date-time-picker/CoarZonedDateTimePicker.vue.d.ts +1 -1
- package/dist/components/date-time/zoned-date-time-picker/CoarZonedDateTimePicker.vue.d.ts.map +1 -1
- package/dist/components/dual-listbox/CoarDualListbox.vue.d.ts +3 -0
- package/dist/components/dual-listbox/CoarDualListbox.vue.d.ts.map +1 -1
- package/dist/components/form-field/CoarFormField.vue.d.ts +1 -1
- package/dist/components/form-field/CoarFormField.vue.d.ts.map +1 -1
- package/dist/components/icon/CoarIcon.vue.d.ts +2 -2
- package/dist/components/icon/CoarIcon.vue.d.ts.map +1 -1
- package/dist/components/listbox/CoarListbox.vue.d.ts +7 -0
- package/dist/components/listbox/CoarListbox.vue.d.ts.map +1 -1
- package/dist/components/number-input/CoarNumberInput.vue.d.ts +1 -1
- package/dist/components/number-input/CoarNumberInput.vue.d.ts.map +1 -1
- package/dist/components/otp-input/CoarOtpInput.vue.d.ts +1 -1
- package/dist/components/otp-input/CoarOtpInput.vue.d.ts.map +1 -1
- package/dist/components/password-input/CoarPasswordInput.vue.d.ts +1 -1
- package/dist/components/password-input/CoarPasswordInput.vue.d.ts.map +1 -1
- package/dist/components/switch/CoarSwitch.vue.d.ts +1 -1
- package/dist/components/switch/CoarSwitch.vue.d.ts.map +1 -1
- package/dist/components/text-input/CoarTextInput.vue.d.ts +1 -1
- package/dist/components/text-input/CoarTextInput.vue.d.ts.map +1 -1
- package/dist/composables/dragRegistry.d.ts +12 -0
- package/dist/composables/dragRegistry.d.ts.map +1 -1
- package/dist/composables/index.d.ts +2 -2
- package/dist/composables/index.d.ts.map +1 -1
- package/dist/composables/useDragDrop.d.ts +62 -6
- package/dist/composables/useDragDrop.d.ts.map +1 -1
- package/dist/composables/useVirtualList.d.ts +21 -1
- package/dist/composables/useVirtualList.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4508 -2039
- package/package.json +5 -3
- package/skills/cocoar-vue-ui/SKILL.md +244 -0
- package/skills/cocoar-vue-ui/references/components/avatar.md +178 -0
- package/skills/cocoar-vue-ui/references/components/badge.md +290 -0
- package/skills/cocoar-vue-ui/references/components/breadcrumb.md +238 -0
- package/skills/cocoar-vue-ui/references/components/button.md +252 -0
- package/skills/cocoar-vue-ui/references/components/calendar/agenda-view.md +353 -0
- package/skills/cocoar-vue-ui/references/components/calendar/coar-calendar.md +1645 -0
- package/skills/cocoar-vue-ui/references/components/calendar/day-view.md +361 -0
- package/skills/cocoar-vue-ui/references/components/calendar/index.md +312 -0
- package/skills/cocoar-vue-ui/references/components/calendar/month-view.md +475 -0
- package/skills/cocoar-vue-ui/references/components/calendar/performance.md +186 -0
- package/skills/cocoar-vue-ui/references/components/calendar/timeline-view.md +301 -0
- package/skills/cocoar-vue-ui/references/components/calendar/week-view.md +382 -0
- package/skills/cocoar-vue-ui/references/components/calendar/work-week-view.md +145 -0
- package/skills/cocoar-vue-ui/references/components/calendar/year-view.md +63 -0
- package/skills/cocoar-vue-ui/references/components/card.md +151 -0
- package/skills/cocoar-vue-ui/references/components/checkbox-group.md +103 -0
- package/skills/cocoar-vue-ui/references/components/checkbox.md +279 -0
- package/skills/cocoar-vue-ui/references/components/code-block.md +241 -0
- package/skills/cocoar-vue-ui/references/components/context-menu.md +355 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/checkbox.md +213 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/date-columns.md +272 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/editing.md +236 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/multi-select.md +193 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/number.md +147 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/select.md +202 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/text.md +127 -0
- package/skills/cocoar-vue-ui/references/components/data-grid.md +1225 -0
- package/skills/cocoar-vue-ui/references/components/data-list.md +2121 -0
- package/skills/cocoar-vue-ui/references/components/date-or-time-picker.md +200 -0
- package/skills/cocoar-vue-ui/references/components/date-picker.md +203 -0
- package/skills/cocoar-vue-ui/references/components/date-time-picker.md +154 -0
- package/skills/cocoar-vue-ui/references/components/date-views.md +212 -0
- package/skills/cocoar-vue-ui/references/components/dialog.md +148 -0
- package/skills/cocoar-vue-ui/references/components/divider.md +157 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/annotations.md +400 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/coar-document-viewer.md +327 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/index.md +234 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/toolbar.md +221 -0
- package/skills/cocoar-vue-ui/references/components/drag-drop.md +267 -0
- package/skills/cocoar-vue-ui/references/components/dual-listbox.md +449 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/asset-store.md +327 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/in-memory-store.md +176 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/index.md +311 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/use-file-explorer.md +300 -0
- package/skills/cocoar-vue-ui/references/components/form-field.md +1025 -0
- package/skills/cocoar-vue-ui/references/components/fragment-parser.md +298 -0
- package/skills/cocoar-vue-ui/references/components/link.md +235 -0
- package/skills/cocoar-vue-ui/references/components/listbox.md +575 -0
- package/skills/cocoar-vue-ui/references/components/map/editor.md +448 -0
- package/skills/cocoar-vue-ui/references/components/map/index.md +351 -0
- package/skills/cocoar-vue-ui/references/components/markdown-diagrams.md +210 -0
- package/skills/cocoar-vue-ui/references/components/markdown-editor.md +1478 -0
- package/skills/cocoar-vue-ui/references/components/markdown-embeds.md +387 -0
- package/skills/cocoar-vue-ui/references/components/markdown-form.md +447 -0
- package/skills/cocoar-vue-ui/references/components/markdown.md +276 -0
- package/skills/cocoar-vue-ui/references/components/menu.md +380 -0
- package/skills/cocoar-vue-ui/references/components/mermaid.md +172 -0
- package/skills/cocoar-vue-ui/references/components/navbar.md +147 -0
- package/skills/cocoar-vue-ui/references/components/note.md +96 -0
- package/skills/cocoar-vue-ui/references/components/notice.md +131 -0
- package/skills/cocoar-vue-ui/references/components/number-input.md +215 -0
- package/skills/cocoar-vue-ui/references/components/otp-input.md +324 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/authoring-contract.md +271 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-builder.md +476 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-renderer.md +677 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/custom-elements.md +441 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/idp-integration.md +122 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/index.md +573 -0
- package/skills/cocoar-vue-ui/references/components/pagination.md +150 -0
- package/skills/cocoar-vue-ui/references/components/panel-layout.md +372 -0
- package/skills/cocoar-vue-ui/references/components/password-input.md +175 -0
- package/skills/cocoar-vue-ui/references/components/popconfirm.md +186 -0
- package/skills/cocoar-vue-ui/references/components/popover.md +173 -0
- package/skills/cocoar-vue-ui/references/components/progress-bar.md +178 -0
- package/skills/cocoar-vue-ui/references/components/radio-group.md +225 -0
- package/skills/cocoar-vue-ui/references/components/script-editor.md +1271 -0
- package/skills/cocoar-vue-ui/references/components/segmented-control.md +238 -0
- package/skills/cocoar-vue-ui/references/components/select.md +463 -0
- package/skills/cocoar-vue-ui/references/components/sidebar.md +421 -0
- package/skills/cocoar-vue-ui/references/components/spinner.md +132 -0
- package/skills/cocoar-vue-ui/references/components/switch.md +195 -0
- package/skills/cocoar-vue-ui/references/components/table.md +170 -0
- package/skills/cocoar-vue-ui/references/components/tabs.md +382 -0
- package/skills/cocoar-vue-ui/references/components/tag.md +178 -0
- package/skills/cocoar-vue-ui/references/components/text-input.md +256 -0
- package/skills/cocoar-vue-ui/references/components/toast.md +160 -0
- package/skills/cocoar-vue-ui/references/components/tooltip.md +121 -0
- package/skills/cocoar-vue-ui/references/components/transitions.md +193 -0
- package/skills/cocoar-vue-ui/references/components/tree.md +2388 -0
- package/skills/cocoar-vue-ui/references/components/virtual-list.md +212 -0
- package/skills/cocoar-vue-ui/references/components/wizard.md +251 -0
- package/skills/cocoar-vue-ui/references/components/zoned-date-time-picker.md +177 -0
- package/skills/cocoar-vue-ui/references/foundations/colors.md +708 -0
- package/skills/cocoar-vue-ui/references/foundations/design-principles.md +115 -0
- package/skills/cocoar-vue-ui/references/foundations/icons.md +381 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/formatting.md +530 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/setup.md +86 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/timezones.md +182 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/translations.md +305 -0
- package/skills/cocoar-vue-ui/references/foundations/motion.md +549 -0
- package/skills/cocoar-vue-ui/references/foundations/spacing.md +330 -0
- package/skills/cocoar-vue-ui/references/foundations/theming.md +140 -0
- package/skills/cocoar-vue-ui/references/foundations/typography.md +206 -0
- package/skills/cocoar-vue-ui/references/guide/error-handling.md +162 -0
- package/skills/cocoar-vue-ui/references/guide/getting-started.md +119 -0
- package/skills/cocoar-vue-ui/references/guide/migration-page-builder-3.md +207 -0
- package/skills/cocoar-vue-ui/references/guide/migration.md +140 -0
- 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°</span></div>
|
|
215
|
+
<div class="rotation-item"><CoarIcon name="chevron-right" size="l" :rotate="90" /><span class="rotation-label">90°</span></div>
|
|
216
|
+
<div class="rotation-item"><CoarIcon name="chevron-right" size="l" :rotate="180" /><span class="rotation-label">180°</span></div>
|
|
217
|
+
<div class="rotation-item"><CoarIcon name="chevron-right" size="l" :rotate="270" /><span class="rotation-label">270°</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 |
|