vireuikit 0.7.0 → 0.8.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 +52 -5
- package/dist/{chunk-AR2AM3BR.js → chunk-VY5MD3CX.js} +320 -193
- package/dist/chunk-VY5MD3CX.js.map +1 -0
- package/dist/context-DQaAcRq-.d.cts +104 -0
- package/dist/context-DQaAcRq-.d.ts +104 -0
- package/dist/index.cjs +604 -184
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +401 -127
- package/dist/index.d.ts +401 -127
- package/dist/index.js +250 -1
- package/dist/index.js.map +1 -1
- package/dist/web.cjs +297 -99
- package/dist/web.cjs.map +1 -1
- package/dist/web.d.cts +28 -2
- package/dist/web.d.ts +28 -2
- package/dist/web.js +148 -33
- package/dist/web.js.map +1 -1
- package/package.json +1 -1
- package/dist/a11y-D3SS74I3.d.cts +0 -25
- package/dist/a11y-D3SS74I3.d.ts +0 -25
- package/dist/chunk-AR2AM3BR.js.map +0 -1
package/dist/web.cjs
CHANGED
|
@@ -79,6 +79,67 @@ function atomBody(base, state = ATOM_AT_REST, frost = false) {
|
|
|
79
79
|
}
|
|
80
80
|
return { alpha, white, lift };
|
|
81
81
|
}
|
|
82
|
+
var CONTROL_SIZES = ["touch", "small", "medium", "large", "xlarge"];
|
|
83
|
+
var MIN_TOUCH_TARGET_DP = 44;
|
|
84
|
+
var MIN_POINTER_TARGET_DP = 24;
|
|
85
|
+
var capsule = (height, paddingX) => ({
|
|
86
|
+
height,
|
|
87
|
+
paddingX,
|
|
88
|
+
icon: Math.round(height / 2),
|
|
89
|
+
radius: height / 2,
|
|
90
|
+
shape: "capsule"
|
|
91
|
+
});
|
|
92
|
+
var rounded = (height, paddingX) => ({
|
|
93
|
+
height,
|
|
94
|
+
paddingX,
|
|
95
|
+
icon: Math.round(height / 2),
|
|
96
|
+
radius: height / 4,
|
|
97
|
+
shape: "rounded"
|
|
98
|
+
});
|
|
99
|
+
var BUTTON_SIZES = {
|
|
100
|
+
touch: capsule(44, 20),
|
|
101
|
+
small: rounded(24, 10),
|
|
102
|
+
medium: rounded(32, 14),
|
|
103
|
+
large: capsule(40, 18),
|
|
104
|
+
xlarge: capsule(48, 22)
|
|
105
|
+
};
|
|
106
|
+
function iconButtonSize(size) {
|
|
107
|
+
const spec = BUTTON_SIZES[size];
|
|
108
|
+
return { ...spec, width: spec.height, paddingX: 0 };
|
|
109
|
+
}
|
|
110
|
+
var MENU_PADDING = 0.3;
|
|
111
|
+
function menuSize(size) {
|
|
112
|
+
const spec = BUTTON_SIZES[size];
|
|
113
|
+
const padding = Math.round(spec.height * MENU_PADDING);
|
|
114
|
+
return {
|
|
115
|
+
row: spec.height,
|
|
116
|
+
padding,
|
|
117
|
+
itemRadius: spec.radius,
|
|
118
|
+
radius: spec.radius + padding,
|
|
119
|
+
icon: spec.icon,
|
|
120
|
+
labelPad: spec.paddingX
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function defaultSize(input) {
|
|
124
|
+
return input.touch ? "touch" : "medium";
|
|
125
|
+
}
|
|
126
|
+
function hitSlop(bodyDp, minTargetDp) {
|
|
127
|
+
return bodyDp >= minTargetDp ? 0 : (minTargetDp - bodyDp) / 2;
|
|
128
|
+
}
|
|
129
|
+
function minTarget(input) {
|
|
130
|
+
return input.touch ? MIN_TOUCH_TARGET_DP : MIN_POINTER_TARGET_DP;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/kit/adaptive/input.ts
|
|
134
|
+
function sizeTier(input) {
|
|
135
|
+
return defaultSize({ touch: input.primary === "coarse" });
|
|
136
|
+
}
|
|
137
|
+
function hitTarget(input) {
|
|
138
|
+
return minTarget({ touch: input.anyCoarse });
|
|
139
|
+
}
|
|
140
|
+
function hoversWith(pointerType) {
|
|
141
|
+
return pointerType !== "touch";
|
|
142
|
+
}
|
|
82
143
|
|
|
83
144
|
// src/kit/behavior/focus.ts
|
|
84
145
|
function stepFocus(event) {
|
|
@@ -108,8 +169,6 @@ function stepPress(state, event, enabled2) {
|
|
|
108
169
|
}
|
|
109
170
|
|
|
110
171
|
// src/kit/behavior/control.ts
|
|
111
|
-
var TOUCH_INPUT = { hover: false };
|
|
112
|
-
var POINTER_INPUT = { hover: true };
|
|
113
172
|
var CONTROL_IDLE = {
|
|
114
173
|
press: PRESS_IDLE,
|
|
115
174
|
hovered: false,
|
|
@@ -347,56 +406,6 @@ var SINKING = { grow: 0.06, defocus: 1 };
|
|
|
347
406
|
function pressResponse(kind) {
|
|
348
407
|
return atomLift(kind) === 1 ? LIFTING : SINKING;
|
|
349
408
|
}
|
|
350
|
-
var CONTROL_SIZES = ["touch", "small", "medium", "large", "xlarge"];
|
|
351
|
-
var MIN_TOUCH_TARGET_DP = 44;
|
|
352
|
-
var MIN_POINTER_TARGET_DP = 24;
|
|
353
|
-
var capsule = (height, paddingX) => ({
|
|
354
|
-
height,
|
|
355
|
-
paddingX,
|
|
356
|
-
icon: Math.round(height / 2),
|
|
357
|
-
radius: height / 2,
|
|
358
|
-
shape: "capsule"
|
|
359
|
-
});
|
|
360
|
-
var rounded = (height, paddingX) => ({
|
|
361
|
-
height,
|
|
362
|
-
paddingX,
|
|
363
|
-
icon: Math.round(height / 2),
|
|
364
|
-
radius: height / 4,
|
|
365
|
-
shape: "rounded"
|
|
366
|
-
});
|
|
367
|
-
var BUTTON_SIZES = {
|
|
368
|
-
touch: capsule(44, 20),
|
|
369
|
-
small: rounded(24, 10),
|
|
370
|
-
medium: rounded(32, 14),
|
|
371
|
-
large: capsule(40, 18),
|
|
372
|
-
xlarge: capsule(48, 22)
|
|
373
|
-
};
|
|
374
|
-
function iconButtonSize(size) {
|
|
375
|
-
const spec = BUTTON_SIZES[size];
|
|
376
|
-
return { ...spec, width: spec.height, paddingX: 0 };
|
|
377
|
-
}
|
|
378
|
-
var MENU_PADDING = 0.3;
|
|
379
|
-
function menuSize(size) {
|
|
380
|
-
const spec = BUTTON_SIZES[size];
|
|
381
|
-
const padding = Math.round(spec.height * MENU_PADDING);
|
|
382
|
-
return {
|
|
383
|
-
row: spec.height,
|
|
384
|
-
padding,
|
|
385
|
-
itemRadius: spec.radius,
|
|
386
|
-
radius: spec.radius + padding,
|
|
387
|
-
icon: spec.icon,
|
|
388
|
-
labelPad: spec.paddingX
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
function defaultSize(input) {
|
|
392
|
-
return input.touch ? "touch" : "medium";
|
|
393
|
-
}
|
|
394
|
-
function hitSlop(bodyDp, minTargetDp) {
|
|
395
|
-
return bodyDp >= minTargetDp ? 0 : (minTargetDp - bodyDp) / 2;
|
|
396
|
-
}
|
|
397
|
-
function minTarget(input) {
|
|
398
|
-
return input.touch ? MIN_TOUCH_TARGET_DP : MIN_POINTER_TARGET_DP;
|
|
399
|
-
}
|
|
400
409
|
|
|
401
410
|
// src/web/a11y.ts
|
|
402
411
|
var QUERIES = {
|
|
@@ -443,6 +452,184 @@ function effectiveA11y(own) {
|
|
|
443
452
|
return resolveA11y(systemA11y(), merged);
|
|
444
453
|
}
|
|
445
454
|
|
|
455
|
+
// src/kit/geometry.ts
|
|
456
|
+
function intersectRect(a, b) {
|
|
457
|
+
const x = Math.max(a.x, b.x);
|
|
458
|
+
const y = Math.max(a.y, b.y);
|
|
459
|
+
const right = Math.min(a.x + a.width, b.x + b.width);
|
|
460
|
+
const bottom = Math.min(a.y + a.height, b.y + b.height);
|
|
461
|
+
return right > x && bottom > y ? { x, y, width: right - x, height: bottom - y } : null;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// src/kit/adaptive/context.ts
|
|
465
|
+
var POSTURE_FLAT = { kind: "flat" };
|
|
466
|
+
function postureFromSegments(window2, segments) {
|
|
467
|
+
if (segments.length !== 2) return POSTURE_FLAT;
|
|
468
|
+
const [a, b] = [...segments].sort((p, q) => p.x - q.x || p.y - q.y);
|
|
469
|
+
const gapX = b.x - (a.x + a.width);
|
|
470
|
+
if (gapX >= 0 && a.y < b.y + b.height && b.y < a.y + a.height) {
|
|
471
|
+
return { kind: "book", fold: { bounds: { x: a.x + a.width, y: 0, width: gapX, height: window2.height }, occluding: gapX > 0 } };
|
|
472
|
+
}
|
|
473
|
+
const [top, bottom] = [...segments].sort((p, q) => p.y - q.y);
|
|
474
|
+
const gapY = bottom.y - (top.y + top.height);
|
|
475
|
+
if (gapY >= 0) {
|
|
476
|
+
return { kind: "tabletop", fold: { bounds: { x: 0, y: top.y + top.height, width: window2.width, height: gapY }, occluding: gapY > 0 } };
|
|
477
|
+
}
|
|
478
|
+
return POSTURE_FLAT;
|
|
479
|
+
}
|
|
480
|
+
var area = (r) => r ? r.width * r.height : 0;
|
|
481
|
+
function segmentOf(box, segments) {
|
|
482
|
+
const cx = box.x + box.width / 2;
|
|
483
|
+
const cy = box.y + box.height / 2;
|
|
484
|
+
const holding = segments.find((s) => cx >= s.x && cx < s.x + s.width && cy >= s.y && cy < s.y + s.height);
|
|
485
|
+
if (holding) return holding;
|
|
486
|
+
let best;
|
|
487
|
+
let most = 0;
|
|
488
|
+
for (const s of segments) {
|
|
489
|
+
const overlap = area(intersectRect(s, box));
|
|
490
|
+
if (overlap > most) {
|
|
491
|
+
most = overlap;
|
|
492
|
+
best = s;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
if (best) return best;
|
|
496
|
+
let nearest;
|
|
497
|
+
let distance = Number.POSITIVE_INFINITY;
|
|
498
|
+
for (const s of segments) {
|
|
499
|
+
const d = Math.hypot(s.x + s.width / 2 - cx, s.y + s.height / 2 - cy);
|
|
500
|
+
if (d < distance) {
|
|
501
|
+
distance = d;
|
|
502
|
+
nearest = s;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return nearest;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// src/web/environment.ts
|
|
509
|
+
var QUERIES2 = {
|
|
510
|
+
coarse: "(pointer: coarse)",
|
|
511
|
+
anyCoarse: "(any-pointer: coarse)",
|
|
512
|
+
anyHover: "(any-hover: hover)"
|
|
513
|
+
};
|
|
514
|
+
var media = (query) => typeof matchMedia !== "undefined" && matchMedia(query).matches;
|
|
515
|
+
var keyboardSeen = false;
|
|
516
|
+
var inputOverride = {};
|
|
517
|
+
var inputListeners = /* @__PURE__ */ new Set();
|
|
518
|
+
var viewportOverride = null;
|
|
519
|
+
var viewportListeners = /* @__PURE__ */ new Set();
|
|
520
|
+
function systemInput() {
|
|
521
|
+
if (typeof matchMedia === "undefined") return { primary: "fine", anyCoarse: false, hover: true, keyboard: keyboardSeen };
|
|
522
|
+
const coarse = media(QUERIES2.coarse);
|
|
523
|
+
return {
|
|
524
|
+
primary: coarse ? "coarse" : "fine",
|
|
525
|
+
anyCoarse: coarse || media(QUERIES2.anyCoarse),
|
|
526
|
+
hover: media(QUERIES2.anyHover),
|
|
527
|
+
keyboard: keyboardSeen
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
function setInputOverride(next) {
|
|
531
|
+
inputOverride = { ...inputOverride, ...next };
|
|
532
|
+
for (const listener of [...inputListeners]) listener();
|
|
533
|
+
}
|
|
534
|
+
function getInputOverride() {
|
|
535
|
+
return inputOverride;
|
|
536
|
+
}
|
|
537
|
+
function effectiveInput() {
|
|
538
|
+
const system = systemInput();
|
|
539
|
+
return {
|
|
540
|
+
primary: inputOverride.primary ?? system.primary,
|
|
541
|
+
anyCoarse: inputOverride.anyCoarse ?? system.anyCoarse,
|
|
542
|
+
hover: inputOverride.hover ?? system.hover,
|
|
543
|
+
keyboard: inputOverride.keyboard ?? system.keyboard
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
var editable = (target) => target instanceof Element && target.closest('input, textarea, select, [contenteditable]:not([contenteditable="false"])') !== null;
|
|
547
|
+
function onKey(e) {
|
|
548
|
+
const target = e.composedPath()[0] ?? e.target;
|
|
549
|
+
if (keyboardSeen || e.isComposing || e.key === "Unidentified" || e.key === "Process" || editable(target)) return;
|
|
550
|
+
keyboardSeen = true;
|
|
551
|
+
for (const listener of [...inputListeners]) listener();
|
|
552
|
+
}
|
|
553
|
+
function watchInput(onChange) {
|
|
554
|
+
inputListeners.add(onChange);
|
|
555
|
+
const lists = typeof matchMedia === "undefined" ? [] : Object.values(QUERIES2).map((q) => matchMedia(q));
|
|
556
|
+
for (const list of lists) list.addEventListener("change", onChange);
|
|
557
|
+
if (inputListeners.size === 1 && typeof window !== "undefined") window.addEventListener("keydown", onKey, true);
|
|
558
|
+
return () => {
|
|
559
|
+
inputListeners.delete(onChange);
|
|
560
|
+
for (const list of lists) list.removeEventListener("change", onChange);
|
|
561
|
+
if (inputListeners.size === 0 && typeof window !== "undefined") window.removeEventListener("keydown", onKey, true);
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
var pointerLayers = ({ primary, anyCoarse, hover }) => `${primary} ${anyCoarse} ${hover}`;
|
|
565
|
+
function watchPointerInput(onChange) {
|
|
566
|
+
let last2 = pointerLayers(effectiveInput());
|
|
567
|
+
return watchInput(() => {
|
|
568
|
+
const next = pointerLayers(effectiveInput());
|
|
569
|
+
if (next === last2) return;
|
|
570
|
+
last2 = next;
|
|
571
|
+
onChange();
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
function setViewportOverride(next) {
|
|
575
|
+
viewportOverride = next;
|
|
576
|
+
for (const listener of [...viewportListeners]) listener();
|
|
577
|
+
}
|
|
578
|
+
function viewportSegments() {
|
|
579
|
+
if (viewportOverride?.root.isConnected) {
|
|
580
|
+
const r = viewportOverride.root.getBoundingClientRect();
|
|
581
|
+
const viewport2 = { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
582
|
+
const local = viewportOverride.segments ?? [{ x: 0, y: 0, width: r.width, height: r.height }];
|
|
583
|
+
return { viewport: viewport2, segments: local.map((s) => ({ x: s.x + r.x, y: s.y + r.y, width: s.width, height: s.height })) };
|
|
584
|
+
}
|
|
585
|
+
const root = typeof document === "undefined" ? null : document.documentElement;
|
|
586
|
+
const viewport = { x: 0, y: 0, width: root?.clientWidth ?? 0, height: root?.clientHeight ?? 0 };
|
|
587
|
+
const api = typeof window === "undefined" ? null : window.viewport?.segments;
|
|
588
|
+
const segments = api && api.length > 1 ? api.map((s) => ({ x: s.x, y: s.y, width: s.width, height: s.height })) : [viewport];
|
|
589
|
+
return { viewport, segments };
|
|
590
|
+
}
|
|
591
|
+
function watchViewport(onChange) {
|
|
592
|
+
viewportListeners.add(onChange);
|
|
593
|
+
if (typeof window !== "undefined") window.addEventListener("resize", onChange);
|
|
594
|
+
return () => {
|
|
595
|
+
viewportListeners.delete(onChange);
|
|
596
|
+
if (typeof window !== "undefined") window.removeEventListener("resize", onChange);
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
function contextOf(root) {
|
|
600
|
+
const r = root.getBoundingClientRect();
|
|
601
|
+
const window2 = { width: r.width, height: r.height };
|
|
602
|
+
const box = { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
603
|
+
const local = viewportSegments().segments.map((s) => intersectRect(s, box)).filter((s) => s !== null).map((s) => ({ x: s.x - r.x, y: s.y - r.y, width: s.width, height: s.height }));
|
|
604
|
+
return {
|
|
605
|
+
window: window2,
|
|
606
|
+
input: effectiveInput(),
|
|
607
|
+
posture: postureFromSegments(window2, local),
|
|
608
|
+
reduceMotion: effectiveA11y({}).reduceMotion
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
function watchAdaptiveContext(root, onChange) {
|
|
612
|
+
let last2 = "";
|
|
613
|
+
const emit = () => {
|
|
614
|
+
if (!root.isConnected) return;
|
|
615
|
+
const ctx = contextOf(root);
|
|
616
|
+
const key = JSON.stringify(ctx);
|
|
617
|
+
if (key === last2) return;
|
|
618
|
+
last2 = key;
|
|
619
|
+
onChange(ctx);
|
|
620
|
+
};
|
|
621
|
+
const cleanups = [watchInput(emit), watchViewport(emit), watchSystemA11y(emit), watchA11yOverride(emit)];
|
|
622
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
623
|
+
const observer = new ResizeObserver(emit);
|
|
624
|
+
observer.observe(root);
|
|
625
|
+
cleanups.push(() => observer.disconnect());
|
|
626
|
+
}
|
|
627
|
+
emit();
|
|
628
|
+
return () => {
|
|
629
|
+
for (const cleanup of cleanups) cleanup();
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
|
|
446
633
|
// src/web/glass.ts
|
|
447
634
|
async function attachControlGlass(el, params, stillWanted) {
|
|
448
635
|
const { attachGlass, probeBackdrop } = await import('vireglass/dom');
|
|
@@ -482,19 +669,6 @@ async function attachControlGlass(el, params, stillWanted) {
|
|
|
482
669
|
};
|
|
483
670
|
}
|
|
484
671
|
|
|
485
|
-
// src/web/input.ts
|
|
486
|
-
var COARSE = "(pointer: coarse)";
|
|
487
|
-
function isCoarsePointer() {
|
|
488
|
-
return typeof matchMedia !== "undefined" && matchMedia(COARSE).matches;
|
|
489
|
-
}
|
|
490
|
-
function watchCoarsePointer(onChange) {
|
|
491
|
-
if (typeof matchMedia === "undefined") return () => {
|
|
492
|
-
};
|
|
493
|
-
const list = matchMedia(COARSE);
|
|
494
|
-
list.addEventListener("change", onChange);
|
|
495
|
-
return () => list.removeEventListener("change", onChange);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
672
|
// src/web/styles.ts
|
|
499
673
|
var HOST = ":is(vire-button,vire-icon-button)[data-vk]";
|
|
500
674
|
var BODY = `${HOST}>button`;
|
|
@@ -620,13 +794,14 @@ var FORCED = {
|
|
|
620
794
|
};
|
|
621
795
|
var MATERIAL_STEPS = 10;
|
|
622
796
|
var SUPPRESS_MS = 100;
|
|
797
|
+
var HOVER2 = { hover: true };
|
|
798
|
+
var NO_HOVER = { hover: false };
|
|
623
799
|
function createControlElementClass(kind, options = {}) {
|
|
624
800
|
const response = pressResponse(kind);
|
|
625
801
|
return class VireControl extends HTMLElement {
|
|
626
802
|
static observedAttributes = ["glass", "size", "disabled", FORCE_ATTRIBUTE];
|
|
627
803
|
#control = null;
|
|
628
804
|
#state = CONTROL_IDLE;
|
|
629
|
-
#caps = POINTER_INPUT;
|
|
630
805
|
#visual = createControlVisual();
|
|
631
806
|
#own = {};
|
|
632
807
|
#mode = null;
|
|
@@ -681,7 +856,7 @@ function createControlElementClass(kind, options = {}) {
|
|
|
681
856
|
}
|
|
682
857
|
this.#hadStyle.host = this.hasAttribute("style");
|
|
683
858
|
ensureStyles(this, options.nonce);
|
|
684
|
-
this.#cleanups.push(
|
|
859
|
+
this.#cleanups.push(watchPointerInput(() => this.#onInputChange()));
|
|
685
860
|
this.#cleanups.push(watchSystemA11y(() => this.#refreshMode()));
|
|
686
861
|
this.#cleanups.push(watchA11yOverride(() => this.#refreshMode()));
|
|
687
862
|
this.#awaitControl();
|
|
@@ -736,7 +911,6 @@ function createControlElementClass(kind, options = {}) {
|
|
|
736
911
|
this.#control = control;
|
|
737
912
|
this.#hadStyle.control = control.hasAttribute("style");
|
|
738
913
|
this.setAttribute("data-vk", "");
|
|
739
|
-
this.#caps = isCoarsePointer() ? TOUCH_INPUT : POINTER_INPUT;
|
|
740
914
|
this.#listen(control);
|
|
741
915
|
this.#cleanups.push(this.#observeSize(control));
|
|
742
916
|
this.#syncDisabled();
|
|
@@ -748,13 +922,13 @@ function createControlElementClass(kind, options = {}) {
|
|
|
748
922
|
}
|
|
749
923
|
#onInputChange() {
|
|
750
924
|
if (!this.#control) return;
|
|
751
|
-
this.#
|
|
925
|
+
if (this.#state.hovered && !effectiveInput().hover) this.#dispatch({ type: "enter" }, NO_HOVER);
|
|
752
926
|
this.#refreshMode(true);
|
|
753
927
|
}
|
|
754
928
|
#size() {
|
|
755
929
|
const wanted = this.getAttribute("size");
|
|
756
930
|
if (wanted && CONTROL_SIZES.includes(wanted)) return wanted;
|
|
757
|
-
return
|
|
931
|
+
return sizeTier(effectiveInput());
|
|
758
932
|
}
|
|
759
933
|
#glassMode() {
|
|
760
934
|
const wanted = this.getAttribute("glass");
|
|
@@ -765,9 +939,9 @@ function createControlElementClass(kind, options = {}) {
|
|
|
765
939
|
const wanted = this.getAttribute(FORCE_ATTRIBUTE);
|
|
766
940
|
return wanted !== null && Object.hasOwn(FORCED, wanted) ? wanted : null;
|
|
767
941
|
}
|
|
768
|
-
#dispatch(event) {
|
|
942
|
+
#dispatch(event, caps = HOVER2) {
|
|
769
943
|
if (this.#forced()) return false;
|
|
770
|
-
const step = stepControl(this.#state, event,
|
|
944
|
+
const step = stepControl(this.#state, event, caps);
|
|
771
945
|
this.#state = step.state;
|
|
772
946
|
this.#render();
|
|
773
947
|
return step.activated;
|
|
@@ -811,7 +985,7 @@ function createControlElementClass(kind, options = {}) {
|
|
|
811
985
|
if (mine(e)) this.#dispatch({ type: "cancel" });
|
|
812
986
|
});
|
|
813
987
|
on(target, "pointerenter", (e) => {
|
|
814
|
-
if (mine(e)
|
|
988
|
+
if (mine(e)) this.#dispatch({ type: "enter" }, hoversWith(e.pointerType) ? HOVER2 : NO_HOVER);
|
|
815
989
|
});
|
|
816
990
|
on(target, "pointerleave", (e) => {
|
|
817
991
|
if (mine(e) && !control.hasPointerCapture?.(e.pointerId)) this.#dispatch({ type: "leave" });
|
|
@@ -873,7 +1047,7 @@ function createControlElementClass(kind, options = {}) {
|
|
|
873
1047
|
#applySlop() {
|
|
874
1048
|
const control = this.#control;
|
|
875
1049
|
if (!control) return;
|
|
876
|
-
const floor =
|
|
1050
|
+
const floor = hitTarget(effectiveInput());
|
|
877
1051
|
this.#slop = { x: hitSlop(control.offsetWidth, floor), y: hitSlop(control.offsetHeight, floor) };
|
|
878
1052
|
this.style.setProperty("--vk-slop-x", String(this.#slop.x));
|
|
879
1053
|
this.style.setProperty("--vk-slop-y", String(this.#slop.y));
|
|
@@ -885,7 +1059,7 @@ function createControlElementClass(kind, options = {}) {
|
|
|
885
1059
|
const disabled = control.disabled;
|
|
886
1060
|
if (this.#forced()) return;
|
|
887
1061
|
if (disabled !== this.#state.disabled) {
|
|
888
|
-
this.#state = stepControl(this.#state, { type: "disable", disabled },
|
|
1062
|
+
this.#state = stepControl(this.#state, { type: "disable", disabled }, HOVER2).state;
|
|
889
1063
|
this.#render();
|
|
890
1064
|
}
|
|
891
1065
|
}
|
|
@@ -1081,40 +1255,46 @@ var MENU_CORNERS = {
|
|
|
1081
1255
|
"bottom-left": { x: -1, y: 1 },
|
|
1082
1256
|
"bottom-right": { x: 1, y: 1 }
|
|
1083
1257
|
};
|
|
1084
|
-
function menuCorner(trigger,
|
|
1258
|
+
function menuCorner(trigger, region) {
|
|
1259
|
+
const x0 = region.x ?? 0;
|
|
1260
|
+
const y0 = region.y ?? 0;
|
|
1085
1261
|
return {
|
|
1086
|
-
x: trigger.x + trigger.width / 2 <=
|
|
1087
|
-
y: trigger.y + trigger.height / 2 <=
|
|
1262
|
+
x: trigger.x + trigger.width / 2 <= x0 + region.width / 2 ? -1 : 1,
|
|
1263
|
+
y: trigger.y + trigger.height / 2 <= y0 + region.height / 2 ? -1 : 1
|
|
1088
1264
|
};
|
|
1089
1265
|
}
|
|
1090
1266
|
function along(start, length, size, side) {
|
|
1091
1267
|
return side < 0 ? start : start + length - size;
|
|
1092
1268
|
}
|
|
1093
|
-
function fits(at, size,
|
|
1094
|
-
return at >= margin && at + size <=
|
|
1269
|
+
function fits(at, size, lo, hi, margin) {
|
|
1270
|
+
return at >= lo + margin && at + size <= hi - margin;
|
|
1095
1271
|
}
|
|
1096
1272
|
var clamp = (v, lo, hi) => Math.min(Math.max(v, lo), Math.max(lo, hi));
|
|
1097
|
-
function menuPlacement(trigger, menu,
|
|
1273
|
+
function menuPlacement(trigger, menu, region, options = {}) {
|
|
1098
1274
|
const margin = options.margin ?? 8;
|
|
1099
|
-
const
|
|
1100
|
-
const
|
|
1101
|
-
const
|
|
1275
|
+
const x0 = region.x ?? 0;
|
|
1276
|
+
const y0 = region.y ?? 0;
|
|
1277
|
+
const x1 = x0 + region.width;
|
|
1278
|
+
const y1 = y0 + region.height;
|
|
1279
|
+
const width = Math.max(0, Math.min(menu.width, region.width - 2 * margin));
|
|
1280
|
+
const height = Math.max(0, Math.min(menu.height, region.height - 2 * margin));
|
|
1281
|
+
const corner = { ...options.corner ?? menuCorner(trigger, region) };
|
|
1102
1282
|
let x = along(trigger.x, trigger.width, width, corner.x);
|
|
1103
1283
|
let y = along(trigger.y, trigger.height, height, corner.y);
|
|
1104
1284
|
if (!options.corner) {
|
|
1105
1285
|
const fx = along(trigger.x, trigger.width, width, corner.x === -1 ? 1 : -1);
|
|
1106
|
-
if (!fits(x, width,
|
|
1286
|
+
if (!fits(x, width, x0, x1, margin) && fits(fx, width, x0, x1, margin)) {
|
|
1107
1287
|
corner.x = corner.x === -1 ? 1 : -1;
|
|
1108
1288
|
x = fx;
|
|
1109
1289
|
}
|
|
1110
1290
|
const fy = along(trigger.y, trigger.height, height, corner.y === -1 ? 1 : -1);
|
|
1111
|
-
if (!fits(y, height,
|
|
1291
|
+
if (!fits(y, height, y0, y1, margin) && fits(fy, height, y0, y1, margin)) {
|
|
1112
1292
|
corner.y = corner.y === -1 ? 1 : -1;
|
|
1113
1293
|
y = fy;
|
|
1114
1294
|
}
|
|
1115
1295
|
}
|
|
1116
|
-
x = clamp(x, margin,
|
|
1117
|
-
y = clamp(y, margin,
|
|
1296
|
+
x = clamp(x, x0 + margin, x1 - margin - width);
|
|
1297
|
+
y = clamp(y, y0 + margin, y1 - margin - height);
|
|
1118
1298
|
const rect = { x, y, width, height };
|
|
1119
1299
|
return {
|
|
1120
1300
|
rect,
|
|
@@ -1128,7 +1308,7 @@ function menuActivity(phase) {
|
|
|
1128
1308
|
const grow = Math.min(Math.max(phase.grow, 0), 1);
|
|
1129
1309
|
return shrink * (1 - grow);
|
|
1130
1310
|
}
|
|
1131
|
-
function menuSurfaceFrame(trigger, menu, anchor, phase) {
|
|
1311
|
+
function menuSurfaceFrame(trigger, menu, anchor, phase, bounds) {
|
|
1132
1312
|
const frame = growthFrame(
|
|
1133
1313
|
{ geometry: { width: trigger.width, height: trigger.height, cornerRadius: trigger.radius }, center: center(trigger) },
|
|
1134
1314
|
{ geometry: { width: menu.width, height: menu.height, cornerRadius: menu.radius }, center: center(menu) },
|
|
@@ -1136,16 +1316,24 @@ function menuSurfaceFrame(trigger, menu, anchor, phase) {
|
|
|
1136
1316
|
phase
|
|
1137
1317
|
);
|
|
1138
1318
|
const { geometry, center: c } = frame.body;
|
|
1139
|
-
|
|
1319
|
+
let box = {
|
|
1140
1320
|
x: c.x - geometry.width / 2,
|
|
1141
1321
|
y: c.y - geometry.height / 2,
|
|
1142
1322
|
width: geometry.width,
|
|
1143
1323
|
height: geometry.height,
|
|
1144
1324
|
radius: geometry.cornerRadius
|
|
1145
1325
|
};
|
|
1326
|
+
let morph = frame.merge;
|
|
1327
|
+
const held = bounds ? intersectRect(box, bounds) : null;
|
|
1328
|
+
if (held && (held.width < box.width || held.height < box.height)) {
|
|
1329
|
+
const was = center(box);
|
|
1330
|
+
const now = center(held);
|
|
1331
|
+
box = { ...held, radius: Math.min(box.radius, held.width / 2, held.height / 2) };
|
|
1332
|
+
if (morph) morph = { ...morph, offsetX: morph.offsetX + was.x - now.x, offsetY: morph.offsetY + was.y - now.y };
|
|
1333
|
+
}
|
|
1146
1334
|
return {
|
|
1147
1335
|
box,
|
|
1148
|
-
morph
|
|
1336
|
+
morph,
|
|
1149
1337
|
content: { x: menu.x - box.x, y: menu.y - box.y },
|
|
1150
1338
|
ink: frame.ink,
|
|
1151
1339
|
activity: menuActivity(phase)
|
|
@@ -1212,6 +1400,7 @@ function createMenuElementClass(options = {}) {
|
|
|
1212
1400
|
#from = null;
|
|
1213
1401
|
#to = null;
|
|
1214
1402
|
#anchor = null;
|
|
1403
|
+
#region = null;
|
|
1215
1404
|
#natural = null;
|
|
1216
1405
|
#out = false;
|
|
1217
1406
|
#viaPointer = false;
|
|
@@ -1262,7 +1451,7 @@ function createMenuElementClass(options = {}) {
|
|
|
1262
1451
|
}
|
|
1263
1452
|
this.#hadStyle.host = this.hasAttribute("style");
|
|
1264
1453
|
ensureStyles(this, options.nonce);
|
|
1265
|
-
this.#cleanups.push(
|
|
1454
|
+
this.#cleanups.push(watchPointerInput(() => this.#list && this.#refreshMode(true)));
|
|
1266
1455
|
this.#cleanups.push(watchSystemA11y(() => this.#list && this.#refreshMode()));
|
|
1267
1456
|
this.#cleanups.push(watchA11yOverride(() => this.#list && this.#refreshMode()));
|
|
1268
1457
|
this.#awaitParts();
|
|
@@ -1293,7 +1482,7 @@ function createMenuElementClass(options = {}) {
|
|
|
1293
1482
|
this.#state = MENU_CLOSED;
|
|
1294
1483
|
this.#growth = createGrowthState();
|
|
1295
1484
|
this.#out = false;
|
|
1296
|
-
this.#from = this.#to = this.#anchor = null;
|
|
1485
|
+
this.#from = this.#to = this.#anchor = this.#region = null;
|
|
1297
1486
|
this.#natural = null;
|
|
1298
1487
|
this.#held = null;
|
|
1299
1488
|
this.#readySince = null;
|
|
@@ -1532,7 +1721,7 @@ function createMenuElementClass(options = {}) {
|
|
|
1532
1721
|
);
|
|
1533
1722
|
on(root, "scroll", (e) => this.#follow(e), true);
|
|
1534
1723
|
});
|
|
1535
|
-
|
|
1724
|
+
this.#cleanups.push(watchViewport(() => this.#follow()));
|
|
1536
1725
|
if (typeof ResizeObserver !== "undefined") {
|
|
1537
1726
|
const resized = new ResizeObserver(() => this.#out && this.#follow());
|
|
1538
1727
|
resized.observe(this.#carrier ?? trigger);
|
|
@@ -1625,9 +1814,11 @@ function createMenuElementClass(options = {}) {
|
|
|
1625
1814
|
const spec = menuSize(this.#size());
|
|
1626
1815
|
this.#natural ??= this.#measure();
|
|
1627
1816
|
const natural = this.#natural;
|
|
1628
|
-
const viewport = { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight };
|
|
1629
1817
|
const trigger = this.#triggerBox();
|
|
1630
|
-
const
|
|
1818
|
+
const { viewport, segments } = viewportSegments();
|
|
1819
|
+
const region = segmentOf(trigger, segments) ?? viewport;
|
|
1820
|
+
this.#region = region;
|
|
1821
|
+
const placement = menuPlacement(trigger, natural, region, { corner: this.#corner(), margin: VIEWPORT_MARGIN });
|
|
1631
1822
|
this.#from = trigger;
|
|
1632
1823
|
this.#to = { ...placement.rect, radius: spec.radius };
|
|
1633
1824
|
this.#anchor = placement.anchor;
|
|
@@ -1693,7 +1884,7 @@ function createMenuElementClass(options = {}) {
|
|
|
1693
1884
|
this.removeAttribute("data-phase");
|
|
1694
1885
|
this.#out = false;
|
|
1695
1886
|
this.#held = null;
|
|
1696
|
-
this.#from = this.#to = this.#anchor = null;
|
|
1887
|
+
this.#from = this.#to = this.#anchor = this.#region = null;
|
|
1697
1888
|
this.#glass?.setSample(this.#sample);
|
|
1698
1889
|
this.#carrier?.setCarried?.(null);
|
|
1699
1890
|
}
|
|
@@ -1701,7 +1892,7 @@ function createMenuElementClass(options = {}) {
|
|
|
1701
1892
|
const list = this.#list;
|
|
1702
1893
|
if (!list || !this.#out || !this.#from || !this.#to || !this.#anchor) return;
|
|
1703
1894
|
const phase = growthPhase(this.#growth);
|
|
1704
|
-
const f = menuSurfaceFrame(this.#from, this.#to, this.#anchor, phase);
|
|
1895
|
+
const f = menuSurfaceFrame(this.#from, this.#to, this.#anchor, phase, this.#region ?? void 0);
|
|
1705
1896
|
const settled = phase.shrink === 1 && phase.grow === 1;
|
|
1706
1897
|
const inkIn = Math.round(f.ink.incoming * 1e3) / 1e3;
|
|
1707
1898
|
if (this.#state.open && inkIn >= 1) {
|
|
@@ -1781,7 +1972,7 @@ function createMenuElementClass(options = {}) {
|
|
|
1781
1972
|
#size() {
|
|
1782
1973
|
const wanted = this.getAttribute("size");
|
|
1783
1974
|
if (wanted && CONTROL_SIZES.includes(wanted)) return wanted;
|
|
1784
|
-
return
|
|
1975
|
+
return sizeTier(effectiveInput());
|
|
1785
1976
|
}
|
|
1786
1977
|
#wantsGlass() {
|
|
1787
1978
|
const wanted = this.getAttribute("glass");
|
|
@@ -1885,8 +2076,15 @@ exports.ICON_BUTTON_TAG = ICON_BUTTON_TAG;
|
|
|
1885
2076
|
exports.MENU_TAG = MENU_TAG;
|
|
1886
2077
|
exports.STYLES = STYLES;
|
|
1887
2078
|
exports.defineVireElements = defineVireElements;
|
|
2079
|
+
exports.effectiveInput = effectiveInput;
|
|
1888
2080
|
exports.getA11yOverride = getA11yOverride;
|
|
2081
|
+
exports.getInputOverride = getInputOverride;
|
|
1889
2082
|
exports.setA11yOverride = setA11yOverride;
|
|
2083
|
+
exports.setInputOverride = setInputOverride;
|
|
2084
|
+
exports.setViewportOverride = setViewportOverride;
|
|
1890
2085
|
exports.systemA11y = systemA11y;
|
|
2086
|
+
exports.systemInput = systemInput;
|
|
2087
|
+
exports.viewportSegments = viewportSegments;
|
|
2088
|
+
exports.watchAdaptiveContext = watchAdaptiveContext;
|
|
1891
2089
|
//# sourceMappingURL=web.cjs.map
|
|
1892
2090
|
//# sourceMappingURL=web.cjs.map
|