@vanduo-oss/framework 1.5.1 → 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 +34 -2
- package/README.md +25 -154
- 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/navbar.css +11 -0
- package/css/components/popover.css +97 -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/components/theme-customizer.css +53 -0
- package/css/core/colors-fib-base.css +524 -0
- package/css/core/colors-palette.css +786 -0
- package/css/core/colors.css +54 -46
- package/css/core/helpers.css +17 -0
- package/css/core/tokens.css +19 -19
- package/css/utilities/table.css +9 -0
- package/css/vanduo.css +11 -1
- package/dist/build-info.json +3 -3
- package/dist/vanduo-core.css +2147 -93
- 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 +387 -6
- package/dist/vanduo.cjs.js.map +3 -3
- package/dist/vanduo.cjs.min.js +16 -10
- package/dist/vanduo.cjs.min.js.map +4 -4
- package/dist/vanduo.css +2147 -93
- package/dist/vanduo.css.map +1 -1
- package/dist/vanduo.esm.js +387 -6
- package/dist/vanduo.esm.js.map +3 -3
- package/dist/vanduo.esm.min.js +16 -10
- package/dist/vanduo.esm.min.js.map +4 -4
- package/dist/vanduo.js +387 -6
- package/dist/vanduo.js.map +3 -3
- package/dist/vanduo.min.css +2 -2
- package/dist/vanduo.min.css.map +1 -1
- package/dist/vanduo.min.js +16 -10
- package/dist/vanduo.min.js.map +4 -4
- package/js/components/doc-search.js +9 -4
- package/js/components/popover.js +295 -0
- package/js/components/search.js +108 -0
- package/js/components/theme-customizer.js +54 -1
- package/js/index.js +2 -0
- package/js/utils/helpers.js +12 -4
- package/package.json +8 -4
package/CHANGELOG.md
CHANGED
|
@@ -8,16 +8,48 @@ 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.
|
|
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
|
+
|
|
27
|
+
## [1.6.0] - 2026-06-27
|
|
28
|
+
|
|
29
|
+
Additive release. Adds the Popover and Search primitives and an optional
|
|
30
|
+
Fibonacci palette; **Open Color remains the default look.** One HTML-sanitization
|
|
31
|
+
behavior change to note (see Security).
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **Popover component** (`window.VanduoPopover`) — a general popover primitive separate from `.vd-bubble`: click / hover / focus triggers (combinable via `data-vd-popover-trigger`), external-panel composition through `data-vd-popover-target`, `.vd-popover-sm` / `.vd-popover-lg` size variants, and auto-placement flip on viewport overflow (`data-vd-popover-flip`). New `css/components/popover.css` + `js/components/popover.js`, wired into `css/vanduo.css` and `js/index.js`. Playwright spec at `tests/components/popover.spec.ts`.
|
|
35
|
+
- **Search helper** (`window.VanduoSearch`) — a registry so consumers can register their own data sources: `register(source)` / `unregister(name)` / `list()` / `query(text, options?)`. Sources return `Promise<Result[]>`; results merge across sources with an optional per-source limit. New `js/components/search.js`; spec at `tests/components/search.spec.ts`.
|
|
36
|
+
- **Optional Fibonacci palette** — a golden-angle generated palette (`--vd-fib-*` + `--vd-golden-1..8` accent track), opt in at runtime via `data-palette="fibonacci"` on `<html>`. Open Color (`--vd-oc-*`) is the default and `data-primary` / `data-neutral` remaps work under either palette.
|
|
12
37
|
|
|
13
38
|
### Changed
|
|
14
|
-
-
|
|
39
|
+
- Dependencies updated to latest; pnpm config migrated to `pnpm-workspace.yaml`.
|
|
40
|
+
|
|
41
|
+
### Security
|
|
42
|
+
- **Behavior change — `sanitizeHtml` denies inline `style` by default.** Rich HTML passed to Bubble / Popover now has `style` attributes stripped unless explicitly allowed, closing an attribute-injection vector. Move inline styles to classes.
|
|
43
|
+
- `escapeHtml` is now quote-safe for attribute contexts.
|
|
44
|
+
|
|
45
|
+
## [1.5.1] - 2026-06-20
|
|
15
46
|
|
|
16
47
|
### Enhanced
|
|
17
48
|
- **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.
|
|
18
49
|
|
|
19
50
|
### Fixed
|
|
20
51
|
- **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.
|
|
52
|
+
- **Expanding Cards — mobile polish** — Resolved mobile layout overflow clipping and keyboard focus edge cases.
|
|
21
53
|
|
|
22
54
|
## [1.5.0] - 2026-06-18
|
|
23
55
|
|
package/README.md
CHANGED
|
@@ -1,178 +1,49 @@
|
|
|
1
|
-
# Vanduo Framework v1.5.1
|
|
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
|
-
- 47+ 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.5.1
|
|
29
|
-
|
|
30
|
-
- Development branch opened for the v1.5.1 patch cycle (`dev-v151`).
|
|
31
|
-
|
|
32
|
-
## Previous: 1.5.0
|
|
33
|
-
|
|
34
|
-
- **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.
|
|
35
|
-
- **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.
|
|
36
|
-
|
|
37
|
-
## Previous: 1.4.6
|
|
38
|
-
|
|
39
|
-
- **Leaner default CSS** — `css/vanduo.css` now bundles the `regular` + `fill` icon weights only (~45% smaller minified CSS). Need all six weights? Import `css/icons/icons-all.css`.
|
|
40
|
-
- **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.
|
|
41
|
-
- **Smaller package** — the build ships only the icon weights the bundle actually uses into `dist/icons/`, instead of all six.
|
|
42
|
-
- **TypeScript types** — a hand-written `dist/vanduo.d.ts` for the `Vanduo` runtime, exposed via the `types` field.
|
|
43
|
-
- **In-repo changelog** — a new [CHANGELOG.md](CHANGELOG.md) (Keep a Changelog), now validated by `check:versions`.
|
|
44
|
-
- **Version-consistency now covers prose** — `pnpm check:versions` validates README, `SECURITY.md`, `llms.txt`, and `CHANGELOG.md`, not just the dist banners.
|
|
45
|
-
- **Lint guard** — raw `innerHTML` assignment is now flagged by ESLint outside the sanitization helpers.
|
|
46
|
-
- **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.
|
|
5
|
+
# @vanduo-oss/framework
|
|
47
6
|
|
|
48
|
-
|
|
7
|
+
[](https://www.npmjs.com/package/@vanduo-oss/framework)
|
|
8
|
+
[](https://github.com/vanduo-oss/framework/actions/workflows/ci.yml)
|
|
9
|
+
[](./LICENSE)
|
|
49
10
|
|
|
50
|
-
|
|
51
|
-
- **Background-clip audit** — Playwright `@audit` harness at `tests/audit/background-clip-audit.spec.ts` for regression checks.
|
|
52
|
-
- Normative API: [openspec/specs/draggable/spec.md](openspec/specs/draggable/spec.md).
|
|
11
|
+
> The zero-build **Vanilla** engine of the Vanduo design system.
|
|
53
12
|
|
|
54
|
-
|
|
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).
|
|
55
14
|
|
|
56
|
-
|
|
15
|
+
## Install
|
|
57
16
|
|
|
58
|
-
```
|
|
59
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.5.1/dist/vanduo.min.css">
|
|
60
|
-
<script src="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.5.1/dist/vanduo.min.js"></script>
|
|
61
|
-
<script>
|
|
62
|
-
Vanduo.init();
|
|
63
|
-
</script>
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
> **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`.
|
|
67
|
-
|
|
68
|
-
### Local Dist Files
|
|
69
|
-
|
|
70
|
-
```html
|
|
71
|
-
<link rel="stylesheet" href="dist/vanduo.min.css">
|
|
72
|
-
<script src="dist/vanduo.min.js"></script>
|
|
73
|
-
<script>
|
|
74
|
-
Vanduo.init();
|
|
75
|
-
</script>
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Package Install
|
|
79
|
-
|
|
80
|
-
```bash
|
|
17
|
+
```sh
|
|
81
18
|
pnpm add @vanduo-oss/framework
|
|
82
19
|
```
|
|
83
20
|
|
|
84
21
|
```js
|
|
85
|
-
import
|
|
86
|
-
import { Vanduo } from
|
|
22
|
+
import "@vanduo-oss/framework/css";
|
|
23
|
+
import { Vanduo } from "@vanduo-oss/framework";
|
|
87
24
|
|
|
88
25
|
Vanduo.init();
|
|
89
26
|
```
|
|
90
27
|
|
|
91
|
-
##
|
|
92
|
-
|
|
93
|
-
```js
|
|
94
|
-
Vanduo.init(root);
|
|
95
|
-
Vanduo.initComponents(root);
|
|
96
|
-
Vanduo.reinit('lazyLoad', root);
|
|
97
|
-
Vanduo.destroy(root);
|
|
98
|
-
Vanduo.destroyAll();
|
|
99
|
-
Vanduo.getComponent('docSearch');
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
- Omit `root` to target the full document.
|
|
103
|
-
- Pass an `Element` to initialize or destroy only a subtree.
|
|
104
|
-
- Canonical component registry names use `lowerCamelCase`.
|
|
105
|
-
- `LazyLoad` remains available as a compatibility alias for `lazyLoad` in `1.4.x`.
|
|
106
|
-
|
|
107
|
-
## Token API
|
|
108
|
-
|
|
109
|
-
Vanduo `1.4.1` treats `--vd-*` as the only shipped custom-property namespace:
|
|
110
|
-
|
|
111
|
-
- Palette: `--vd-red-*`, `--vd-primary-*`, `--vd-gray-*`, and related scales
|
|
112
|
-
- Colors: `--vd-color-*`
|
|
113
|
-
- Backgrounds: `--vd-bg-*`
|
|
114
|
-
- Text: `--vd-text-*`
|
|
115
|
-
- Borders: `--vd-border-*`
|
|
116
|
-
- Shadows: `--vd-shadow-*`
|
|
117
|
-
- Components/effects: `--vd-btn-*`, `--vd-card-*`, `--vd-morph-*`, and related internals
|
|
118
|
-
|
|
119
|
-
Legacy unprefixed token aliases were removed in `1.4.1`; update custom themes and overrides to use the `--vd-*` equivalents.
|
|
120
|
-
|
|
121
|
-
```css
|
|
122
|
-
.cta {
|
|
123
|
-
color: var(--vd-text-inverse);
|
|
124
|
-
background: var(--vd-color-primary);
|
|
125
|
-
border-color: var(--vd-border-color);
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
More detail lives in [TOKENS.md](TOKENS.md).
|
|
130
|
-
|
|
131
|
-
## CSS Bundle Notes
|
|
132
|
-
|
|
133
|
-
- `css/vanduo.css` remains the main framework entrypoint in `1.4.1`.
|
|
134
|
-
- The main bundle still includes framework-wide form defaults for native inputs and textareas.
|
|
135
|
-
- New component styling should prefer `.vd-*` hooks over new raw element selectors.
|
|
136
|
-
|
|
137
|
-
## Project Structure
|
|
138
|
-
|
|
139
|
-
```text
|
|
140
|
-
framework/
|
|
141
|
-
├── css/ # Foundation, utilities, effects, components
|
|
142
|
-
├── js/ # Runtime, lifecycle, components
|
|
143
|
-
├── dist/ # Built artifacts
|
|
144
|
-
├── tests/ # Playwright fixtures and specs
|
|
145
|
-
├── scripts/ # Build, verification, and inventory scripts
|
|
146
|
-
├── openspec/ # Spec-driven change proposals and component specs
|
|
147
|
-
└── docs/*.md # Release and architecture notes
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
## Development
|
|
28
|
+
## Quick start (no build)
|
|
151
29
|
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
pnpm test
|
|
159
|
-
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>
|
|
160
36
|
```
|
|
161
37
|
|
|
162
|
-
|
|
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/).
|
|
163
39
|
|
|
164
|
-
##
|
|
40
|
+
## Documentation
|
|
165
41
|
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
- Token model
|
|
169
|
-
-
|
|
170
|
-
- Draggable spec: [openspec/specs/draggable/spec.md](openspec/specs/draggable/spec.md)
|
|
171
|
-
- Changelog policy: [openspec/specs/changelog/spec.md](openspec/specs/changelog/spec.md)
|
|
172
|
-
- QA strategy: [QA-Automation-Strategy.md](QA-Automation-Strategy.md)
|
|
173
|
-
- Contributor workflow: [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
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)
|
|
174
46
|
|
|
175
47
|
## License
|
|
176
48
|
|
|
177
|
-
MIT -
|
|
178
|
-
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
|
+
}
|