vireuikit 0.5.0 → 0.6.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/README.md +56 -1
- package/dist/a11y-D3SS74I3.d.cts +25 -0
- package/dist/a11y-D3SS74I3.d.ts +25 -0
- package/dist/chunk-I3BD3XGC.js +392 -0
- package/dist/chunk-I3BD3XGC.js.map +1 -0
- package/dist/index.cjs +236 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +119 -1
- package/dist/index.d.ts +119 -1
- package/dist/index.js +1 -186
- package/dist/index.js.map +1 -1
- package/dist/web.cjs +826 -0
- package/dist/web.cjs.map +1 -0
- package/dist/web.d.cts +27 -0
- package/dist/web.d.ts +27 -0
- package/dist/web.js +567 -0
- package/dist/web.js.map +1 -0
- package/package.json +18 -6
package/dist/web.cjs
ADDED
|
@@ -0,0 +1,826 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vireglass = require('vireglass');
|
|
4
|
+
|
|
5
|
+
// src/web/element.ts
|
|
6
|
+
|
|
7
|
+
// src/kit/a11y.ts
|
|
8
|
+
var A11Y_NONE = {
|
|
9
|
+
reduceTransparency: false,
|
|
10
|
+
increaseContrast: false,
|
|
11
|
+
reduceMotion: false
|
|
12
|
+
};
|
|
13
|
+
function resolveA11y(system, override = {}) {
|
|
14
|
+
return {
|
|
15
|
+
reduceTransparency: override.reduceTransparency ?? system.reduceTransparency,
|
|
16
|
+
increaseContrast: override.increaseContrast ?? system.increaseContrast,
|
|
17
|
+
reduceMotion: override.reduceMotion ?? system.reduceMotion
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function presentationFor(mode, wantsGlass) {
|
|
21
|
+
return {
|
|
22
|
+
glass: wantsGlass,
|
|
23
|
+
frost: wantsGlass && mode.reduceTransparency,
|
|
24
|
+
surface: wantsGlass ? "glass" : "plain",
|
|
25
|
+
contrastBorder: mode.increaseContrast,
|
|
26
|
+
instantSprings: mode.reduceMotion
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function sameA11y(a, b) {
|
|
30
|
+
return a.reduceTransparency === b.reduceTransparency && a.increaseContrast === b.increaseContrast && a.reduceMotion === b.reduceMotion;
|
|
31
|
+
}
|
|
32
|
+
var ATOM_AT_REST = {
|
|
33
|
+
pressed: 0,
|
|
34
|
+
hovered: 0,
|
|
35
|
+
selected: 0,
|
|
36
|
+
disabled: false
|
|
37
|
+
};
|
|
38
|
+
function atomLift(kind) {
|
|
39
|
+
switch (kind) {
|
|
40
|
+
case "iconButton":
|
|
41
|
+
case "switch":
|
|
42
|
+
case "slider":
|
|
43
|
+
return 1;
|
|
44
|
+
default:
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
var DISABLED_PRESENCE = 0.25;
|
|
49
|
+
var HOVER_GAIN = 0.35;
|
|
50
|
+
function activation(state) {
|
|
51
|
+
if (state.disabled) return 0;
|
|
52
|
+
const clamp = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
53
|
+
return Math.max(clamp(state.selected), clamp(state.pressed), clamp(state.hovered) * HOVER_GAIN);
|
|
54
|
+
}
|
|
55
|
+
function atomMaterial(base, kind, state = ATOM_AT_REST) {
|
|
56
|
+
const out = vireglass.activeMaterial(base, activation(state));
|
|
57
|
+
if (!state.disabled) return out;
|
|
58
|
+
return { ...out, presence: out.presence * DISABLED_PRESENCE };
|
|
59
|
+
}
|
|
60
|
+
var REST_BODY = { alpha: 0.25, white: 0.15, lift: 0.1 };
|
|
61
|
+
var PRESSED_BODY = { alpha: 0.34, white: 0.35, lift: 0 };
|
|
62
|
+
var FROST_LIFT = 0.26;
|
|
63
|
+
function atomBody(base, state = ATOM_AT_REST, frost = false) {
|
|
64
|
+
const on = activation(state);
|
|
65
|
+
const mix = (key) => REST_BODY[key] + (PRESSED_BODY[key] - REST_BODY[key]) * on;
|
|
66
|
+
let alpha = mix("alpha");
|
|
67
|
+
let white = mix("white");
|
|
68
|
+
let lift = mix("lift");
|
|
69
|
+
if (state.disabled) alpha *= DISABLED_PRESENCE;
|
|
70
|
+
if (frost) {
|
|
71
|
+
const density = vireglass.applyAccessibility(vireglass.resolveOptics(base), {
|
|
72
|
+
reduceTransparency: true,
|
|
73
|
+
increaseContrast: false,
|
|
74
|
+
reduceMotion: false
|
|
75
|
+
}).bodyDensity;
|
|
76
|
+
alpha = Math.max(alpha, density);
|
|
77
|
+
white = 0;
|
|
78
|
+
lift = FROST_LIFT;
|
|
79
|
+
}
|
|
80
|
+
return { alpha, white, lift };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/kit/behavior/focus.ts
|
|
84
|
+
function stepFocus(event) {
|
|
85
|
+
return event.type === "focus" && event.visible;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/kit/behavior/hover.ts
|
|
89
|
+
function stepHover(event, canHover) {
|
|
90
|
+
return canHover && event.type === "enter";
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// src/kit/behavior/press.ts
|
|
94
|
+
var PRESS_IDLE = { by: null };
|
|
95
|
+
function stepPress(state, event, enabled) {
|
|
96
|
+
switch (event.type) {
|
|
97
|
+
case "down":
|
|
98
|
+
if (!enabled || state.by !== null) return { state, activated: false };
|
|
99
|
+
return { state: { by: event.source }, activated: false };
|
|
100
|
+
case "up":
|
|
101
|
+
if (state.by !== event.source) return { state, activated: false };
|
|
102
|
+
return { state: PRESS_IDLE, activated: enabled };
|
|
103
|
+
case "cancel":
|
|
104
|
+
return { state: PRESS_IDLE, activated: false };
|
|
105
|
+
case "leave":
|
|
106
|
+
return state.by === "pointer" ? { state: PRESS_IDLE, activated: false } : { state, activated: false };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/kit/behavior/control.ts
|
|
111
|
+
var TOUCH_INPUT = { hover: false };
|
|
112
|
+
var POINTER_INPUT = { hover: true };
|
|
113
|
+
var CONTROL_IDLE = {
|
|
114
|
+
press: PRESS_IDLE,
|
|
115
|
+
hovered: false,
|
|
116
|
+
focused: false,
|
|
117
|
+
disabled: false
|
|
118
|
+
};
|
|
119
|
+
function stepControl(state, event, caps) {
|
|
120
|
+
switch (event.type) {
|
|
121
|
+
case "down":
|
|
122
|
+
case "up":
|
|
123
|
+
case "cancel": {
|
|
124
|
+
const next = stepPress(state.press, event, !state.disabled);
|
|
125
|
+
return { state: { ...state, press: next.state }, activated: next.activated };
|
|
126
|
+
}
|
|
127
|
+
case "leave": {
|
|
128
|
+
const next = stepPress(state.press, event, !state.disabled);
|
|
129
|
+
return { state: { ...state, press: next.state, hovered: false }, activated: false };
|
|
130
|
+
}
|
|
131
|
+
case "enter":
|
|
132
|
+
return {
|
|
133
|
+
state: { ...state, hovered: !state.disabled && stepHover(event, caps.hover) },
|
|
134
|
+
activated: false
|
|
135
|
+
};
|
|
136
|
+
case "focus":
|
|
137
|
+
case "blur": {
|
|
138
|
+
const press = event.type === "blur" && state.press.by === "keyboard" ? PRESS_IDLE : state.press;
|
|
139
|
+
return {
|
|
140
|
+
state: { ...state, press, focused: !state.disabled && stepFocus(event) },
|
|
141
|
+
activated: false
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
case "disable":
|
|
145
|
+
return {
|
|
146
|
+
state: event.disabled ? { press: PRESS_IDLE, hovered: false, focused: false, disabled: true } : { ...state, disabled: false },
|
|
147
|
+
activated: false
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function controlTargets(state) {
|
|
152
|
+
return {
|
|
153
|
+
pressed: state.press.by !== null ? 1 : 0,
|
|
154
|
+
hovered: state.hovered ? 1 : 0,
|
|
155
|
+
focus: state.focused ? 1 : 0,
|
|
156
|
+
disabled: state.disabled
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function stepSpring(s, dt, response, damping, instant = false) {
|
|
160
|
+
if (instant) {
|
|
161
|
+
const moved = s.x !== s.target || s.v !== 0;
|
|
162
|
+
s.x = s.target;
|
|
163
|
+
s.v = 0;
|
|
164
|
+
return moved;
|
|
165
|
+
}
|
|
166
|
+
const stiffness = (2 * Math.PI / response) ** 2;
|
|
167
|
+
const friction = 4 * Math.PI * damping / response;
|
|
168
|
+
const h = 1 / 240;
|
|
169
|
+
for (let left = Math.min(dt, 0.05); left > 0; left -= h) {
|
|
170
|
+
const step = Math.min(left, h);
|
|
171
|
+
s.v += (stiffness * (s.target - s.x) - friction * s.v) * step;
|
|
172
|
+
s.x += s.v * step;
|
|
173
|
+
}
|
|
174
|
+
if (Math.abs(s.target - s.x) < 1e-3 && Math.abs(s.v) < 0.01) {
|
|
175
|
+
s.x = s.target;
|
|
176
|
+
s.v = 0;
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/kit/behavior/visual.ts
|
|
183
|
+
var createControlVisual = () => ({
|
|
184
|
+
pressed: { x: 0, v: 0, target: 0 },
|
|
185
|
+
hovered: { x: 0, v: 0, target: 0 },
|
|
186
|
+
focus: { x: 0, v: 0, target: 0 }
|
|
187
|
+
});
|
|
188
|
+
var PRESS = { response: 0.18, damping: 0.78 };
|
|
189
|
+
var HOVER = { response: 0.22, damping: 1 };
|
|
190
|
+
var FOCUS = { response: 0.16, damping: 1 };
|
|
191
|
+
function stepControlVisual(visual, dt, state, instant = false) {
|
|
192
|
+
const t = controlTargets(state);
|
|
193
|
+
visual.pressed.target = t.pressed;
|
|
194
|
+
visual.hovered.target = t.hovered;
|
|
195
|
+
visual.focus.target = t.focus;
|
|
196
|
+
const a = stepSpring(visual.pressed, dt, PRESS.response, PRESS.damping, instant);
|
|
197
|
+
const b = stepSpring(visual.hovered, dt, HOVER.response, HOVER.damping, instant);
|
|
198
|
+
const c = stepSpring(visual.focus, dt, FOCUS.response, FOCUS.damping, instant);
|
|
199
|
+
return a || b || c;
|
|
200
|
+
}
|
|
201
|
+
function visualAtomState(visual, state) {
|
|
202
|
+
return {
|
|
203
|
+
pressed: visual.pressed.x,
|
|
204
|
+
hovered: visual.hovered.x,
|
|
205
|
+
selected: 0,
|
|
206
|
+
disabled: state.disabled
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function settleControlVisual(visual, state) {
|
|
210
|
+
stepControlVisual(visual, 0, state, true);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// src/kit/response.ts
|
|
214
|
+
var LIFTING = { grow: 0.18, defocus: 1.6 };
|
|
215
|
+
var SINKING = { grow: 0.06, defocus: 1 };
|
|
216
|
+
function pressResponse(kind) {
|
|
217
|
+
return atomLift(kind) === 1 ? LIFTING : SINKING;
|
|
218
|
+
}
|
|
219
|
+
var CONTROL_SIZES = ["touch", "small", "medium", "large", "xlarge"];
|
|
220
|
+
var MIN_TOUCH_TARGET_DP = 44;
|
|
221
|
+
var MIN_POINTER_TARGET_DP = 24;
|
|
222
|
+
var capsule = (height, paddingX) => ({
|
|
223
|
+
height,
|
|
224
|
+
paddingX,
|
|
225
|
+
icon: Math.round(height / 2),
|
|
226
|
+
radius: height / 2,
|
|
227
|
+
shape: "capsule"
|
|
228
|
+
});
|
|
229
|
+
var rounded = (height, paddingX) => ({
|
|
230
|
+
height,
|
|
231
|
+
paddingX,
|
|
232
|
+
icon: Math.round(height / 2),
|
|
233
|
+
radius: height / 4,
|
|
234
|
+
shape: "rounded"
|
|
235
|
+
});
|
|
236
|
+
var BUTTON_SIZES = {
|
|
237
|
+
touch: capsule(44, 20),
|
|
238
|
+
small: rounded(24, 10),
|
|
239
|
+
medium: rounded(32, 14),
|
|
240
|
+
large: capsule(40, 18),
|
|
241
|
+
xlarge: capsule(48, 22)
|
|
242
|
+
};
|
|
243
|
+
function iconButtonSize(size) {
|
|
244
|
+
const spec = BUTTON_SIZES[size];
|
|
245
|
+
return { ...spec, width: spec.height, paddingX: 0 };
|
|
246
|
+
}
|
|
247
|
+
function defaultSize(input) {
|
|
248
|
+
return input.touch ? "touch" : "medium";
|
|
249
|
+
}
|
|
250
|
+
function hitSlop(bodyDp, minTargetDp) {
|
|
251
|
+
return bodyDp >= minTargetDp ? 0 : (minTargetDp - bodyDp) / 2;
|
|
252
|
+
}
|
|
253
|
+
function minTarget(input) {
|
|
254
|
+
return input.touch ? MIN_TOUCH_TARGET_DP : MIN_POINTER_TARGET_DP;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// src/web/a11y.ts
|
|
258
|
+
var QUERIES = {
|
|
259
|
+
reduceMotion: "(prefers-reduced-motion: reduce)",
|
|
260
|
+
increaseContrast: "(prefers-contrast: more)",
|
|
261
|
+
reduceTransparency: "(prefers-reduced-transparency: reduce)"
|
|
262
|
+
};
|
|
263
|
+
var KEYS = Object.keys(QUERIES);
|
|
264
|
+
function systemA11y() {
|
|
265
|
+
if (typeof matchMedia === "undefined") return A11Y_NONE;
|
|
266
|
+
return {
|
|
267
|
+
reduceMotion: matchMedia(QUERIES.reduceMotion).matches,
|
|
268
|
+
increaseContrast: matchMedia(QUERIES.increaseContrast).matches,
|
|
269
|
+
reduceTransparency: matchMedia(QUERIES.reduceTransparency).matches
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function watchSystemA11y(onChange) {
|
|
273
|
+
if (typeof matchMedia === "undefined") return () => {
|
|
274
|
+
};
|
|
275
|
+
const lists = KEYS.map((key) => matchMedia(QUERIES[key]));
|
|
276
|
+
for (const list of lists) list.addEventListener("change", onChange);
|
|
277
|
+
return () => {
|
|
278
|
+
for (const list of lists) list.removeEventListener("change", onChange);
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
var globalOverride = {};
|
|
282
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
283
|
+
function setA11yOverride(next) {
|
|
284
|
+
globalOverride = { ...globalOverride, ...next };
|
|
285
|
+
for (const listener of listeners) listener();
|
|
286
|
+
}
|
|
287
|
+
function getA11yOverride() {
|
|
288
|
+
return globalOverride;
|
|
289
|
+
}
|
|
290
|
+
function watchA11yOverride(onChange) {
|
|
291
|
+
listeners.add(onChange);
|
|
292
|
+
return () => {
|
|
293
|
+
listeners.delete(onChange);
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
function effectiveA11y(own) {
|
|
297
|
+
const merged = { ...globalOverride };
|
|
298
|
+
for (const key of KEYS) if (own[key] !== void 0) merged[key] = own[key];
|
|
299
|
+
return resolveA11y(systemA11y(), merged);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// src/web/glass.ts
|
|
303
|
+
async function attachControlGlass(el, params, stillWanted) {
|
|
304
|
+
const { attachGlass } = await import('vireglass/dom');
|
|
305
|
+
if (!stillWanted()) return null;
|
|
306
|
+
const opts = {
|
|
307
|
+
material: params.material,
|
|
308
|
+
geometry: params.geometry,
|
|
309
|
+
accessibility: params.accessibility,
|
|
310
|
+
variant: params.onTouch ? "interactive" : "present",
|
|
311
|
+
// The kit paints its own body: the core's is not lighter than its surround over a light backdrop and
|
|
312
|
+
// near black under reduced transparency with light ink (docs/acceptance.md, "Resting body").
|
|
313
|
+
body: false
|
|
314
|
+
};
|
|
315
|
+
if (params.sample) opts.sample = params.sample;
|
|
316
|
+
const handle = attachGlass(el, opts);
|
|
317
|
+
return {
|
|
318
|
+
setMaterial(material) {
|
|
319
|
+
opts.material = material;
|
|
320
|
+
handle.update();
|
|
321
|
+
},
|
|
322
|
+
setGeometry(geometry) {
|
|
323
|
+
opts.geometry = geometry;
|
|
324
|
+
handle.update();
|
|
325
|
+
},
|
|
326
|
+
setAppear: (t) => handle.setAppear(t),
|
|
327
|
+
setMorph: (morph) => handle.setMorph(morph),
|
|
328
|
+
setSample: (sample) => handle.setSample(sample),
|
|
329
|
+
destroy: () => handle.destroy()
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// src/web/input.ts
|
|
334
|
+
var COARSE = "(pointer: coarse)";
|
|
335
|
+
function isCoarsePointer() {
|
|
336
|
+
return typeof matchMedia !== "undefined" && matchMedia(COARSE).matches;
|
|
337
|
+
}
|
|
338
|
+
function watchCoarsePointer(onChange) {
|
|
339
|
+
if (typeof matchMedia === "undefined") return () => {
|
|
340
|
+
};
|
|
341
|
+
const list = matchMedia(COARSE);
|
|
342
|
+
list.addEventListener("change", onChange);
|
|
343
|
+
return () => list.removeEventListener("change", onChange);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// src/web/styles.ts
|
|
347
|
+
var HOST = ":is(vire-button,vire-icon-button)[data-vk]";
|
|
348
|
+
var BODY = `${HOST}>button`;
|
|
349
|
+
var STYLES = `
|
|
350
|
+
vire-button,vire-icon-button{display:inline-flex;vertical-align:middle}
|
|
351
|
+
${HOST}{position:relative;--vk-press:0;--vk-hover:0;--vk-body-alpha:0;--vk-body-white:0;--vk-body-lift:0;--vk-grow:0;--vk-defocus:0;--vk-slop-x:0;--vk-slop-y:0}
|
|
352
|
+
${HOST}::before{content:'';position:absolute;inset:calc(var(--vk-slop-y)*-1px) calc(var(--vk-slop-x)*-1px)}
|
|
353
|
+
${BODY}{appearance:none;-webkit-appearance:none;box-sizing:border-box;margin:0;border:0;outline:none;
|
|
354
|
+
font:inherit;font-weight:500;line-height:1;white-space:nowrap;color:inherit;
|
|
355
|
+
display:inline-flex;align-items:center;justify-content:center;gap:8px;position:relative;
|
|
356
|
+
height:var(--vk-height);min-width:var(--vk-height);padding:0 var(--vk-pad-x);border-radius:var(--vk-radius);
|
|
357
|
+
-webkit-text-fill-color:color-mix(in srgb,currentColor calc((1 - var(--vk-press)*.55)*100%),transparent);
|
|
358
|
+
text-shadow:0 0 calc(var(--vk-press)*var(--vk-defocus)*1px) currentColor;
|
|
359
|
+
background:transparent;cursor:pointer;touch-action:manipulation;user-select:none;-webkit-tap-highlight-color:transparent;
|
|
360
|
+
transform:scale(calc(1 + var(--vk-press)*var(--vk-grow)))}
|
|
361
|
+
vire-icon-button[data-vk]>button{padding:0;width:var(--vk-height)}
|
|
362
|
+
${BODY}>svg{width:var(--vk-icon);height:var(--vk-icon);flex:none;
|
|
363
|
+
opacity:calc(1 - var(--vk-press)*.45);filter:blur(calc(var(--vk-press)*var(--vk-defocus)*1px))}
|
|
364
|
+
${BODY}:disabled{cursor:default}
|
|
365
|
+
${HOST}[data-disabled]>button{-webkit-text-fill-color:color-mix(in srgb,currentColor 40%,transparent)}
|
|
366
|
+
${HOST}[data-disabled]>button>svg{opacity:.4}
|
|
367
|
+
${HOST}[data-focus]>button{outline:2px solid currentColor;outline-offset:2px}
|
|
368
|
+
|
|
369
|
+
${HOST}[data-surface=glass]>button{color:var(--vireglass-ink-color,inherit);
|
|
370
|
+
background:color-mix(in srgb,color-mix(in srgb,#fff calc((var(--vk-body-white) + var(--vk-body-lift)*2)*100%),var(--vireglass-tint-color,#fff)) calc(var(--vk-body-alpha)*100%),transparent);
|
|
371
|
+
background:oklab(from color-mix(in srgb,#fff calc(var(--vk-body-white)*100%),var(--vireglass-tint-color,#fff)) calc(l + var(--vk-body-lift)) a b / var(--vk-body-alpha))}
|
|
372
|
+
${HOST}[data-frost][data-surface=glass]>button{color:oklab(from var(--vireglass-tint-color,#fff) calc(.95 - .87*clamp(0,(l + var(--vk-body-lift) - .6)*20,1)) 0 0)}
|
|
373
|
+
|
|
374
|
+
${HOST}[data-surface=plain]>button{background:color-mix(in srgb,currentColor calc(10% + var(--vk-hover)*6% + var(--vk-press)*14%),transparent)}
|
|
375
|
+
|
|
376
|
+
${HOST}[data-surface=frosted]>button{
|
|
377
|
+
background:color-mix(in srgb,Canvas calc(88% - var(--vk-hover)*4% - var(--vk-press)*10%),currentColor);
|
|
378
|
+
backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
|
|
379
|
+
box-shadow:0 1px 3px color-mix(in srgb,currentColor 22%,transparent)}
|
|
380
|
+
|
|
381
|
+
@supports not (color:oklab(from red l a b)){
|
|
382
|
+
${HOST}[data-frost][data-surface=glass]>button{color:inherit;background:color-mix(in srgb,Canvas 82%,currentColor)}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
${HOST}[data-contrast]:is([data-surface=plain],[data-surface=frosted])>button{box-shadow:inset 0 0 0 2px currentColor}
|
|
386
|
+
${HOST}[data-contrast][data-surface=frosted]>button{background:Canvas}
|
|
387
|
+
${HOST}[data-contrast][data-surface=glass]>button{background:color-mix(in srgb,color-mix(in srgb,#fff calc((1 - var(--vireglass-ink,0))*100%),#000) 88%,transparent)}
|
|
388
|
+
|
|
389
|
+
@media (forced-colors:active){
|
|
390
|
+
${BODY}{-webkit-text-fill-color:currentColor;text-shadow:none;color:ButtonText;background:ButtonFace;border:1px solid ButtonText;backdrop-filter:none;-webkit-backdrop-filter:none;transform:none}
|
|
391
|
+
${BODY}>svg{opacity:1;filter:none}
|
|
392
|
+
${HOST}[data-disabled]>button{-webkit-text-fill-color:currentColor;color:GrayText;border-color:GrayText}
|
|
393
|
+
${HOST}[data-focus]>button{outline-color:Highlight}
|
|
394
|
+
}
|
|
395
|
+
`;
|
|
396
|
+
var STYLE_ATTR = "data-vireuikit";
|
|
397
|
+
function ensureStyles(from, nonce) {
|
|
398
|
+
const root = from.getRootNode();
|
|
399
|
+
const host = root instanceof ShadowRoot ? root : from.ownerDocument;
|
|
400
|
+
if (host.querySelector(`style[${STYLE_ATTR}]`)) return;
|
|
401
|
+
const style = from.ownerDocument.createElement("style");
|
|
402
|
+
style.setAttribute(STYLE_ATTR, "");
|
|
403
|
+
if (nonce) style.nonce = nonce;
|
|
404
|
+
style.textContent = STYLES;
|
|
405
|
+
(host instanceof ShadowRoot ? host : host.head).appendChild(style);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// src/web/element.ts
|
|
409
|
+
var FORCE_ATTRIBUTE = "data-vire-force-state";
|
|
410
|
+
var FORCED = {
|
|
411
|
+
rest: CONTROL_IDLE,
|
|
412
|
+
hover: { ...CONTROL_IDLE, hovered: true },
|
|
413
|
+
focus: { ...CONTROL_IDLE, focused: true },
|
|
414
|
+
pressed: { ...CONTROL_IDLE, press: { by: "pointer" } },
|
|
415
|
+
disabled: { ...CONTROL_IDLE, disabled: true }
|
|
416
|
+
};
|
|
417
|
+
var MATERIAL_STEPS = 10;
|
|
418
|
+
var SUPPRESS_MS = 100;
|
|
419
|
+
function createControlElementClass(kind, options = {}) {
|
|
420
|
+
const response = pressResponse(kind);
|
|
421
|
+
return class VireControl extends HTMLElement {
|
|
422
|
+
static observedAttributes = ["glass", "size", "disabled", FORCE_ATTRIBUTE];
|
|
423
|
+
#control = null;
|
|
424
|
+
#state = CONTROL_IDLE;
|
|
425
|
+
#caps = POINTER_INPUT;
|
|
426
|
+
#visual = createControlVisual();
|
|
427
|
+
#own = {};
|
|
428
|
+
#mode = null;
|
|
429
|
+
#presentation = null;
|
|
430
|
+
#glass = null;
|
|
431
|
+
#glassToken = 0;
|
|
432
|
+
#glassKey = "";
|
|
433
|
+
#glassBroken = false;
|
|
434
|
+
#lastMaterialKey = "";
|
|
435
|
+
#frame = 0;
|
|
436
|
+
#lastFrame = 0;
|
|
437
|
+
#cleanups = [];
|
|
438
|
+
#suppressClick = false;
|
|
439
|
+
#suppressTimer = 0;
|
|
440
|
+
#slop = { x: 0, y: 0 };
|
|
441
|
+
#morph = null;
|
|
442
|
+
#sample = null;
|
|
443
|
+
get a11y() {
|
|
444
|
+
return this.#own;
|
|
445
|
+
}
|
|
446
|
+
set a11y(next) {
|
|
447
|
+
this.#own = { ...next };
|
|
448
|
+
if (this.#control) this.#refreshMode();
|
|
449
|
+
}
|
|
450
|
+
get sample() {
|
|
451
|
+
return this.#sample;
|
|
452
|
+
}
|
|
453
|
+
set sample(next) {
|
|
454
|
+
this.#sample = next;
|
|
455
|
+
this.#glass?.setSample(next);
|
|
456
|
+
}
|
|
457
|
+
setMorph(morph) {
|
|
458
|
+
this.#morph = morph;
|
|
459
|
+
this.#glass?.setMorph(morph);
|
|
460
|
+
}
|
|
461
|
+
connectedCallback() {
|
|
462
|
+
for (const key of ["a11y", "sample"]) {
|
|
463
|
+
if (!Object.prototype.hasOwnProperty.call(this, key)) continue;
|
|
464
|
+
const value = Reflect.get(this, key);
|
|
465
|
+
Reflect.deleteProperty(this, key);
|
|
466
|
+
Reflect.set(this, key, value);
|
|
467
|
+
}
|
|
468
|
+
ensureStyles(this, options.nonce);
|
|
469
|
+
this.#cleanups.push(watchCoarsePointer(() => this.#onInputChange()));
|
|
470
|
+
this.#cleanups.push(watchSystemA11y(() => this.#refreshMode()));
|
|
471
|
+
this.#cleanups.push(watchA11yOverride(() => this.#refreshMode()));
|
|
472
|
+
this.#awaitControl();
|
|
473
|
+
}
|
|
474
|
+
disconnectedCallback() {
|
|
475
|
+
for (const cleanup of this.#cleanups.splice(0)) cleanup();
|
|
476
|
+
cancelAnimationFrame(this.#frame);
|
|
477
|
+
clearTimeout(this.#suppressTimer);
|
|
478
|
+
this.#frame = 0;
|
|
479
|
+
this.#dropGlass();
|
|
480
|
+
this.#control = null;
|
|
481
|
+
this.#state = CONTROL_IDLE;
|
|
482
|
+
this.#suppressClick = false;
|
|
483
|
+
for (const name of ["data-vk", "data-surface", "data-glass", "data-frost", "data-size"]) this.removeAttribute(name);
|
|
484
|
+
for (const name of Array.from(this.style)) if (name.startsWith("--vk-")) this.style.removeProperty(name);
|
|
485
|
+
this.#presentation = null;
|
|
486
|
+
this.#mode = null;
|
|
487
|
+
}
|
|
488
|
+
attributeChangedCallback(name) {
|
|
489
|
+
if (!this.#control) return;
|
|
490
|
+
if (name === "disabled") {
|
|
491
|
+
const wanted = this.hasAttribute("disabled");
|
|
492
|
+
if (this.#control.disabled !== wanted) this.#control.disabled = wanted;
|
|
493
|
+
this.#syncDisabled();
|
|
494
|
+
} else if (name === FORCE_ATTRIBUTE) {
|
|
495
|
+
this.#applyForced();
|
|
496
|
+
} else {
|
|
497
|
+
this.#refreshMode(true);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
// The parser connects the element before its children exist, so the button is waited for
|
|
501
|
+
// rather than made up.
|
|
502
|
+
#awaitControl() {
|
|
503
|
+
const found = this.querySelector(":scope > button");
|
|
504
|
+
if (found) {
|
|
505
|
+
this.#upgrade(found);
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
const observer = new MutationObserver(() => {
|
|
509
|
+
const button = this.querySelector(":scope > button");
|
|
510
|
+
if (!button) return;
|
|
511
|
+
observer.disconnect();
|
|
512
|
+
this.#upgrade(button);
|
|
513
|
+
});
|
|
514
|
+
observer.observe(this, { childList: true });
|
|
515
|
+
this.#cleanups.push(() => observer.disconnect());
|
|
516
|
+
}
|
|
517
|
+
#upgrade(control) {
|
|
518
|
+
this.#control = control;
|
|
519
|
+
this.setAttribute("data-vk", "");
|
|
520
|
+
this.#caps = isCoarsePointer() ? TOUCH_INPUT : POINTER_INPUT;
|
|
521
|
+
this.#listen(control);
|
|
522
|
+
this.#cleanups.push(this.#observeSize(control));
|
|
523
|
+
this.#syncDisabled();
|
|
524
|
+
if (control.matches(":focus")) {
|
|
525
|
+
this.#dispatch({ type: "focus", visible: control.matches(":focus-visible") });
|
|
526
|
+
}
|
|
527
|
+
this.#mode = null;
|
|
528
|
+
this.#refreshMode();
|
|
529
|
+
}
|
|
530
|
+
#onInputChange() {
|
|
531
|
+
if (!this.#control) return;
|
|
532
|
+
this.#caps = isCoarsePointer() ? TOUCH_INPUT : POINTER_INPUT;
|
|
533
|
+
this.#refreshMode(true);
|
|
534
|
+
}
|
|
535
|
+
#size() {
|
|
536
|
+
const wanted = this.getAttribute("size");
|
|
537
|
+
if (wanted && CONTROL_SIZES.includes(wanted)) return wanted;
|
|
538
|
+
return defaultSize({ touch: isCoarsePointer() });
|
|
539
|
+
}
|
|
540
|
+
#glassMode() {
|
|
541
|
+
const wanted = this.getAttribute("glass");
|
|
542
|
+
if (wanted === "touch") return "touch";
|
|
543
|
+
return wanted === "" || wanted === "present" ? "present" : "off";
|
|
544
|
+
}
|
|
545
|
+
#forced() {
|
|
546
|
+
const wanted = this.getAttribute(FORCE_ATTRIBUTE);
|
|
547
|
+
return wanted !== null && Object.hasOwn(FORCED, wanted) ? wanted : null;
|
|
548
|
+
}
|
|
549
|
+
#dispatch(event) {
|
|
550
|
+
if (this.#forced()) return false;
|
|
551
|
+
const step = stepControl(this.#state, event, this.#caps);
|
|
552
|
+
this.#state = step.state;
|
|
553
|
+
this.#render();
|
|
554
|
+
return step.activated;
|
|
555
|
+
}
|
|
556
|
+
#listen(control) {
|
|
557
|
+
const on = (target, type, handler, capture = false) => {
|
|
558
|
+
target.addEventListener(type, handler, capture);
|
|
559
|
+
this.#cleanups.push(() => target.removeEventListener(type, handler, capture));
|
|
560
|
+
};
|
|
561
|
+
const inside = (e) => {
|
|
562
|
+
const r = this.getBoundingClientRect();
|
|
563
|
+
return e.clientX >= r.left - this.#slop.x && e.clientX <= r.right + this.#slop.x && e.clientY >= r.top - this.#slop.y && e.clientY <= r.bottom + this.#slop.y;
|
|
564
|
+
};
|
|
565
|
+
const holdSuppression = () => {
|
|
566
|
+
this.#suppressClick = true;
|
|
567
|
+
clearTimeout(this.#suppressTimer);
|
|
568
|
+
this.#suppressTimer = window.setTimeout(() => this.#suppressClick = false, SUPPRESS_MS);
|
|
569
|
+
};
|
|
570
|
+
const releaseSuppression = () => {
|
|
571
|
+
this.#suppressClick = false;
|
|
572
|
+
clearTimeout(this.#suppressTimer);
|
|
573
|
+
};
|
|
574
|
+
const bind = (target, own) => {
|
|
575
|
+
const mine = (e) => own || e.target === this;
|
|
576
|
+
on(target, "pointerdown", (e) => {
|
|
577
|
+
if (e.button !== 0 || !mine(e)) return;
|
|
578
|
+
releaseSuppression();
|
|
579
|
+
this.#dispatch({ type: "down", source: "pointer" });
|
|
580
|
+
});
|
|
581
|
+
on(target, "pointermove", (e) => {
|
|
582
|
+
if (!mine(e)) return;
|
|
583
|
+
if (this.#state.press.by === "pointer" && !inside(e)) this.#dispatch({ type: "leave" });
|
|
584
|
+
});
|
|
585
|
+
on(target, "pointerup", (e) => {
|
|
586
|
+
if (!mine(e)) return;
|
|
587
|
+
const wasPressed = this.#state.press.by === "pointer";
|
|
588
|
+
const activated = this.#dispatch({ type: "up", source: "pointer" });
|
|
589
|
+
if (own && !activated && !wasPressed && !inside(e)) holdSuppression();
|
|
590
|
+
});
|
|
591
|
+
on(target, "pointercancel", (e) => {
|
|
592
|
+
if (mine(e)) this.#dispatch({ type: "cancel" });
|
|
593
|
+
});
|
|
594
|
+
on(target, "pointerenter", (e) => {
|
|
595
|
+
if (mine(e) && e.pointerType !== "touch") this.#dispatch({ type: "enter" });
|
|
596
|
+
});
|
|
597
|
+
on(target, "pointerleave", (e) => {
|
|
598
|
+
if (mine(e) && !control.hasPointerCapture?.(e.pointerId)) this.#dispatch({ type: "leave" });
|
|
599
|
+
});
|
|
600
|
+
};
|
|
601
|
+
bind(control, true);
|
|
602
|
+
bind(this, false);
|
|
603
|
+
on(
|
|
604
|
+
this,
|
|
605
|
+
"click",
|
|
606
|
+
(e) => {
|
|
607
|
+
if (e.target !== this) return;
|
|
608
|
+
e.stopImmediatePropagation();
|
|
609
|
+
e.preventDefault();
|
|
610
|
+
control.click();
|
|
611
|
+
},
|
|
612
|
+
true
|
|
613
|
+
);
|
|
614
|
+
on(
|
|
615
|
+
control,
|
|
616
|
+
"click",
|
|
617
|
+
(e) => {
|
|
618
|
+
if (!this.#suppressClick) return;
|
|
619
|
+
releaseSuppression();
|
|
620
|
+
if (e.detail === 0) return;
|
|
621
|
+
e.preventDefault();
|
|
622
|
+
e.stopImmediatePropagation();
|
|
623
|
+
},
|
|
624
|
+
true
|
|
625
|
+
);
|
|
626
|
+
on(control, "keydown", (e) => {
|
|
627
|
+
releaseSuppression();
|
|
628
|
+
if ((e.key === " " || e.key === "Enter") && !e.repeat) this.#dispatch({ type: "down", source: "keyboard" });
|
|
629
|
+
});
|
|
630
|
+
on(control, "keyup", (e) => {
|
|
631
|
+
if (e.key === " " || e.key === "Enter") this.#dispatch({ type: "up", source: "keyboard" });
|
|
632
|
+
});
|
|
633
|
+
on(control, "focus", () => this.#dispatch({ type: "focus", visible: control.matches(":focus-visible") }));
|
|
634
|
+
on(control, "blur", () => this.#dispatch({ type: "blur" }));
|
|
635
|
+
on(control, "focusout", () => this.#dispatch({ type: "blur" }));
|
|
636
|
+
const mutations = new MutationObserver(() => this.#syncDisabled());
|
|
637
|
+
mutations.observe(control, { attributes: true, attributeFilter: ["disabled"] });
|
|
638
|
+
this.#cleanups.push(() => mutations.disconnect());
|
|
639
|
+
}
|
|
640
|
+
#observeSize(control) {
|
|
641
|
+
if (typeof ResizeObserver === "undefined") return () => {
|
|
642
|
+
};
|
|
643
|
+
const observer = new ResizeObserver(() => {
|
|
644
|
+
this.#applySlop();
|
|
645
|
+
this.#glass?.setGeometry(this.#geometry(control));
|
|
646
|
+
});
|
|
647
|
+
observer.observe(control);
|
|
648
|
+
return () => observer.disconnect();
|
|
649
|
+
}
|
|
650
|
+
#geometry(control) {
|
|
651
|
+
const radius = parseFloat(getComputedStyle(control).borderTopLeftRadius) || 0;
|
|
652
|
+
return { width: control.offsetWidth, height: control.offsetHeight, cornerRadius: radius };
|
|
653
|
+
}
|
|
654
|
+
#applySlop() {
|
|
655
|
+
const control = this.#control;
|
|
656
|
+
if (!control) return;
|
|
657
|
+
const floor = minTarget({ touch: isCoarsePointer() });
|
|
658
|
+
this.#slop = { x: hitSlop(control.offsetWidth, floor), y: hitSlop(control.offsetHeight, floor) };
|
|
659
|
+
this.style.setProperty("--vk-slop-x", String(this.#slop.x));
|
|
660
|
+
this.style.setProperty("--vk-slop-y", String(this.#slop.y));
|
|
661
|
+
}
|
|
662
|
+
#syncDisabled() {
|
|
663
|
+
const control = this.#control;
|
|
664
|
+
if (!control) return;
|
|
665
|
+
if (this.hasAttribute("disabled") && !control.disabled) control.disabled = true;
|
|
666
|
+
const disabled = control.disabled;
|
|
667
|
+
if (this.#forced()) return;
|
|
668
|
+
if (disabled !== this.#state.disabled) {
|
|
669
|
+
this.#state = stepControl(this.#state, { type: "disable", disabled }, this.#caps).state;
|
|
670
|
+
this.#render();
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
#applyForced() {
|
|
674
|
+
const forced = this.#forced();
|
|
675
|
+
if (forced) {
|
|
676
|
+
this.#state = FORCED[forced];
|
|
677
|
+
settleControlVisual(this.#visual, this.#state);
|
|
678
|
+
if (forced === "disabled" && this.#control && !this.#control.disabled) this.#control.disabled = true;
|
|
679
|
+
} else {
|
|
680
|
+
this.#state = CONTROL_IDLE;
|
|
681
|
+
this.#syncDisabled();
|
|
682
|
+
}
|
|
683
|
+
this.#render(true);
|
|
684
|
+
}
|
|
685
|
+
#refreshMode(force = false, afterFailure = false) {
|
|
686
|
+
if (!afterFailure) this.#glassBroken = false;
|
|
687
|
+
const mode = effectiveA11y(this.#own);
|
|
688
|
+
let next = presentationFor(mode, this.#glassMode() !== "off");
|
|
689
|
+
if (this.#glassBroken && next.glass) next = { ...next, glass: false, surface: next.frost ? "frosted" : "plain" };
|
|
690
|
+
const changed = force || !this.#mode || !sameA11y(this.#mode, mode) || next.surface !== this.#presentation?.surface;
|
|
691
|
+
this.#mode = mode;
|
|
692
|
+
this.#presentation = next;
|
|
693
|
+
this.#applySize();
|
|
694
|
+
this.setAttribute("data-surface", next.surface);
|
|
695
|
+
this.toggleAttribute("data-contrast", next.contrastBorder);
|
|
696
|
+
this.toggleAttribute("data-frost", next.frost);
|
|
697
|
+
this.setAttribute("data-glass", next.glass ? "on" : "off");
|
|
698
|
+
if (changed) this.#reattachGlass(mode);
|
|
699
|
+
if (this.#forced()) this.#applyForced();
|
|
700
|
+
else this.#render(true);
|
|
701
|
+
}
|
|
702
|
+
#applySize() {
|
|
703
|
+
const size = this.#size();
|
|
704
|
+
const spec = kind === "iconButton" ? iconButtonSize(size) : BUTTON_SIZES[size];
|
|
705
|
+
const set = (name, value) => this.style.setProperty(name, value);
|
|
706
|
+
set("--vk-height", `${spec.height}px`);
|
|
707
|
+
set("--vk-pad-x", `${spec.paddingX}px`);
|
|
708
|
+
set("--vk-icon", `${spec.icon}px`);
|
|
709
|
+
set("--vk-radius", `${spec.radius}px`);
|
|
710
|
+
set("--vk-grow", String(response.grow));
|
|
711
|
+
set("--vk-defocus", String(response.defocus));
|
|
712
|
+
this.setAttribute("data-size", size);
|
|
713
|
+
this.#applySlop();
|
|
714
|
+
}
|
|
715
|
+
#dropGlass() {
|
|
716
|
+
this.#glassToken += 1;
|
|
717
|
+
this.#glass?.destroy();
|
|
718
|
+
this.#glass = null;
|
|
719
|
+
this.#glassKey = "";
|
|
720
|
+
this.#lastMaterialKey = "";
|
|
721
|
+
}
|
|
722
|
+
#reattachGlass(mode) {
|
|
723
|
+
const control = this.#control;
|
|
724
|
+
const want = this.#presentation?.glass === true && control !== null;
|
|
725
|
+
const key = want ? `${this.#glassMode()}|${JSON.stringify(mode)}|${this.#size()}` : "";
|
|
726
|
+
if (key === this.#glassKey) return;
|
|
727
|
+
this.#dropGlass();
|
|
728
|
+
this.#glassKey = key;
|
|
729
|
+
if (!want || !control) return;
|
|
730
|
+
const token = this.#glassToken;
|
|
731
|
+
const sample = this.#sample;
|
|
732
|
+
void attachControlGlass(
|
|
733
|
+
control,
|
|
734
|
+
{
|
|
735
|
+
material: vireglass.VIREGLASS_CONTROL_MATERIAL,
|
|
736
|
+
geometry: this.#geometry(control),
|
|
737
|
+
accessibility: mode,
|
|
738
|
+
onTouch: this.#glassMode() === "touch",
|
|
739
|
+
sample
|
|
740
|
+
},
|
|
741
|
+
() => token === this.#glassToken && this.isConnected
|
|
742
|
+
).then((session) => {
|
|
743
|
+
if (!session) return;
|
|
744
|
+
this.#glass = session;
|
|
745
|
+
if (this.#morph) session.setMorph(this.#morph);
|
|
746
|
+
if (this.#sample !== sample) session.setSample(this.#sample);
|
|
747
|
+
this.#pushMaterial(true);
|
|
748
|
+
this.dispatchEvent(new CustomEvent("vire-glass-ready"));
|
|
749
|
+
}).catch(() => {
|
|
750
|
+
if (token !== this.#glassToken) return;
|
|
751
|
+
this.#glassKey = "";
|
|
752
|
+
this.#glassBroken = true;
|
|
753
|
+
this.#refreshMode(false, true);
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
#pushMaterial(force = false) {
|
|
757
|
+
const glass = this.#glass;
|
|
758
|
+
if (!glass) return;
|
|
759
|
+
const atom = visualAtomState(this.#visual, this.#state);
|
|
760
|
+
const snap = (v) => Math.round(Math.min(Math.max(v, 0), 1) * MATERIAL_STEPS) / MATERIAL_STEPS;
|
|
761
|
+
const quantized = { ...atom, pressed: snap(atom.pressed), hovered: snap(atom.hovered) };
|
|
762
|
+
const key = `${quantized.pressed}|${quantized.hovered}|${quantized.disabled}`;
|
|
763
|
+
if (!force && key === this.#lastMaterialKey) return;
|
|
764
|
+
this.#lastMaterialKey = key;
|
|
765
|
+
const material = atomMaterial(vireglass.VIREGLASS_CONTROL_MATERIAL, kind, quantized);
|
|
766
|
+
glass.setMaterial(material);
|
|
767
|
+
if (this.#glassMode() === "touch" && this.#forced()) glass.setAppear(quantized.pressed);
|
|
768
|
+
}
|
|
769
|
+
#render(immediate = false) {
|
|
770
|
+
if (immediate && this.#forced()) settleControlVisual(this.#visual, this.#state);
|
|
771
|
+
this.#paint();
|
|
772
|
+
if (this.#frame || immediate && this.#forced()) return;
|
|
773
|
+
this.#lastFrame = 0;
|
|
774
|
+
this.#frame = requestAnimationFrame((t) => this.#tick(t));
|
|
775
|
+
}
|
|
776
|
+
#tick(now) {
|
|
777
|
+
this.#frame = 0;
|
|
778
|
+
if (!this.isConnected) return;
|
|
779
|
+
const dt = this.#lastFrame ? Math.min((now - this.#lastFrame) / 1e3, 0.05) : 1 / 60;
|
|
780
|
+
this.#lastFrame = now;
|
|
781
|
+
const moving = stepControlVisual(this.#visual, dt, this.#state, this.#presentation?.instantSprings ?? false);
|
|
782
|
+
this.#paint();
|
|
783
|
+
if (moving) this.#frame = requestAnimationFrame((t) => this.#tick(t));
|
|
784
|
+
}
|
|
785
|
+
#paint() {
|
|
786
|
+
const v = this.#visual;
|
|
787
|
+
const set = (name, value) => this.style.setProperty(name, value.toFixed(3));
|
|
788
|
+
set("--vk-press", v.pressed.x);
|
|
789
|
+
set("--vk-hover", v.hovered.x);
|
|
790
|
+
const body = atomBody(vireglass.VIREGLASS_CONTROL_MATERIAL, visualAtomState(v, this.#state), this.#presentation?.frost ?? false);
|
|
791
|
+
set("--vk-body-alpha", body.alpha);
|
|
792
|
+
set("--vk-body-white", body.white);
|
|
793
|
+
set("--vk-body-lift", body.lift);
|
|
794
|
+
this.toggleAttribute("data-pressed", this.#state.press.by !== null);
|
|
795
|
+
this.toggleAttribute("data-hovered", this.#state.hovered);
|
|
796
|
+
this.toggleAttribute("data-focus", this.#state.focused);
|
|
797
|
+
this.toggleAttribute("data-disabled", this.#state.disabled);
|
|
798
|
+
this.#pushMaterial();
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// src/web/index.ts
|
|
804
|
+
var BUTTON_TAG = "vire-button";
|
|
805
|
+
var ICON_BUTTON_TAG = "vire-icon-button";
|
|
806
|
+
function defineVireElements(options = {}) {
|
|
807
|
+
const registry = options.registry ?? (typeof customElements === "undefined" ? void 0 : customElements);
|
|
808
|
+
if (!registry) return;
|
|
809
|
+
const pairs = [
|
|
810
|
+
[BUTTON_TAG, "button"],
|
|
811
|
+
[ICON_BUTTON_TAG, "iconButton"]
|
|
812
|
+
];
|
|
813
|
+
for (const [tag, kind] of pairs) {
|
|
814
|
+
if (!registry.get(tag)) registry.define(tag, createControlElementClass(kind, { nonce: options.nonce }));
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
exports.BUTTON_TAG = BUTTON_TAG;
|
|
819
|
+
exports.ICON_BUTTON_TAG = ICON_BUTTON_TAG;
|
|
820
|
+
exports.STYLES = STYLES;
|
|
821
|
+
exports.defineVireElements = defineVireElements;
|
|
822
|
+
exports.getA11yOverride = getA11yOverride;
|
|
823
|
+
exports.setA11yOverride = setA11yOverride;
|
|
824
|
+
exports.systemA11y = systemA11y;
|
|
825
|
+
//# sourceMappingURL=web.cjs.map
|
|
826
|
+
//# sourceMappingURL=web.cjs.map
|