@vanduo-oss/framework 1.6.0 → 1.7.0
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/CHANGELOG.md +16 -0
- package/README.md +25 -177
- package/SKILL.md +58 -0
- package/css/components/accordion.css +80 -0
- package/css/components/alerts.css +65 -0
- package/css/components/avatar.css +2 -1
- package/css/components/badges.css +2 -1
- package/css/components/buttons.css +44 -0
- package/css/components/cards.css +26 -0
- package/css/components/code-snippet.css +23 -0
- package/css/components/collections.css +21 -1
- package/css/components/flow.css +20 -0
- package/css/components/forms.css +12 -1
- package/css/components/modals.css +69 -0
- package/css/components/preloader.css +31 -0
- package/css/components/progress.css +46 -0
- package/css/components/separator.css +50 -0
- package/css/components/skeleton.css +42 -0
- package/css/components/slider.css +92 -0
- package/css/components/tabs.css +46 -0
- package/css/core/helpers.css +17 -0
- package/css/utilities/table.css +9 -0
- package/css/vanduo.css +3 -0
- package/dist/build-info.json +3 -3
- package/dist/vanduo-core.css +613 -6
- package/dist/vanduo-core.css.map +1 -1
- package/dist/vanduo-core.min.css +2 -2
- package/dist/vanduo-core.min.css.map +1 -1
- package/dist/vanduo.cjs.js +2 -2
- package/dist/vanduo.cjs.min.js +2 -2
- package/dist/vanduo.css +613 -6
- package/dist/vanduo.css.map +1 -1
- package/dist/vanduo.esm.js +2 -2
- package/dist/vanduo.esm.min.js +2 -2
- package/dist/vanduo.js +2 -2
- package/dist/vanduo.min.css +2 -2
- package/dist/vanduo.min.css.map +1 -1
- package/dist/vanduo.min.js +2 -2
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
Full release notes — covering the framework, the documentation site, and
|
|
9
9
|
ecosystem packages side by side — live at <https://vanduo.dev/#changelog>.
|
|
10
10
|
|
|
11
|
+
## [1.7.0] - 2026-06-29
|
|
12
|
+
|
|
13
|
+
Additive minor backing the `@vanduo-oss/vue` 0.3.0 release. Adds CSS for new
|
|
14
|
+
components plus alias classes the Vue components render, so the framework
|
|
15
|
+
stylesheet (which `@vanduo-oss/vue` ships as its CSS) styles every class. No
|
|
16
|
+
vanilla class names changed; every rule is additive and container-level rules
|
|
17
|
+
that could collide with legacy base styles are gated with `:has()`.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- **Separator + Slider components** — new `css/components/separator.css` (`.vd-separator`, `-vertical`, `-labeled`, `-label`) and `css/components/slider.css` (`.vd-slider` range input, `.vd-slider-field`/`-row`/`-value`), wired into `css/vanduo.css`. (`VdSwitch` reuses `.vd-form-switch`; `VdMenu` reuses `.vd-dropdown`.)
|
|
21
|
+
- **Unified status-palette aliases** — `.vd-input-danger` + `.vd-badge-danger` (aliases of the `-error` validation/variant), `.vd-alert-secondary` (new), plus `.vd-form-label` and `.vd-form-radio-icon` form helpers — backing the unified `primary/secondary/success/warning/danger/info` vocabulary in `@vanduo-oss/vue`.
|
|
22
|
+
- **Accordion component** — new `css/components/accordion.css` (`.vd-accordion`, `-item`, `-header`, `-icon`, `-panel`), wired into `css/vanduo.css`. Previously no accordion CSS existed.
|
|
23
|
+
- **Panel-based modal aliases** (`css/components/modals.css`) — `.vd-modal.vd-modal-open` (container open state), `.vd-modal-open .vd-modal-backdrop` (backdrop visibility), `.vd-modal-panel` (merges the legacy `.vd-modal-dialog` + `.vd-modal-content` box), and `.vd-modal-panel-{sm,md,lg}` sizes. Fixes invisible `VdModal` dialogs.
|
|
24
|
+
- **Component sub-element aliases** — `.vd-alert-body` / `.vd-alert-dismiss` (alerts), `.vd-btn-spinner` (a real loading spinner element; legacy `::after` suppressed when present), `.vd-card-interactive` (cards), `.vd-progress-track` / `-fill` / `-label` + `.vd-progress.is-indeterminate` (progress), `.vd-avatar-img` (alias for `.vd-avatar img`), `.vd-tab` / `.vd-tab-panels` (tabs), `.vd-code-snippet-pre` (code snippet), `.vd-collection-list` / `-text-secondary` (collections), `.vd-flow-controls` / `-position` (flow), `.vd-skeleton-lines` / `-text-short` / `-card-header` / `-card-body` / `-card-{sm,md,lg,xl}` (skeleton), `.vd-preloader-spinner` (preloader), and `.vd-table-caption` (tables).
|
|
25
|
+
- **Utilities** — `.vd-muted` and `.vd-visually-hidden` (`css/core/helpers.css`).
|
|
26
|
+
|
|
11
27
|
## [1.6.0] - 2026-06-27
|
|
12
28
|
|
|
13
29
|
Additive release. Adds the Popover and Search primitives and an optional
|
package/README.md
CHANGED
|
@@ -1,201 +1,49 @@
|
|
|
1
|
-
# Vanduo Framework v1.6.0
|
|
2
|
-
|
|
3
|
-
<p align="center">
|
|
4
|
-
<img src="vanduo-banner.svg" alt="Vanduo Framework Banner" width="100%">
|
|
5
|
-
</p>
|
|
6
|
-
|
|
7
1
|
<p align="center">
|
|
8
|
-
<
|
|
9
|
-
<a href="https://github.com/vanduo-oss/framework/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/vanduo-oss/framework/ci.yml?branch=main&style=flat-square&color=10b981" alt="Build Status"></a>
|
|
10
|
-
<a href="https://github.com/vanduo-oss/framework/blob/main/LICENSE"><img src="https://img.shields.io/github/license/vanduo-oss/framework?style=flat-square&color=64748b" alt="License"></a>
|
|
2
|
+
<img src="vanduo-banner.svg" alt="Vanduo Framework" width="100%">
|
|
11
3
|
</p>
|
|
12
4
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
[Browse Docs](https://vanduo.dev/#docs)
|
|
16
|
-
|
|
17
|
-
## Highlights
|
|
18
|
-
|
|
19
|
-
- Zero runtime dependencies
|
|
20
|
-
- 48+ components across layout, navigation, overlays, search, and effects
|
|
21
|
-
- Scoped runtime APIs for dynamic DOM work
|
|
22
|
-
- Strict design token API under `--vd-*`
|
|
23
|
-
- Built-in dark, light, and system theming
|
|
24
|
-
- Theme customizer with color, font, and radius controls
|
|
25
|
-
- Theme Switcher menu variant for icon-only light/dark/system selection in navbars
|
|
26
|
-
- Playwright-based browser coverage across Chromium, Firefox, and WebKit
|
|
27
|
-
|
|
28
|
-
## What's New in 1.6.0
|
|
29
|
-
|
|
30
|
-
Additive release — two new primitives and an optional palette, plus one HTML-sanitization behavior change to note.
|
|
31
|
-
|
|
32
|
-
- **New — Popover component** (`window.VanduoPopover`) — a general popover primitive with click / hover / focus triggers, external-panel composition via `data-vd-popover-target`, size variants, and auto-placement flip on overflow — alongside the existing `.vd-bubble`.
|
|
33
|
-
- **New — Search helper** (`window.VanduoSearch`) — a small registry letting consumers register their own data sources (`register` / `unregister` / `list` / `query`) behind a single search surface; results merge across sources.
|
|
34
|
-
- **New — Optional Fibonacci palette** — a golden-angle generated palette, opt in at runtime via `data-palette="fibonacci"` on `<html>`. **Open Color remains the default look.**
|
|
35
|
-
- **Behavior change — HTML sanitization denies inline styles by default** — `sanitizeHtml` (used by Bubble / Popover rich content) now strips `style` attributes, closing an attribute-injection vector. Move inline styles to classes; opt back in only where you fully trust the source.
|
|
36
|
-
- **Hardening** — `escapeHtml` is now quote-safe for attribute contexts.
|
|
37
|
-
- **Tooling** — dependencies updated to latest; pnpm config migrated to `pnpm-workspace.yaml`.
|
|
38
|
-
|
|
39
|
-
## Previous: 1.5.1
|
|
40
|
-
|
|
41
|
-
- **Expanding Cards — mobile** — below `768px`, panels stack vertically and expand in place using the same flex-grow redistribution as the desktop strip (replacing progressive hide and non-animatable `order` reorder). Inactive rows render as compact stripes with icon + title; labels and subtitles transition smoothly. `ArrowUp`/`ArrowDown` keyboard navigation added alongside left/right.
|
|
42
|
-
- **Expanding Cards — photo backgrounds** — active panels use `background-size: cover` and `background-repeat: no-repeat` so wide expanded cards no longer show tiled repeats on the sides.
|
|
43
|
-
- **Expanding Cards — polish** — mobile overflow clipping and keyboard focus edge cases resolved.
|
|
44
|
-
|
|
45
|
-
## Previous: 1.5.0
|
|
46
|
-
|
|
47
|
-
- **Layout primitives** — new CSS-only layout containers — `.vd-box`, `.vd-stack`, `.vd-inline`, `.vd-center`, `.vd-frame` (golden-ratio aspect box), `.vd-cover`, and `.vd-switcher` (container-query-free responsive row→column) — with a `data-*` API (`data-pad`, `data-gap`, `data-align`, `data-justify`, `data-round`, `data-ratio`…) that consumes the existing Fibonacci spacing/radius and semantic tokens. They are the composition layer between utilities and components — *utilities style an element; primitives arrange elements*. Zero JS, zero new public tokens.
|
|
48
|
-
- **Hex grid is now a standalone package** — `VdHexGrid` was never part of the bundle; its source has moved out of the framework tree. Install [`@vanduo-oss/hex-grid`](https://www.npmjs.com/package/@vanduo-oss/hex-grid) directly.
|
|
5
|
+
# @vanduo-oss/framework
|
|
49
6
|
|
|
50
|
-
|
|
7
|
+
[](https://www.npmjs.com/package/@vanduo-oss/framework)
|
|
8
|
+
[](https://github.com/vanduo-oss/framework/actions/workflows/ci.yml)
|
|
9
|
+
[](./LICENSE)
|
|
51
10
|
|
|
52
|
-
|
|
53
|
-
- **No-icons core build** — new `dist/vanduo-core.min.css` (`@vanduo-oss/framework/css/core`) drops the bundled icons entirely (~123 KB lighter) for consumers who ship their own icon set.
|
|
54
|
-
- **Smaller package** — the build ships only the icon weights the bundle actually uses into `dist/icons/`, instead of all six.
|
|
55
|
-
- **TypeScript types** — a hand-written `dist/vanduo.d.ts` for the `Vanduo` runtime, exposed via the `types` field.
|
|
56
|
-
- **In-repo changelog** — a new [CHANGELOG.md](CHANGELOG.md) (Keep a Changelog), now validated by `check:versions`.
|
|
57
|
-
- **Version-consistency now covers prose** — `pnpm check:versions` validates README, `SECURITY.md`, `llms.txt`, and `CHANGELOG.md`, not just the dist banners.
|
|
58
|
-
- **Lint guard** — raw `innerHTML` assignment is now flagged by ESLint outside the sanitization helpers.
|
|
59
|
-
- **Parallax & print fixes (now tested)** — speed/direction classes and the print stylesheet's hide-list now use the canonical `vd-` prefix, with new Playwright regression specs; removed the unused internal `doc-tabs` styles from the bundle.
|
|
11
|
+
> The zero-build **Vanilla** engine of the Vanduo design system.
|
|
60
12
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
- **Rounded-corner background fixes** — draggable surfaces and input-group addons use `background-clip: padding-box` so opaque fills no longer bleed past border arcs at large `data-radius` presets.
|
|
64
|
-
- **Background-clip audit** — Playwright `@audit` harness at `tests/audit/background-clip-audit.spec.ts` for regression checks.
|
|
65
|
-
- Normative API: [openspec/specs/draggable/spec.md](openspec/specs/draggable/spec.md).
|
|
66
|
-
|
|
67
|
-
## Quick Start
|
|
68
|
-
|
|
69
|
-
### CDN
|
|
70
|
-
|
|
71
|
-
```html
|
|
72
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.6.0/dist/vanduo.min.css">
|
|
73
|
-
<script src="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.6.0/dist/vanduo.min.js"></script>
|
|
74
|
-
<script>
|
|
75
|
-
Vanduo.init();
|
|
76
|
-
</script>
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
> **Production tip:** harden CDN tags with Subresource Integrity — add `integrity="sha384-…" crossorigin="anonymous"`. Copy the hash from [jsdelivr.com](https://www.jsdelivr.com/) (per-file "SRI" button) or generate it with `openssl dgst -sha384 -binary dist/vanduo.min.js | openssl base64 -A`.
|
|
80
|
-
|
|
81
|
-
### Local Dist Files
|
|
82
|
-
|
|
83
|
-
```html
|
|
84
|
-
<link rel="stylesheet" href="dist/vanduo.min.css">
|
|
85
|
-
<script src="dist/vanduo.min.js"></script>
|
|
86
|
-
<script>
|
|
87
|
-
Vanduo.init();
|
|
88
|
-
</script>
|
|
89
|
-
```
|
|
13
|
+
Drop-in HTML/CSS/JS — 48+ components driven by `.vd-*` classes and `data-vd-*` attributes, an imperative `window.Vanduo` runtime, and a strict `--vd-*` token API. Zero runtime dependencies; consumes design tokens from [`@vanduo-oss/core`](https://www.npmjs.com/package/@vanduo-oss/core). Need Vue 3 instead? See [`@vanduo-oss/vue`](https://www.npmjs.com/package/@vanduo-oss/vue).
|
|
90
14
|
|
|
91
|
-
|
|
15
|
+
## Install
|
|
92
16
|
|
|
93
|
-
```
|
|
17
|
+
```sh
|
|
94
18
|
pnpm add @vanduo-oss/framework
|
|
95
19
|
```
|
|
96
20
|
|
|
97
21
|
```js
|
|
98
|
-
import
|
|
99
|
-
import { Vanduo } from
|
|
22
|
+
import "@vanduo-oss/framework/css";
|
|
23
|
+
import { Vanduo } from "@vanduo-oss/framework";
|
|
100
24
|
|
|
101
25
|
Vanduo.init();
|
|
102
26
|
```
|
|
103
27
|
|
|
104
|
-
##
|
|
105
|
-
|
|
106
|
-
```js
|
|
107
|
-
Vanduo.init(root);
|
|
108
|
-
Vanduo.initComponents(root);
|
|
109
|
-
Vanduo.reinit('lazyLoad', root);
|
|
110
|
-
Vanduo.destroy(root);
|
|
111
|
-
Vanduo.destroyAll();
|
|
112
|
-
Vanduo.getComponent('docSearch');
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
- Omit `root` to target the full document.
|
|
116
|
-
- Pass an `Element` to initialize or destroy only a subtree.
|
|
117
|
-
- Canonical component registry names use `lowerCamelCase`.
|
|
118
|
-
- `LazyLoad` remains available as a compatibility alias for `lazyLoad` in `1.4.x`.
|
|
119
|
-
|
|
120
|
-
## Token API
|
|
121
|
-
|
|
122
|
-
Vanduo `1.4.1` treats `--vd-*` as the only shipped custom-property namespace:
|
|
123
|
-
|
|
124
|
-
- Palette: `--vd-red-*`, `--vd-primary-*`, `--vd-gray-*`, and related scales. The
|
|
125
|
-
default palette is **Open Color** (`--vd-oc-*`); **Fibonacci** (golden-angle
|
|
126
|
-
generated, `--vd-fib-*`, with a `--vd-golden-1..8` accent track) is opt-in via
|
|
127
|
-
`data-palette="fibonacci"`. See [TOKENS.md](TOKENS.md#palette-system-open-color-default--fibonacci-optional).
|
|
128
|
-
- Colors: `--vd-color-*`
|
|
129
|
-
- Backgrounds: `--vd-bg-*`
|
|
130
|
-
- Text: `--vd-text-*`
|
|
131
|
-
- Borders: `--vd-border-*`
|
|
132
|
-
- Shadows: `--vd-shadow-*`
|
|
133
|
-
- Components/effects: `--vd-btn-*`, `--vd-card-*`, `--vd-morph-*`, and related internals
|
|
134
|
-
|
|
135
|
-
Legacy unprefixed token aliases were removed in `1.4.1`; update custom themes and overrides to use the `--vd-*` equivalents.
|
|
136
|
-
|
|
137
|
-
```css
|
|
138
|
-
.cta {
|
|
139
|
-
color: var(--vd-text-inverse);
|
|
140
|
-
background: var(--vd-color-primary);
|
|
141
|
-
border-color: var(--vd-border-color);
|
|
142
|
-
}
|
|
143
|
-
```
|
|
28
|
+
## Quick start (no build)
|
|
144
29
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
- New component styling should prefer `.vd-*` hooks over new raw element selectors.
|
|
152
|
-
|
|
153
|
-
## Project Structure
|
|
154
|
-
|
|
155
|
-
```text
|
|
156
|
-
framework/
|
|
157
|
-
├── css/ # Foundation, utilities, effects, components
|
|
158
|
-
├── js/ # Runtime, lifecycle, components
|
|
159
|
-
├── dist/ # Built artifacts
|
|
160
|
-
├── tests/ # Playwright fixtures and specs
|
|
161
|
-
├── scripts/ # Build, verification, and inventory scripts
|
|
162
|
-
├── openspec/ # Spec-driven change proposals and component specs
|
|
163
|
-
└── docs/*.md # Release and architecture notes
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
## Development
|
|
167
|
-
|
|
168
|
-
```bash
|
|
169
|
-
corepack enable
|
|
170
|
-
pnpm install
|
|
171
|
-
pnpm run lint
|
|
172
|
-
pnpm run build
|
|
173
|
-
pnpm run check:versions
|
|
174
|
-
pnpm test
|
|
175
|
-
pnpm run stats:css
|
|
30
|
+
```html
|
|
31
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.7.0/dist/vanduo.min.css">
|
|
32
|
+
<script src="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.7.0/dist/vanduo.min.js"></script>
|
|
33
|
+
<script>
|
|
34
|
+
Vanduo.init();
|
|
35
|
+
</script>
|
|
176
36
|
```
|
|
177
37
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
## Release Notes
|
|
181
|
-
|
|
182
|
-
- Changelog: [CHANGELOG.md](CHANGELOG.md)
|
|
183
|
-
- Architecture notes: [ARCHITECTURE.md](ARCHITECTURE.md)
|
|
184
|
-
- Token model: [TOKENS.md](TOKENS.md)
|
|
185
|
-
- Theme Switcher spec: [openspec/specs/theme-switcher/spec.md](openspec/specs/theme-switcher/spec.md)
|
|
186
|
-
- Draggable spec: [openspec/specs/draggable/spec.md](openspec/specs/draggable/spec.md)
|
|
187
|
-
- Changelog policy: [openspec/specs/changelog/spec.md](openspec/specs/changelog/spec.md)
|
|
188
|
-
- QA strategy: [QA-Automation-Strategy.md](QA-Automation-Strategy.md)
|
|
189
|
-
- Contributor workflow: [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
38
|
+
> **Production tip:** pin the version and add Subresource Integrity (`integrity="sha384-…" crossorigin="anonymous"`) to CDN tags. Get the hash from the per-file "SRI" button on [jsdelivr.com](https://www.jsdelivr.com/).
|
|
190
39
|
|
|
191
|
-
##
|
|
40
|
+
## Documentation
|
|
192
41
|
|
|
193
|
-
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
42
|
+
- Docs & live demos — https://vanduo.dev
|
|
43
|
+
- Agent / LLM reference — [SKILL.md](./SKILL.md)
|
|
44
|
+
- Token model — [TOKENS.md](./TOKENS.md) · Architecture — [ARCHITECTURE.md](./ARCHITECTURE.md)
|
|
45
|
+
- Changelog — [CHANGELOG.md](./CHANGELOG.md) · Security — [SECURITY.md](./SECURITY.md)
|
|
197
46
|
|
|
198
47
|
## License
|
|
199
48
|
|
|
200
|
-
MIT -
|
|
201
|
-
Third-party notices are listed in [THIRD-PARTY-LICENSES](THIRD-PARTY-LICENSES).
|
|
49
|
+
[MIT](./LICENSE) © Vanduo — third-party notices in [THIRD-PARTY-LICENSES](./THIRD-PARTY-LICENSES).
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vanduo-framework
|
|
3
|
+
description: Use when building UIs with @vanduo-oss/framework — the zero-build "Vanilla" HTML/CSS/JS engine of the Vanduo design system (data-attribute components + an imperative window.Vanduo runtime). Covers install (CDN/ESM/IIFE), the runtime API, the --vd-* token model, security, and caveats.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @vanduo-oss/framework
|
|
7
|
+
|
|
8
|
+
The **Vanilla (zero-build) engine** of the Vanduo design system: drop-in HTML/CSS/JS — 48+ components driven by `.vd-*` classes + `data-vd-*` attributes, an imperative `window.Vanduo` runtime, and a strict `--vd-*` token API. Consumes the values from `@vanduo-oss/core`. No build step required.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
pnpm add @vanduo-oss/framework # Node >=18
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<!-- or CDN (pin a version; add SRI in production) -->
|
|
18
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.7.0/dist/vanduo.min.css">
|
|
19
|
+
<script src="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.7.0/dist/vanduo.min.js"></script>
|
|
20
|
+
<script>Vanduo.init()</script>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Build variants in `dist/`: `vanduo.min.css` (or `vanduo-core.min.css`, no bundled icons), `vanduo.esm.js` (bundler), `vanduo.cjs.js` (CJS), `vanduo.min.js` (IIFE → global `window.Vanduo`). Subpaths: `@vanduo-oss/framework/css`, `/css/core`, `/iife`.
|
|
24
|
+
|
|
25
|
+
## Architecture
|
|
26
|
+
|
|
27
|
+
- **Component model** — `.vd-*` classes for styling + `data-vd-*` attributes that the runtime wires up (modal, flow, bubble, stepper, etc.).
|
|
28
|
+
- **Runtime** — `Vanduo.init()` once on load auto-initializes components; `reinit`/`destroy` handle dynamic DOM.
|
|
29
|
+
- **Tokens** — everything themable via `--vd-*` CSS custom properties (Open Color default; opt-in Fibonacci palette via `data-palette="fibonacci"` on `<html>`).
|
|
30
|
+
- **ESM vs IIFE** — ESM bundles into an app; IIFE runs standalone and populates `window.Vanduo`.
|
|
31
|
+
|
|
32
|
+
## API
|
|
33
|
+
|
|
34
|
+
Runtime (`window.Vanduo`): `init(root?)`, `initComponents(root?)`, `reinit(name, root?)`, `destroy(root?)`, `destroyAll()`, `getComponent(name)`, `register(name, comp, opts?)`. Registry names are `lowerCamelCase`.
|
|
35
|
+
|
|
36
|
+
Component methods via `Vanduo.components.*` — e.g. `toast.show({title,message,type,duration})`, `flow.next/prev/goTo`, `bubble.show/hide`, `stepper.setStep/next/prev`, `rating.get/setValue`, `transfer.getSelected`, `tree.getChecked`, `spotlight.start/next/prev/stop`, `validate.validateForm/addRule`, `waypoint.refresh`.
|
|
37
|
+
|
|
38
|
+
Helpers (global): `sanitizeHtml(html, {allowStyle?, allowSvg?})`, `escapeHtml(str)`, `ready(cb)`, `safeStorageGet/Set`, `debounce`, `throttle`.
|
|
39
|
+
|
|
40
|
+
CSS entrypoints: `/css` (full), `/css/core` (tokens + components, no icons). Token namespaces: `--vd-color/bg/text/border/shadow-*`, `--vd-btn/card/morph-*`, palette scales `--vd-oc-*` / `--vd-fib-*`.
|
|
41
|
+
|
|
42
|
+
## Security
|
|
43
|
+
|
|
44
|
+
- `sanitizeHtml()` — whitelist-based; **denies inline `style` by default** (attribute-injection vector), opt back in only for trusted source. Bubble/Popover restrict links to `http/https/mailto`.
|
|
45
|
+
- `escapeHtml()` is quote-safe for attribute contexts.
|
|
46
|
+
- ESLint flags raw `innerHTML` assignment outside the sanitize helpers (`no-restricted-syntax`).
|
|
47
|
+
- No bundled-style nonce injection — apply your own CSP; harden CDN tags with Subresource Integrity.
|
|
48
|
+
|
|
49
|
+
## Caveats
|
|
50
|
+
|
|
51
|
+
- No-build consumers use CDN or local `/dist`; bare ESM specifiers need a bundler/import map.
|
|
52
|
+
- ES2022, modern browsers (no IE11 shims).
|
|
53
|
+
- Theming persists to `localStorage` (`vanduo-theme-preference`); `data-palette="fibonacci"` is runtime opt-in (Open Color is default).
|
|
54
|
+
- Hex grid and music player are **separate packages** (`@vanduo-oss/hex-grid`, `@vanduo-oss/music-player`).
|
|
55
|
+
|
|
56
|
+
## Docs
|
|
57
|
+
|
|
58
|
+
Full documentation and live demos: https://vanduo.dev
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vanduo Framework - Accordion
|
|
3
|
+
* Added in 1.6.1 to back @vanduo-oss/vue's VdAccordion.
|
|
4
|
+
*
|
|
5
|
+
* VdAccordion renders:
|
|
6
|
+
* ul.vd-accordion
|
|
7
|
+
* li.vd-accordion-item(.is-open)
|
|
8
|
+
* button.vd-accordion-header > span + span.vd-accordion-icon
|
|
9
|
+
* div.vd-accordion-panel (toggled via v-show)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
:root {
|
|
13
|
+
--vd-accordion-border-color: var(--vd-border-color);
|
|
14
|
+
--vd-accordion-header-bg: transparent;
|
|
15
|
+
--vd-accordion-header-bg-hover: var(--vd-bg-secondary);
|
|
16
|
+
--vd-accordion-padding-x: 1.3125rem; /* 21px - fib */
|
|
17
|
+
--vd-accordion-padding-y: 0.8125rem; /* 13px - fib */
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.vd-accordion {
|
|
21
|
+
margin: 0;
|
|
22
|
+
padding: 0;
|
|
23
|
+
list-style: none;
|
|
24
|
+
border: 1px solid var(--vd-accordion-border-color);
|
|
25
|
+
border-radius: var(--vd-btn-border-radius);
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.vd-accordion-item {
|
|
30
|
+
border-top: 1px solid var(--vd-accordion-border-color);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.vd-accordion-item:first-child {
|
|
34
|
+
border-top: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.vd-accordion-header {
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: space-between;
|
|
41
|
+
gap: 0.75rem;
|
|
42
|
+
width: 100%;
|
|
43
|
+
padding: var(--vd-accordion-padding-y) var(--vd-accordion-padding-x);
|
|
44
|
+
background: var(--vd-accordion-header-bg);
|
|
45
|
+
border: none;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
font-size: var(--vd-font-size-base);
|
|
48
|
+
font-weight: var(--vd-font-weight-medium);
|
|
49
|
+
color: var(--vd-text-primary);
|
|
50
|
+
text-align: left;
|
|
51
|
+
transition: background-color 0.15s ease;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.vd-accordion-header:hover {
|
|
55
|
+
background: var(--vd-accordion-header-bg-hover);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.vd-accordion-header:focus-visible {
|
|
59
|
+
outline: 2px solid var(--vd-color-primary);
|
|
60
|
+
outline-offset: -2px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.vd-accordion-icon {
|
|
64
|
+
flex-shrink: 0;
|
|
65
|
+
font-size: 1.25rem;
|
|
66
|
+
line-height: 1;
|
|
67
|
+
color: var(--vd-text-secondary);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.vd-accordion-panel {
|
|
71
|
+
padding: var(--vd-accordion-padding-y) var(--vd-accordion-padding-x);
|
|
72
|
+
color: var(--vd-text-primary);
|
|
73
|
+
border-top: 1px solid var(--vd-accordion-border-color);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@media (prefers-reduced-motion: reduce) {
|
|
77
|
+
.vd-accordion-header {
|
|
78
|
+
transition: none;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -94,6 +94,23 @@
|
|
|
94
94
|
color: var(--vd-alert-info-text);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/* Secondary variant (added 1.7.0 for the unified status palette) */
|
|
98
|
+
.vd-alert-secondary {
|
|
99
|
+
background-color: var(--vd-color-secondary-alpha-10);
|
|
100
|
+
border-color: var(--vd-color-secondary);
|
|
101
|
+
color: var(--vd-color-secondary-dark);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
[data-theme="dark"] .vd-alert-secondary {
|
|
105
|
+
color: var(--vd-color-secondary-light);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@media (prefers-color-scheme: dark) {
|
|
109
|
+
:root:not([data-theme]) .vd-alert-secondary {
|
|
110
|
+
color: var(--vd-color-secondary-light);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
97
114
|
/* Alert with Icon */
|
|
98
115
|
.vd-alert-icon {
|
|
99
116
|
display: flex;
|
|
@@ -222,3 +239,51 @@
|
|
|
222
239
|
transition: none;
|
|
223
240
|
}
|
|
224
241
|
}
|
|
242
|
+
|
|
243
|
+
/* ==========================================================================
|
|
244
|
+
@vanduo-oss/vue VdAlert markup (additive; added in 1.6.1)
|
|
245
|
+
VdAlert renders `.vd-alert > .vd-alert-icon + .vd-alert-body + .vd-alert-dismiss`.
|
|
246
|
+
.vd-alert-body wraps the title + content; .vd-alert-dismiss replaces the legacy
|
|
247
|
+
.vd-alert-close. Scoped with :has() so legacy alert markup is untouched.
|
|
248
|
+
========================================================================== */
|
|
249
|
+
.vd-alert:has(.vd-alert-body) {
|
|
250
|
+
display: flex;
|
|
251
|
+
align-items: flex-start;
|
|
252
|
+
gap: 0.75rem;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.vd-alert:has(.vd-alert-body) > .vd-alert-icon {
|
|
256
|
+
flex-shrink: 0;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.vd-alert-body {
|
|
260
|
+
flex: 1 1 auto;
|
|
261
|
+
min-width: 0;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.vd-alert-dismiss {
|
|
265
|
+
flex-shrink: 0;
|
|
266
|
+
padding: 0;
|
|
267
|
+
background: transparent;
|
|
268
|
+
border: none;
|
|
269
|
+
cursor: pointer;
|
|
270
|
+
opacity: 0.5;
|
|
271
|
+
color: inherit;
|
|
272
|
+
line-height: 1;
|
|
273
|
+
transition: opacity 0.15s ease;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.vd-alert-dismiss:hover {
|
|
277
|
+
opacity: 1;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.vd-alert-dismiss:focus-visible {
|
|
281
|
+
outline: 2px solid currentColor;
|
|
282
|
+
outline-offset: 2px;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@media (prefers-reduced-motion: reduce) {
|
|
286
|
+
.vd-alert-dismiss {
|
|
287
|
+
transition: none;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
@@ -527,4 +527,48 @@ a.vd-btn:hover {
|
|
|
527
527
|
to {
|
|
528
528
|
transform: rotate(360deg);
|
|
529
529
|
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/* ==========================================================================
|
|
533
|
+
@vanduo-oss/vue VdButton spinner (additive; added in 1.6.1)
|
|
534
|
+
VdButton renders a real `<span class="vd-btn-spinner">` while loading (the
|
|
535
|
+
button also gets .is-loading). Style the real element and suppress the legacy
|
|
536
|
+
::after so only one spinner is shown.
|
|
537
|
+
========================================================================== */
|
|
538
|
+
.vd-btn.is-loading:has(.vd-btn-spinner)::after {
|
|
539
|
+
content: none;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
.vd-btn-spinner {
|
|
543
|
+
position: absolute;
|
|
544
|
+
top: 50%;
|
|
545
|
+
left: 50%;
|
|
546
|
+
width: 1em;
|
|
547
|
+
height: 1em;
|
|
548
|
+
margin: -0.5em 0 0 -0.5em;
|
|
549
|
+
border: 2px solid var(--vd-color-primary);
|
|
550
|
+
border-right-color: transparent;
|
|
551
|
+
border-radius: 50%;
|
|
552
|
+
animation: btn-spinner 0.6s linear infinite;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
.vd-btn-primary .vd-btn-spinner,
|
|
556
|
+
.vd-btn-secondary .vd-btn-spinner,
|
|
557
|
+
.vd-btn-success .vd-btn-spinner,
|
|
558
|
+
.vd-btn-danger .vd-btn-spinner,
|
|
559
|
+
.vd-btn-error .vd-btn-spinner,
|
|
560
|
+
.vd-btn-info .vd-btn-spinner {
|
|
561
|
+
border-color: var(--vd-color-white);
|
|
562
|
+
border-right-color: transparent;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
.vd-btn-warning .vd-btn-spinner {
|
|
566
|
+
border-color: var(--vd-color-black);
|
|
567
|
+
border-right-color: transparent;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
@media (prefers-reduced-motion: reduce) {
|
|
571
|
+
.vd-btn-spinner {
|
|
572
|
+
animation-duration: 1.2s;
|
|
573
|
+
}
|
|
530
574
|
}
|
package/css/components/cards.css
CHANGED
|
@@ -323,3 +323,29 @@ a.vd-card:active {
|
|
|
323
323
|
flex: 1 1 0%;
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
|
+
|
|
327
|
+
/* @vanduo-oss/vue VdCard :interactive (additive; added in 1.6.1) */
|
|
328
|
+
.vd-card-interactive {
|
|
329
|
+
cursor: pointer;
|
|
330
|
+
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.vd-card-interactive:hover {
|
|
334
|
+
transform: translateY(-2px) translateZ(0);
|
|
335
|
+
box-shadow: var(--vd-shadow-lg);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.vd-card-interactive:focus-visible {
|
|
339
|
+
outline: 2px solid var(--vd-color-primary);
|
|
340
|
+
outline-offset: 2px;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
@media (prefers-reduced-motion: reduce) {
|
|
344
|
+
.vd-card-interactive {
|
|
345
|
+
transition: none;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.vd-card-interactive:hover {
|
|
349
|
+
transform: none;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
@@ -553,3 +553,26 @@
|
|
|
553
553
|
transition: none;
|
|
554
554
|
}
|
|
555
555
|
}
|
|
556
|
+
|
|
557
|
+
/* ==========================================================================
|
|
558
|
+
@vanduo-oss/vue VdCodeSnippet <pre> (additive; added in 1.6.1)
|
|
559
|
+
VdCodeSnippet renders `figure.vd-code-snippet > pre.vd-code-snippet-pre > code`.
|
|
560
|
+
========================================================================== */
|
|
561
|
+
.vd-code-snippet-pre {
|
|
562
|
+
margin: 0;
|
|
563
|
+
padding: var(--vd-code-padding-y) var(--vd-code-padding-x);
|
|
564
|
+
overflow-x: auto;
|
|
565
|
+
-webkit-overflow-scrolling: touch;
|
|
566
|
+
background-color: var(--vd-code-bg);
|
|
567
|
+
font-family: var(--vd-font-family-mono, 'JetBrains Mono', 'Fira Code', 'Consolas', monospace);
|
|
568
|
+
font-size: var(--vd-code-font-size);
|
|
569
|
+
line-height: var(--vd-code-line-height);
|
|
570
|
+
color: var(--vd-code-text);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
.vd-code-snippet-pre code {
|
|
574
|
+
font: inherit;
|
|
575
|
+
color: inherit;
|
|
576
|
+
white-space: pre;
|
|
577
|
+
tab-size: 2;
|
|
578
|
+
}
|
|
@@ -242,7 +242,7 @@
|
|
|
242
242
|
.vd-collection-item {
|
|
243
243
|
flex-wrap: wrap;
|
|
244
244
|
}
|
|
245
|
-
|
|
245
|
+
|
|
246
246
|
.vd-collection-action {
|
|
247
247
|
width: 100%;
|
|
248
248
|
margin-left: 0;
|
|
@@ -251,3 +251,23 @@
|
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
/* ==========================================================================
|
|
255
|
+
@vanduo-oss/vue VdCollection additions (additive; added in 1.6.1)
|
|
256
|
+
VdCollection wraps items in `ul.vd-collection-list` and renders a
|
|
257
|
+
`.vd-collection-text-secondary` subtitle.
|
|
258
|
+
========================================================================== */
|
|
259
|
+
.vd-collection-list {
|
|
260
|
+
display: flex;
|
|
261
|
+
flex-direction: column;
|
|
262
|
+
margin: 0;
|
|
263
|
+
padding: 0;
|
|
264
|
+
list-style: none;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.vd-collection-text-secondary {
|
|
268
|
+
display: block;
|
|
269
|
+
margin-top: 0.125rem;
|
|
270
|
+
font-size: var(--vd-font-size-sm);
|
|
271
|
+
color: var(--vd-text-secondary);
|
|
272
|
+
}
|
|
273
|
+
|
package/css/components/flow.css
CHANGED
|
@@ -263,3 +263,23 @@
|
|
|
263
263
|
padding: 0.8125rem 0.8125rem 2rem;
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
|
+
|
|
267
|
+
/* ==========================================================================
|
|
268
|
+
@vanduo-oss/vue VdFlow inline controls (additive; added in 1.6.1)
|
|
269
|
+
VdFlow renders a `.vd-flow-controls` bar with prev/next buttons and a
|
|
270
|
+
`.vd-flow-position` "n / total" label below the track.
|
|
271
|
+
========================================================================== */
|
|
272
|
+
.vd-flow-controls {
|
|
273
|
+
display: flex;
|
|
274
|
+
align-items: center;
|
|
275
|
+
justify-content: center;
|
|
276
|
+
gap: 0.75rem;
|
|
277
|
+
margin-top: 0.8125rem;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.vd-flow-position {
|
|
281
|
+
min-width: 4ch;
|
|
282
|
+
font-size: var(--vd-font-size-sm);
|
|
283
|
+
color: var(--vd-text-secondary);
|
|
284
|
+
text-align: center;
|
|
285
|
+
}
|