@vobs/ui 0.3.0 → 1.1.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/LICENSE +1 -1
- package/README.md +60 -0
- package/package.json +52 -110
- package/src/activity-rail.ts +125 -0
- package/src/alert.ts +65 -0
- package/src/assets/icons/alert-circle.svg +1 -0
- package/src/assets/icons/alert-triangle.svg +1 -0
- package/src/assets/icons/alert.d27e24.svg +1 -0
- package/src/assets/icons/alert.svg +1 -0
- package/src/assets/icons/apple.svg +1 -0
- package/src/assets/icons/arrow-down.svg +1 -0
- package/src/assets/icons/arrow-expand.svg +1 -0
- package/src/assets/icons/arrow-left.svg +1 -0
- package/src/assets/icons/arrow-minimize.svg +1 -0
- package/src/assets/icons/arrow-right-to-line.svg +1 -0
- package/src/assets/icons/arrow-right.svg +1 -0
- package/src/assets/icons/arrow-up-right.svg +1 -0
- package/src/assets/icons/arrow-up.0c0c0d.svg +1 -0
- package/src/assets/icons/arrow-up.svg +1 -0
- package/src/assets/icons/at.svg +1 -0
- package/src/assets/icons/atom.0c0c0d.svg +1 -0
- package/src/assets/icons/atom.svg +1 -0
- package/src/assets/icons/bar.svg +1 -0
- package/src/assets/icons/bell.svg +1 -0
- package/src/assets/icons/box.svg +1 -0
- package/src/assets/icons/bug.svg +1 -0
- package/src/assets/icons/calendar.svg +1 -0
- package/src/assets/icons/check-circle.33c192.svg +1 -0
- package/src/assets/icons/check-circle.svg +1 -0
- package/src/assets/icons/check.d1d3db.svg +1 -0
- package/src/assets/icons/check.svg +1 -0
- package/src/assets/icons/chevron-down.svg +1 -0
- package/src/assets/icons/chevron-right.svg +1 -0
- package/src/assets/icons/chevron-up.svg +1 -0
- package/src/assets/icons/circle.svg +1 -0
- package/src/assets/icons/clock.svg +1 -0
- package/src/assets/icons/cmd.svg +1 -0
- package/src/assets/icons/code.svg +1 -0
- package/src/assets/icons/columns.svg +1 -0
- package/src/assets/icons/copy.svg +1 -0
- package/src/assets/icons/cpu.svg +1 -0
- package/src/assets/icons/dashboard.0c0c0d.svg +1 -0
- package/src/assets/icons/dashboard.svg +1 -0
- package/src/assets/icons/dollar.svg +1 -0
- package/src/assets/icons/download.svg +1 -0
- package/src/assets/icons/edit.svg +1 -0
- package/src/assets/icons/extensions.svg +1 -0
- package/src/assets/icons/external.svg +1 -0
- package/src/assets/icons/eye.svg +1 -0
- package/src/assets/icons/file-text.svg +1 -0
- package/src/assets/icons/file.svg +1 -0
- package/src/assets/icons/files.svg +1 -0
- package/src/assets/icons/filter.svg +1 -0
- package/src/assets/icons/folder.svg +1 -0
- package/src/assets/icons/gear.svg +1 -0
- package/src/assets/icons/git.svg +1 -0
- package/src/assets/icons/github.svg +1 -0
- package/src/assets/icons/globe.svg +1 -0
- package/src/assets/icons/grid-2x2.svg +1 -0
- package/src/assets/icons/hash.svg +1 -0
- package/src/assets/icons/heart.svg +1 -0
- package/src/assets/icons/help.svg +1 -0
- package/src/assets/icons/home.svg +1 -0
- package/src/assets/icons/image.svg +1 -0
- package/src/assets/icons/info-circle.svg +1 -0
- package/src/assets/icons/info-square.svg +1 -0
- package/src/assets/icons/info.387bff.svg +1 -0
- package/src/assets/icons/info.svg +1 -0
- package/src/assets/icons/key.svg +1 -0
- package/src/assets/icons/layers.svg +1 -0
- package/src/assets/icons/layout.svg +1 -0
- package/src/assets/icons/link.svg +1 -0
- package/src/assets/icons/list.svg +1 -0
- package/src/assets/icons/lock.svg +1 -0
- package/src/assets/icons/log-out.svg +1 -0
- package/src/assets/icons/logo.svg +1 -0
- package/src/assets/icons/mail.svg +1 -0
- package/src/assets/icons/menu.svg +1 -0
- package/src/assets/icons/message-circle.svg +1 -0
- package/src/assets/icons/message-plus.svg +1 -0
- package/src/assets/icons/message-square.svg +1 -0
- package/src/assets/icons/mic.svg +1 -0
- package/src/assets/icons/minus.svg +1 -0
- package/src/assets/icons/moon.svg +1 -0
- package/src/assets/icons/more-h.svg +1 -0
- package/src/assets/icons/mouse.svg +1 -0
- package/src/assets/icons/palette.svg +1 -0
- package/src/assets/icons/panel-bottom.svg +1 -0
- package/src/assets/icons/pause.svg +1 -0
- package/src/assets/icons/play.svg +1 -0
- package/src/assets/icons/plug.svg +1 -0
- package/src/assets/icons/plus.0c0c0d.svg +1 -0
- package/src/assets/icons/plus.svg +1 -0
- package/src/assets/icons/refresh.svg +1 -0
- package/src/assets/icons/ruler.svg +1 -0
- package/src/assets/icons/scroll-text.svg +1 -0
- package/src/assets/icons/search-menu.svg +1 -0
- package/src/assets/icons/search.svg +1 -0
- package/src/assets/icons/send.0c0c0d.svg +1 -0
- package/src/assets/icons/send.svg +1 -0
- package/src/assets/icons/settings.0c0c0d.svg +1 -0
- package/src/assets/icons/settings.svg +1 -0
- package/src/assets/icons/shield.svg +1 -0
- package/src/assets/icons/sidebar-left.svg +1 -0
- package/src/assets/icons/sidebar-right.svg +1 -0
- package/src/assets/icons/sliders.svg +1 -0
- package/src/assets/icons/sparkles.32f08c.svg +1 -0
- package/src/assets/icons/sparkles.svg +1 -0
- package/src/assets/icons/square.svg +1 -0
- package/src/assets/icons/star.svg +1 -0
- package/src/assets/icons/sun.svg +1 -0
- package/src/assets/icons/terminal.svg +1 -0
- package/src/assets/icons/trash.svg +1 -0
- package/src/assets/icons/trending-down.svg +1 -0
- package/src/assets/icons/trending-up.svg +1 -0
- package/src/assets/icons/type.svg +1 -0
- package/src/assets/icons/upload.svg +1 -0
- package/src/assets/icons/user-circle.svg +1 -0
- package/src/assets/icons/user.svg +1 -0
- package/src/assets/icons/users.svg +1 -0
- package/src/assets/icons/wrench.svg +1 -0
- package/src/assets/icons/x-circle.svg +1 -0
- package/src/assets/icons/x.svg +1 -0
- package/src/assets/icons/zap.0c0c0d.svg +1 -0
- package/src/assets/icons/zap.svg +1 -0
- package/src/avatar.ts +64 -0
- package/src/button.ts +88 -0
- package/src/card.ts +59 -0
- package/src/chat-composer.ts +156 -0
- package/src/dialog.ts +127 -0
- package/src/drawer.ts +131 -0
- package/src/editor-tabs.ts +184 -0
- package/src/file-tree.ts +214 -0
- package/src/forms.ts +270 -0
- package/src/icon.ts +118 -0
- package/src/icons.js +165 -0
- package/src/index.test.ts +213 -0
- package/src/index.ts +94 -0
- package/src/kbd.ts +72 -0
- package/src/menu.ts +119 -0
- package/src/nav-list.ts +157 -0
- package/src/overlay.test.ts +66 -0
- package/src/overlay.ts +205 -0
- package/src/page-header.ts +97 -0
- package/src/pagination.ts +163 -0
- package/src/second-batch.test.ts +205 -0
- package/src/stat-card.ts +92 -0
- package/src/status-bar.ts +108 -0
- package/src/styles/base.css +240 -0
- package/src/styles/components.css +1234 -0
- package/{dist → src/styles}/styles.css +2 -0
- package/src/styles/toast.css +57 -0
- package/src/styles/tokens.css +438 -0
- package/src/styles/vui.css +47 -0
- package/src/table.ts +191 -0
- package/src/tabs.ts +100 -0
- package/src/tag.ts +33 -0
- package/src/third-batch.test.ts +137 -0
- package/src/toast.test.ts +55 -0
- package/src/toast.ts +79 -0
- package/src/types.ts +25 -0
- package/src/utils.ts +221 -0
- package/src/workbench-titlebar.ts +137 -0
- package/dist/app-shell-dom.d.ts +0 -30
- package/dist/app-shell-dom.js +0 -913
- package/dist/app-shell.d.ts +0 -235
- package/dist/app-shell.js +0 -415
- package/dist/base.css +0 -51
- package/dist/calendar-picker.d.ts +0 -45
- package/dist/calendar-picker.js +0 -217
- package/dist/calendar.d.ts +0 -95
- package/dist/calendar.js +0 -194
- package/dist/complex-inputs.d.ts +0 -300
- package/dist/complex-inputs.js +0 -866
- package/dist/components.css +0 -4756
- package/dist/data-display.d.ts +0 -1094
- package/dist/data-display.js +0 -2341
- package/dist/dialog.d.ts +0 -26
- package/dist/dialog.js +0 -94
- package/dist/feedback.d.ts +0 -88
- package/dist/feedback.js +0 -281
- package/dist/forms.d.ts +0 -378
- package/dist/forms.js +0 -1019
- package/dist/icons-config.d.ts +0 -25
- package/dist/icons-config.js +0 -14
- package/dist/icons.d.ts +0 -41
- package/dist/icons.js +0 -185
- package/dist/index.d.ts +0 -31
- package/dist/index.js +0 -40
- package/dist/locale/en-US.d.ts +0 -31
- package/dist/locale/en-US.js +0 -20
- package/dist/locale/zh-CN.d.ts +0 -31
- package/dist/locale/zh-CN.js +0 -20
- package/dist/navigation.d.ts +0 -609
- package/dist/navigation.js +0 -1707
- package/dist/overlay.d.ts +0 -308
- package/dist/overlay.js +0 -974
- package/dist/page-state.d.ts +0 -23
- package/dist/page-state.js +0 -96
- package/dist/primitives.d.ts +0 -268
- package/dist/primitives.js +0 -764
- package/dist/theme-data.d.ts +0 -394
- package/dist/theme-data.js +0 -417
- package/dist/theme.d.ts +0 -97
- package/dist/theme.js +0 -301
- package/dist/tokens.css +0 -570
- package/dist/tree.d.ts +0 -144
- package/dist/tree.js +0 -475
- package/dist/virtual-list.d.ts +0 -190
- package/dist/virtual-list.js +0 -538
- package/dist/workbench.d.ts +0 -136
- package/dist/workbench.js +0 -156
package/dist/theme.js
DELETED
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
/** @license MIT
|
|
2
|
-
* Copyright (c) 2026 vobsjs
|
|
3
|
-
* @vobs/ui
|
|
4
|
-
*/
|
|
5
|
-
import { brandPresets, contrastRatio, DEFAULT_BRAND_ID, DEFAULT_THEME, deriveBrandTokens, deriveBrandTextColor, resolveBrandColor, themeTokenValues, } from './theme-data.js';
|
|
6
|
-
export { brandPresets, contrastRatio, DEFAULT_BRAND_COLOR, DEFAULT_BRAND_ID, DEFAULT_THEME, deriveBrandTokens, deriveBrandTextColor, normalizeHexColor, resolveBrandColor, } from './theme-data.js';
|
|
7
|
-
export const THEME_PREFERENCE_CHANGE_EVENT = 'vobs:theme-preference-change';
|
|
8
|
-
export const THEME_STATE_CHANGE_EVENT = 'vobs:theme-state-change';
|
|
9
|
-
const brandVariableNames = [
|
|
10
|
-
'--bg-brand',
|
|
11
|
-
'--bg-brand-hover',
|
|
12
|
-
'--bg-brand-disabled',
|
|
13
|
-
'--bg-brand-popup',
|
|
14
|
-
'--bg-brand-overlay',
|
|
15
|
-
'--text-brand',
|
|
16
|
-
'--text-brand-hover',
|
|
17
|
-
'--icon-brand',
|
|
18
|
-
'--icon-brand-hover',
|
|
19
|
-
'--border-brand',
|
|
20
|
-
'--text-onbrand',
|
|
21
|
-
'--icon-onbrand',
|
|
22
|
-
'--color-primary',
|
|
23
|
-
'--color-primary-hover',
|
|
24
|
-
'--color-primary-disabled',
|
|
25
|
-
'--color-primary-soft',
|
|
26
|
-
'--color-accent',
|
|
27
|
-
'--color-on-primary',
|
|
28
|
-
];
|
|
29
|
-
export function createThemeController(options) {
|
|
30
|
-
const listeners = new Set();
|
|
31
|
-
const persistedPreference = readPersistedTheme(options.persistence);
|
|
32
|
-
let preference = persistedPreference ??
|
|
33
|
-
options.initialPreference ??
|
|
34
|
-
(options.initialTheme === undefined && options.systemPreference !== undefined
|
|
35
|
-
? 'system'
|
|
36
|
-
: (options.initialTheme ?? DEFAULT_THEME));
|
|
37
|
-
let followsSystem = preference === 'system';
|
|
38
|
-
let theme = resolveTheme(preference, options);
|
|
39
|
-
let brand = readPersistedBrand(options.persistence, options.onWarning) ??
|
|
40
|
-
readBrand(options.initialBrand ?? DEFAULT_BRAND_ID, options.onWarning);
|
|
41
|
-
let stopSystemPreference;
|
|
42
|
-
let destroyed = false;
|
|
43
|
-
applyTheme(options.target, theme);
|
|
44
|
-
applyBrand(options.target, brand, theme);
|
|
45
|
-
subscribeToSystemPreference();
|
|
46
|
-
function state() {
|
|
47
|
-
return { theme, brand };
|
|
48
|
-
}
|
|
49
|
-
function notify() {
|
|
50
|
-
const value = state();
|
|
51
|
-
for (const listener of listeners)
|
|
52
|
-
listener(value);
|
|
53
|
-
}
|
|
54
|
-
function setTheme(nextTheme) {
|
|
55
|
-
setPreference(nextTheme);
|
|
56
|
-
}
|
|
57
|
-
function setPreference(nextPreference) {
|
|
58
|
-
assertThemePreference(nextPreference);
|
|
59
|
-
followsSystem = nextPreference === 'system';
|
|
60
|
-
stopSystemPreference?.();
|
|
61
|
-
stopSystemPreference = undefined;
|
|
62
|
-
preference = nextPreference;
|
|
63
|
-
theme = resolveTheme(preference, options);
|
|
64
|
-
applyTheme(options.target, theme);
|
|
65
|
-
applyBrand(options.target, brand, theme);
|
|
66
|
-
if (preference === 'system')
|
|
67
|
-
options.persistence?.writeSystemTheme?.();
|
|
68
|
-
else
|
|
69
|
-
options.persistence?.writeTheme?.(theme);
|
|
70
|
-
subscribeToSystemPreference();
|
|
71
|
-
notify();
|
|
72
|
-
}
|
|
73
|
-
function subscribeToSystemPreference() {
|
|
74
|
-
if (!followsSystem || options.systemPreference?.subscribe === undefined)
|
|
75
|
-
return;
|
|
76
|
-
stopSystemPreference = options.systemPreference.subscribe((nextTheme) => {
|
|
77
|
-
if (destroyed || !followsSystem)
|
|
78
|
-
return;
|
|
79
|
-
theme = nextTheme;
|
|
80
|
-
applyTheme(options.target, theme);
|
|
81
|
-
applyBrand(options.target, brand, theme);
|
|
82
|
-
notify();
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
get theme() {
|
|
87
|
-
return theme;
|
|
88
|
-
},
|
|
89
|
-
get preference() {
|
|
90
|
-
return preference;
|
|
91
|
-
},
|
|
92
|
-
get brand() {
|
|
93
|
-
return brand;
|
|
94
|
-
},
|
|
95
|
-
get state() {
|
|
96
|
-
return state();
|
|
97
|
-
},
|
|
98
|
-
setTheme,
|
|
99
|
-
setPreference,
|
|
100
|
-
toggleTheme() {
|
|
101
|
-
const nextTheme = theme === 'dark' ? 'light' : 'dark';
|
|
102
|
-
setTheme(nextTheme);
|
|
103
|
-
return nextTheme;
|
|
104
|
-
},
|
|
105
|
-
setBrand(nextBrand) {
|
|
106
|
-
brand = readBrand(nextBrand, options.onWarning);
|
|
107
|
-
applyBrand(options.target, brand, theme);
|
|
108
|
-
options.persistence?.writeBrand?.(brand);
|
|
109
|
-
notify();
|
|
110
|
-
return brand;
|
|
111
|
-
},
|
|
112
|
-
subscribe(listener) {
|
|
113
|
-
listeners.add(listener);
|
|
114
|
-
return () => listeners.delete(listener);
|
|
115
|
-
},
|
|
116
|
-
destroy() {
|
|
117
|
-
if (destroyed)
|
|
118
|
-
return;
|
|
119
|
-
destroyed = true;
|
|
120
|
-
followsSystem = false;
|
|
121
|
-
stopSystemPreference?.();
|
|
122
|
-
stopSystemPreference = undefined;
|
|
123
|
-
listeners.clear();
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
export function createStorageThemePersistence(storage, keys = {}) {
|
|
128
|
-
const themeKey = keys.theme ?? 'vobs-theme';
|
|
129
|
-
const brandKey = keys.brand ?? 'vobs-brand-color';
|
|
130
|
-
return {
|
|
131
|
-
readTheme() {
|
|
132
|
-
return storage.getItem(themeKey);
|
|
133
|
-
},
|
|
134
|
-
writeTheme(theme) {
|
|
135
|
-
storage.setItem(themeKey, theme);
|
|
136
|
-
},
|
|
137
|
-
writeSystemTheme() {
|
|
138
|
-
storage.setItem(themeKey, 'system');
|
|
139
|
-
},
|
|
140
|
-
readBrand() {
|
|
141
|
-
const stored = storage.getItem(brandKey);
|
|
142
|
-
if (stored === null)
|
|
143
|
-
return undefined;
|
|
144
|
-
try {
|
|
145
|
-
return JSON.parse(stored);
|
|
146
|
-
}
|
|
147
|
-
catch {
|
|
148
|
-
return stored;
|
|
149
|
-
}
|
|
150
|
-
},
|
|
151
|
-
writeBrand(brand) {
|
|
152
|
-
storage.setItem(brandKey, JSON.stringify(brand));
|
|
153
|
-
},
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
export function createMediaThemePreference(query) {
|
|
157
|
-
return {
|
|
158
|
-
read() {
|
|
159
|
-
return query.matches ? 'light' : 'dark';
|
|
160
|
-
},
|
|
161
|
-
subscribe(listener) {
|
|
162
|
-
const handleChange = (event) => {
|
|
163
|
-
listener(event.matches ? 'light' : 'dark');
|
|
164
|
-
};
|
|
165
|
-
query.addEventListener('change', handleChange);
|
|
166
|
-
return () => query.removeEventListener('change', handleChange);
|
|
167
|
-
},
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
export function createThemeState(theme = DEFAULT_THEME, brand = DEFAULT_BRAND_ID) {
|
|
171
|
-
assertTheme(theme);
|
|
172
|
-
return { theme, brand: resolveBrandColor(brand) };
|
|
173
|
-
}
|
|
174
|
-
export function createThemeAttributes(state) {
|
|
175
|
-
const attributes = {
|
|
176
|
-
'data-theme': state.theme,
|
|
177
|
-
'data-brand': state.brand.id,
|
|
178
|
-
...(isPresetBrand(state.brand) ? {} : { style: serializeBrandStyle(state.brand, state.theme) }),
|
|
179
|
-
};
|
|
180
|
-
return attributes;
|
|
181
|
-
}
|
|
182
|
-
export function createThemeBootstrapScript(state) {
|
|
183
|
-
const attributes = createThemeAttributes(state);
|
|
184
|
-
const variables = isPresetBrand(state.brand) ? {} : brandCssVariables(state.brand, state.theme);
|
|
185
|
-
return `(function(){var d=document.documentElement;d.setAttribute("data-theme",${JSON.stringify(attributes['data-theme'])});d.setAttribute("data-brand",${JSON.stringify(attributes['data-brand'])});var v=${JSON.stringify(variables)};for(var k in v){d.style.setProperty(k,v[k])}})()`;
|
|
186
|
-
}
|
|
187
|
-
function readPersistedTheme(persistence) {
|
|
188
|
-
const value = persistence?.readTheme?.();
|
|
189
|
-
return value === 'dark' || value === 'light' || value === 'system' ? value : undefined;
|
|
190
|
-
}
|
|
191
|
-
function resolveTheme(preference, options) {
|
|
192
|
-
return preference === 'system'
|
|
193
|
-
? (options.systemPreference?.read() ?? options.initialTheme ?? DEFAULT_THEME)
|
|
194
|
-
: preference;
|
|
195
|
-
}
|
|
196
|
-
function readPersistedBrand(persistence, onWarning) {
|
|
197
|
-
const value = persistence?.readBrand?.();
|
|
198
|
-
try {
|
|
199
|
-
if (typeof value === 'string')
|
|
200
|
-
return readBrand(value, onWarning);
|
|
201
|
-
if (isBrandColorInput(value))
|
|
202
|
-
return readBrand(value, onWarning);
|
|
203
|
-
}
|
|
204
|
-
catch {
|
|
205
|
-
onWarning?.('Ignored invalid persisted brand color');
|
|
206
|
-
return undefined;
|
|
207
|
-
}
|
|
208
|
-
if (value !== undefined && value !== null)
|
|
209
|
-
onWarning?.('Ignored invalid persisted brand color');
|
|
210
|
-
return undefined;
|
|
211
|
-
}
|
|
212
|
-
function readBrand(value, onWarning) {
|
|
213
|
-
const brand = resolveBrandColor(value);
|
|
214
|
-
if (!isPresetBrand(brand)) {
|
|
215
|
-
const darkContrast = contrastRatio(brand.color, themeTokenValues.dark['--bg-base-default']);
|
|
216
|
-
const lightContrast = contrastRatio(brand.color, themeTokenValues.light['--bg-base-default']);
|
|
217
|
-
if (Math.min(darkContrast, lightContrast) < 3) {
|
|
218
|
-
onWarning?.(`Custom brand ${brand.color} has low contrast against a theme background`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
return brand;
|
|
222
|
-
}
|
|
223
|
-
function applyTheme(target, theme) {
|
|
224
|
-
target.setAttribute('data-theme', theme);
|
|
225
|
-
}
|
|
226
|
-
function applyBrand(target, brand, theme) {
|
|
227
|
-
target.setAttribute('data-brand', brand.id);
|
|
228
|
-
if (isPresetBrand(brand)) {
|
|
229
|
-
for (const name of brandVariableNames)
|
|
230
|
-
target.style.removeProperty(name);
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
for (const [name, value] of Object.entries(brandCssVariables(brand, theme))) {
|
|
234
|
-
target.style.setProperty(name, value);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
function brandCssVariables(brand, theme = DEFAULT_THEME) {
|
|
238
|
-
const tokens = deriveBrandTokens(brand.color);
|
|
239
|
-
const readable = theme === 'light' ? deriveBrandTextColor(brand.color) : tokens.background;
|
|
240
|
-
const readableHover = theme === 'light' ? deriveBrandTextColor(tokens.hover) : tokens.hover;
|
|
241
|
-
return {
|
|
242
|
-
'--bg-brand': tokens.background,
|
|
243
|
-
'--bg-brand-hover': tokens.hover,
|
|
244
|
-
'--bg-brand-disabled': tokens.disabled,
|
|
245
|
-
'--bg-brand-popup': tokens.soft,
|
|
246
|
-
'--bg-brand-overlay': tokens.soft,
|
|
247
|
-
'--text-brand': readable,
|
|
248
|
-
'--text-brand-hover': readableHover,
|
|
249
|
-
'--icon-brand': readable,
|
|
250
|
-
'--icon-brand-hover': readableHover,
|
|
251
|
-
'--border-brand': readable,
|
|
252
|
-
'--text-onbrand': tokens.onBrand,
|
|
253
|
-
'--icon-onbrand': tokens.onBrand,
|
|
254
|
-
'--color-primary': tokens.background,
|
|
255
|
-
'--color-primary-hover': tokens.hover,
|
|
256
|
-
'--color-primary-disabled': tokens.disabled,
|
|
257
|
-
'--color-primary-soft': tokens.soft,
|
|
258
|
-
'--color-accent': tokens.background,
|
|
259
|
-
'--color-on-primary': tokens.onBrand,
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
function serializeBrandStyle(brand, theme) {
|
|
263
|
-
return Object.entries(brandCssVariables(brand, theme))
|
|
264
|
-
.map(([name, value]) => `${name}:${value}`)
|
|
265
|
-
.join(';');
|
|
266
|
-
}
|
|
267
|
-
function isPresetBrand(brand) {
|
|
268
|
-
return brandPresets.some((preset) => preset.id === brand.id && preset.color === brand.color);
|
|
269
|
-
}
|
|
270
|
-
function isBrandColorInput(value) {
|
|
271
|
-
return (typeof value === 'object' &&
|
|
272
|
-
value !== null &&
|
|
273
|
-
'color' in value &&
|
|
274
|
-
typeof value.color === 'string' &&
|
|
275
|
-
(!('id' in value) || value.id === undefined || typeof value.id === 'string') &&
|
|
276
|
-
(!('label' in value) || value.label === undefined || typeof value.label === 'string'));
|
|
277
|
-
}
|
|
278
|
-
function assertTheme(theme) {
|
|
279
|
-
if (theme !== 'dark' && theme !== 'light')
|
|
280
|
-
throw new TypeError(`Invalid theme: ${theme}`);
|
|
281
|
-
}
|
|
282
|
-
function assertThemePreference(preference) {
|
|
283
|
-
if (preference !== 'dark' && preference !== 'light' && preference !== 'system') {
|
|
284
|
-
throw new TypeError(`Invalid theme preference: ${preference}`);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Reads a design-token value (CSS variable) for the active theme, for third-party adapters (contract ui-adapters.md §3.1).
|
|
289
|
-
* Data source: tokens.css variables on html[data-theme] (getComputedStyle reads the latest effective value).
|
|
290
|
-
* Returns undefined without a document (SSR/non-browser) or when the variable is undefined — adapters must degrade gracefully.
|
|
291
|
-
*/
|
|
292
|
-
export function resolveUiToken(name) {
|
|
293
|
-
const doc = globalThis.document;
|
|
294
|
-
if (doc === undefined)
|
|
295
|
-
return undefined;
|
|
296
|
-
const value = doc.defaultView
|
|
297
|
-
?.getComputedStyle(doc.documentElement)
|
|
298
|
-
.getPropertyValue(name)
|
|
299
|
-
.trim();
|
|
300
|
-
return value === undefined || value === '' ? undefined : value;
|
|
301
|
-
}
|