@capgo/capacitor-sheets 8.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +437 -0
- package/dist/angular/index.d.mts +114 -0
- package/dist/angular/index.d.ts +114 -0
- package/dist/angular/index.js +1890 -0
- package/dist/angular/index.js.map +1 -0
- package/dist/angular/index.mjs +1863 -0
- package/dist/angular/index.mjs.map +1 -0
- package/dist/chunk-LAUTMWR7.mjs +261 -0
- package/dist/chunk-LAUTMWR7.mjs.map +1 -0
- package/dist/chunk-YBLI7KN6.mjs +1629 -0
- package/dist/chunk-YBLI7KN6.mjs.map +1 -0
- package/dist/components-4JACDCD4.mjs +48 -0
- package/dist/components-4JACDCD4.mjs.map +1 -0
- package/dist/index.d.mts +513 -0
- package/dist/index.d.ts +513 -0
- package/dist/index.js +2069 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +70 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react/index.d.mts +240 -0
- package/dist/react/index.d.ts +240 -0
- package/dist/react/index.js +1900 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +1871 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/solid/index.d.mts +114 -0
- package/dist/solid/index.d.ts +114 -0
- package/dist/solid/index.js +1890 -0
- package/dist/solid/index.js.map +1 -0
- package/dist/solid/index.mjs +1863 -0
- package/dist/solid/index.mjs.map +1 -0
- package/dist/styles-ZKNWSPZR.mjs +9 -0
- package/dist/styles-ZKNWSPZR.mjs.map +1 -0
- package/dist/svelte/index.d.mts +121 -0
- package/dist/svelte/index.d.ts +121 -0
- package/dist/svelte/index.js +1904 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/svelte/index.mjs +1876 -0
- package/dist/svelte/index.mjs.map +1 -0
- package/dist/vue/index.d.mts +114 -0
- package/dist/vue/index.d.ts +114 -0
- package/dist/vue/index.js +1890 -0
- package/dist/vue/index.js.map +1 -0
- package/dist/vue/index.mjs +1863 -0
- package/dist/vue/index.mjs.map +1 -0
- package/docs/demos/bottom-sheet.webp +0 -0
- package/docs/demos/card.webp +0 -0
- package/docs/demos/detached-sheet.webp +0 -0
- package/docs/demos/lightbox.webp +0 -0
- package/docs/demos/long-sheet.webp +0 -0
- package/docs/demos/page-from-bottom.webp +0 -0
- package/docs/demos/page.webp +0 -0
- package/docs/demos/parallax-page.webp +0 -0
- package/docs/demos/persistent-sheet-with-detent.webp +0 -0
- package/docs/demos/sheet-with-depth.webp +0 -0
- package/docs/demos/sheet-with-detent.webp +0 -0
- package/docs/demos/sheet-with-keyboard.webp +0 -0
- package/docs/demos/sheet-with-stacking.webp +0 -0
- package/docs/demos/sidebar.webp +0 -0
- package/docs/demos/toast.webp +0 -0
- package/docs/demos/top-sheet.webp +0 -0
- package/package.json +162 -0
|
@@ -0,0 +1,1629 @@
|
|
|
1
|
+
import {
|
|
2
|
+
injectCapSheetStyles
|
|
3
|
+
} from "./chunk-LAUTMWR7.mjs";
|
|
4
|
+
|
|
5
|
+
// src/core/utils.ts
|
|
6
|
+
var focusableSelector = [
|
|
7
|
+
"a[href]",
|
|
8
|
+
"area[href]",
|
|
9
|
+
"button:not([disabled])",
|
|
10
|
+
'input:not([disabled]):not([type="hidden"])',
|
|
11
|
+
"select:not([disabled])",
|
|
12
|
+
"textarea:not([disabled])",
|
|
13
|
+
"iframe",
|
|
14
|
+
"object",
|
|
15
|
+
"embed",
|
|
16
|
+
"[contenteditable]",
|
|
17
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
18
|
+
"cap-sheet-handle",
|
|
19
|
+
"cap-sheet-trigger"
|
|
20
|
+
].join(",");
|
|
21
|
+
function clamp(value, min, max) {
|
|
22
|
+
return Math.min(Math.max(value, min), max);
|
|
23
|
+
}
|
|
24
|
+
function parseBoolean(value, defaultValue) {
|
|
25
|
+
if (value === null) return defaultValue;
|
|
26
|
+
if (value === "" || value === "true") return true;
|
|
27
|
+
if (value === "false") return false;
|
|
28
|
+
return defaultValue;
|
|
29
|
+
}
|
|
30
|
+
function parseList(value) {
|
|
31
|
+
return value ? value.split(/[,\s]+/).map((item) => item.trim()).filter(Boolean) : [];
|
|
32
|
+
}
|
|
33
|
+
function parseTracks(value, fallback) {
|
|
34
|
+
const tracks = parseList(value).filter(
|
|
35
|
+
(item) => ["top", "bottom", "left", "right"].includes(item)
|
|
36
|
+
);
|
|
37
|
+
return tracks.length > 0 ? tracks : [fallback];
|
|
38
|
+
}
|
|
39
|
+
function parsePlacement(value) {
|
|
40
|
+
return ["top", "bottom", "left", "right", "center"].includes(value || "") ? value : "bottom";
|
|
41
|
+
}
|
|
42
|
+
function trackForPlacement(placement, tracks) {
|
|
43
|
+
if (placement !== "center" && tracks.includes(placement)) return placement;
|
|
44
|
+
return tracks[0] || (placement === "center" ? "bottom" : placement);
|
|
45
|
+
}
|
|
46
|
+
function isVerticalTrack(track) {
|
|
47
|
+
return track === "top" || track === "bottom";
|
|
48
|
+
}
|
|
49
|
+
function trackSign(track) {
|
|
50
|
+
return track === "bottom" || track === "right" ? 1 : -1;
|
|
51
|
+
}
|
|
52
|
+
function getEmPx(element) {
|
|
53
|
+
if (!element?.ownerDocument.defaultView) return 16;
|
|
54
|
+
const fontSize = element.ownerDocument.defaultView.getComputedStyle(element).fontSize;
|
|
55
|
+
const parsed = Number.parseFloat(fontSize);
|
|
56
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 16;
|
|
57
|
+
}
|
|
58
|
+
function toEm(element, value) {
|
|
59
|
+
return value / getEmPx(element);
|
|
60
|
+
}
|
|
61
|
+
function measureCssLength(length, context, axis) {
|
|
62
|
+
const doc = context.ownerDocument;
|
|
63
|
+
const probe = doc.createElement("div");
|
|
64
|
+
probe.style.position = "absolute";
|
|
65
|
+
probe.style.visibility = "hidden";
|
|
66
|
+
probe.style.pointerEvents = "none";
|
|
67
|
+
probe.style.inset = "0";
|
|
68
|
+
if (axis === "x") {
|
|
69
|
+
probe.style.width = length;
|
|
70
|
+
probe.style.height = "0";
|
|
71
|
+
} else {
|
|
72
|
+
probe.style.height = length;
|
|
73
|
+
probe.style.width = "0";
|
|
74
|
+
}
|
|
75
|
+
context.appendChild(probe);
|
|
76
|
+
const rect = probe.getBoundingClientRect();
|
|
77
|
+
probe.remove();
|
|
78
|
+
return axis === "x" ? rect.width : rect.height;
|
|
79
|
+
}
|
|
80
|
+
function getFocusable(container) {
|
|
81
|
+
return Array.from(container.querySelectorAll(focusableSelector)).filter((element) => {
|
|
82
|
+
if (element.hasAttribute("disabled")) return false;
|
|
83
|
+
if (element.getAttribute("aria-hidden") === "true") return false;
|
|
84
|
+
const rects = element.getClientRects();
|
|
85
|
+
return rects.length > 0;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function dispatch(target, type, detail) {
|
|
89
|
+
target.dispatchEvent(new CustomEvent(type, { bubbles: true, composed: true, detail }));
|
|
90
|
+
}
|
|
91
|
+
function defineElement(name, constructor) {
|
|
92
|
+
if (typeof customElements === "undefined") return;
|
|
93
|
+
if (!customElements.get(name)) {
|
|
94
|
+
customElements.define(name, constructor);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function shouldSkipMotion(settingsSkip) {
|
|
98
|
+
if (settingsSkip === true) return true;
|
|
99
|
+
if (settingsSkip === "auto" && typeof matchMedia !== "undefined") {
|
|
100
|
+
return matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
function createId(prefix) {
|
|
105
|
+
return `${prefix}-${Math.random().toString(36).slice(2, 10)}`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/components/cap-scroll.ts
|
|
109
|
+
var CapScroll = class extends HTMLElement {
|
|
110
|
+
scrollTarget = this;
|
|
111
|
+
connectedCallback() {
|
|
112
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
113
|
+
this.scrollTarget = this;
|
|
114
|
+
this.addEventListener("scroll", this.handleScroll, { passive: true });
|
|
115
|
+
}
|
|
116
|
+
disconnectedCallback() {
|
|
117
|
+
this.removeEventListener("scroll", this.handleScroll);
|
|
118
|
+
}
|
|
119
|
+
/** Return scroll progress from `0` to `1`. */
|
|
120
|
+
getProgress() {
|
|
121
|
+
return this.getAvailableDistance() === 0 ? 0 : clamp(this.getDistance() / this.getAvailableDistance(), 0, 1);
|
|
122
|
+
}
|
|
123
|
+
/** Return traveled distance in CSS pixels. */
|
|
124
|
+
getDistance() {
|
|
125
|
+
return this.axis === "x" ? this.scrollTarget.scrollLeft : this.scrollTarget.scrollTop;
|
|
126
|
+
}
|
|
127
|
+
/** Return available travel distance in CSS pixels. */
|
|
128
|
+
getAvailableDistance() {
|
|
129
|
+
return this.axis === "x" ? Math.max(0, this.scrollTarget.scrollWidth - this.scrollTarget.clientWidth) : Math.max(0, this.scrollTarget.scrollHeight - this.scrollTarget.clientHeight);
|
|
130
|
+
}
|
|
131
|
+
scrollTo(optionsOrX, y) {
|
|
132
|
+
if (typeof optionsOrX === "number") {
|
|
133
|
+
super.scrollTo(optionsOrX, y ?? 0);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (!optionsOrX || "top" in optionsOrX || "left" in optionsOrX) {
|
|
137
|
+
super.scrollTo(optionsOrX);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const travelOptions = optionsOrX;
|
|
141
|
+
const distance = this.resolveDistance(travelOptions.progress, travelOptions.distance);
|
|
142
|
+
this.scrollTarget.scrollTo({
|
|
143
|
+
left: this.axis === "x" ? distance : void 0,
|
|
144
|
+
top: this.axis === "y" ? distance : void 0,
|
|
145
|
+
behavior: travelOptions.behavior
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
scrollBy(optionsOrX, y) {
|
|
149
|
+
if (typeof optionsOrX === "number") {
|
|
150
|
+
super.scrollBy(optionsOrX, y ?? 0);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (!optionsOrX || "top" in optionsOrX || "left" in optionsOrX) {
|
|
154
|
+
super.scrollBy(optionsOrX);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const travelOptions = optionsOrX;
|
|
158
|
+
const distance = this.resolveDistance(travelOptions.progress, travelOptions.distance);
|
|
159
|
+
this.scrollTarget.scrollBy({
|
|
160
|
+
left: this.axis === "x" ? distance : void 0,
|
|
161
|
+
top: this.axis === "y" ? distance : void 0,
|
|
162
|
+
behavior: travelOptions.behavior
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
get axis() {
|
|
166
|
+
return this.getAttribute("axis") === "x" ? "x" : "y";
|
|
167
|
+
}
|
|
168
|
+
resolveDistance(progress, distance) {
|
|
169
|
+
if (distance !== void 0) return distance;
|
|
170
|
+
return clamp(progress ?? 0, 0, 1) * this.getAvailableDistance();
|
|
171
|
+
}
|
|
172
|
+
handleScroll = () => {
|
|
173
|
+
dispatch(this, "cap-scroll", {
|
|
174
|
+
progress: this.getProgress(),
|
|
175
|
+
distance: this.getDistance(),
|
|
176
|
+
availableDistance: this.getAvailableDistance()
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
var CapScrollContent = class extends HTMLElement {
|
|
181
|
+
connectedCallback() {
|
|
182
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// src/core/theme-color.ts
|
|
187
|
+
var baseThemeColor = null;
|
|
188
|
+
var activeDimmerCount = 0;
|
|
189
|
+
function getThemeMeta(documentRef) {
|
|
190
|
+
return documentRef.querySelector('meta[name="theme-color"]');
|
|
191
|
+
}
|
|
192
|
+
function parseHexColor(color) {
|
|
193
|
+
const normalized = color.trim().replace("#", "");
|
|
194
|
+
if (![3, 6].includes(normalized.length)) return null;
|
|
195
|
+
const expanded = normalized.length === 3 ? normalized.split("").map((char) => `${char}${char}`).join("") : normalized;
|
|
196
|
+
const value = Number.parseInt(expanded, 16);
|
|
197
|
+
if (!Number.isFinite(value)) return null;
|
|
198
|
+
return [value >> 16 & 255, value >> 8 & 255, value & 255];
|
|
199
|
+
}
|
|
200
|
+
function parseRgbColor(color) {
|
|
201
|
+
const match = color.match(/rgba?\(([^)]+)\)/i);
|
|
202
|
+
if (!match) return null;
|
|
203
|
+
const values = match[1].split(/[\s,/]+/).map((item) => Number.parseFloat(item)).filter((item) => Number.isFinite(item));
|
|
204
|
+
if (values.length < 3) return null;
|
|
205
|
+
return [values[0], values[1], values[2]];
|
|
206
|
+
}
|
|
207
|
+
function toHex(channel) {
|
|
208
|
+
return Math.round(channel).toString(16).padStart(2, "0");
|
|
209
|
+
}
|
|
210
|
+
function blend(base, overlay, alpha) {
|
|
211
|
+
const baseRgb = parseHexColor(base) || parseRgbColor(base);
|
|
212
|
+
const overlayRgb = parseHexColor(overlay) || parseRgbColor(overlay);
|
|
213
|
+
if (!baseRgb || !overlayRgb) return null;
|
|
214
|
+
const [r, g, b] = baseRgb.map((channel, index) => channel * (1 - alpha) + overlayRgb[index] * alpha);
|
|
215
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
216
|
+
}
|
|
217
|
+
function updateThemeColor(color, documentRef = document) {
|
|
218
|
+
const meta = getThemeMeta(documentRef);
|
|
219
|
+
if (!meta) return;
|
|
220
|
+
if (activeDimmerCount > 0) {
|
|
221
|
+
baseThemeColor = color;
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
meta.content = color;
|
|
225
|
+
}
|
|
226
|
+
function setThemeColorDimming(documentRef, alpha, overlayColor = "rgb(0 0 0)") {
|
|
227
|
+
const meta = getThemeMeta(documentRef);
|
|
228
|
+
if (!meta) return;
|
|
229
|
+
if (baseThemeColor === null) {
|
|
230
|
+
baseThemeColor = meta.content;
|
|
231
|
+
}
|
|
232
|
+
const next = blend(baseThemeColor, overlayColor, alpha);
|
|
233
|
+
if (next) {
|
|
234
|
+
meta.content = next;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function retainThemeColorDimmer() {
|
|
238
|
+
activeDimmerCount += 1;
|
|
239
|
+
}
|
|
240
|
+
function releaseThemeColorDimmer(documentRef) {
|
|
241
|
+
activeDimmerCount = Math.max(0, activeDimmerCount - 1);
|
|
242
|
+
if (activeDimmerCount === 0 && baseThemeColor !== null) {
|
|
243
|
+
const meta = getThemeMeta(documentRef);
|
|
244
|
+
if (meta) {
|
|
245
|
+
meta.content = baseThemeColor;
|
|
246
|
+
}
|
|
247
|
+
baseThemeColor = null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/core/sheet-controller.ts
|
|
252
|
+
var defaultOptions = {
|
|
253
|
+
contentPlacement: "bottom",
|
|
254
|
+
sheetRole: "dialog",
|
|
255
|
+
safeArea: "auto",
|
|
256
|
+
swipe: true,
|
|
257
|
+
swipeDismissal: true,
|
|
258
|
+
swipeOvershoot: true,
|
|
259
|
+
swipeTrap: true,
|
|
260
|
+
inertOutside: true,
|
|
261
|
+
nativeEdgeSwipePrevention: true,
|
|
262
|
+
nativeFocusScrollPrevention: true,
|
|
263
|
+
closeOnOutsideClick: true,
|
|
264
|
+
closeOnEscape: true,
|
|
265
|
+
focusTrap: true,
|
|
266
|
+
restoreFocus: true,
|
|
267
|
+
themeColorDimming: "auto"
|
|
268
|
+
};
|
|
269
|
+
var defaultAnimation = {
|
|
270
|
+
duration: 420,
|
|
271
|
+
easing: "cubic-bezier(0.22, 1, 0.36, 1)",
|
|
272
|
+
skip: "auto",
|
|
273
|
+
contentMove: true
|
|
274
|
+
};
|
|
275
|
+
var stackRegistry = /* @__PURE__ */ new Map();
|
|
276
|
+
function parseNumber(value) {
|
|
277
|
+
if (value === null) return void 0;
|
|
278
|
+
const parsed = Number.parseInt(value, 10);
|
|
279
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
280
|
+
}
|
|
281
|
+
function normalizeDetents(value) {
|
|
282
|
+
if (Array.isArray(value)) return value.filter(Boolean);
|
|
283
|
+
return parseList(value || null);
|
|
284
|
+
}
|
|
285
|
+
var safeAreaEdges = ["top", "bottom", "left", "right"];
|
|
286
|
+
function parseSafeArea(value) {
|
|
287
|
+
if (value === null) return void 0;
|
|
288
|
+
const normalized = value.trim().toLowerCase();
|
|
289
|
+
if (!normalized || normalized === "true" || normalized === "auto" || normalized === "all") return "auto";
|
|
290
|
+
if (normalized === "false" || normalized === "none" || normalized === "off") return "none";
|
|
291
|
+
const edges = parseList(normalized).filter(
|
|
292
|
+
(edge) => safeAreaEdges.includes(edge)
|
|
293
|
+
);
|
|
294
|
+
return edges.length > 0 ? edges : "auto";
|
|
295
|
+
}
|
|
296
|
+
function resolveSafeAreaEdges(value) {
|
|
297
|
+
if (value === false || value === "none") return [];
|
|
298
|
+
if (Array.isArray(value)) return value.filter((edge) => safeAreaEdges.includes(edge));
|
|
299
|
+
return safeAreaEdges;
|
|
300
|
+
}
|
|
301
|
+
function readOptionsFromElement(root) {
|
|
302
|
+
const placement = parsePlacement(root.getAttribute("content-placement"));
|
|
303
|
+
const defaultActiveDetent = parseNumber(root.getAttribute("default-active-detent"));
|
|
304
|
+
const activeDetent = parseNumber(root.getAttribute("active-detent"));
|
|
305
|
+
return {
|
|
306
|
+
componentId: root.getAttribute("component-id") || root.id || void 0,
|
|
307
|
+
stack: root.getAttribute("stack") || void 0,
|
|
308
|
+
defaultPresented: parseBoolean(root.getAttribute("default-presented"), false),
|
|
309
|
+
presented: root.hasAttribute("presented") ? parseBoolean(root.getAttribute("presented"), true) : void 0,
|
|
310
|
+
defaultActiveDetent,
|
|
311
|
+
activeDetent,
|
|
312
|
+
detents: normalizeDetents(root.getAttribute("detents") || void 0),
|
|
313
|
+
sheetRole: root.getAttribute("sheet-role") || defaultOptions.sheetRole,
|
|
314
|
+
contentPlacement: placement,
|
|
315
|
+
safeArea: parseSafeArea(root.getAttribute("safe-area")),
|
|
316
|
+
tracks: parseTracks(root.getAttribute("tracks"), placement === "center" ? "bottom" : placement),
|
|
317
|
+
swipe: parseBoolean(root.getAttribute("swipe"), defaultOptions.swipe),
|
|
318
|
+
swipeDismissal: parseBoolean(root.getAttribute("swipe-dismissal"), defaultOptions.swipeDismissal),
|
|
319
|
+
swipeOvershoot: parseBoolean(root.getAttribute("swipe-overshoot"), defaultOptions.swipeOvershoot),
|
|
320
|
+
swipeTrap: parseBoolean(root.getAttribute("swipe-trap"), defaultOptions.swipeTrap),
|
|
321
|
+
inertOutside: parseBoolean(root.getAttribute("inert-outside"), defaultOptions.inertOutside),
|
|
322
|
+
nativeEdgeSwipePrevention: parseBoolean(
|
|
323
|
+
root.getAttribute("native-edge-swipe-prevention"),
|
|
324
|
+
defaultOptions.nativeEdgeSwipePrevention
|
|
325
|
+
),
|
|
326
|
+
nativeFocusScrollPrevention: parseBoolean(
|
|
327
|
+
root.getAttribute("native-focus-scroll-prevention"),
|
|
328
|
+
defaultOptions.nativeFocusScrollPrevention
|
|
329
|
+
),
|
|
330
|
+
closeOnOutsideClick: parseBoolean(root.getAttribute("close-on-outside-click"), defaultOptions.closeOnOutsideClick),
|
|
331
|
+
closeOnEscape: parseBoolean(root.getAttribute("close-on-escape"), defaultOptions.closeOnEscape),
|
|
332
|
+
focusTrap: parseBoolean(root.getAttribute("focus-trap"), defaultOptions.focusTrap),
|
|
333
|
+
restoreFocus: parseBoolean(root.getAttribute("restore-focus"), defaultOptions.restoreFocus),
|
|
334
|
+
themeColorDimming: root.getAttribute("theme-color-dimming") === "false" ? false : root.getAttribute("theme-color-dimming") === "auto" ? "auto" : defaultOptions.themeColorDimming
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
function resolveAnimation(settings) {
|
|
338
|
+
const preset = settings?.preset || "smooth";
|
|
339
|
+
const presetDefaults = {
|
|
340
|
+
gentle: { duration: 520, easing: "cubic-bezier(0.16, 1, 0.3, 1)" },
|
|
341
|
+
smooth: { duration: defaultAnimation.duration, easing: defaultAnimation.easing },
|
|
342
|
+
snappy: { duration: 260, easing: "cubic-bezier(0.2, 0, 0, 1)" }
|
|
343
|
+
};
|
|
344
|
+
return {
|
|
345
|
+
...defaultAnimation,
|
|
346
|
+
...presetDefaults[preset],
|
|
347
|
+
duration: settings?.duration ?? presetDefaults[preset]?.duration ?? defaultAnimation.duration,
|
|
348
|
+
easing: settings?.easing ?? presetDefaults[preset]?.easing ?? defaultAnimation.easing,
|
|
349
|
+
skip: settings?.skip ?? defaultAnimation.skip,
|
|
350
|
+
contentMove: settings?.contentMove ?? defaultAnimation.contentMove
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
function attributeBoolean(value) {
|
|
354
|
+
return value ? "true" : "false";
|
|
355
|
+
}
|
|
356
|
+
var SheetController = class {
|
|
357
|
+
root;
|
|
358
|
+
id;
|
|
359
|
+
parts = {
|
|
360
|
+
outlets: /* @__PURE__ */ new Set(),
|
|
361
|
+
islands: /* @__PURE__ */ new Set(),
|
|
362
|
+
externalOverlays: /* @__PURE__ */ new Set()
|
|
363
|
+
};
|
|
364
|
+
options;
|
|
365
|
+
presented = false;
|
|
366
|
+
activeDetent = 0;
|
|
367
|
+
status = "idle";
|
|
368
|
+
detentOffsetsPx = [0, 0];
|
|
369
|
+
hiddenOffsetPx = 0;
|
|
370
|
+
currentOffsetPx = 0;
|
|
371
|
+
activeTrack = "bottom";
|
|
372
|
+
pointerTravel = null;
|
|
373
|
+
connected = false;
|
|
374
|
+
lockedScroll = false;
|
|
375
|
+
previousBodyOverflow = "";
|
|
376
|
+
previousBodyTouchAction = "";
|
|
377
|
+
inertedElements = /* @__PURE__ */ new Map();
|
|
378
|
+
previousFocus = null;
|
|
379
|
+
hasThemeDimmer = false;
|
|
380
|
+
stackId = null;
|
|
381
|
+
documentListenersAttached = false;
|
|
382
|
+
viewListenersElement = null;
|
|
383
|
+
visualViewportListenersAttached = false;
|
|
384
|
+
handleVisualViewportResize = () => {
|
|
385
|
+
const view = this.parts.view;
|
|
386
|
+
const visualViewport = this.root.ownerDocument.defaultView?.visualViewport;
|
|
387
|
+
if (!view) return;
|
|
388
|
+
if (!visualViewport || this.options.nativeFocusScrollPrevention === false) {
|
|
389
|
+
view.style.setProperty("--cap-sheet-keyboard-offset", "0em");
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const layoutHeight = this.root.ownerDocument.documentElement.clientHeight;
|
|
393
|
+
const keyboardOffset = Math.max(0, layoutHeight - visualViewport.height - visualViewport.offsetTop);
|
|
394
|
+
view.style.setProperty("--cap-sheet-keyboard-offset", `${toEm(view, keyboardOffset)}em`);
|
|
395
|
+
};
|
|
396
|
+
handleDocumentKeyDown = (event) => {
|
|
397
|
+
if (!this.presented) return;
|
|
398
|
+
if (event.key === "Escape" && this.options.closeOnEscape !== false) {
|
|
399
|
+
event.preventDefault();
|
|
400
|
+
void this.dismiss({ source: "escape" });
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
if (event.key === "Tab" && this.options.focusTrap !== false) {
|
|
404
|
+
this.trapFocus(event);
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
handleViewClick = (event) => {
|
|
408
|
+
if (!this.presented || this.options.closeOnOutsideClick === false) return;
|
|
409
|
+
if (event.target === this.parts.view || event.target === this.parts.backdrop) {
|
|
410
|
+
void this.dismiss({ source: "outside" });
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
handlePointerDown = (event) => {
|
|
414
|
+
if (!this.presented || this.options.swipe === false || this.options.contentPlacement === "center") return;
|
|
415
|
+
if (!(event.target instanceof Element)) return;
|
|
416
|
+
if (!this.parts.content?.contains(event.target) && event.target !== this.parts.backdrop) return;
|
|
417
|
+
if (this.options.nativeEdgeSwipePrevention !== false && this.isNativeEdgePointer(event)) {
|
|
418
|
+
event.preventDefault();
|
|
419
|
+
}
|
|
420
|
+
this.remeasure();
|
|
421
|
+
this.pointerTravel = {
|
|
422
|
+
id: event.pointerId,
|
|
423
|
+
startOffsetPx: this.currentOffsetPx,
|
|
424
|
+
startX: event.clientX,
|
|
425
|
+
startY: event.clientY,
|
|
426
|
+
lastX: event.clientX,
|
|
427
|
+
lastY: event.clientY,
|
|
428
|
+
lastTime: performance.now(),
|
|
429
|
+
velocity: 0,
|
|
430
|
+
dragging: false
|
|
431
|
+
};
|
|
432
|
+
};
|
|
433
|
+
handlePointerMove = (event) => {
|
|
434
|
+
const travel = this.pointerTravel;
|
|
435
|
+
if (travel?.id !== event.pointerId) return;
|
|
436
|
+
const axis = isVerticalTrack(this.activeTrack) ? "y" : "x";
|
|
437
|
+
const current = axis === "y" ? event.clientY : event.clientX;
|
|
438
|
+
const start = axis === "y" ? travel.startY : travel.startX;
|
|
439
|
+
const delta = current - start;
|
|
440
|
+
const crossDelta = axis === "y" ? event.clientX - travel.startX : event.clientY - travel.startY;
|
|
441
|
+
if (!travel.dragging) {
|
|
442
|
+
if (Math.abs(delta) < 6 || Math.abs(crossDelta) > Math.abs(delta) * 1.25) return;
|
|
443
|
+
travel.dragging = true;
|
|
444
|
+
event.currentTarget?.setPointerCapture?.(event.pointerId);
|
|
445
|
+
this.setStatus("dragging");
|
|
446
|
+
dispatch(this.root, "cap-sheet-drag-start", this.getTravelEvent());
|
|
447
|
+
}
|
|
448
|
+
if (this.options.swipeTrap !== false) {
|
|
449
|
+
event.preventDefault();
|
|
450
|
+
}
|
|
451
|
+
const now = performance.now();
|
|
452
|
+
const previous = axis === "y" ? travel.lastY : travel.lastX;
|
|
453
|
+
const elapsed = Math.max(now - travel.lastTime, 1);
|
|
454
|
+
travel.velocity = (current - previous) / elapsed * 1e3;
|
|
455
|
+
travel.lastX = event.clientX;
|
|
456
|
+
travel.lastY = event.clientY;
|
|
457
|
+
travel.lastTime = now;
|
|
458
|
+
const nextOffset = this.limitOffset(travel.startOffsetPx + delta);
|
|
459
|
+
this.applyOffset(nextOffset, "dragging");
|
|
460
|
+
};
|
|
461
|
+
handlePointerUp = (event) => {
|
|
462
|
+
const travel = this.pointerTravel;
|
|
463
|
+
if (travel?.id !== event.pointerId) return;
|
|
464
|
+
const currentTarget = event.currentTarget;
|
|
465
|
+
if (currentTarget?.hasPointerCapture?.(event.pointerId)) {
|
|
466
|
+
currentTarget.releasePointerCapture(event.pointerId);
|
|
467
|
+
}
|
|
468
|
+
this.pointerTravel = null;
|
|
469
|
+
if (!travel.dragging) return;
|
|
470
|
+
const nearest = this.nearestDetentForOffset(this.currentOffsetPx, travel.velocity);
|
|
471
|
+
dispatch(this.root, "cap-sheet-drag-end", this.getTravelEvent());
|
|
472
|
+
if (nearest === 0 && this.options.swipeDismissal !== false) {
|
|
473
|
+
void this.dismiss({ source: "gesture" });
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
void this.stepTo(nearest, { source: "gesture" });
|
|
477
|
+
};
|
|
478
|
+
handleWheel = (event) => {
|
|
479
|
+
if (!this.presented || this.options.swipe === false || this.options.contentPlacement === "center") return;
|
|
480
|
+
if (!(event.target instanceof Element)) return;
|
|
481
|
+
if (!this.parts.content?.contains(event.target) && event.target !== this.parts.backdrop) return;
|
|
482
|
+
const delta = isVerticalTrack(this.activeTrack) ? event.deltaY : event.deltaX;
|
|
483
|
+
if (Math.abs(delta) < 1) return;
|
|
484
|
+
const nextOffset = this.limitOffset(this.currentOffsetPx + delta);
|
|
485
|
+
if (Math.abs(nextOffset - this.currentOffsetPx) < 0.5) return;
|
|
486
|
+
event.preventDefault();
|
|
487
|
+
this.applyOffset(nextOffset, "dragging");
|
|
488
|
+
window.clearTimeout(this.root.__capWheelSettle);
|
|
489
|
+
this.root.__capWheelSettle = window.setTimeout(() => {
|
|
490
|
+
const nearest = this.nearestDetentForOffset(this.currentOffsetPx, delta * 10);
|
|
491
|
+
if (nearest === 0 && this.options.swipeDismissal !== false) {
|
|
492
|
+
void this.dismiss({ source: "gesture" });
|
|
493
|
+
} else {
|
|
494
|
+
void this.stepTo(nearest, { source: "gesture" });
|
|
495
|
+
}
|
|
496
|
+
}, 120);
|
|
497
|
+
};
|
|
498
|
+
constructor(root) {
|
|
499
|
+
this.root = root;
|
|
500
|
+
this.options = readOptionsFromElement(root);
|
|
501
|
+
this.id = this.options.componentId || root.id || createId("cap-sheet");
|
|
502
|
+
if (!root.id) root.id = this.id;
|
|
503
|
+
}
|
|
504
|
+
/** Connect the controller to the DOM and initialize current state. */
|
|
505
|
+
connect() {
|
|
506
|
+
if (this.connected) return;
|
|
507
|
+
this.connected = true;
|
|
508
|
+
this.configure(readOptionsFromElement(this.root));
|
|
509
|
+
const nextPresented = this.options.presented ?? this.options.defaultPresented ?? false;
|
|
510
|
+
this.activeDetent = this.resolveInitialDetent();
|
|
511
|
+
this.presented = nextPresented;
|
|
512
|
+
this.setStatus("idle");
|
|
513
|
+
this.remeasure();
|
|
514
|
+
this.applyOffset(
|
|
515
|
+
nextPresented ? this.detentOffsetsPx[this.activeDetent] || 0 : this.detentOffsetsPx[0] || 0,
|
|
516
|
+
"idle"
|
|
517
|
+
);
|
|
518
|
+
this.updateDomState(false);
|
|
519
|
+
this.addGlobalListeners();
|
|
520
|
+
this.registerStack();
|
|
521
|
+
}
|
|
522
|
+
/** Disconnect listeners and restore outside DOM state. */
|
|
523
|
+
disconnect() {
|
|
524
|
+
this.connected = false;
|
|
525
|
+
this.removeGlobalListeners();
|
|
526
|
+
this.unlockPage();
|
|
527
|
+
this.clearInert();
|
|
528
|
+
this.releaseThemeDimmer();
|
|
529
|
+
this.unregisterStack();
|
|
530
|
+
}
|
|
531
|
+
/** Update options from attributes or setup helpers. */
|
|
532
|
+
configure(options) {
|
|
533
|
+
this.options = {
|
|
534
|
+
...defaultOptions,
|
|
535
|
+
...this.options,
|
|
536
|
+
...options,
|
|
537
|
+
detents: normalizeDetents(options.detents ?? this.options.detents)
|
|
538
|
+
};
|
|
539
|
+
const placement = this.options.contentPlacement || defaultOptions.contentPlacement;
|
|
540
|
+
const tracks = Array.isArray(this.options.tracks) ? this.options.tracks : this.options.tracks ? [this.options.tracks] : [placement === "center" ? "bottom" : placement];
|
|
541
|
+
this.activeTrack = trackForPlacement(placement, tracks);
|
|
542
|
+
this.parts.view?.setAttribute("content-placement", placement);
|
|
543
|
+
this.parts.view?.setAttribute("role", this.options.sheetRole || "dialog");
|
|
544
|
+
this.applySafeArea();
|
|
545
|
+
this.handleVisualViewportResize();
|
|
546
|
+
if (this.parts.content) {
|
|
547
|
+
this.parts.content.setAttribute("aria-modal", attributeBoolean(this.options.inertOutside !== false));
|
|
548
|
+
}
|
|
549
|
+
this.linkAccessibleNames();
|
|
550
|
+
this.registerStack();
|
|
551
|
+
}
|
|
552
|
+
/** Register a view, backdrop, content, or semantic part. */
|
|
553
|
+
registerPart(part, element) {
|
|
554
|
+
this.parts[part] = element;
|
|
555
|
+
this.configure(this.options);
|
|
556
|
+
if (this.connected && part === "view") {
|
|
557
|
+
this.addViewListeners();
|
|
558
|
+
this.addVisualViewportListeners();
|
|
559
|
+
this.handleVisualViewportResize();
|
|
560
|
+
}
|
|
561
|
+
this.remeasure();
|
|
562
|
+
this.applyOffset(
|
|
563
|
+
this.presented ? this.detentOffsetsPx[this.activeDetent] || 0 : this.detentOffsetsPx[0] || this.hiddenOffsetPx,
|
|
564
|
+
this.status
|
|
565
|
+
);
|
|
566
|
+
this.updateDomState(this.presented);
|
|
567
|
+
}
|
|
568
|
+
/** Unregister a view, backdrop, content, or semantic part. */
|
|
569
|
+
unregisterPart(part, element) {
|
|
570
|
+
if (this.parts[part] === element) {
|
|
571
|
+
if (part === "view") this.removeViewListeners();
|
|
572
|
+
this.parts[part] = void 0;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
/** Register an outlet animated by sheet progress. */
|
|
576
|
+
registerOutlet(element) {
|
|
577
|
+
this.parts.outlets.add(element);
|
|
578
|
+
this.updateOutletProgress();
|
|
579
|
+
}
|
|
580
|
+
/** Unregister an outlet. */
|
|
581
|
+
unregisterOutlet(element) {
|
|
582
|
+
this.parts.outlets.delete(element);
|
|
583
|
+
}
|
|
584
|
+
/** Register an outside island that remains interactive with inert outside enabled. */
|
|
585
|
+
registerIsland(element) {
|
|
586
|
+
this.parts.islands.add(element);
|
|
587
|
+
if (this.presented) this.applyInert();
|
|
588
|
+
}
|
|
589
|
+
/** Unregister an outside island. */
|
|
590
|
+
unregisterIsland(element) {
|
|
591
|
+
this.parts.islands.delete(element);
|
|
592
|
+
if (this.presented) this.applyInert();
|
|
593
|
+
}
|
|
594
|
+
/** Present the sheet. */
|
|
595
|
+
async present(options = {}) {
|
|
596
|
+
this.remeasure();
|
|
597
|
+
if (this.presented) {
|
|
598
|
+
await this.stepTo(options.detent ?? this.activeDetent, options);
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
this.previousFocus = this.root.ownerDocument.activeElement;
|
|
602
|
+
this.presented = true;
|
|
603
|
+
this.activeDetent = clamp(options.detent ?? this.resolveInitialDetent(), 1, this.detentOffsetsPx.length - 1);
|
|
604
|
+
this.updateDomState(true);
|
|
605
|
+
this.lockPage();
|
|
606
|
+
this.applyInert();
|
|
607
|
+
this.retainThemeDimmer();
|
|
608
|
+
this.setStatus("entering");
|
|
609
|
+
dispatch(this.root, "cap-sheet-present", this.getTravelEvent());
|
|
610
|
+
await this.animateTo(this.detentOffsetsPx[this.activeDetent] || 0, {
|
|
611
|
+
...this.options.enteringAnimationSettings || {},
|
|
612
|
+
...options.animation || {}
|
|
613
|
+
});
|
|
614
|
+
this.setStatus("idle");
|
|
615
|
+
this.focusInitialElement();
|
|
616
|
+
this.emitPresentedChange(true, options.source || "programmatic");
|
|
617
|
+
this.emitActiveDetentChange(this.activeDetent, 0);
|
|
618
|
+
this.updateStack();
|
|
619
|
+
}
|
|
620
|
+
/** Dismiss the sheet. */
|
|
621
|
+
async dismiss(options = {}) {
|
|
622
|
+
if (!this.presented) return;
|
|
623
|
+
this.remeasure();
|
|
624
|
+
const previous = this.activeDetent;
|
|
625
|
+
this.presented = false;
|
|
626
|
+
this.activeDetent = 0;
|
|
627
|
+
this.setStatus("exiting");
|
|
628
|
+
dispatch(this.root, "cap-sheet-dismiss", this.getTravelEvent());
|
|
629
|
+
await this.animateTo(this.detentOffsetsPx[0] || this.hiddenOffsetPx, {
|
|
630
|
+
...this.options.exitingAnimationSettings || {},
|
|
631
|
+
...options.animation || {}
|
|
632
|
+
});
|
|
633
|
+
this.setStatus("idle");
|
|
634
|
+
this.updateDomState(false);
|
|
635
|
+
this.unlockPage();
|
|
636
|
+
this.clearInert();
|
|
637
|
+
this.releaseThemeDimmer();
|
|
638
|
+
this.restoreFocus();
|
|
639
|
+
this.emitPresentedChange(false, options.source || "programmatic");
|
|
640
|
+
this.emitActiveDetentChange(0, previous);
|
|
641
|
+
this.updateStack();
|
|
642
|
+
}
|
|
643
|
+
/** Toggle presentation state. */
|
|
644
|
+
async toggle(options = {}) {
|
|
645
|
+
if (this.presented) {
|
|
646
|
+
await this.dismiss(options);
|
|
647
|
+
} else {
|
|
648
|
+
await this.present(options);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
/** Step to a specific detent index. */
|
|
652
|
+
async stepTo(detent, options = {}) {
|
|
653
|
+
this.remeasure();
|
|
654
|
+
const target = clamp(detent, this.options.swipeDismissal === false ? 1 : 0, this.detentOffsetsPx.length - 1);
|
|
655
|
+
if (target === 0) {
|
|
656
|
+
await this.dismiss(options);
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
if (!this.presented) {
|
|
660
|
+
await this.present({ ...options, detent: target });
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
const previous = this.activeDetent;
|
|
664
|
+
this.activeDetent = target;
|
|
665
|
+
this.setStatus("settling");
|
|
666
|
+
await this.animateTo(this.detentOffsetsPx[target] || 0, {
|
|
667
|
+
...this.options.steppingAnimationSettings || {},
|
|
668
|
+
...options.animation || {}
|
|
669
|
+
});
|
|
670
|
+
this.setStatus("idle");
|
|
671
|
+
if (previous !== target) {
|
|
672
|
+
this.emitActiveDetentChange(target, previous);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
/** Step up or down one detent. */
|
|
676
|
+
async step(direction = "up", options = {}) {
|
|
677
|
+
const delta = direction === "up" ? 1 : -1;
|
|
678
|
+
await this.stepTo(this.activeDetent + delta, options);
|
|
679
|
+
}
|
|
680
|
+
/** Recalculate content size and detent offsets. */
|
|
681
|
+
remeasure() {
|
|
682
|
+
const content = this.parts.content;
|
|
683
|
+
if (!content) return;
|
|
684
|
+
const placement = this.options.contentPlacement || "bottom";
|
|
685
|
+
if (placement === "center") {
|
|
686
|
+
this.hiddenOffsetPx = 0;
|
|
687
|
+
this.detentOffsetsPx = [0, 0];
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
const view = this.parts.view;
|
|
691
|
+
const shouldMeasureHiddenView = Boolean(view?.hidden);
|
|
692
|
+
const previousVisibility = view?.style.visibility || "";
|
|
693
|
+
const previousPointerEvents = view?.style.pointerEvents || "";
|
|
694
|
+
if (view && shouldMeasureHiddenView) {
|
|
695
|
+
view.hidden = false;
|
|
696
|
+
view.style.visibility = "hidden";
|
|
697
|
+
view.style.pointerEvents = "none";
|
|
698
|
+
}
|
|
699
|
+
try {
|
|
700
|
+
const track = this.activeTrack;
|
|
701
|
+
const sign = trackSign(track);
|
|
702
|
+
const axis = isVerticalTrack(track) ? "y" : "x";
|
|
703
|
+
const rect = content.getBoundingClientRect();
|
|
704
|
+
const size = axis === "y" ? rect.height : rect.width;
|
|
705
|
+
this.hiddenOffsetPx = Math.max(size, 1) * sign;
|
|
706
|
+
const detents = normalizeDetents(this.options.detents);
|
|
707
|
+
const offsets = [this.hiddenOffsetPx];
|
|
708
|
+
for (const detent of detents) {
|
|
709
|
+
const visible = measureCssLength(detent, content, axis);
|
|
710
|
+
const offset = Math.max(Math.abs(this.hiddenOffsetPx) - visible, 0) * sign;
|
|
711
|
+
offsets.push(offset);
|
|
712
|
+
}
|
|
713
|
+
offsets.push(0);
|
|
714
|
+
this.detentOffsetsPx = offsets;
|
|
715
|
+
this.activeDetent = clamp(this.activeDetent, this.options.swipeDismissal === false ? 1 : 0, offsets.length - 1);
|
|
716
|
+
dispatch(this.root, "cap-sheet-travel-range-change", {
|
|
717
|
+
offsets: offsets.map((offset) => toEm(content, offset)),
|
|
718
|
+
count: offsets.length
|
|
719
|
+
});
|
|
720
|
+
} finally {
|
|
721
|
+
if (view && shouldMeasureHiddenView) {
|
|
722
|
+
view.hidden = true;
|
|
723
|
+
view.style.visibility = previousVisibility;
|
|
724
|
+
view.style.pointerEvents = previousPointerEvents;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
/** Read current normalized travel details. */
|
|
729
|
+
getTravelEvent() {
|
|
730
|
+
const progress = this.getProgressForOffset(this.currentOffsetPx);
|
|
731
|
+
return {
|
|
732
|
+
progress,
|
|
733
|
+
activeDetent: this.activeDetent,
|
|
734
|
+
offset: toEm(this.parts.content || this.root, this.currentOffsetPx),
|
|
735
|
+
status: this.status
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
resolveInitialDetent() {
|
|
739
|
+
const detents = normalizeDetents(this.options.detents);
|
|
740
|
+
const last = detents.length + 1;
|
|
741
|
+
const configured = this.options.activeDetent ?? this.options.defaultActiveDetent;
|
|
742
|
+
if (configured !== void 0) return clamp(configured, 1, last);
|
|
743
|
+
return detents.length > 0 ? 1 : last;
|
|
744
|
+
}
|
|
745
|
+
applyOffset(offsetPx, status) {
|
|
746
|
+
this.currentOffsetPx = offsetPx;
|
|
747
|
+
this.setStatus(status);
|
|
748
|
+
const content = this.parts.content;
|
|
749
|
+
const backdrop = this.parts.backdrop;
|
|
750
|
+
const view = this.parts.view;
|
|
751
|
+
const placement = this.options.contentPlacement || "bottom";
|
|
752
|
+
const progress = this.getProgressForOffset(offsetPx);
|
|
753
|
+
if (content) {
|
|
754
|
+
if (placement === "center") {
|
|
755
|
+
const scale = 0.96 + progress * 0.04;
|
|
756
|
+
content.style.transform = `translate3d(0, 0, 0) scale(${scale})`;
|
|
757
|
+
content.style.opacity = String(progress);
|
|
758
|
+
} else {
|
|
759
|
+
const offsetEm = toEm(content, offsetPx);
|
|
760
|
+
const x = isVerticalTrack(this.activeTrack) ? "0" : `${offsetEm}em`;
|
|
761
|
+
const y = isVerticalTrack(this.activeTrack) ? `${offsetEm}em` : "0";
|
|
762
|
+
content.style.transform = `translate3d(${x}, ${y}, 0)`;
|
|
763
|
+
content.style.opacity = "1";
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
if (backdrop) {
|
|
767
|
+
backdrop.style.opacity = String(
|
|
768
|
+
progress * Number.parseFloat(getComputedStyle(backdrop).getPropertyValue("--cap-sheet-backdrop-opacity") || "0.44")
|
|
769
|
+
);
|
|
770
|
+
backdrop.style.pointerEvents = progress > 0.01 && !this.hasInteractiveOutside() ? "auto" : "none";
|
|
771
|
+
}
|
|
772
|
+
if (view) {
|
|
773
|
+
view.style.pointerEvents = progress > 0.01 && !this.hasInteractiveOutside() ? "auto" : "none";
|
|
774
|
+
view.dataset.presented = this.presented ? "true" : "false";
|
|
775
|
+
view.dataset.status = status;
|
|
776
|
+
view.dataset.outsideInteractive = this.hasInteractiveOutside() ? "true" : "false";
|
|
777
|
+
}
|
|
778
|
+
this.applyOutletAnimations(progress);
|
|
779
|
+
this.updateThemeDimming(progress);
|
|
780
|
+
dispatch(this.root, "cap-sheet-travel", this.getTravelEvent());
|
|
781
|
+
}
|
|
782
|
+
async animateTo(targetOffsetPx, settings) {
|
|
783
|
+
const content = this.parts.content;
|
|
784
|
+
const backdrop = this.parts.backdrop;
|
|
785
|
+
const resolved = resolveAnimation(settings);
|
|
786
|
+
if (!content || shouldSkipMotion(resolved.skip)) {
|
|
787
|
+
this.applyOffset(targetOffsetPx, "idle");
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
const startOffset = this.currentOffsetPx;
|
|
791
|
+
const fromProgress = this.getProgressForOffset(startOffset);
|
|
792
|
+
const toProgress = this.getProgressForOffset(targetOffsetPx);
|
|
793
|
+
const duration = Math.max(0, resolved.duration);
|
|
794
|
+
const axis = isVerticalTrack(this.activeTrack) ? "y" : "x";
|
|
795
|
+
const fromEm = toEm(content, startOffset);
|
|
796
|
+
const targetEm = toEm(content, targetOffsetPx);
|
|
797
|
+
const fromTransform = this.options.contentPlacement === "center" ? `translate3d(0, 0, 0) scale(${0.96 + fromProgress * 0.04})` : axis === "y" ? `translate3d(0, ${fromEm}em, 0)` : `translate3d(${fromEm}em, 0, 0)`;
|
|
798
|
+
const toTransform = this.options.contentPlacement === "center" ? `translate3d(0, 0, 0) scale(${0.96 + toProgress * 0.04})` : axis === "y" ? `translate3d(0, ${targetEm}em, 0)` : `translate3d(${targetEm}em, 0, 0)`;
|
|
799
|
+
const contentAnimation = resolved.contentMove ? content.animate(
|
|
800
|
+
[
|
|
801
|
+
{ transform: fromTransform, opacity: this.options.contentPlacement === "center" ? fromProgress : 1 },
|
|
802
|
+
{ transform: toTransform, opacity: this.options.contentPlacement === "center" ? toProgress : 1 }
|
|
803
|
+
],
|
|
804
|
+
{ duration, easing: resolved.easing, fill: "both" }
|
|
805
|
+
) : null;
|
|
806
|
+
const backdropOpacity = backdrop ? Number.parseFloat(getComputedStyle(backdrop).getPropertyValue("--cap-sheet-backdrop-opacity") || "0.44") : 0;
|
|
807
|
+
const backdropAnimation = backdrop?.animate(
|
|
808
|
+
[{ opacity: fromProgress * backdropOpacity }, { opacity: toProgress * backdropOpacity }],
|
|
809
|
+
{ duration, easing: resolved.easing, fill: "both" }
|
|
810
|
+
);
|
|
811
|
+
const started = performance.now();
|
|
812
|
+
let frame;
|
|
813
|
+
const tick = () => {
|
|
814
|
+
const progress = duration === 0 ? 1 : clamp((performance.now() - started) / duration, 0, 1);
|
|
815
|
+
const offset = startOffset + (targetOffsetPx - startOffset) * progress;
|
|
816
|
+
this.currentOffsetPx = offset;
|
|
817
|
+
this.applyOutletAnimations(this.getProgressForOffset(offset));
|
|
818
|
+
this.updateThemeDimming(this.getProgressForOffset(offset));
|
|
819
|
+
dispatch(this.root, "cap-sheet-travel", this.getTravelEvent());
|
|
820
|
+
if (progress < 1) frame = requestAnimationFrame(tick);
|
|
821
|
+
};
|
|
822
|
+
frame = requestAnimationFrame(tick);
|
|
823
|
+
await Promise.allSettled([
|
|
824
|
+
contentAnimation?.finished,
|
|
825
|
+
backdropAnimation ? backdropAnimation.finished : Promise.resolve()
|
|
826
|
+
]);
|
|
827
|
+
cancelAnimationFrame(frame);
|
|
828
|
+
contentAnimation?.cancel();
|
|
829
|
+
backdropAnimation?.cancel();
|
|
830
|
+
this.applyOffset(targetOffsetPx, "idle");
|
|
831
|
+
}
|
|
832
|
+
getProgressForOffset(offsetPx) {
|
|
833
|
+
if (this.options.contentPlacement === "center") {
|
|
834
|
+
return this.presented ? 1 : 0;
|
|
835
|
+
}
|
|
836
|
+
const hidden = Math.abs(this.hiddenOffsetPx) || 1;
|
|
837
|
+
return clamp(1 - Math.abs(offsetPx) / hidden, 0, 1);
|
|
838
|
+
}
|
|
839
|
+
limitOffset(offsetPx) {
|
|
840
|
+
const sign = trackSign(this.activeTrack);
|
|
841
|
+
const maxAbs = Math.abs(this.hiddenOffsetPx);
|
|
842
|
+
const min = sign < 0 ? -maxAbs : 0;
|
|
843
|
+
const max = sign < 0 ? 0 : maxAbs;
|
|
844
|
+
if (this.options.swipeOvershoot === false) return clamp(offsetPx, min, max);
|
|
845
|
+
if (offsetPx < min) return min + (offsetPx - min) * 0.18;
|
|
846
|
+
if (offsetPx > max) return max + (offsetPx - max) * 0.18;
|
|
847
|
+
return offsetPx;
|
|
848
|
+
}
|
|
849
|
+
nearestDetentForOffset(offsetPx, velocity) {
|
|
850
|
+
const sign = trackSign(this.activeTrack);
|
|
851
|
+
const fling = Math.abs(velocity) > 700 ? Math.sign(velocity) * sign : 0;
|
|
852
|
+
if (fling > 0) return Math.max(0, this.activeDetent - 1);
|
|
853
|
+
if (fling < 0) return Math.min(this.detentOffsetsPx.length - 1, this.activeDetent + 1);
|
|
854
|
+
let nearest = 0;
|
|
855
|
+
let nearestDistance = Number.POSITIVE_INFINITY;
|
|
856
|
+
this.detentOffsetsPx.forEach((offset, index) => {
|
|
857
|
+
if (index === 0 && this.options.swipeDismissal === false) return;
|
|
858
|
+
const distance = Math.abs(offset - offsetPx);
|
|
859
|
+
if (distance < nearestDistance) {
|
|
860
|
+
nearest = index;
|
|
861
|
+
nearestDistance = distance;
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
return nearest;
|
|
865
|
+
}
|
|
866
|
+
hasInteractiveOutside() {
|
|
867
|
+
return this.options.inertOutside === false && this.options.closeOnOutsideClick === false;
|
|
868
|
+
}
|
|
869
|
+
isNativeEdgePointer(event) {
|
|
870
|
+
const view = this.parts.view;
|
|
871
|
+
if (!view) return false;
|
|
872
|
+
const rect = view.getBoundingClientRect();
|
|
873
|
+
const edgeSize = Math.max(20, rect.width * 0.04);
|
|
874
|
+
return event.clientX - rect.left <= edgeSize || rect.right - event.clientX <= edgeSize || event.clientY - rect.top <= edgeSize || rect.bottom - event.clientY <= edgeSize;
|
|
875
|
+
}
|
|
876
|
+
applySafeArea() {
|
|
877
|
+
const view = this.parts.view;
|
|
878
|
+
if (!view) return;
|
|
879
|
+
const edges = new Set(resolveSafeAreaEdges(this.options.safeArea));
|
|
880
|
+
view.dataset.safeArea = edges.size > 0 ? Array.from(edges).join(" ") : "none";
|
|
881
|
+
for (const edge of safeAreaEdges) {
|
|
882
|
+
view.style.setProperty(
|
|
883
|
+
`--cap-sheet-applied-safe-area-${edge}`,
|
|
884
|
+
edges.has(edge) ? `var(--cap-sheet-safe-area-${edge})` : "0em"
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
addGlobalListeners() {
|
|
889
|
+
const doc = this.root.ownerDocument;
|
|
890
|
+
if (!this.documentListenersAttached) {
|
|
891
|
+
doc.addEventListener("keydown", this.handleDocumentKeyDown);
|
|
892
|
+
this.documentListenersAttached = true;
|
|
893
|
+
}
|
|
894
|
+
this.addViewListeners();
|
|
895
|
+
this.addVisualViewportListeners();
|
|
896
|
+
}
|
|
897
|
+
removeGlobalListeners() {
|
|
898
|
+
const doc = this.root.ownerDocument;
|
|
899
|
+
if (this.documentListenersAttached) {
|
|
900
|
+
doc.removeEventListener("keydown", this.handleDocumentKeyDown);
|
|
901
|
+
this.documentListenersAttached = false;
|
|
902
|
+
}
|
|
903
|
+
this.removeViewListeners();
|
|
904
|
+
this.removeVisualViewportListeners();
|
|
905
|
+
}
|
|
906
|
+
addViewListeners() {
|
|
907
|
+
const view = this.parts.view;
|
|
908
|
+
if (!view || this.viewListenersElement === view) return;
|
|
909
|
+
this.removeViewListeners();
|
|
910
|
+
view.addEventListener("click", this.handleViewClick);
|
|
911
|
+
view.addEventListener("pointerdown", this.handlePointerDown);
|
|
912
|
+
view.addEventListener("pointermove", this.handlePointerMove, { passive: false });
|
|
913
|
+
view.addEventListener("pointerup", this.handlePointerUp);
|
|
914
|
+
view.addEventListener("pointercancel", this.handlePointerUp);
|
|
915
|
+
view.addEventListener("wheel", this.handleWheel, { passive: false });
|
|
916
|
+
this.viewListenersElement = view;
|
|
917
|
+
}
|
|
918
|
+
removeViewListeners() {
|
|
919
|
+
const view = this.viewListenersElement;
|
|
920
|
+
if (!view) return;
|
|
921
|
+
view.removeEventListener("click", this.handleViewClick);
|
|
922
|
+
view.removeEventListener("pointerdown", this.handlePointerDown);
|
|
923
|
+
view.removeEventListener("pointermove", this.handlePointerMove);
|
|
924
|
+
view.removeEventListener("pointerup", this.handlePointerUp);
|
|
925
|
+
view.removeEventListener("pointercancel", this.handlePointerUp);
|
|
926
|
+
view.removeEventListener("wheel", this.handleWheel);
|
|
927
|
+
this.viewListenersElement = null;
|
|
928
|
+
}
|
|
929
|
+
addVisualViewportListeners() {
|
|
930
|
+
const visualViewport = this.root.ownerDocument.defaultView?.visualViewport;
|
|
931
|
+
if (!visualViewport || this.visualViewportListenersAttached) return;
|
|
932
|
+
visualViewport.addEventListener("resize", this.handleVisualViewportResize);
|
|
933
|
+
visualViewport.addEventListener("scroll", this.handleVisualViewportResize);
|
|
934
|
+
this.visualViewportListenersAttached = true;
|
|
935
|
+
this.handleVisualViewportResize();
|
|
936
|
+
}
|
|
937
|
+
removeVisualViewportListeners() {
|
|
938
|
+
const visualViewport = this.root.ownerDocument.defaultView?.visualViewport;
|
|
939
|
+
if (!visualViewport || !this.visualViewportListenersAttached) return;
|
|
940
|
+
visualViewport.removeEventListener("resize", this.handleVisualViewportResize);
|
|
941
|
+
visualViewport.removeEventListener("scroll", this.handleVisualViewportResize);
|
|
942
|
+
this.visualViewportListenersAttached = false;
|
|
943
|
+
}
|
|
944
|
+
updateDomState(presented) {
|
|
945
|
+
const view = this.parts.view;
|
|
946
|
+
const content = this.parts.content;
|
|
947
|
+
if (view) {
|
|
948
|
+
view.hidden = !presented && Math.abs(this.currentOffsetPx) === Math.abs(this.detentOffsetsPx[0] || 0);
|
|
949
|
+
view.dataset.presented = presented ? "true" : "false";
|
|
950
|
+
view.dataset.status = this.status;
|
|
951
|
+
view.style.setProperty("--cap-sheet-z-index", String(this.getStackZIndex()));
|
|
952
|
+
}
|
|
953
|
+
if (content) {
|
|
954
|
+
content.setAttribute("aria-hidden", attributeBoolean(!presented));
|
|
955
|
+
content.setAttribute("tabindex", content.getAttribute("tabindex") || "-1");
|
|
956
|
+
}
|
|
957
|
+
this.root.toggleAttribute("presented", presented);
|
|
958
|
+
}
|
|
959
|
+
linkAccessibleNames() {
|
|
960
|
+
if (!this.parts.content) return;
|
|
961
|
+
if (this.parts.title) {
|
|
962
|
+
if (!this.parts.title.id) this.parts.title.id = createId("cap-sheet-title");
|
|
963
|
+
this.parts.content.setAttribute("aria-labelledby", this.parts.title.id);
|
|
964
|
+
}
|
|
965
|
+
if (this.parts.description) {
|
|
966
|
+
if (!this.parts.description.id) this.parts.description.id = createId("cap-sheet-description");
|
|
967
|
+
this.parts.content.setAttribute("aria-describedby", this.parts.description.id);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
focusInitialElement() {
|
|
971
|
+
const content = this.parts.content;
|
|
972
|
+
if (!content) return;
|
|
973
|
+
const target = this.parts.autoFocusTarget || content.querySelector("cap-auto-focus-target, [autofocus]");
|
|
974
|
+
const focusable = target || getFocusable(content)[0] || content;
|
|
975
|
+
requestAnimationFrame(() => focusable.focus({ preventScroll: this.options.nativeFocusScrollPrevention !== false }));
|
|
976
|
+
}
|
|
977
|
+
restoreFocus() {
|
|
978
|
+
if (this.options.restoreFocus === false) return;
|
|
979
|
+
if (this.previousFocus instanceof HTMLElement && this.previousFocus.isConnected) {
|
|
980
|
+
this.previousFocus.focus({ preventScroll: true });
|
|
981
|
+
}
|
|
982
|
+
this.previousFocus = null;
|
|
983
|
+
}
|
|
984
|
+
trapFocus(event) {
|
|
985
|
+
const content = this.parts.content;
|
|
986
|
+
if (!content) return;
|
|
987
|
+
const focusable = getFocusable(content);
|
|
988
|
+
if (focusable.length === 0) {
|
|
989
|
+
event.preventDefault();
|
|
990
|
+
content.focus({ preventScroll: true });
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
const first = focusable[0];
|
|
994
|
+
const last = focusable[focusable.length - 1];
|
|
995
|
+
const active = this.root.ownerDocument.activeElement;
|
|
996
|
+
if (event.shiftKey && active === first) {
|
|
997
|
+
event.preventDefault();
|
|
998
|
+
last.focus({ preventScroll: true });
|
|
999
|
+
} else if (!event.shiftKey && active === last) {
|
|
1000
|
+
event.preventDefault();
|
|
1001
|
+
first.focus({ preventScroll: true });
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
lockPage() {
|
|
1005
|
+
if (this.lockedScroll) return;
|
|
1006
|
+
const body = this.root.ownerDocument.body;
|
|
1007
|
+
this.previousBodyOverflow = body.style.overflow;
|
|
1008
|
+
this.previousBodyTouchAction = body.style.touchAction;
|
|
1009
|
+
body.dataset.capSheetScrollLocked = "true";
|
|
1010
|
+
body.style.overflow = "hidden";
|
|
1011
|
+
body.style.touchAction = "none";
|
|
1012
|
+
this.lockedScroll = true;
|
|
1013
|
+
}
|
|
1014
|
+
unlockPage() {
|
|
1015
|
+
if (!this.lockedScroll) return;
|
|
1016
|
+
const body = this.root.ownerDocument.body;
|
|
1017
|
+
delete body.dataset.capSheetScrollLocked;
|
|
1018
|
+
body.style.overflow = this.previousBodyOverflow;
|
|
1019
|
+
body.style.touchAction = this.previousBodyTouchAction;
|
|
1020
|
+
this.previousBodyOverflow = "";
|
|
1021
|
+
this.previousBodyTouchAction = "";
|
|
1022
|
+
this.lockedScroll = false;
|
|
1023
|
+
}
|
|
1024
|
+
applyInert() {
|
|
1025
|
+
if (this.options.inertOutside === false || !this.parts.view) return;
|
|
1026
|
+
const body = this.root.ownerDocument.body;
|
|
1027
|
+
const allowed = /* @__PURE__ */ new Set([this.parts.view, ...this.parts.islands, ...this.parts.externalOverlays]);
|
|
1028
|
+
this.clearInert();
|
|
1029
|
+
for (const child of Array.from(body.children)) {
|
|
1030
|
+
if (!(child instanceof HTMLElement)) continue;
|
|
1031
|
+
const isAllowed = Array.from(allowed).some((element) => child === element || child.contains(element));
|
|
1032
|
+
if (isAllowed) continue;
|
|
1033
|
+
this.inertedElements.set(child, child.getAttribute("aria-hidden"));
|
|
1034
|
+
child.inert = true;
|
|
1035
|
+
child.setAttribute("aria-hidden", "true");
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
clearInert() {
|
|
1039
|
+
for (const [element, ariaHidden] of this.inertedElements) {
|
|
1040
|
+
element.inert = false;
|
|
1041
|
+
if (ariaHidden === null) {
|
|
1042
|
+
element.removeAttribute("aria-hidden");
|
|
1043
|
+
} else {
|
|
1044
|
+
element.setAttribute("aria-hidden", ariaHidden);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
this.inertedElements.clear();
|
|
1048
|
+
}
|
|
1049
|
+
retainThemeDimmer() {
|
|
1050
|
+
if (this.hasThemeDimmer || this.options.themeColorDimming !== "auto") return;
|
|
1051
|
+
this.hasThemeDimmer = true;
|
|
1052
|
+
retainThemeColorDimmer();
|
|
1053
|
+
}
|
|
1054
|
+
releaseThemeDimmer() {
|
|
1055
|
+
if (!this.hasThemeDimmer) return;
|
|
1056
|
+
this.hasThemeDimmer = false;
|
|
1057
|
+
releaseThemeColorDimmer(this.root.ownerDocument);
|
|
1058
|
+
}
|
|
1059
|
+
updateThemeDimming(progress) {
|
|
1060
|
+
if (!this.hasThemeDimmer || this.options.themeColorDimming !== "auto") return;
|
|
1061
|
+
const color = this.parts.backdrop ? getComputedStyle(this.parts.backdrop).getPropertyValue("--cap-sheet-backdrop-color") || "rgb(0 0 0)" : "rgb(0 0 0)";
|
|
1062
|
+
setThemeColorDimming(this.root.ownerDocument, clamp(progress * 0.44, 0, 0.7), color);
|
|
1063
|
+
}
|
|
1064
|
+
applyOutletAnimations(progress) {
|
|
1065
|
+
this.updateOutletProgress();
|
|
1066
|
+
for (const outlet of this.parts.outlets) {
|
|
1067
|
+
const animation = outlet.travelAnimation;
|
|
1068
|
+
if (!animation) continue;
|
|
1069
|
+
for (const [property, value] of Object.entries(animation)) {
|
|
1070
|
+
if (value === null || value === void 0) continue;
|
|
1071
|
+
if (Array.isArray(value)) {
|
|
1072
|
+
outlet.style.setProperty(property, tween(value[0], value[1], progress));
|
|
1073
|
+
} else if (typeof value === "function") {
|
|
1074
|
+
const next = value({ progress, tween: (start, end) => tween(start, end, progress) });
|
|
1075
|
+
if (next !== null && next !== void 0) outlet.style.setProperty(property, String(next));
|
|
1076
|
+
} else {
|
|
1077
|
+
outlet.style.setProperty(property, String(value));
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
updateOutletProgress() {
|
|
1083
|
+
const travel = this.getTravelEvent();
|
|
1084
|
+
for (const outlet of this.parts.outlets) {
|
|
1085
|
+
outlet.style.setProperty("--cap-sheet-progress", String(travel.progress));
|
|
1086
|
+
outlet.style.setProperty("--cap-sheet-offset", `${travel.offset}em`);
|
|
1087
|
+
outlet.dataset.sheetStatus = travel.status;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
emitPresentedChange(presented, source) {
|
|
1091
|
+
const detail = { presented, source };
|
|
1092
|
+
dispatch(this.root, "cap-sheet-presented-change", detail);
|
|
1093
|
+
}
|
|
1094
|
+
emitActiveDetentChange(activeDetent, previousActiveDetent) {
|
|
1095
|
+
const detail = { activeDetent, previousActiveDetent };
|
|
1096
|
+
dispatch(this.root, "cap-sheet-active-detent-change", detail);
|
|
1097
|
+
}
|
|
1098
|
+
registerStack() {
|
|
1099
|
+
const nextStack = this.options.stack || this.root.closest("cap-sheet-stack")?.id || null;
|
|
1100
|
+
if (this.stackId === nextStack) return;
|
|
1101
|
+
this.unregisterStack();
|
|
1102
|
+
this.stackId = nextStack;
|
|
1103
|
+
if (!nextStack) return;
|
|
1104
|
+
const stack = stackRegistry.get(nextStack) || /* @__PURE__ */ new Set();
|
|
1105
|
+
stack.add(this);
|
|
1106
|
+
stackRegistry.set(nextStack, stack);
|
|
1107
|
+
this.updateStack();
|
|
1108
|
+
}
|
|
1109
|
+
unregisterStack() {
|
|
1110
|
+
if (!this.stackId) return;
|
|
1111
|
+
const stack = stackRegistry.get(this.stackId);
|
|
1112
|
+
stack?.delete(this);
|
|
1113
|
+
if (stack?.size === 0) stackRegistry.delete(this.stackId);
|
|
1114
|
+
this.stackId = null;
|
|
1115
|
+
}
|
|
1116
|
+
getStackZIndex() {
|
|
1117
|
+
if (!this.stackId) return 1e3;
|
|
1118
|
+
const stack = Array.from(stackRegistry.get(this.stackId) || []);
|
|
1119
|
+
const index = stack.indexOf(this);
|
|
1120
|
+
return 1e3 + Math.max(index, 0) * 2;
|
|
1121
|
+
}
|
|
1122
|
+
updateStack() {
|
|
1123
|
+
if (!this.stackId) return;
|
|
1124
|
+
const stack = Array.from(stackRegistry.get(this.stackId) || []);
|
|
1125
|
+
const presented = stack.filter((controller) => controller.presented);
|
|
1126
|
+
stack.forEach((controller, index) => {
|
|
1127
|
+
controller.parts.view?.style.setProperty("--cap-sheet-z-index", String(1e3 + index * 2));
|
|
1128
|
+
const depth = presented.length - presented.indexOf(controller) - 1;
|
|
1129
|
+
const stackDepth = Math.max(depth, 0);
|
|
1130
|
+
controller.parts.content?.style.setProperty("--cap-sheet-stack-depth", String(stackDepth));
|
|
1131
|
+
controller.applyStackingAnimations(stackDepth);
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
applyStackingAnimations(depth) {
|
|
1135
|
+
const progress = clamp(depth, 0, 4) / 4;
|
|
1136
|
+
for (const outlet of this.parts.outlets) {
|
|
1137
|
+
const animation = outlet.stackingAnimation;
|
|
1138
|
+
if (!animation) continue;
|
|
1139
|
+
for (const [property, value] of Object.entries(animation)) {
|
|
1140
|
+
if (value === null || value === void 0) continue;
|
|
1141
|
+
if (Array.isArray(value)) {
|
|
1142
|
+
outlet.style.setProperty(property, tween(value[0], value[1], progress));
|
|
1143
|
+
} else if (typeof value === "function") {
|
|
1144
|
+
const next = value({ progress, tween: (start, end) => tween(start, end, progress) });
|
|
1145
|
+
if (next !== null && next !== void 0) outlet.style.setProperty(property, String(next));
|
|
1146
|
+
} else {
|
|
1147
|
+
outlet.style.setProperty(property, String(value));
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
setStatus(status) {
|
|
1153
|
+
if (this.status === status) return;
|
|
1154
|
+
const previousStatus = this.status;
|
|
1155
|
+
this.status = status;
|
|
1156
|
+
dispatch(this.root, "cap-sheet-travel-status-change", { previousStatus, status });
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
function tween(start, end, progress) {
|
|
1160
|
+
const startString = String(start);
|
|
1161
|
+
const endString = String(end);
|
|
1162
|
+
const startValue = Number.parseFloat(startString);
|
|
1163
|
+
const endValue = Number.parseFloat(endString);
|
|
1164
|
+
if (!Number.isFinite(startValue) || !Number.isFinite(endValue)) return progress < 1 ? startString : endString;
|
|
1165
|
+
const unit = endString.replace(String(endValue), "") || startString.replace(String(startValue), "");
|
|
1166
|
+
const next = startValue + (endValue - startValue) * progress;
|
|
1167
|
+
return `${next}${unit}`;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
// src/components/cap-sheet.ts
|
|
1171
|
+
var observed = [
|
|
1172
|
+
"active-detent",
|
|
1173
|
+
"close-on-escape",
|
|
1174
|
+
"close-on-outside-click",
|
|
1175
|
+
"content-placement",
|
|
1176
|
+
"default-active-detent",
|
|
1177
|
+
"default-presented",
|
|
1178
|
+
"detents",
|
|
1179
|
+
"focus-trap",
|
|
1180
|
+
"inert-outside",
|
|
1181
|
+
"native-edge-swipe-prevention",
|
|
1182
|
+
"native-focus-scroll-prevention",
|
|
1183
|
+
"presented",
|
|
1184
|
+
"restore-focus",
|
|
1185
|
+
"safe-area",
|
|
1186
|
+
"sheet-role",
|
|
1187
|
+
"stack",
|
|
1188
|
+
"swipe",
|
|
1189
|
+
"swipe-dismissal",
|
|
1190
|
+
"swipe-overshoot",
|
|
1191
|
+
"swipe-trap",
|
|
1192
|
+
"theme-color-dimming",
|
|
1193
|
+
"tracks"
|
|
1194
|
+
];
|
|
1195
|
+
var CapSheet = class extends HTMLElement {
|
|
1196
|
+
controller = new SheetController(this);
|
|
1197
|
+
syncingAttribute = false;
|
|
1198
|
+
static get observedAttributes() {
|
|
1199
|
+
return observed;
|
|
1200
|
+
}
|
|
1201
|
+
connectedCallback() {
|
|
1202
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1203
|
+
this.style.display ||= "contents";
|
|
1204
|
+
this.controller.connect();
|
|
1205
|
+
}
|
|
1206
|
+
disconnectedCallback() {
|
|
1207
|
+
this.controller.disconnect();
|
|
1208
|
+
}
|
|
1209
|
+
attributeChangedCallback() {
|
|
1210
|
+
if (this.syncingAttribute) return;
|
|
1211
|
+
this.controller.configure({});
|
|
1212
|
+
if (this.isConnected) {
|
|
1213
|
+
if (this.hasAttribute("presented") && !this.controller.presented) {
|
|
1214
|
+
void this.present({ source: "programmatic" });
|
|
1215
|
+
} else if (!this.hasAttribute("presented") && this.controller.presented) {
|
|
1216
|
+
void this.dismiss({ source: "programmatic" });
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
/** True when the sheet is currently presented. */
|
|
1221
|
+
get presented() {
|
|
1222
|
+
return this.controller.presented;
|
|
1223
|
+
}
|
|
1224
|
+
set presented(value) {
|
|
1225
|
+
if (value) {
|
|
1226
|
+
void this.present();
|
|
1227
|
+
} else {
|
|
1228
|
+
void this.dismiss();
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
/** Current active detent index. */
|
|
1232
|
+
get activeDetent() {
|
|
1233
|
+
return this.controller.activeDetent;
|
|
1234
|
+
}
|
|
1235
|
+
set activeDetent(value) {
|
|
1236
|
+
void this.stepTo(value);
|
|
1237
|
+
}
|
|
1238
|
+
/** Configure the sheet imperatively without depending on a framework adapter. */
|
|
1239
|
+
configure(options) {
|
|
1240
|
+
this.controller.configure(options);
|
|
1241
|
+
}
|
|
1242
|
+
/** Present the sheet. */
|
|
1243
|
+
async present(options = {}) {
|
|
1244
|
+
await this.controller.present(options);
|
|
1245
|
+
this.syncAttribute("presented", true);
|
|
1246
|
+
}
|
|
1247
|
+
/** Dismiss the sheet. */
|
|
1248
|
+
async dismiss(options = {}) {
|
|
1249
|
+
await this.controller.dismiss(options);
|
|
1250
|
+
this.syncAttribute("presented", false);
|
|
1251
|
+
}
|
|
1252
|
+
/** Toggle presentation state. */
|
|
1253
|
+
async toggle(options = {}) {
|
|
1254
|
+
if (this.presented) {
|
|
1255
|
+
await this.dismiss(options);
|
|
1256
|
+
} else {
|
|
1257
|
+
await this.present(options);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
/** Step to a specific detent index. */
|
|
1261
|
+
async stepTo(detent, options = {}) {
|
|
1262
|
+
await this.controller.stepTo(detent, options);
|
|
1263
|
+
if (this.controller.presented) this.syncAttribute("presented", true);
|
|
1264
|
+
}
|
|
1265
|
+
/** Step one detent up or down. */
|
|
1266
|
+
async step(direction = "up", options = {}) {
|
|
1267
|
+
await this.controller.step(direction, options);
|
|
1268
|
+
}
|
|
1269
|
+
syncAttribute(name, enabled) {
|
|
1270
|
+
this.syncingAttribute = true;
|
|
1271
|
+
this.toggleAttribute(name, enabled);
|
|
1272
|
+
this.syncingAttribute = false;
|
|
1273
|
+
}
|
|
1274
|
+
};
|
|
1275
|
+
function getSheetFromElement(element) {
|
|
1276
|
+
const explicitTarget = element.getAttribute("for");
|
|
1277
|
+
if (explicitTarget) {
|
|
1278
|
+
const found = element.ownerDocument.getElementById(explicitTarget);
|
|
1279
|
+
return isCapSheetElement(found) ? found : null;
|
|
1280
|
+
}
|
|
1281
|
+
const nearest = element.closest("cap-sheet");
|
|
1282
|
+
return isCapSheetElement(nearest) ? nearest : null;
|
|
1283
|
+
}
|
|
1284
|
+
function isCapSheetElement(element) {
|
|
1285
|
+
if (element?.localName !== "cap-sheet") return false;
|
|
1286
|
+
const candidate = element;
|
|
1287
|
+
return typeof candidate.present === "function" && typeof candidate.dismiss === "function";
|
|
1288
|
+
}
|
|
1289
|
+
function applySheetOptions(element, options) {
|
|
1290
|
+
if (options.contentPlacement) element.setAttribute("content-placement", options.contentPlacement);
|
|
1291
|
+
if (options.detents !== void 0) {
|
|
1292
|
+
element.setAttribute("detents", Array.isArray(options.detents) ? options.detents.join(" ") : options.detents);
|
|
1293
|
+
}
|
|
1294
|
+
if (options.activeDetent !== void 0) element.setAttribute("active-detent", String(options.activeDetent));
|
|
1295
|
+
if (options.defaultActiveDetent !== void 0) {
|
|
1296
|
+
element.setAttribute("default-active-detent", String(options.defaultActiveDetent));
|
|
1297
|
+
}
|
|
1298
|
+
if (options.defaultPresented !== void 0)
|
|
1299
|
+
element.setAttribute("default-presented", String(options.defaultPresented));
|
|
1300
|
+
if (options.presented !== void 0) element.toggleAttribute("presented", options.presented);
|
|
1301
|
+
if (options.sheetRole) element.setAttribute("sheet-role", options.sheetRole);
|
|
1302
|
+
if (options.safeArea !== void 0) {
|
|
1303
|
+
element.setAttribute(
|
|
1304
|
+
"safe-area",
|
|
1305
|
+
Array.isArray(options.safeArea) ? options.safeArea.join(" ") : String(options.safeArea)
|
|
1306
|
+
);
|
|
1307
|
+
}
|
|
1308
|
+
if (options.stack) element.setAttribute("stack", options.stack);
|
|
1309
|
+
if (options.tracks)
|
|
1310
|
+
element.setAttribute("tracks", Array.isArray(options.tracks) ? options.tracks.join(" ") : options.tracks);
|
|
1311
|
+
for (const [key, attr] of [
|
|
1312
|
+
["swipe", "swipe"],
|
|
1313
|
+
["swipeDismissal", "swipe-dismissal"],
|
|
1314
|
+
["swipeOvershoot", "swipe-overshoot"],
|
|
1315
|
+
["swipeTrap", "swipe-trap"],
|
|
1316
|
+
["inertOutside", "inert-outside"],
|
|
1317
|
+
["nativeEdgeSwipePrevention", "native-edge-swipe-prevention"],
|
|
1318
|
+
["nativeFocusScrollPrevention", "native-focus-scroll-prevention"],
|
|
1319
|
+
["closeOnOutsideClick", "close-on-outside-click"],
|
|
1320
|
+
["closeOnEscape", "close-on-escape"],
|
|
1321
|
+
["focusTrap", "focus-trap"],
|
|
1322
|
+
["restoreFocus", "restore-focus"]
|
|
1323
|
+
]) {
|
|
1324
|
+
const value = options[key];
|
|
1325
|
+
if (typeof value === "boolean") element.setAttribute(attr, String(value));
|
|
1326
|
+
}
|
|
1327
|
+
if (options.themeColorDimming !== void 0) {
|
|
1328
|
+
element.setAttribute("theme-color-dimming", options.themeColorDimming === false ? "false" : "auto");
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
// src/components/sheet-actions.ts
|
|
1333
|
+
function normalizeAction(value, fallback) {
|
|
1334
|
+
return ["present", "dismiss", "toggle", "step"].includes(value || "") ? value : fallback;
|
|
1335
|
+
}
|
|
1336
|
+
async function runAction(element, fallback) {
|
|
1337
|
+
const sheet = getSheetFromElement(element);
|
|
1338
|
+
if (!sheet) return;
|
|
1339
|
+
const action = normalizeAction(element.getAttribute("action"), fallback);
|
|
1340
|
+
if (action === "present") {
|
|
1341
|
+
await sheet.present({ source: "trigger" });
|
|
1342
|
+
} else if (action === "dismiss") {
|
|
1343
|
+
await sheet.dismiss({ source: "trigger" });
|
|
1344
|
+
} else if (action === "step") {
|
|
1345
|
+
const detent = Number.parseInt(element.getAttribute("detent") || "", 10);
|
|
1346
|
+
if (Number.isFinite(detent)) {
|
|
1347
|
+
await sheet.stepTo(detent, { source: "trigger" });
|
|
1348
|
+
} else {
|
|
1349
|
+
await sheet.step(element.getAttribute("direction") || "up", { source: "trigger" });
|
|
1350
|
+
}
|
|
1351
|
+
} else {
|
|
1352
|
+
await sheet.toggle({ source: "trigger" });
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
var CapSheetTrigger = class extends HTMLElement {
|
|
1356
|
+
connectedCallback() {
|
|
1357
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1358
|
+
this.role ||= "button";
|
|
1359
|
+
if (!this.hasAttribute("tabindex")) this.tabIndex = 0;
|
|
1360
|
+
this.addEventListener("click", this.handleClick);
|
|
1361
|
+
this.addEventListener("keydown", this.handleKeyDown);
|
|
1362
|
+
}
|
|
1363
|
+
disconnectedCallback() {
|
|
1364
|
+
this.removeEventListener("click", this.handleClick);
|
|
1365
|
+
this.removeEventListener("keydown", this.handleKeyDown);
|
|
1366
|
+
}
|
|
1367
|
+
handleClick = () => {
|
|
1368
|
+
void runAction(this, "toggle");
|
|
1369
|
+
};
|
|
1370
|
+
handleKeyDown = (event) => {
|
|
1371
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
1372
|
+
event.preventDefault();
|
|
1373
|
+
void runAction(this, "toggle");
|
|
1374
|
+
};
|
|
1375
|
+
};
|
|
1376
|
+
var CapSheetHandle = class extends HTMLElement {
|
|
1377
|
+
connectedCallback() {
|
|
1378
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1379
|
+
this.role ||= "button";
|
|
1380
|
+
if (!this.hasAttribute("tabindex")) this.tabIndex = 0;
|
|
1381
|
+
this.setAttribute("aria-label", this.getAttribute("aria-label") || "Move sheet");
|
|
1382
|
+
this.addEventListener("click", this.handleClick);
|
|
1383
|
+
this.addEventListener("keydown", this.handleKeyDown);
|
|
1384
|
+
}
|
|
1385
|
+
disconnectedCallback() {
|
|
1386
|
+
this.removeEventListener("click", this.handleClick);
|
|
1387
|
+
this.removeEventListener("keydown", this.handleKeyDown);
|
|
1388
|
+
}
|
|
1389
|
+
handleClick = () => {
|
|
1390
|
+
void runAction(this, "step");
|
|
1391
|
+
};
|
|
1392
|
+
handleKeyDown = (event) => {
|
|
1393
|
+
if (event.key === "ArrowUp") {
|
|
1394
|
+
event.preventDefault();
|
|
1395
|
+
this.setAttribute("direction", "up");
|
|
1396
|
+
void runAction(this, "step");
|
|
1397
|
+
}
|
|
1398
|
+
if (event.key === "ArrowDown") {
|
|
1399
|
+
event.preventDefault();
|
|
1400
|
+
this.setAttribute("direction", "down");
|
|
1401
|
+
void runAction(this, "step");
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
};
|
|
1405
|
+
|
|
1406
|
+
// src/components/sheet-context.ts
|
|
1407
|
+
var CapSheetStack = class extends HTMLElement {
|
|
1408
|
+
connectedCallback() {
|
|
1409
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1410
|
+
this.style.display ||= "contents";
|
|
1411
|
+
if (!this.id) this.id = `cap-sheet-stack-${Math.random().toString(36).slice(2, 10)}`;
|
|
1412
|
+
}
|
|
1413
|
+
};
|
|
1414
|
+
var CapSheetOutlet = class extends HTMLElement {
|
|
1415
|
+
travelAnimation;
|
|
1416
|
+
stackingAnimation;
|
|
1417
|
+
connectedCallback() {
|
|
1418
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1419
|
+
getSheetFromElement(this)?.controller.registerOutlet(this);
|
|
1420
|
+
}
|
|
1421
|
+
disconnectedCallback() {
|
|
1422
|
+
getSheetFromElement(this)?.controller.unregisterOutlet(this);
|
|
1423
|
+
}
|
|
1424
|
+
};
|
|
1425
|
+
var CapSheetSpecialWrapper = class extends HTMLElement {
|
|
1426
|
+
connectedCallback() {
|
|
1427
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1428
|
+
this.style.display ||= "contents";
|
|
1429
|
+
}
|
|
1430
|
+
};
|
|
1431
|
+
var CapSheetSpecialWrapperContent = class extends HTMLElement {
|
|
1432
|
+
connectedCallback() {
|
|
1433
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1434
|
+
this.style.display ||= "contents";
|
|
1435
|
+
}
|
|
1436
|
+
};
|
|
1437
|
+
var CapIsland = class extends HTMLElement {
|
|
1438
|
+
connectedCallback() {
|
|
1439
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1440
|
+
getSheetFromElement(this)?.controller.registerIsland(this);
|
|
1441
|
+
}
|
|
1442
|
+
disconnectedCallback() {
|
|
1443
|
+
getSheetFromElement(this)?.controller.unregisterIsland(this);
|
|
1444
|
+
}
|
|
1445
|
+
};
|
|
1446
|
+
var CapExternalOverlay = class extends HTMLElement {
|
|
1447
|
+
registered = null;
|
|
1448
|
+
connectedCallback() {
|
|
1449
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1450
|
+
this.register();
|
|
1451
|
+
}
|
|
1452
|
+
disconnectedCallback() {
|
|
1453
|
+
this.unregister();
|
|
1454
|
+
}
|
|
1455
|
+
register() {
|
|
1456
|
+
const sheet = getSheetFromElement(this);
|
|
1457
|
+
if (!sheet) return;
|
|
1458
|
+
const selector = this.getAttribute("content-getter");
|
|
1459
|
+
const content = selector ? this.ownerDocument.querySelector(selector) : this;
|
|
1460
|
+
if (!content) return;
|
|
1461
|
+
this.registered = content;
|
|
1462
|
+
sheet.controller.registerIsland(content);
|
|
1463
|
+
}
|
|
1464
|
+
unregister() {
|
|
1465
|
+
const sheet = getSheetFromElement(this);
|
|
1466
|
+
if (sheet && this.registered) {
|
|
1467
|
+
sheet.controller.unregisterIsland(this.registered);
|
|
1468
|
+
}
|
|
1469
|
+
this.registered = null;
|
|
1470
|
+
}
|
|
1471
|
+
};
|
|
1472
|
+
var CapFixed = class extends HTMLElement {
|
|
1473
|
+
connectedCallback() {
|
|
1474
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1475
|
+
}
|
|
1476
|
+
};
|
|
1477
|
+
var CapVisuallyHidden = class extends HTMLElement {
|
|
1478
|
+
connectedCallback() {
|
|
1479
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1480
|
+
}
|
|
1481
|
+
};
|
|
1482
|
+
|
|
1483
|
+
// src/components/sheet-parts.ts
|
|
1484
|
+
var SheetPartElement = class extends HTMLElement {
|
|
1485
|
+
connectedCallback() {
|
|
1486
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1487
|
+
const sheet = getSheetFromElement(this);
|
|
1488
|
+
sheet?.controller.registerPart(this.partName, this);
|
|
1489
|
+
}
|
|
1490
|
+
disconnectedCallback() {
|
|
1491
|
+
const sheet = getSheetFromElement(this);
|
|
1492
|
+
sheet?.controller.unregisterPart(this.partName, this);
|
|
1493
|
+
}
|
|
1494
|
+
};
|
|
1495
|
+
var CapSheetView = class extends SheetPartElement {
|
|
1496
|
+
partName = "view";
|
|
1497
|
+
connectedCallback() {
|
|
1498
|
+
super.connectedCallback();
|
|
1499
|
+
const sheet = getSheetFromElement(this);
|
|
1500
|
+
const placement = this.getAttribute("content-placement") || sheet?.controller.options.contentPlacement || "bottom";
|
|
1501
|
+
this.setAttribute("content-placement", placement);
|
|
1502
|
+
}
|
|
1503
|
+
};
|
|
1504
|
+
var CapSheetBackdrop = class extends SheetPartElement {
|
|
1505
|
+
partName = "backdrop";
|
|
1506
|
+
};
|
|
1507
|
+
var CapSheetContent = class extends SheetPartElement {
|
|
1508
|
+
partName = "content";
|
|
1509
|
+
connectedCallback() {
|
|
1510
|
+
super.connectedCallback();
|
|
1511
|
+
if (!this.hasAttribute("tabindex")) this.tabIndex = -1;
|
|
1512
|
+
}
|
|
1513
|
+
};
|
|
1514
|
+
var CapSheetBleedingBackground = class extends HTMLElement {
|
|
1515
|
+
connectedCallback() {
|
|
1516
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1517
|
+
}
|
|
1518
|
+
};
|
|
1519
|
+
var CapSheetTitle = class extends SheetPartElement {
|
|
1520
|
+
partName = "title";
|
|
1521
|
+
connectedCallback() {
|
|
1522
|
+
if (!this.id) this.id = createId("cap-sheet-title");
|
|
1523
|
+
super.connectedCallback();
|
|
1524
|
+
}
|
|
1525
|
+
};
|
|
1526
|
+
var CapSheetDescription = class extends SheetPartElement {
|
|
1527
|
+
partName = "description";
|
|
1528
|
+
connectedCallback() {
|
|
1529
|
+
if (!this.id) this.id = createId("cap-sheet-description");
|
|
1530
|
+
super.connectedCallback();
|
|
1531
|
+
}
|
|
1532
|
+
};
|
|
1533
|
+
var CapAutoFocusTarget = class extends SheetPartElement {
|
|
1534
|
+
partName = "autoFocusTarget";
|
|
1535
|
+
connectedCallback() {
|
|
1536
|
+
if (!this.hasAttribute("tabindex")) this.tabIndex = -1;
|
|
1537
|
+
super.connectedCallback();
|
|
1538
|
+
}
|
|
1539
|
+
};
|
|
1540
|
+
|
|
1541
|
+
// src/components/sheet-portal.ts
|
|
1542
|
+
var CapSheetPortal = class extends HTMLElement {
|
|
1543
|
+
host = null;
|
|
1544
|
+
connectedCallback() {
|
|
1545
|
+
injectCapSheetStyles(this.ownerDocument);
|
|
1546
|
+
this.style.display ||= "contents";
|
|
1547
|
+
if (this.hasAttribute("disabled")) return;
|
|
1548
|
+
const sheet = this.closest("cap-sheet");
|
|
1549
|
+
if (!sheet) return;
|
|
1550
|
+
if (!sheet.id) sheet.id = createId("cap-sheet");
|
|
1551
|
+
this.host = this.ownerDocument.createElement("div");
|
|
1552
|
+
this.host.dataset.capSheetPortal = sheet.id;
|
|
1553
|
+
this.host.style.display = "contents";
|
|
1554
|
+
for (const child of Array.from(this.children)) {
|
|
1555
|
+
if (child instanceof HTMLElement && !child.hasAttribute("for")) {
|
|
1556
|
+
child.setAttribute("for", sheet.id);
|
|
1557
|
+
for (const descendant of Array.from(
|
|
1558
|
+
child.querySelectorAll(
|
|
1559
|
+
"cap-sheet-view, cap-sheet-backdrop, cap-sheet-content, cap-sheet-title, cap-sheet-description, cap-sheet-trigger, cap-sheet-handle, cap-auto-focus-target"
|
|
1560
|
+
)
|
|
1561
|
+
)) {
|
|
1562
|
+
if (!descendant.hasAttribute("for")) descendant.setAttribute("for", sheet.id);
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
this.host.appendChild(child);
|
|
1566
|
+
}
|
|
1567
|
+
this.ownerDocument.body.appendChild(this.host);
|
|
1568
|
+
}
|
|
1569
|
+
disconnectedCallback() {
|
|
1570
|
+
if (!this.host) return;
|
|
1571
|
+
for (const child of Array.from(this.host.children)) {
|
|
1572
|
+
this.appendChild(child);
|
|
1573
|
+
}
|
|
1574
|
+
this.host.remove();
|
|
1575
|
+
this.host = null;
|
|
1576
|
+
}
|
|
1577
|
+
};
|
|
1578
|
+
|
|
1579
|
+
// src/components/index.ts
|
|
1580
|
+
defineElement("cap-sheet", CapSheet);
|
|
1581
|
+
defineElement("cap-sheet-trigger", CapSheetTrigger);
|
|
1582
|
+
defineElement("cap-sheet-portal", CapSheetPortal);
|
|
1583
|
+
defineElement("cap-sheet-view", CapSheetView);
|
|
1584
|
+
defineElement("cap-sheet-backdrop", CapSheetBackdrop);
|
|
1585
|
+
defineElement("cap-sheet-content", CapSheetContent);
|
|
1586
|
+
defineElement("cap-sheet-bleeding-background", CapSheetBleedingBackground);
|
|
1587
|
+
defineElement("cap-sheet-handle", CapSheetHandle);
|
|
1588
|
+
defineElement("cap-sheet-title", CapSheetTitle);
|
|
1589
|
+
defineElement("cap-sheet-description", CapSheetDescription);
|
|
1590
|
+
defineElement("cap-sheet-special-wrapper", CapSheetSpecialWrapper);
|
|
1591
|
+
defineElement("cap-sheet-special-wrapper-content", CapSheetSpecialWrapperContent);
|
|
1592
|
+
defineElement("cap-sheet-stack", CapSheetStack);
|
|
1593
|
+
defineElement("cap-sheet-outlet", CapSheetOutlet);
|
|
1594
|
+
defineElement("cap-scroll", CapScroll);
|
|
1595
|
+
defineElement("cap-scroll-content", CapScrollContent);
|
|
1596
|
+
defineElement("cap-fixed", CapFixed);
|
|
1597
|
+
defineElement("cap-island", CapIsland);
|
|
1598
|
+
defineElement("cap-external-overlay", CapExternalOverlay);
|
|
1599
|
+
defineElement("cap-visually-hidden", CapVisuallyHidden);
|
|
1600
|
+
defineElement("cap-auto-focus-target", CapAutoFocusTarget);
|
|
1601
|
+
|
|
1602
|
+
export {
|
|
1603
|
+
CapScroll,
|
|
1604
|
+
CapScrollContent,
|
|
1605
|
+
updateThemeColor,
|
|
1606
|
+
SheetController,
|
|
1607
|
+
CapSheet,
|
|
1608
|
+
getSheetFromElement,
|
|
1609
|
+
applySheetOptions,
|
|
1610
|
+
CapSheetTrigger,
|
|
1611
|
+
CapSheetHandle,
|
|
1612
|
+
CapSheetStack,
|
|
1613
|
+
CapSheetOutlet,
|
|
1614
|
+
CapSheetSpecialWrapper,
|
|
1615
|
+
CapSheetSpecialWrapperContent,
|
|
1616
|
+
CapIsland,
|
|
1617
|
+
CapExternalOverlay,
|
|
1618
|
+
CapFixed,
|
|
1619
|
+
CapVisuallyHidden,
|
|
1620
|
+
CapSheetView,
|
|
1621
|
+
CapSheetBackdrop,
|
|
1622
|
+
CapSheetContent,
|
|
1623
|
+
CapSheetBleedingBackground,
|
|
1624
|
+
CapSheetTitle,
|
|
1625
|
+
CapSheetDescription,
|
|
1626
|
+
CapAutoFocusTarget,
|
|
1627
|
+
CapSheetPortal
|
|
1628
|
+
};
|
|
1629
|
+
//# sourceMappingURL=chunk-YBLI7KN6.mjs.map
|