vunor 0.1.2 → 0.1.3
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/README.md +6 -11
- package/dist/AppLayout.mjs +0 -0
- package/dist/AppToasts.mjs +4 -8
- package/dist/Button.mjs +5 -10
- package/dist/ButtonBase.mjs +4 -8
- package/dist/Calendar.mjs +10 -14
- package/dist/Card.mjs +4 -9
- package/dist/CardHeader.mjs +5 -10
- package/dist/CardInner.mjs +4 -9
- package/dist/Checkbox.mjs +4 -8
- package/dist/Combobox.d.mts +9 -9
- package/dist/Combobox.mjs +5 -9
- package/dist/DatePicker.d.mts +9 -9
- package/dist/DatePicker.mjs +12 -17
- package/dist/DatePickerBase.d.mts +9 -9
- package/dist/DatePickerBase.mjs +13 -17
- package/dist/DatePickerInner.mjs +5 -9
- package/dist/DatePickerPopup.mjs +4 -8
- package/dist/DelayedSwitch.mjs +4 -9
- package/dist/DevTools.mjs +583 -150
- package/dist/Dialog.d.mts +6 -6
- package/dist/Dialog.mjs +4 -8
- package/dist/Icon.mjs +4 -9
- package/dist/InnerLoading.mjs +4 -8
- package/dist/Input.d.mts +13 -13
- package/dist/Input.mjs +4 -8
- package/dist/InputBase.d.mts +9 -9
- package/dist/InputBase.mjs +4 -8
- package/dist/Label.mjs +1 -4
- package/dist/LoadingIndicator.mjs +4 -8
- package/dist/Menu.d.mts +2 -2
- package/dist/Menu.mjs +5 -14
- package/dist/MenuItem.mjs +4 -9
- package/dist/OverflowContainer.mjs +4 -8
- package/dist/Pagination.mjs +4 -9
- package/dist/Popover.mjs +4 -9
- package/dist/ProgressBar.mjs +4 -9
- package/dist/RadioGroup.mjs +4 -8
- package/dist/Select.d.mts +9 -9
- package/dist/Select.mjs +4 -9
- package/dist/SelectBase.mjs +4 -8
- package/dist/Slider.mjs +4 -8
- package/dist/Tabs.mjs +4 -9
- package/dist/nuxt.mjs +1 -3
- package/dist/theme.d.mts +35 -0
- package/dist/theme.mjs +289 -336
- package/dist/utils-6bTTIoaw.js +40 -0
- package/dist/utils.d.mts +2 -2
- package/dist/utils.mjs +1 -4
- package/dist/vite.mjs +1 -2
- package/dist/vunor.d.mts +13 -13
- package/dist/vunor.mjs +1 -6
- package/package.json +30 -37
- package/scripts/setup-skills.js +0 -78
- package/skills/vunor/SKILL.md +0 -115
- package/skills/vunor/components.md +0 -320
- package/skills/vunor/core.md +0 -173
- package/skills/vunor/forms.md +0 -348
- package/skills/vunor/palette.md +0 -223
- package/skills/vunor/rules.md +0 -263
- package/skills/vunor/shortcuts.md +0 -239
- package/skills/vunor/typography.md +0 -204
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
# Components overview — vunor
|
|
2
|
-
|
|
3
|
-
> Layout, action, feedback, and utility components: Card, Dialog, Button, Tabs, Menu, Popover, AppLayout, Icon, Loading, etc.
|
|
4
|
-
|
|
5
|
-
## Concepts
|
|
6
|
-
|
|
7
|
-
Vunor ships 30+ accessible Vue 3 components built on Reka UI. All use the `Vu` prefix in templates (`<VuButton>`, `<VuCard>`). Source files omit the prefix (`Button.vue`, `Card.vue`).
|
|
8
|
-
|
|
9
|
-
Components are styled entirely through UnoCSS shortcuts and CSS custom properties — no scoped styles. Override any component's appearance through the shortcut object system (see [shortcuts.md](shortcuts.md)).
|
|
10
|
-
|
|
11
|
-
### Auto-import
|
|
12
|
-
|
|
13
|
-
- **Vite**: Use `VunorVueResolver` with `unplugin-vue-components` — no manual imports needed.
|
|
14
|
-
- **Nuxt**: The `vunor/nuxt` module auto-registers all `Vu*` components globally.
|
|
15
|
-
- **Manual**: `import VuButton from 'vunor/Button'`
|
|
16
|
-
|
|
17
|
-
### Reka UI foundation
|
|
18
|
-
|
|
19
|
-
All interactive components wrap Reka UI primitives, providing:
|
|
20
|
-
- Full keyboard navigation and ARIA attributes
|
|
21
|
-
- Polymorphic rendering via `as` / `asChild` props
|
|
22
|
-
- Portal rendering for popups/dialogs
|
|
23
|
-
- State management (`data-state="checked"`, `aria-disabled="true"`, etc.)
|
|
24
|
-
|
|
25
|
-
### Provide/Inject (PI) pattern
|
|
26
|
-
|
|
27
|
-
Some components use typed provide/inject for parent-child communication via `useProvideInject`:
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
// Parent calls: useInputPi().provide()
|
|
31
|
-
// Child calls: useInputPi().inject(focused)
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Components with PI: **Input** (tracks focused state across input groups), **Card** (passes header level to CardHeader).
|
|
35
|
-
|
|
36
|
-
## API Reference
|
|
37
|
-
|
|
38
|
-
### Layout components
|
|
39
|
-
|
|
40
|
-
#### `<VuCard>`
|
|
41
|
-
|
|
42
|
-
Card container with typography-driven spacing.
|
|
43
|
-
|
|
44
|
-
| Prop | Type | Default | Description |
|
|
45
|
-
|------|------|---------|-------------|
|
|
46
|
-
| `level` | `string` | — | Typography level for spacing: `'h1'`–`'h6'`, `'body'`, `'callout'`, etc. |
|
|
47
|
-
| `dense` | `boolean` | `false` | Reduce padding to 60% |
|
|
48
|
-
| `rounded` | `boolean` | `true` | Apply border radius |
|
|
49
|
-
| `noPadding` | `boolean` | `false` | Remove all padding |
|
|
50
|
-
| `as` | `string` | `'div'` | HTML element to render as |
|
|
51
|
-
| `asChild` | `boolean` | `false` | Render as child element (Reka UI polymorphic) |
|
|
52
|
-
|
|
53
|
-
**Slots**: `default`
|
|
54
|
-
|
|
55
|
-
**CSS classes**: `card`, `card-dense`
|
|
56
|
-
**Data attrs**: `data-rounded`, `data-dense`, `data-level`
|
|
57
|
-
|
|
58
|
-
```html
|
|
59
|
-
<VuCard level="h3">
|
|
60
|
-
<VuCardHeader>Section Title</VuCardHeader>
|
|
61
|
-
<p>Card content with h3-proportional padding</p>
|
|
62
|
-
</VuCard>
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
#### `<VuCardHeader>`
|
|
66
|
-
|
|
67
|
-
Header inside a card. Automatically adapts typography level from parent Card's PI.
|
|
68
|
-
|
|
69
|
-
**Slots**: `default`
|
|
70
|
-
**CSS classes**: `card-header`
|
|
71
|
-
|
|
72
|
-
#### `<VuCardInner>`
|
|
73
|
-
|
|
74
|
-
Nested card section for visual grouping within a card.
|
|
75
|
-
|
|
76
|
-
**Slots**: `default`
|
|
77
|
-
|
|
78
|
-
#### `<VuDialog>`
|
|
79
|
-
|
|
80
|
-
Modal dialog with overlay.
|
|
81
|
-
|
|
82
|
-
| Prop | Type | Default | Description |
|
|
83
|
-
|------|------|---------|-------------|
|
|
84
|
-
| `open` | `boolean` | — | v-model for open state |
|
|
85
|
-
| `defaultOpen` | `boolean` | `false` | Initial open state |
|
|
86
|
-
| `modal` | `boolean` | `true` | Modal behavior |
|
|
87
|
-
| `title` | `string` | — | Dialog title |
|
|
88
|
-
| `level` | `string` | `'h4'` | Typography level for title |
|
|
89
|
-
| `rounded` | `boolean` | `true` | Apply border radius |
|
|
90
|
-
| `closeButton` | `boolean` | `true` | Show close button |
|
|
91
|
-
| `footerButtons` | `Array` | — | Footer action buttons |
|
|
92
|
-
| `focusFirstSelector` | `string` | `'input'` | CSS selector for initial focus |
|
|
93
|
-
|
|
94
|
-
**Emits**: `footer-click`, `footer-click-{buttonId}`
|
|
95
|
-
**Slots**: `header`, `title`, `default`, `footer`
|
|
96
|
-
**CSS classes**: `dialog-overlay`, `dialog-card`, `dialog-header`, `dialog-title`, `dialog-close`, `dialog-footer`
|
|
97
|
-
|
|
98
|
-
```html
|
|
99
|
-
<VuDialog v-model:open="showDialog" title="Confirm">
|
|
100
|
-
<p>Are you sure?</p>
|
|
101
|
-
<template #footer>
|
|
102
|
-
<VuButton class="scope-primary c8-filled" @click="confirm">Yes</VuButton>
|
|
103
|
-
</template>
|
|
104
|
-
</VuDialog>
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
#### `<VuTabs>`
|
|
108
|
-
|
|
109
|
-
Tabbed content panels.
|
|
110
|
-
|
|
111
|
-
| Prop | Type | Default | Description |
|
|
112
|
-
|------|------|---------|-------------|
|
|
113
|
-
| `tabs` | `Array<{ value, label?, icon? }>` | — | Tab definitions |
|
|
114
|
-
| `modelValue` | `string` | — | v-model for active tab |
|
|
115
|
-
| `defaultValue` | `string` | — | Initial active tab |
|
|
116
|
-
| `activationMode` | `'automatic' \| 'manual'` | `'automatic'` | Tab activation mode |
|
|
117
|
-
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Tab list direction |
|
|
118
|
-
| `indicator` | `boolean` | `true` | Show active tab indicator |
|
|
119
|
-
| `noContent` | `boolean` | `false` | Hide content panels |
|
|
120
|
-
| `tabGrow` | `boolean` | `false` | Tabs fill available width |
|
|
121
|
-
| `tabClass` | `string` | `'c8-flat'` | CSS class for tab triggers |
|
|
122
|
-
|
|
123
|
-
**Slots**: `default` (custom tab trigger), named slots per `tab.value` for content
|
|
124
|
-
**CSS classes**: `tabs-indicator`, `tab`
|
|
125
|
-
|
|
126
|
-
```html
|
|
127
|
-
<VuTabs :tabs="[{ value: 'a', label: 'Tab A' }, { value: 'b', label: 'Tab B' }]">
|
|
128
|
-
<template #a>Content A</template>
|
|
129
|
-
<template #b>Content B</template>
|
|
130
|
-
</VuTabs>
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
#### `<VuPopover>`
|
|
134
|
-
|
|
135
|
-
Floating popover anchored to a trigger element. Wraps Reka UI PopoverRoot.
|
|
136
|
-
|
|
137
|
-
**Slots**: `default` (trigger), popover content slot
|
|
138
|
-
**CSS classes**: Uses Reka UI PopoverPortal for rendering.
|
|
139
|
-
|
|
140
|
-
#### `<VuAppLayout>`
|
|
141
|
-
|
|
142
|
-
App shell with header, sidebar, and footer slots.
|
|
143
|
-
|
|
144
|
-
**CSS variables**: `--app-footer-h`, `--app-header-h`, `--app-left-w`, `--app-right-w`, `--app-max-w`
|
|
145
|
-
|
|
146
|
-
### Action components
|
|
147
|
-
|
|
148
|
-
#### `<VuButton>`
|
|
149
|
-
|
|
150
|
-
Button with icon, loading, and link support.
|
|
151
|
-
|
|
152
|
-
| Prop | Type | Default | Description |
|
|
153
|
-
|------|------|---------|-------------|
|
|
154
|
-
| `label` | `string` | — | Button text |
|
|
155
|
-
| `icon` | `string` | — | Icon name (UnoCSS icon class) |
|
|
156
|
-
| `iconSide` | `'left' \| 'right'` | `'left'` | Icon position |
|
|
157
|
-
| `loading` | `boolean` | `false` | Show loading indicator |
|
|
158
|
-
| `disabled` | `boolean` | `false` | Disable button |
|
|
159
|
-
| `active` | `boolean` | `false` | Active state |
|
|
160
|
-
| `pressed` | `boolean` | `false` | Pressed state |
|
|
161
|
-
| `selected` | `boolean` | `false` | Selected state |
|
|
162
|
-
| `to` | `RouteLocationRaw` | — | Vue Router link target |
|
|
163
|
-
| `asLink` | `boolean` | `false` | Render as `<a>` |
|
|
164
|
-
|
|
165
|
-
**Slots**: `default`, `icon-left`, `icon-right`
|
|
166
|
-
**CSS classes**: `btn`, `btn-round`, `btn-square`, `btn-icon`, `btn-label`
|
|
167
|
-
|
|
168
|
-
```html
|
|
169
|
-
<!-- Basic -->
|
|
170
|
-
<VuButton label="Save" class="scope-primary c8-filled" />
|
|
171
|
-
|
|
172
|
-
<!-- With icon -->
|
|
173
|
-
<VuButton icon="i-mdi-check" label="Confirm" class="scope-good c8-filled" />
|
|
174
|
-
|
|
175
|
-
<!-- Icon-only (square) -->
|
|
176
|
-
<VuButton icon="i-mdi-close" class="scope-error c8-flat" />
|
|
177
|
-
|
|
178
|
-
<!-- As router link -->
|
|
179
|
-
<VuButton label="Go Home" :to="{ name: 'home' }" class="c8-flat" />
|
|
180
|
-
|
|
181
|
-
<!-- Loading state -->
|
|
182
|
-
<VuButton label="Saving..." :loading="isSaving" class="scope-primary c8-filled" />
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
#### `<VuMenu>`
|
|
186
|
-
|
|
187
|
-
Navigation / command menu built on Reka UI ComboboxRoot. Supports search filtering and grouping.
|
|
188
|
-
|
|
189
|
-
| Prop | Type | Default | Description |
|
|
190
|
-
|------|------|---------|-------------|
|
|
191
|
-
| `items` | `Array<string \| TItem>` | — | Menu items |
|
|
192
|
-
| `emptyText` | `string` | — | Text when no items match |
|
|
193
|
-
|
|
194
|
-
`TItem`: `{ label, value, icon?, group? }`
|
|
195
|
-
|
|
196
|
-
**Slots**: `empty`, `item`
|
|
197
|
-
**CSS classes**: `menu-root`, `menu-item`
|
|
198
|
-
|
|
199
|
-
#### `<VuMenuItem>`
|
|
200
|
-
|
|
201
|
-
Individual menu item.
|
|
202
|
-
|
|
203
|
-
#### `<VuPagination>`
|
|
204
|
-
|
|
205
|
-
Page navigation component.
|
|
206
|
-
|
|
207
|
-
### Feedback components
|
|
208
|
-
|
|
209
|
-
#### `<VuAppToasts>`
|
|
210
|
-
|
|
211
|
-
Toast notification container. Place once at app root.
|
|
212
|
-
|
|
213
|
-
**CSS classes**: `toast-root`, `toasts-viewport`
|
|
214
|
-
|
|
215
|
-
#### `<VuProgressBar>`
|
|
216
|
-
|
|
217
|
-
Progress bar indicator.
|
|
218
|
-
|
|
219
|
-
**CSS classes**: `progress-bar`
|
|
220
|
-
|
|
221
|
-
#### `<VuLoadingIndicator>`
|
|
222
|
-
|
|
223
|
-
Circular loading spinner.
|
|
224
|
-
|
|
225
|
-
**CSS classes**: `loading-indicator`, `loading-indicator-ring`
|
|
226
|
-
|
|
227
|
-
#### `<VuInnerLoading>`
|
|
228
|
-
|
|
229
|
-
Overlay loading indicator within a container.
|
|
230
|
-
|
|
231
|
-
**CSS classes**: `inner-loading`, `loading-indicator-wrapper`
|
|
232
|
-
|
|
233
|
-
```html
|
|
234
|
-
<div class="relative">
|
|
235
|
-
<p>Content</p>
|
|
236
|
-
<VuInnerLoading v-if="loading" />
|
|
237
|
-
</div>
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### Utility components
|
|
241
|
-
|
|
242
|
-
#### `<VuIcon>`
|
|
243
|
-
|
|
244
|
-
Icon display using UnoCSS icon classes.
|
|
245
|
-
|
|
246
|
-
| Prop | Type | Description |
|
|
247
|
-
|------|------|-------------|
|
|
248
|
-
| `name` | `string` | Icon class name (e.g. `'i-mdi-check'`) |
|
|
249
|
-
|
|
250
|
-
**CSS classes**: `icon-color`, `icon-size`
|
|
251
|
-
|
|
252
|
-
```html
|
|
253
|
-
<VuIcon name="i-mdi-check" />
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
#### `<VuOverflowContainer>`
|
|
257
|
-
|
|
258
|
-
Handles content overflow with scroll indicators.
|
|
259
|
-
|
|
260
|
-
#### `<VuCalendar>`
|
|
261
|
-
|
|
262
|
-
Standalone calendar grid (used internally by DatePicker).
|
|
263
|
-
|
|
264
|
-
**CSS classes**: `calendar-root`, `calendar-header`, `calendar-month-grid`, `calendar-grid-row`, `calendar-cell`
|
|
265
|
-
|
|
266
|
-
## Common patterns
|
|
267
|
-
|
|
268
|
-
### Pattern: Scoped button group
|
|
269
|
-
|
|
270
|
-
```html
|
|
271
|
-
<div class="scope-primary flex gap-$xs">
|
|
272
|
-
<VuButton label="Save" class="c8-filled" />
|
|
273
|
-
<VuButton label="Draft" class="c8-outlined" />
|
|
274
|
-
<VuButton label="Cancel" class="c8-flat" />
|
|
275
|
-
</div>
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
### Pattern: Dialog with footer buttons
|
|
279
|
-
|
|
280
|
-
```html
|
|
281
|
-
<VuDialog
|
|
282
|
-
v-model:open="showConfirm"
|
|
283
|
-
title="Delete Item?"
|
|
284
|
-
:footer-buttons="['cancel', { id: 'delete', label: 'Delete', class: 'scope-error c8-filled' }]"
|
|
285
|
-
@footer-click-delete="handleDelete"
|
|
286
|
-
>
|
|
287
|
-
<p>This action cannot be undone.</p>
|
|
288
|
-
</VuDialog>
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### Pattern: Card with nested sections
|
|
292
|
-
|
|
293
|
-
```html
|
|
294
|
-
<VuCard level="h3">
|
|
295
|
-
<VuCardHeader>User Profile</VuCardHeader>
|
|
296
|
-
<VuCardInner>
|
|
297
|
-
<VuCardHeader>Personal Info</VuCardHeader>
|
|
298
|
-
<p>Name, email, etc.</p>
|
|
299
|
-
</VuCardInner>
|
|
300
|
-
<VuCardInner>
|
|
301
|
-
<VuCardHeader>Preferences</VuCardHeader>
|
|
302
|
-
<p>Settings...</p>
|
|
303
|
-
</VuCardInner>
|
|
304
|
-
</VuCard>
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
## Best practices
|
|
308
|
-
|
|
309
|
-
- Always set `scope-{color}` on or above interactive components — `c8-*` styles rely on it for coloring.
|
|
310
|
-
- Use the `level` prop on `VuCard` to get typography-proportional padding.
|
|
311
|
-
- Place `<VuAppToasts>` once at the app root, not inside conditional renders.
|
|
312
|
-
- For loading states, use `VuInnerLoading` inside a `relative`-positioned container — it uses `absolute` positioning internally.
|
|
313
|
-
|
|
314
|
-
## Gotchas
|
|
315
|
-
|
|
316
|
-
- Reka UI uses `aria-disabled="true"` instead of the HTML `disabled` attribute. Check `aria-disabled` in selectors, not `disabled`.
|
|
317
|
-
- Reka UI uses `data-state="checked"` / `"unchecked"` / `"indeterminate"` for state, not `:checked` pseudo-class.
|
|
318
|
-
- Select/Combobox popups portal to `<body>` — scope CSS selectors to `.select-content` to target them.
|
|
319
|
-
- Reka UI renders hidden native `<select>/<option>` for form submission. `getByRole('option')` matches both native and custom options — scope to `div[role="option"]` within the popup.
|
|
320
|
-
- `VuButton` with a `to` prop renders as a router link. It does not render a `<button>` element in that case.
|
package/skills/vunor/core.md
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
# Core concepts & setup — vunor
|
|
2
|
-
|
|
3
|
-
> Installation, project setup for Vue 3 + Vite and Nuxt 3, mental model, and package exports.
|
|
4
|
-
|
|
5
|
-
## Concepts
|
|
6
|
-
|
|
7
|
-
Vunor is two things in one package:
|
|
8
|
-
|
|
9
|
-
1. **A UnoCSS theme engine** — a custom UnoCSS preset (`presetVunor`) that generates a complete design system from a few mathematical constants: golden ratio for typography/spacing, Oklab for perceptually uniform colors, and structured shortcut objects for mergeable component styles.
|
|
10
|
-
|
|
11
|
-
2. **A Vue 3 component library** — 30+ accessible components built on Reka UI, styled entirely through UnoCSS classes (zero CSS files). Components use the `Vu` prefix in templates (`<VuButton>`, `<VuInput>`).
|
|
12
|
-
|
|
13
|
-
You can use the theme engine without the components, or use both together.
|
|
14
|
-
|
|
15
|
-
### Key principles
|
|
16
|
-
|
|
17
|
-
- **All styling is UnoCSS classes** — no `<style>` blocks, no CSS files, no scoped styles. Component appearance is defined through UnoCSS shortcuts, rules, and CSS custom properties.
|
|
18
|
-
- **Mathematical derivation** — font sizes, spacing, border radii, and touch targets all derive from the golden ratio (1.618). Change one scale factor and the entire system recalculates.
|
|
19
|
-
- **Perceptual color uniformity** — palette generation uses Oklab, so `primary-500` and `error-500` look equally bright regardless of hue.
|
|
20
|
-
- **Deep mergeability** — component styles use structured shortcut objects that can be surgically overridden through deep merging, not string replacement.
|
|
21
|
-
|
|
22
|
-
## Installation
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
pnpm add vunor
|
|
26
|
-
# or: npm install vunor
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Peer dependencies (installed automatically with vunor):
|
|
30
|
-
- `vue` ^3.5
|
|
31
|
-
- `unocss` ^66
|
|
32
|
-
- `reka-ui` ^2.0
|
|
33
|
-
|
|
34
|
-
## Setup — Vue 3 + Vite
|
|
35
|
-
|
|
36
|
-
Three files to configure:
|
|
37
|
-
|
|
38
|
-
### vite.config.ts
|
|
39
|
-
|
|
40
|
-
```ts
|
|
41
|
-
import { defineConfig } from 'vite'
|
|
42
|
-
import vue from '@vitejs/plugin-vue'
|
|
43
|
-
import UnoCSS from 'unocss/vite'
|
|
44
|
-
import Components from 'unplugin-vue-components/vite'
|
|
45
|
-
import { VunorVueResolver } from 'vunor/vite'
|
|
46
|
-
|
|
47
|
-
export default defineConfig({
|
|
48
|
-
plugins: [
|
|
49
|
-
vue(),
|
|
50
|
-
UnoCSS(),
|
|
51
|
-
Components({
|
|
52
|
-
resolvers: [VunorVueResolver],
|
|
53
|
-
}),
|
|
54
|
-
],
|
|
55
|
-
})
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
`VunorVueResolver` maps `<VuButton>` in templates to `import { default as VuButton } from 'vunor/Button'`. No manual imports needed.
|
|
59
|
-
|
|
60
|
-
### uno.config.ts
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
import { defineConfig } from 'unocss'
|
|
64
|
-
import { presetVunor, vunorShortcuts } from 'vunor/theme'
|
|
65
|
-
|
|
66
|
-
export default defineConfig({
|
|
67
|
-
presets: [presetVunor()],
|
|
68
|
-
shortcuts: [vunorShortcuts()],
|
|
69
|
-
})
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
No `safelist` is needed. The preset includes a built-in extractor that detects `<VuButton>`, `<VuInput>`, etc. in templates and automatically includes the required CSS classes.
|
|
73
|
-
|
|
74
|
-
### main.ts
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
import { createApp } from 'vue'
|
|
78
|
-
import '@unocss/reset/tailwind.css'
|
|
79
|
-
import 'virtual:uno.css'
|
|
80
|
-
import App from './App.vue'
|
|
81
|
-
|
|
82
|
-
createApp(App).mount('#app')
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Setup — Nuxt 3
|
|
86
|
-
|
|
87
|
-
```ts
|
|
88
|
-
// nuxt.config.ts
|
|
89
|
-
export default defineNuxtConfig({
|
|
90
|
-
modules: ['vunor/nuxt'],
|
|
91
|
-
})
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
The Nuxt module auto-registers all `Vu*` components globally. No additional configuration is needed for basic usage.
|
|
95
|
-
|
|
96
|
-
## Package exports
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
vunor Provide/inject composables: useInputPi, useCardPI, useInputProps, etc.
|
|
100
|
-
vunor/theme UnoCSS preset, shortcuts, palette: presetVunor, vunorShortcuts, defineShortcuts, etc.
|
|
101
|
-
vunor/utils Utilities: mergeCssClasses, useProvideInject
|
|
102
|
-
vunor/vite Component resolver: VunorVueResolver
|
|
103
|
-
vunor/nuxt Nuxt 3 module (auto-registers Vu* components)
|
|
104
|
-
vunor/{Name} Individual Vue components, e.g. vunor/Button, vunor/Input, vunor/Card
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### Key exports from `vunor/theme`
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
import {
|
|
111
|
-
presetVunor, // UnoCSS preset factory
|
|
112
|
-
vunorShortcuts, // Returns merged shortcuts array for UnoCSS config
|
|
113
|
-
defineShortcuts, // Type-safe shortcut object builder
|
|
114
|
-
mergeVunorShortcuts, // Merge multiple shortcut arrays (later wins)
|
|
115
|
-
toUnoShortcut, // Flatten a shortcut object to a UnoCSS string
|
|
116
|
-
} from 'vunor/theme'
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### Key exports from `vunor`
|
|
120
|
-
|
|
121
|
-
```ts
|
|
122
|
-
import {
|
|
123
|
-
useInputPi, // Provide/inject for Input component groups
|
|
124
|
-
useInputProps, // Computed props helper for Input
|
|
125
|
-
useInputBaseProps, // Computed props helper for InputBase
|
|
126
|
-
useCardPI, // Provide/inject for Card → CardHeader
|
|
127
|
-
} from 'vunor'
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
## presetVunor options
|
|
131
|
-
|
|
132
|
-
```ts
|
|
133
|
-
presetVunor({
|
|
134
|
-
// Color palette — see palette.md
|
|
135
|
-
palette: { colors: { primary: '#6B4EFF' } },
|
|
136
|
-
|
|
137
|
-
// Golden ratio spacing factor (default: 1.618)
|
|
138
|
-
spacingFactor: 1.618,
|
|
139
|
-
|
|
140
|
-
// Global border radius (default: ~0.618em = 1/golden-ratio)
|
|
141
|
-
baseRadius: '0.5em',
|
|
142
|
-
|
|
143
|
-
// Typography overrides — see typography.md
|
|
144
|
-
typography: { h1: { size: 4, weight: 300 } },
|
|
145
|
-
|
|
146
|
-
// Font rendering correction
|
|
147
|
-
actualFontHeightFactor: 0.76,
|
|
148
|
-
actualFontHeightTopBottomRatio: 0.5,
|
|
149
|
-
|
|
150
|
-
// Touch target sizes
|
|
151
|
-
fingertip: { xs: '1.25em', s: '2em', m: '3em', l: '3.5em', xl: '4em' },
|
|
152
|
-
|
|
153
|
-
// Card padding multipliers
|
|
154
|
-
cardSpacingFactor: { regular: 1, dense: 0.6 },
|
|
155
|
-
|
|
156
|
-
// Layer direction
|
|
157
|
-
layers: { reverseDark: false, reverseLight: false },
|
|
158
|
-
})
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
## Best practices
|
|
162
|
-
|
|
163
|
-
- Always include both `presetVunor()` in `presets` and `vunorShortcuts()` in `shortcuts` — they work together.
|
|
164
|
-
- Use `VunorVueResolver` with `unplugin-vue-components` for tree-shaking — only components you use get bundled.
|
|
165
|
-
- Do not add component CSS classes to `safelist` — the built-in extractor handles this automatically.
|
|
166
|
-
- For Nuxt projects, prefer the `vunor/nuxt` module over manual Vite plugin setup.
|
|
167
|
-
|
|
168
|
-
## Gotchas
|
|
169
|
-
|
|
170
|
-
- The preset expects UnoCSS ^66. Earlier versions may have incompatible APIs.
|
|
171
|
-
- Components require Reka UI ^2.0 as a peer dependency. The Reka UI v1 API is not compatible.
|
|
172
|
-
- `vunor/theme` is a separate entry point from `vunor` — import preset/shortcut utilities from `vunor/theme`, not `vunor`.
|
|
173
|
-
- The built-in CSS extractor matches `Vu` prefix patterns. If you alias components to different names, the extractor won't detect them and you'll need to add the component's CSS classes manually.
|