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.
Files changed (62) hide show
  1. package/README.md +6 -11
  2. package/dist/AppLayout.mjs +0 -0
  3. package/dist/AppToasts.mjs +4 -8
  4. package/dist/Button.mjs +5 -10
  5. package/dist/ButtonBase.mjs +4 -8
  6. package/dist/Calendar.mjs +10 -14
  7. package/dist/Card.mjs +4 -9
  8. package/dist/CardHeader.mjs +5 -10
  9. package/dist/CardInner.mjs +4 -9
  10. package/dist/Checkbox.mjs +4 -8
  11. package/dist/Combobox.d.mts +9 -9
  12. package/dist/Combobox.mjs +5 -9
  13. package/dist/DatePicker.d.mts +9 -9
  14. package/dist/DatePicker.mjs +12 -17
  15. package/dist/DatePickerBase.d.mts +9 -9
  16. package/dist/DatePickerBase.mjs +13 -17
  17. package/dist/DatePickerInner.mjs +5 -9
  18. package/dist/DatePickerPopup.mjs +4 -8
  19. package/dist/DelayedSwitch.mjs +4 -9
  20. package/dist/DevTools.mjs +583 -150
  21. package/dist/Dialog.d.mts +6 -6
  22. package/dist/Dialog.mjs +4 -8
  23. package/dist/Icon.mjs +4 -9
  24. package/dist/InnerLoading.mjs +4 -8
  25. package/dist/Input.d.mts +13 -13
  26. package/dist/Input.mjs +4 -8
  27. package/dist/InputBase.d.mts +9 -9
  28. package/dist/InputBase.mjs +4 -8
  29. package/dist/Label.mjs +1 -4
  30. package/dist/LoadingIndicator.mjs +4 -8
  31. package/dist/Menu.d.mts +2 -2
  32. package/dist/Menu.mjs +5 -14
  33. package/dist/MenuItem.mjs +4 -9
  34. package/dist/OverflowContainer.mjs +4 -8
  35. package/dist/Pagination.mjs +4 -9
  36. package/dist/Popover.mjs +4 -9
  37. package/dist/ProgressBar.mjs +4 -9
  38. package/dist/RadioGroup.mjs +4 -8
  39. package/dist/Select.d.mts +9 -9
  40. package/dist/Select.mjs +4 -9
  41. package/dist/SelectBase.mjs +4 -8
  42. package/dist/Slider.mjs +4 -8
  43. package/dist/Tabs.mjs +4 -9
  44. package/dist/nuxt.mjs +1 -3
  45. package/dist/theme.d.mts +35 -0
  46. package/dist/theme.mjs +289 -336
  47. package/dist/utils-6bTTIoaw.js +40 -0
  48. package/dist/utils.d.mts +2 -2
  49. package/dist/utils.mjs +1 -4
  50. package/dist/vite.mjs +1 -2
  51. package/dist/vunor.d.mts +13 -13
  52. package/dist/vunor.mjs +1 -6
  53. package/package.json +30 -37
  54. package/scripts/setup-skills.js +0 -78
  55. package/skills/vunor/SKILL.md +0 -115
  56. package/skills/vunor/components.md +0 -320
  57. package/skills/vunor/core.md +0 -173
  58. package/skills/vunor/forms.md +0 -348
  59. package/skills/vunor/palette.md +0 -223
  60. package/skills/vunor/rules.md +0 -263
  61. package/skills/vunor/shortcuts.md +0 -239
  62. 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.
@@ -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.