@marianmeres/stuic 3.150.0 → 3.152.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/dist/actions/dim-behind/dim-behind.fixture.svelte +54 -0
- package/dist/actions/dim-behind/dim-behind.fixture.svelte.d.ts +9 -0
- package/dist/actions/dim-behind/dim-behind.svelte.d.ts +10 -0
- package/dist/actions/dim-behind/dim-behind.svelte.js +72 -41
- package/dist/actions/popover/README.md +37 -17
- package/dist/actions/popover/popover.container.fixture.svelte +26 -0
- package/dist/actions/popover/popover.container.fixture.svelte.d.ts +7 -0
- package/dist/actions/popover/popover.svelte.d.ts +10 -0
- package/dist/actions/popover/popover.svelte.js +20 -7
- package/dist/actions/spotlight/spotlight.container.fixture.svelte +33 -0
- package/dist/actions/spotlight/spotlight.container.fixture.svelte.d.ts +7 -0
- package/dist/actions/spotlight/spotlight.svelte.d.ts +9 -0
- package/dist/actions/spotlight/spotlight.svelte.js +95 -37
- package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte +3 -2
- package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte.d.ts +3 -2
- package/dist/components/AlertConfirmPrompt/Current.svelte +44 -10
- package/dist/components/AlertConfirmPrompt/Current.svelte.d.ts +3 -2
- package/dist/components/AlertConfirmPrompt/README.md +29 -27
- package/dist/components/AlertConfirmPrompt/alert-confirm-prompt-stack.svelte.d.ts +8 -0
- package/dist/components/DropdownMenu/DropdownMenu.svelte +14 -7
- package/dist/components/DropdownMenu/README.md +1 -0
- package/dist/components/Float/Float.svelte +21 -0
- package/dist/components/Float/README.md +1 -1
- package/dist/components/HoverExpandableWidth/HoverExpandableWidth.svelte +30 -5
- package/dist/utils/anchor-position.d.ts +12 -3
- package/dist/utils/anchor-position.js +35 -15
- package/dist/utils/containing-block.d.ts +55 -0
- package/dist/utils/containing-block.js +131 -0
- package/dist/utils/overlay-container.d.ts +16 -0
- package/dist/utils/overlay-container.js +12 -0
- package/package.json +12 -12
|
@@ -24,7 +24,10 @@
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<script lang="ts">
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
fixedContainingBlockAncestor,
|
|
29
|
+
fixedContainingBlockRect,
|
|
30
|
+
} from "../../utils/containing-block.js";
|
|
28
31
|
import { DevicePointer } from "../../utils/device-pointer.svelte.js";
|
|
29
32
|
import { waitForNextRepaint, waitForTransitionEnd } from "../../utils/paint.js";
|
|
30
33
|
import { prefersReducedMotion } from "../../utils/prefers-reduced-motion.svelte.js";
|
|
@@ -82,12 +85,34 @@
|
|
|
82
85
|
isExpanded = true;
|
|
83
86
|
isExpanding = true;
|
|
84
87
|
|
|
88
|
+
// Pin the element in place: the inset values below resolve against the
|
|
89
|
+
// containing block once `position: fixed` is applied — the viewport,
|
|
90
|
+
// unless an ancestor (`transform`, `contain: layout|paint`, …)
|
|
91
|
+
// establishes one. Insets are LAYOUT px in the CB's content space, while
|
|
92
|
+
// rects are visual: divide out the accumulated ancestor scale, add the
|
|
93
|
+
// CB's scroll offsets (a fixed element whose CB is a scroll container
|
|
94
|
+
// behaves like an absolute one — it scrolls with the content), and
|
|
95
|
+
// derive bottom/right from the CB size so the top+height+bottom
|
|
96
|
+
// constraint stays exact. With no CB ancestor this reduces to the plain
|
|
97
|
+
// viewport-edge distances.
|
|
85
98
|
box = el.getBoundingClientRect();
|
|
99
|
+
const cbEl = fixedContainingBlockAncestor(el);
|
|
100
|
+
const cb = fixedContainingBlockRect(el);
|
|
101
|
+
const sx =
|
|
102
|
+
el.offsetWidth && Math.abs(box.width - el.offsetWidth) > 1
|
|
103
|
+
? box.width / el.offsetWidth
|
|
104
|
+
: 1;
|
|
105
|
+
const sy =
|
|
106
|
+
el.offsetHeight && Math.abs(box.height - el.offsetHeight) > 1
|
|
107
|
+
? box.height / el.offsetHeight
|
|
108
|
+
: 1;
|
|
109
|
+
const top = (box.top - cb.top) / sy + (cbEl?.scrollTop ?? 0);
|
|
110
|
+
const left = (box.left - cb.left) / sx + (cbEl?.scrollLeft ?? 0);
|
|
86
111
|
const pos = {
|
|
87
|
-
top
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
right:
|
|
112
|
+
top,
|
|
113
|
+
left,
|
|
114
|
+
bottom: cb.height / sy - top - box.height / sy,
|
|
115
|
+
right: cb.width / sx - left - box.width / sx,
|
|
91
116
|
};
|
|
92
117
|
|
|
93
118
|
// <offset-x>, <offset-y>, <blur-radius>, <spread-radius>
|
|
@@ -19,7 +19,11 @@
|
|
|
19
19
|
*/
|
|
20
20
|
export declare function buildPositionTryFallbacks(position: string): string;
|
|
21
21
|
/**
|
|
22
|
-
* Pull an element fully into
|
|
22
|
+
* Pull an element fully into its containing block with a corrective
|
|
23
|
+
* `transform`. For a fixed element that is the viewport — unless an ancestor
|
|
24
|
+
* (`transform`, `contain: layout|paint`, …) establishes a containing block, in
|
|
25
|
+
* which case the element is clamped into that ancestor's box instead (see
|
|
26
|
+
* {@link fixedContainingBlockRect}).
|
|
23
27
|
*
|
|
24
28
|
* This is the backstop for CSS Anchor Positioning: `position-try` can only swap
|
|
25
29
|
* between discrete declared positions and cannot slide a centered annotation
|
|
@@ -36,6 +40,11 @@ export declare function buildPositionTryFallbacks(position: string): string;
|
|
|
36
40
|
* correction applies instantly. The caller owns the element's `transform`.
|
|
37
41
|
*
|
|
38
42
|
* @param el - The (anchored, position:fixed) element to clamp
|
|
39
|
-
* @param margin - Minimum gap from each
|
|
43
|
+
* @param margin - Minimum gap from each containing-block edge, in px (default 8)
|
|
44
|
+
* @param cb - Optional explicit containing-block rect (viewport/visual
|
|
45
|
+
* coordinates). Callers that can measure the CB empirically (e.g. spotlight,
|
|
46
|
+
* via its own `inset: 0` backdrop) pass it to stay self-consistent even
|
|
47
|
+
* where the heuristic walker and the engine disagree (WebKit filter cases);
|
|
48
|
+
* defaults to {@link fixedContainingBlockRect}.
|
|
40
49
|
*/
|
|
41
|
-
export declare function clampIntoViewport(el: HTMLElement, margin?: number): void;
|
|
50
|
+
export declare function clampIntoViewport(el: HTMLElement, margin?: number, cb?: DOMRectReadOnly): void;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Shared helpers for CSS Anchor Positioning based actions (spotlight, popover,
|
|
3
3
|
* tooltip).
|
|
4
4
|
*/
|
|
5
|
+
import { fixedContainingBlockRect } from "./containing-block.js";
|
|
5
6
|
/**
|
|
6
7
|
* Builds the `position-try-fallbacks` value for an anchored element at a given
|
|
7
8
|
* position.
|
|
@@ -28,7 +29,11 @@ export function buildPositionTryFallbacks(position) {
|
|
|
28
29
|
return flips;
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
31
|
-
* Pull an element fully into
|
|
32
|
+
* Pull an element fully into its containing block with a corrective
|
|
33
|
+
* `transform`. For a fixed element that is the viewport — unless an ancestor
|
|
34
|
+
* (`transform`, `contain: layout|paint`, …) establishes a containing block, in
|
|
35
|
+
* which case the element is clamped into that ancestor's box instead (see
|
|
36
|
+
* {@link fixedContainingBlockRect}).
|
|
32
37
|
*
|
|
33
38
|
* This is the backstop for CSS Anchor Positioning: `position-try` can only swap
|
|
34
39
|
* between discrete declared positions and cannot slide a centered annotation
|
|
@@ -45,25 +50,40 @@ export function buildPositionTryFallbacks(position) {
|
|
|
45
50
|
* correction applies instantly. The caller owns the element's `transform`.
|
|
46
51
|
*
|
|
47
52
|
* @param el - The (anchored, position:fixed) element to clamp
|
|
48
|
-
* @param margin - Minimum gap from each
|
|
53
|
+
* @param margin - Minimum gap from each containing-block edge, in px (default 8)
|
|
54
|
+
* @param cb - Optional explicit containing-block rect (viewport/visual
|
|
55
|
+
* coordinates). Callers that can measure the CB empirically (e.g. spotlight,
|
|
56
|
+
* via its own `inset: 0` backdrop) pass it to stay self-consistent even
|
|
57
|
+
* where the heuristic walker and the engine disagree (WebKit filter cases);
|
|
58
|
+
* defaults to {@link fixedContainingBlockRect}.
|
|
49
59
|
*/
|
|
50
|
-
export function clampIntoViewport(el, margin = 8) {
|
|
60
|
+
export function clampIntoViewport(el, margin = 8, cb = fixedContainingBlockRect(el)) {
|
|
51
61
|
// Remove any prior correction so we measure the natural (anchored or
|
|
52
62
|
// left/top) position, then recompute from scratch.
|
|
53
63
|
el.style.transform = "";
|
|
54
64
|
const a = el.getBoundingClientRect();
|
|
55
|
-
const vw = window.innerWidth;
|
|
56
|
-
const vh = window.innerHeight;
|
|
57
65
|
let dx = 0;
|
|
58
66
|
let dy = 0;
|
|
59
|
-
if (a.left < margin)
|
|
60
|
-
dx = margin - a.left;
|
|
61
|
-
else if (a.right >
|
|
62
|
-
dx =
|
|
63
|
-
if (a.top < margin)
|
|
64
|
-
dy = margin - a.top;
|
|
65
|
-
else if (a.bottom >
|
|
66
|
-
dy =
|
|
67
|
-
if (dx || dy)
|
|
68
|
-
|
|
67
|
+
if (a.left < cb.left + margin)
|
|
68
|
+
dx = cb.left + margin - a.left;
|
|
69
|
+
else if (a.right > cb.right - margin)
|
|
70
|
+
dx = cb.right - margin - a.right;
|
|
71
|
+
if (a.top < cb.top + margin)
|
|
72
|
+
dy = cb.top + margin - a.top;
|
|
73
|
+
else if (a.bottom > cb.bottom - margin)
|
|
74
|
+
dy = cb.bottom - margin - a.bottom;
|
|
75
|
+
if (dx || dy) {
|
|
76
|
+
// The deltas above are visual (rect) px, but the translate applies in the
|
|
77
|
+
// element's local space — inside a scaled ancestor (`transform: scale()`
|
|
78
|
+
// zoom/preview wrapper) they differ by the accumulated scale factor.
|
|
79
|
+
// offsetWidth is integer-rounded, so treat sub-pixel differences as
|
|
80
|
+
// "unscaled" (a ratio threshold would misfire on small elements).
|
|
81
|
+
const sx = el.offsetWidth && Math.abs(a.width - el.offsetWidth) > 1
|
|
82
|
+
? a.width / el.offsetWidth
|
|
83
|
+
: 1;
|
|
84
|
+
const sy = el.offsetHeight && Math.abs(a.height - el.offsetHeight) > 1
|
|
85
|
+
? a.height / el.offsetHeight
|
|
86
|
+
: 1;
|
|
87
|
+
el.style.transform = `translate(${dx / sx}px, ${dy / sy}px)`;
|
|
88
|
+
}
|
|
69
89
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for working with the containing block (CB) of `position: fixed`
|
|
3
|
+
* elements.
|
|
4
|
+
*
|
|
5
|
+
* A fixed-positioned element resolves against the viewport UNLESS an ancestor
|
|
6
|
+
* establishes a fixed containing block — via `transform`/`translate`/`rotate`/
|
|
7
|
+
* `scale`/`perspective`/`filter`/`backdrop-filter`, a `will-change` naming any
|
|
8
|
+
* of those, or layout/paint containment (`contain: layout|paint|strict|content`,
|
|
9
|
+
* which `content-visibility: auto` also applies). Overlay code that measures
|
|
10
|
+
* "does this fixed element fit" must therefore compare against the CB rect,
|
|
11
|
+
* not `window.innerWidth/innerHeight` — the two only coincide in the (common)
|
|
12
|
+
* no-such-ancestor case.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Does this element establish a containing block for `position: fixed`
|
|
16
|
+
* descendants?
|
|
17
|
+
*
|
|
18
|
+
* Mirrors floating-ui's battle-tested `isContainingBlock`, with the same two
|
|
19
|
+
* deliberate omissions relative to a naive reading of MDN:
|
|
20
|
+
*
|
|
21
|
+
* - `filter`/`backdrop-filter` are ignored on WebKit: Safari historically does
|
|
22
|
+
* NOT form a fixed CB from them (plain `filter` was only fixed in Safari 26).
|
|
23
|
+
* Misdetecting a CB the browser doesn't honor would break correct layouts;
|
|
24
|
+
* missing one merely preserves the pre-CB-aware behavior.
|
|
25
|
+
* - `container-type` is NOT checked: the CSSWG removed layout containment from
|
|
26
|
+
* it (2024, csswg-drafts#10544) and Chrome 129+/Firefox/Safari all shipped
|
|
27
|
+
* the change, so container queries no longer re-parent fixed descendants.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isFixedContainingBlock(el: Element): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The nearest ancestor of `el` that establishes a containing block for
|
|
32
|
+
* `position: fixed` descendants, or `null` when fixed descendants resolve
|
|
33
|
+
* against the viewport. The walk stops (returning `null`) at top-layer
|
|
34
|
+
* elements — a modal `<dialog>`, an open `[popover]`, a fullscreen element —
|
|
35
|
+
* since the top layer escapes every ancestor containing block by design
|
|
36
|
+
* (unless such an element is itself CB-forming, e.g. a transformed dialog).
|
|
37
|
+
*/
|
|
38
|
+
export declare function fixedContainingBlockAncestor(el: HTMLElement): HTMLElement | null;
|
|
39
|
+
/**
|
|
40
|
+
* The rect that `position: fixed` descendants of `el` actually resolve
|
|
41
|
+
* against, in viewport (visual) coordinates.
|
|
42
|
+
*
|
|
43
|
+
* Walks up from `el`'s parent looking for the nearest containing-block-forming
|
|
44
|
+
* ancestor (see {@link fixedContainingBlockAncestor}) and returns its padding
|
|
45
|
+
* box — per CSS, the CB is the padding box, not the border box. When no such
|
|
46
|
+
* ancestor exists (the overwhelmingly common case) it returns the viewport
|
|
47
|
+
* rect based on `window.innerWidth/innerHeight`, byte-identical to what the
|
|
48
|
+
* pre-CB-aware code measured.
|
|
49
|
+
*
|
|
50
|
+
* Known limitation: for a ROTATED CB ancestor the returned rect is the
|
|
51
|
+
* axis-aligned bounding box of the rotated element — consumers comparing
|
|
52
|
+
* rects (overflow checks, clamps) get an approximation there. Scaled
|
|
53
|
+
* ancestors are handled (border widths are converted to visual px).
|
|
54
|
+
*/
|
|
55
|
+
export declare function fixedContainingBlockRect(el: HTMLElement): DOMRectReadOnly;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for working with the containing block (CB) of `position: fixed`
|
|
3
|
+
* elements.
|
|
4
|
+
*
|
|
5
|
+
* A fixed-positioned element resolves against the viewport UNLESS an ancestor
|
|
6
|
+
* establishes a fixed containing block — via `transform`/`translate`/`rotate`/
|
|
7
|
+
* `scale`/`perspective`/`filter`/`backdrop-filter`, a `will-change` naming any
|
|
8
|
+
* of those, or layout/paint containment (`contain: layout|paint|strict|content`,
|
|
9
|
+
* which `content-visibility: auto` also applies). Overlay code that measures
|
|
10
|
+
* "does this fixed element fit" must therefore compare against the CB rect,
|
|
11
|
+
* not `window.innerWidth/innerHeight` — the two only coincide in the (common)
|
|
12
|
+
* no-such-ancestor case.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* `will-change` values that force a fixed containing block: any property whose
|
|
16
|
+
* non-initial value would form one. (Same set floating-ui checks.)
|
|
17
|
+
*/
|
|
18
|
+
const WILL_CHANGE_RE = /transform|translate|scale|rotate|perspective|filter/;
|
|
19
|
+
/** `contain` values that apply layout and/or paint containment. */
|
|
20
|
+
const CONTAIN_RE = /paint|layout|strict|content/;
|
|
21
|
+
let _isWebKit;
|
|
22
|
+
/**
|
|
23
|
+
* WebKit (Safari) detection — the same probe floating-ui uses. Only Safari
|
|
24
|
+
* supports the `-webkit-` prefixed backdrop-filter.
|
|
25
|
+
*/
|
|
26
|
+
function isWebKit() {
|
|
27
|
+
if (_isWebKit === undefined) {
|
|
28
|
+
_isWebKit =
|
|
29
|
+
typeof CSS !== "undefined" &&
|
|
30
|
+
typeof CSS.supports === "function" &&
|
|
31
|
+
CSS.supports("-webkit-backdrop-filter", "none");
|
|
32
|
+
}
|
|
33
|
+
return _isWebKit;
|
|
34
|
+
}
|
|
35
|
+
function notNone(value) {
|
|
36
|
+
return !!value && value !== "none";
|
|
37
|
+
}
|
|
38
|
+
// Elements promoted to the TOP LAYER (modal dialogs via `showModal()`, open
|
|
39
|
+
// `[popover]`s, fullscreen elements) escape every ancestor containing block by
|
|
40
|
+
// design — their fixed descendants resolve against the viewport again. Each
|
|
41
|
+
// selector is probed separately: an engine that doesn't know one would
|
|
42
|
+
// otherwise reject the whole list.
|
|
43
|
+
const TOP_LAYER_SELECTORS = [":modal", ":popover-open", ":fullscreen"];
|
|
44
|
+
function isTopLayer(el) {
|
|
45
|
+
return TOP_LAYER_SELECTORS.some((s) => {
|
|
46
|
+
try {
|
|
47
|
+
return el.matches(s);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Does this element establish a containing block for `position: fixed`
|
|
56
|
+
* descendants?
|
|
57
|
+
*
|
|
58
|
+
* Mirrors floating-ui's battle-tested `isContainingBlock`, with the same two
|
|
59
|
+
* deliberate omissions relative to a naive reading of MDN:
|
|
60
|
+
*
|
|
61
|
+
* - `filter`/`backdrop-filter` are ignored on WebKit: Safari historically does
|
|
62
|
+
* NOT form a fixed CB from them (plain `filter` was only fixed in Safari 26).
|
|
63
|
+
* Misdetecting a CB the browser doesn't honor would break correct layouts;
|
|
64
|
+
* missing one merely preserves the pre-CB-aware behavior.
|
|
65
|
+
* - `container-type` is NOT checked: the CSSWG removed layout containment from
|
|
66
|
+
* it (2024, csswg-drafts#10544) and Chrome 129+/Firefox/Safari all shipped
|
|
67
|
+
* the change, so container queries no longer re-parent fixed descendants.
|
|
68
|
+
*/
|
|
69
|
+
export function isFixedContainingBlock(el) {
|
|
70
|
+
const s = getComputedStyle(el);
|
|
71
|
+
return (notNone(s.transform) ||
|
|
72
|
+
notNone(s.translate) ||
|
|
73
|
+
notNone(s.rotate) ||
|
|
74
|
+
notNone(s.scale) ||
|
|
75
|
+
notNone(s.perspective) ||
|
|
76
|
+
(!isWebKit() && (notNone(s.filter) || notNone(s.backdropFilter))) ||
|
|
77
|
+
s.contentVisibility === "auto" ||
|
|
78
|
+
WILL_CHANGE_RE.test(s.willChange) ||
|
|
79
|
+
CONTAIN_RE.test(s.contain));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The nearest ancestor of `el` that establishes a containing block for
|
|
83
|
+
* `position: fixed` descendants, or `null` when fixed descendants resolve
|
|
84
|
+
* against the viewport. The walk stops (returning `null`) at top-layer
|
|
85
|
+
* elements — a modal `<dialog>`, an open `[popover]`, a fullscreen element —
|
|
86
|
+
* since the top layer escapes every ancestor containing block by design
|
|
87
|
+
* (unless such an element is itself CB-forming, e.g. a transformed dialog).
|
|
88
|
+
*/
|
|
89
|
+
export function fixedContainingBlockAncestor(el) {
|
|
90
|
+
for (let n = el.parentElement; n; n = n.parentElement) {
|
|
91
|
+
if (isFixedContainingBlock(n))
|
|
92
|
+
return n;
|
|
93
|
+
if (isTopLayer(n))
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The rect that `position: fixed` descendants of `el` actually resolve
|
|
100
|
+
* against, in viewport (visual) coordinates.
|
|
101
|
+
*
|
|
102
|
+
* Walks up from `el`'s parent looking for the nearest containing-block-forming
|
|
103
|
+
* ancestor (see {@link fixedContainingBlockAncestor}) and returns its padding
|
|
104
|
+
* box — per CSS, the CB is the padding box, not the border box. When no such
|
|
105
|
+
* ancestor exists (the overwhelmingly common case) it returns the viewport
|
|
106
|
+
* rect based on `window.innerWidth/innerHeight`, byte-identical to what the
|
|
107
|
+
* pre-CB-aware code measured.
|
|
108
|
+
*
|
|
109
|
+
* Known limitation: for a ROTATED CB ancestor the returned rect is the
|
|
110
|
+
* axis-aligned bounding box of the rotated element — consumers comparing
|
|
111
|
+
* rects (overflow checks, clamps) get an approximation there. Scaled
|
|
112
|
+
* ancestors are handled (border widths are converted to visual px).
|
|
113
|
+
*/
|
|
114
|
+
export function fixedContainingBlockRect(el) {
|
|
115
|
+
const n = fixedContainingBlockAncestor(el);
|
|
116
|
+
if (n) {
|
|
117
|
+
const s = getComputedStyle(n);
|
|
118
|
+
const r = n.getBoundingClientRect();
|
|
119
|
+
// computed border widths are layout px; the rect is visual (post-
|
|
120
|
+
// transform) px — convert via the ancestor's accumulated scale so the
|
|
121
|
+
// inset is correct inside scaled wrappers too
|
|
122
|
+
const sx = n.offsetWidth ? r.width / n.offsetWidth : 1;
|
|
123
|
+
const sy = n.offsetHeight ? r.height / n.offsetHeight : 1;
|
|
124
|
+
const bl = (parseFloat(s.borderLeftWidth) || 0) * sx;
|
|
125
|
+
const bt = (parseFloat(s.borderTopWidth) || 0) * sy;
|
|
126
|
+
const br = (parseFloat(s.borderRightWidth) || 0) * sx;
|
|
127
|
+
const bb = (parseFloat(s.borderBottomWidth) || 0) * sy;
|
|
128
|
+
return new DOMRectReadOnly(r.left + bl, r.top + bt, r.width - bl - br, r.height - bt - bb);
|
|
129
|
+
}
|
|
130
|
+
return new DOMRectReadOnly(0, 0, window.innerWidth, window.innerHeight);
|
|
131
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared bits for overlay actions (`popover`, `spotlight`, `dimBehind`) that
|
|
3
|
+
* can portal their DOM into a consumer-provided container instead of
|
|
4
|
+
* `document.body`.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* The `container` option shape: a concrete element, or a lazy factory (useful
|
|
8
|
+
* when the element does not exist yet at action-setup time). A factory
|
|
9
|
+
* returning `null` means "use the default".
|
|
10
|
+
*/
|
|
11
|
+
export type OverlayContainerOption = HTMLElement | (() => HTMLElement | null);
|
|
12
|
+
/**
|
|
13
|
+
* Resolve a `container` option to an element, or `null` when unset (callers
|
|
14
|
+
* then fall back to their default — typically `document.body`).
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveContainerOption(option: OverlayContainerOption | undefined | null): HTMLElement | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared bits for overlay actions (`popover`, `spotlight`, `dimBehind`) that
|
|
3
|
+
* can portal their DOM into a consumer-provided container instead of
|
|
4
|
+
* `document.body`.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a `container` option to an element, or `null` when unset (callers
|
|
8
|
+
* then fall back to their default — typically `document.body`).
|
|
9
|
+
*/
|
|
10
|
+
export function resolveContainerOption(option) {
|
|
11
|
+
return (typeof option === "function" ? option() : option) ?? null;
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marianmeres/stuic",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.152.0",
|
|
4
4
|
"packageManager": "pnpm@11.5.0",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
@@ -136,15 +136,15 @@
|
|
|
136
136
|
"@codemirror/view": "^6.43.8",
|
|
137
137
|
"@eslint/js": "^9.39.5",
|
|
138
138
|
"@marianmeres/random-human-readable": "^1.10.2",
|
|
139
|
-
"@milkdown/core": "^7.22.
|
|
140
|
-
"@milkdown/ctx": "^7.22.
|
|
141
|
-
"@milkdown/plugin-history": "^7.22.
|
|
142
|
-
"@milkdown/plugin-listener": "^7.22.
|
|
143
|
-
"@milkdown/preset-commonmark": "^7.22.
|
|
144
|
-
"@milkdown/preset-gfm": "^7.22.
|
|
145
|
-
"@milkdown/prose": "^7.22.
|
|
146
|
-
"@milkdown/transformer": "^7.22.
|
|
147
|
-
"@milkdown/utils": "^7.22.
|
|
139
|
+
"@milkdown/core": "^7.22.1",
|
|
140
|
+
"@milkdown/ctx": "^7.22.1",
|
|
141
|
+
"@milkdown/plugin-history": "^7.22.1",
|
|
142
|
+
"@milkdown/plugin-listener": "^7.22.1",
|
|
143
|
+
"@milkdown/preset-commonmark": "^7.22.1",
|
|
144
|
+
"@milkdown/preset-gfm": "^7.22.1",
|
|
145
|
+
"@milkdown/prose": "^7.22.1",
|
|
146
|
+
"@milkdown/transformer": "^7.22.1",
|
|
147
|
+
"@milkdown/utils": "^7.22.1",
|
|
148
148
|
"@sveltejs/adapter-auto": "^4.0.0",
|
|
149
149
|
"@sveltejs/kit": "^2.70.2",
|
|
150
150
|
"@sveltejs/package": "^2.5.8",
|
|
@@ -162,8 +162,8 @@
|
|
|
162
162
|
"prettier": "^3.9.6",
|
|
163
163
|
"prettier-plugin-svelte": "^3.5.2",
|
|
164
164
|
"publint": "^0.3.23",
|
|
165
|
-
"svelte": "^5.56.
|
|
166
|
-
"svelte-check": "^4.7.
|
|
165
|
+
"svelte": "^5.56.9",
|
|
166
|
+
"svelte-check": "^4.7.6",
|
|
167
167
|
"tailwindcss": "^4.3.3",
|
|
168
168
|
"tsx": "^4.23.12",
|
|
169
169
|
"typescript": "^5.9.3",
|