@vanduo-oss/framework 1.4.2 → 1.4.4

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 CHANGED
@@ -1,4 +1,4 @@
1
- # Vanduo Framework v1.4.2
1
+ # Vanduo Framework v1.4.4
2
2
 
3
3
  <p align="center">
4
4
  <img src="vanduo-banner.svg" alt="Vanduo Framework Banner" width="100%">
@@ -22,15 +22,23 @@ Vanduo is a zero-dependency UI framework built with HTML, CSS, and vanilla JavaS
22
22
  - Strict design token API under `--vd-*`
23
23
  - Built-in dark, light, and system theming
24
24
  - Theme customizer with color, font, and radius controls
25
+ - Theme Switcher menu variant for icon-only light/dark/system selection in navbars
25
26
  - Playwright-based browser coverage across Chromium, Firefox, and WebKit
26
27
 
28
+ ## What's New in 1.4.4
29
+
30
+ - **Theme Switcher menu variant** — `.vd-theme-switcher[data-theme-ui="menu"]` opens an icon-only picker; option click applies the theme without cycling on toggle. Cycle (`button[data-toggle="theme"]`) and select variants are unchanged.
31
+ - **New stylesheet** — `css/components/theme-switcher.css` for menu layout, active state, and navbar alignment.
32
+ - **Optional tooltips** — add `data-tooltip` on the toggle or menu options when the Tooltips component is loaded (opt-in).
33
+ - Normative API: [openspec/specs/theme-switcher/spec.md](openspec/specs/theme-switcher/spec.md).
34
+
27
35
  ## Quick Start
28
36
 
29
37
  ### CDN
30
38
 
31
39
  ```html
32
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.4.2/dist/vanduo.min.css">
33
- <script src="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.4.2/dist/vanduo.min.js"></script>
40
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.4.4/dist/vanduo.min.css">
41
+ <script src="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.4.4/dist/vanduo.min.js"></script>
34
42
  <script>
35
43
  Vanduo.init();
36
44
  </script>
@@ -114,6 +122,7 @@ framework/
114
122
  ├── dist/ # Built artifacts
115
123
  ├── tests/ # Playwright fixtures and specs
116
124
  ├── scripts/ # Build, verification, and inventory scripts
125
+ ├── openspec/ # Spec-driven change proposals and component specs
117
126
  └── docs/*.md # Release and architecture notes
118
127
  ```
119
128
 
@@ -129,11 +138,14 @@ pnpm test
129
138
  pnpm run stats:css
130
139
  ```
131
140
 
141
+ CI runs **Chromium Desktop smoke tests on pull requests** and the **full cross-browser Playwright matrix on push to `main`** (see [`.github/workflows/tests.yml`](.github/workflows/tests.yml) and [QA-Automation-Strategy.md](QA-Automation-Strategy.md)).
142
+
132
143
  ## Release Notes
133
144
 
134
145
  - Architecture notes: [ARCHITECTURE.md](ARCHITECTURE.md)
135
146
  - Token model: [TOKENS.md](TOKENS.md)
136
147
  - `1.4.1` token migration notes: [changes-v141.md](changes-v141.md)
148
+ - Theme Switcher spec: [openspec/specs/theme-switcher/spec.md](openspec/specs/theme-switcher/spec.md)
137
149
  - QA strategy: [QA-Automation-Strategy.md](QA-Automation-Strategy.md)
138
150
  - Contributor workflow: [CONTRIBUTING.md](CONTRIBUTING.md)
139
151
 
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Vanduo Framework - Theme Switcher
3
+ * Icon-only menu variant for explicit theme selection
4
+ */
5
+
6
+ :root {
7
+ --vd-theme-switcher-menu-bg: var(--vd-color-white);
8
+ --vd-theme-switcher-menu-border-color: var(--vd-border-color);
9
+ --vd-theme-switcher-option-hover-bg: var(--vd-bg-secondary);
10
+ --vd-theme-switcher-option-active-bg: var(--vd-color-primary-alpha-10);
11
+ --vd-theme-switcher-option-active-color: var(--vd-color-primary);
12
+ --vd-theme-switcher-z-index: 1000;
13
+ }
14
+
15
+ [data-theme="dark"] {
16
+ --vd-theme-switcher-menu-bg: var(--vd-bg-primary);
17
+ --vd-theme-switcher-option-hover-bg: var(--vd-bg-secondary);
18
+ }
19
+
20
+ @media (prefers-color-scheme: dark) {
21
+ :root:not([data-theme]) {
22
+ --vd-theme-switcher-menu-bg: var(--vd-bg-primary);
23
+ --vd-theme-switcher-option-hover-bg: var(--vd-bg-secondary);
24
+ }
25
+ }
26
+
27
+ .vd-theme-switcher {
28
+ position: relative;
29
+ display: inline-block;
30
+ }
31
+
32
+ .vd-theme-switcher-toggle {
33
+ display: inline-flex;
34
+ align-items: center;
35
+ justify-content: center;
36
+ width: 2.375rem;
37
+ height: 2.375rem;
38
+ padding: 0;
39
+ border: 1px solid var(--vd-border-color);
40
+ border-radius: var(--vd-btn-border-radius, var(--vd-card-border-radius));
41
+ background: transparent;
42
+ color: var(--vd-text-secondary);
43
+ cursor: pointer;
44
+ font-size: 1.15rem;
45
+ line-height: 1;
46
+ transition: color 0.2s, border-color 0.2s, background 0.2s;
47
+ }
48
+
49
+ .vd-theme-switcher-toggle:hover,
50
+ .vd-theme-switcher-toggle:focus-visible {
51
+ color: var(--vd-color-primary);
52
+ border-color: var(--vd-color-primary);
53
+ background: var(--vd-color-primary-alpha-10);
54
+ outline: none;
55
+ }
56
+
57
+ .vd-theme-switcher-menu {
58
+ position: absolute;
59
+ top: calc(100% + 0.375rem);
60
+ left: 0;
61
+ z-index: var(--vd-theme-switcher-z-index);
62
+ display: none;
63
+ flex-direction: column;
64
+ gap: 0.25rem;
65
+ min-width: auto;
66
+ padding: 0.375rem;
67
+ margin: 0;
68
+ background: var(--vd-theme-switcher-menu-bg, #ffffff);
69
+ border: 1px solid var(--vd-theme-switcher-menu-border-color);
70
+ border-radius: var(--vd-btn-border-radius, var(--vd-card-border-radius));
71
+ box-shadow: var(--vd-shadow-lg);
72
+ list-style: none;
73
+ isolation: isolate;
74
+ backdrop-filter: none;
75
+ -webkit-backdrop-filter: none;
76
+ visibility: hidden;
77
+ pointer-events: none;
78
+ transform: translateY(-6px);
79
+ transition: visibility var(--vd-transition-duration-base, 0.2s) var(--vd-transition-ease, ease),
80
+ transform var(--vd-transition-duration-base, 0.2s) var(--vd-transition-ease, ease);
81
+ }
82
+
83
+ .vd-theme-switcher-menu-end .vd-theme-switcher-menu,
84
+ .vd-theme-switcher.vd-theme-switcher-menu-end .vd-theme-switcher-menu {
85
+ right: 0;
86
+ left: auto;
87
+ }
88
+
89
+ .vd-theme-switcher.is-open .vd-theme-switcher-menu,
90
+ .vd-theme-switcher-menu.is-open {
91
+ display: flex;
92
+ visibility: visible;
93
+ pointer-events: auto;
94
+ transform: translateY(0);
95
+ }
96
+
97
+ .vd-theme-switcher-option,
98
+ .vd-theme-switcher-menu [data-theme-value] {
99
+ display: inline-flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ width: 2.375rem;
103
+ height: 2.375rem;
104
+ padding: 0;
105
+ border: 1px solid transparent;
106
+ border-radius: var(--vd-btn-border-radius-sm, var(--vd-radius-fib-3));
107
+ background: transparent;
108
+ color: var(--vd-text-secondary);
109
+ cursor: pointer;
110
+ font-size: 1.15rem;
111
+ line-height: 1;
112
+ transition: color 0.2s, background 0.2s, border-color 0.2s;
113
+ }
114
+
115
+ .vd-theme-switcher-option:hover,
116
+ .vd-theme-switcher-option:focus-visible,
117
+ .vd-theme-switcher-menu [data-theme-value]:hover,
118
+ .vd-theme-switcher-menu [data-theme-value]:focus-visible {
119
+ color: var(--vd-text-primary);
120
+ background: var(--vd-theme-switcher-option-hover-bg);
121
+ outline: none;
122
+ }
123
+
124
+ .vd-theme-switcher-option.is-active,
125
+ .vd-theme-switcher-menu [data-theme-value].is-active {
126
+ color: var(--vd-theme-switcher-option-active-color);
127
+ background: var(--vd-theme-switcher-option-active-bg);
128
+ border-color: var(--vd-color-primary-alpha-20, transparent);
129
+ }
package/css/vanduo.css CHANGED
@@ -53,6 +53,7 @@
53
53
  @import url('components/spinner.css');
54
54
  @import url('components/button-group.css');
55
55
  @import url('components/theme-customizer.css');
56
+ @import url('components/theme-switcher.css');
56
57
  @import url('components/image-box.css');
57
58
  @import url('components/doc-tabs.css');
58
59
  @import url('components/doc-search.css');
@@ -72,7 +73,6 @@
72
73
  @import url('components/transfer.css');
73
74
  @import url('components/tree.css');
74
75
  @import url('components/spotlight.css');
75
- @import url('components/music-player.css');
76
76
 
77
77
  /* Layer 5: Effects */
78
78
  @import url('effects/parallax.css');
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.4.2",
3
- "builtAt": "2026-05-23T19:59:36.731Z",
4
- "commit": "adbe750",
2
+ "version": "1.4.4",
3
+ "builtAt": "2026-06-07T19:14:20.877Z",
4
+ "commit": "781df0d",
5
5
  "mode": "development+production"
6
6
  }