wj-elements 0.6.0 → 0.7.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.
Files changed (32) hide show
  1. package/dist/packages/wje-breadcrumbs/breadcrumbs.element.d.ts +1 -1
  2. package/dist/packages/wje-dropdown/dropdown.element.d.ts +18 -0
  3. package/dist/packages/wje-orgchart/orgchart.element.d.ts +15 -0
  4. package/dist/packages/wje-orgchart-item/orgchart-item.element.d.ts +3 -1
  5. package/dist/packages/wje-popup/popup.element.d.ts +48 -1
  6. package/dist/packages/wje-sliding-container/sliding-container.element.d.ts +360 -3
  7. package/dist/packages/wje-toolbar-action/toolbar-action.element.d.ts +11 -0
  8. package/dist/{popup.element-C8-g3WLs.js → popup.element-CwXvVFK7.js} +275 -43
  9. package/dist/popup.element-CwXvVFK7.js.map +1 -0
  10. package/dist/styles.css +0 -38
  11. package/dist/wje-animation.js +1 -1
  12. package/dist/wje-breadcrumbs.js +4 -0
  13. package/dist/wje-breadcrumbs.js.map +1 -1
  14. package/dist/wje-dropdown.js +28 -4
  15. package/dist/wje-dropdown.js.map +1 -1
  16. package/dist/wje-master.js +1 -1
  17. package/dist/wje-orgchart-group.js +1 -1
  18. package/dist/wje-orgchart-item.js +13 -4
  19. package/dist/wje-orgchart-item.js.map +1 -1
  20. package/dist/wje-orgchart.js +27 -0
  21. package/dist/wje-orgchart.js.map +1 -1
  22. package/dist/wje-popup.js +1 -1
  23. package/dist/wje-select.js +28 -5
  24. package/dist/wje-select.js.map +1 -1
  25. package/dist/wje-sliding-container.js +865 -14
  26. package/dist/wje-sliding-container.js.map +1 -1
  27. package/dist/wje-toolbar-action.js +25 -1
  28. package/dist/wje-toolbar-action.js.map +1 -1
  29. package/dist/wje-toolbar.js +1 -1
  30. package/dist/wje-tooltip.js +1 -1
  31. package/package.json +2 -1
  32. package/dist/popup.element-C8-g3WLs.js.map +0 -1
@@ -3,7 +3,9 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import WJElement from "./wje-element.js";
5
5
  import { event } from "./event.js";
6
- const styles = ":host {\n display: block;\n z-index: 9999;\n position: relative;\n height: 100%;\n right: unset;\n left: unset;\n .close-button {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 1000;\n }\n}\n\n:host([hide-button]) {\n .close-button {\n display: none;\n }\n}\n\n.sliding-container-wrapper {\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.native-sliding-container {\n\n position: absolute;\n width: 0;\n height: 100%;\n}\n\n.native-sliding-container-inner {\n height: 100%;\n position: absolute;\n}\n";
6
+ const styles = ":host {\n display: block;\n z-index: 9999;\n position: relative;\n height: 100%;\n right: unset;\n left: unset;\n .close-button {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 1000;\n }\n}\n\n:host([hide-button]) {\n .close-button {\n display: none;\n }\n}\n\n.sliding-container-backdrop {\n display: none;\n}\n\n.sliding-container-wrapper {\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n\n.native-sliding-container {\n\n position: absolute;\n width: 0;\n height: 100%;\n}\n\n.native-sliding-container-inner {\n height: 100%;\n position: absolute;\n}\n\n.sliding-container-sheet-handle-area {\n display: none;\n}\n\n:host(.bottom-sheet) {\n inset: 0;\n pointer-events: none;\n}\n\n:host(.bottom-sheet.open) {\n pointer-events: auto;\n overscroll-behavior: contain;\n}\n\n:host(.bottom-sheet) .sliding-container-backdrop {\n display: block;\n position: fixed;\n inset: 0;\n z-index: 0;\n opacity: 0;\n pointer-events: none;\n touch-action: none;\n overscroll-behavior: none;\n background: var(--wje-sliding-container-backdrop-background, var(--wje-backdrop, rgba(0, 0, 0, .35)));\n}\n\n:host(.bottom-sheet.open) .sliding-container-backdrop {\n pointer-events: auto;\n}\n\n:host(.bottom-sheet) .sliding-container-wrapper {\n position: fixed;\n inset: 0;\n overflow: visible;\n pointer-events: none;\n z-index: 1;\n}\n\n:host(.bottom-sheet) .sliding-container-transparent {\n display: none;\n}\n\n:host(.bottom-sheet) .native-sliding-container {\n position: fixed;\n top: auto;\n height: fit-content;\n overflow: hidden;\n pointer-events: auto;\n display: flex;\n flex-direction: column;\n overscroll-behavior: contain;\n background: var(--wje-sliding-container-background);\n box-shadow: var(--wje-sliding-container-box-shadow, var(--wje-sliding-container-shadow));\n border-radius: var(--wje-sliding-container-sheet-border-radius, var(--wje-sliding-container-border-radius) var(--wje-sliding-container-border-radius) 0 0);\n}\n\n:host(.bottom-sheet) .native-sliding-container-inner {\n position: relative;\n flex: 1 1 auto;\n min-height: 0;\n height: auto;\n max-height: inherit;\n overflow: auto;\n overscroll-behavior: contain;\n}\n\n:host(.bottom-sheet) .sliding-container-sheet-handle-area {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 var(--wje-sliding-container-sheet-handle-area-height, 24px);\n height: var(--wje-sliding-container-sheet-handle-area-height, 24px);\n cursor: ns-resize;\n pointer-events: auto;\n touch-action: none;\n user-select: none;\n -webkit-user-select: none;\n}\n\n:host(.bottom-sheet) .sliding-container-sheet-handle {\n width: var(--wje-sliding-container-sheet-handle-width, 36px);\n height: var(--wje-sliding-container-sheet-handle-height, 2px);\n background: var(--wje-sliding-container-sheet-handle-background, var(--wje-border-color));\n border-radius: var(--wje-sliding-container-sheet-handle-radius, 999px);\n}\n";
7
+ let documentScrollLocks = 0;
8
+ let documentScrollState = null;
7
9
  class SlidingContainer extends WJElement {
8
10
  /**
9
11
  * Creates an instance of SlidingContainer.
@@ -12,6 +14,183 @@ class SlidingContainer extends WJElement {
12
14
  constructor() {
13
15
  super();
14
16
  __publicField(this, "className", "SlidingContainer");
17
+ /**
18
+ * Stops a handle interaction from dismissing the bottom sheet.
19
+ * @param {Event} e The interaction emitted by the resize handle.
20
+ */
21
+ __publicField(this, "stopSheetHandleEvent", (e) => {
22
+ var _a;
23
+ if (!this.isBottomSheet()) return;
24
+ this._sheetIgnoreDismissUntil = Date.now() + 500;
25
+ e.preventDefault();
26
+ e.stopPropagation();
27
+ (_a = e.stopImmediatePropagation) == null ? void 0 : _a.call(e);
28
+ });
29
+ /**
30
+ * Prevents scroll events from reaching the page behind the bottom sheet.
31
+ * @param {Event} e The scroll event.
32
+ */
33
+ __publicField(this, "preventBottomSheetScroll", (e) => {
34
+ if (!this.isBottomSheet() || !this.classList.contains("open")) return;
35
+ e.preventDefault();
36
+ e.stopPropagation();
37
+ });
38
+ /**
39
+ * Starts mobile bottom sheet resizing.
40
+ * @param {PointerEvent} e The pointer event.
41
+ */
42
+ __publicField(this, "handleSheetDragStart", (e) => {
43
+ var _a, _b;
44
+ if (!this.sheetResizable || !this.isBottomSheet()) return;
45
+ e.preventDefault();
46
+ e.stopPropagation();
47
+ (_a = e.stopImmediatePropagation) == null ? void 0 : _a.call(e);
48
+ this._sheetIgnoreDismissUntil = Date.now() + 500;
49
+ if (this._sheetDrag) return;
50
+ this.startSheetDrag(e.pointerId, e.clientY);
51
+ try {
52
+ (_b = this.sheetHandleArea) == null ? void 0 : _b.setPointerCapture(e.pointerId);
53
+ } catch {
54
+ }
55
+ window.addEventListener("pointermove", this.handleSheetDragMove);
56
+ window.addEventListener("pointerup", this.handleSheetDragEnd);
57
+ window.addEventListener("pointercancel", this.handleSheetDragEnd);
58
+ });
59
+ /**
60
+ * Starts mobile bottom sheet resizing from a touch event.
61
+ * @param {TouchEvent} e The touch event.
62
+ */
63
+ __publicField(this, "handleSheetTouchStart", (e) => {
64
+ var _a, _b;
65
+ if (!this.sheetResizable || !this.isBottomSheet() || this._sheetDrag) return;
66
+ const touch = (_a = e.touches) == null ? void 0 : _a[0];
67
+ if (!touch) return;
68
+ e.preventDefault();
69
+ e.stopPropagation();
70
+ (_b = e.stopImmediatePropagation) == null ? void 0 : _b.call(e);
71
+ this._sheetIgnoreDismissUntil = Date.now() + 500;
72
+ this.startSheetDrag("touch", touch.clientY);
73
+ window.addEventListener("touchmove", this.handleSheetTouchMove, { passive: false });
74
+ window.addEventListener("touchend", this.handleSheetTouchEnd, { passive: false });
75
+ window.addEventListener("touchcancel", this.handleSheetTouchEnd, { passive: false });
76
+ });
77
+ /**
78
+ * Starts tracking a possible backdrop dismiss tap.
79
+ * @param {PointerEvent} e The pointer event.
80
+ */
81
+ __publicField(this, "handleBackdropPointerStart", (e) => {
82
+ if (!this.isBottomSheet() || e.target !== this.backdropElement || this.isEventInsideSheet(e) || Date.now() < this._sheetIgnoreDismissUntil) {
83
+ this._sheetBackdropGesture = null;
84
+ return;
85
+ }
86
+ this._sheetBackdropGesture = {
87
+ pointerId: e.pointerId,
88
+ startX: e.clientX,
89
+ startY: e.clientY,
90
+ hasMoved: false
91
+ };
92
+ });
93
+ /**
94
+ * Tracks movement during a possible backdrop dismiss tap.
95
+ * @param {PointerEvent} e The pointer event.
96
+ */
97
+ __publicField(this, "handleBackdropPointerMove", (e) => {
98
+ if (!this._sheetBackdropGesture || e.pointerId !== this._sheetBackdropGesture.pointerId) return;
99
+ const distanceX = Math.abs(e.clientX - this._sheetBackdropGesture.startX);
100
+ const distanceY = Math.abs(e.clientY - this._sheetBackdropGesture.startY);
101
+ if (distanceX > 8 || distanceY > 8) {
102
+ this._sheetBackdropGesture.hasMoved = true;
103
+ }
104
+ });
105
+ /**
106
+ * Finishes a possible backdrop dismiss tap.
107
+ * @param {PointerEvent} e The pointer event.
108
+ */
109
+ __publicField(this, "handleBackdropPointerEnd", (e) => {
110
+ if (!this._sheetBackdropGesture || e.pointerId !== this._sheetBackdropGesture.pointerId) return;
111
+ const shouldClose = !this._sheetBackdropGesture.hasMoved && e.target === this.backdropElement && !this.isEventInsideSheet(e) && Date.now() >= this._sheetIgnoreDismissUntil;
112
+ this._sheetBackdropGesture = null;
113
+ this._sheetBackdropHandledUntil = Date.now() + 350;
114
+ if (shouldClose) {
115
+ e.preventDefault();
116
+ e.stopPropagation();
117
+ this.close(e);
118
+ }
119
+ });
120
+ /**
121
+ * Cancels a possible backdrop dismiss tap.
122
+ */
123
+ __publicField(this, "handleBackdropPointerCancel", () => {
124
+ this._sheetBackdropGesture = null;
125
+ this._sheetBackdropHandledUntil = Date.now() + 350;
126
+ });
127
+ /**
128
+ * Resizes the mobile bottom sheet during dragging.
129
+ * @param {PointerEvent} e The pointer event.
130
+ */
131
+ __publicField(this, "handleSheetDragMove", (e) => {
132
+ var _a;
133
+ if (!this._sheetDrag || e.pointerId !== this._sheetDrag.pointerId) return;
134
+ e.preventDefault();
135
+ e.stopPropagation();
136
+ (_a = e.stopImmediatePropagation) == null ? void 0 : _a.call(e);
137
+ this.updateSheetDrag(e.clientY);
138
+ });
139
+ /**
140
+ * Resizes the mobile bottom sheet during touch dragging.
141
+ * @param {TouchEvent} e The touch event.
142
+ */
143
+ __publicField(this, "handleSheetTouchMove", (e) => {
144
+ var _a, _b;
145
+ if (!this._sheetDrag || this._sheetDrag.pointerId !== "touch") return;
146
+ const touch = (_a = e.touches) == null ? void 0 : _a[0];
147
+ if (!touch) return;
148
+ e.preventDefault();
149
+ e.stopPropagation();
150
+ (_b = e.stopImmediatePropagation) == null ? void 0 : _b.call(e);
151
+ this.updateSheetDrag(touch.clientY);
152
+ });
153
+ /**
154
+ * Ends mobile bottom sheet resizing.
155
+ * @param {PointerEvent} e The pointer event.
156
+ */
157
+ __publicField(this, "handleSheetDragEnd", (e) => {
158
+ var _a, _b, _c;
159
+ const hasMoved = (_a = this._sheetDrag) == null ? void 0 : _a.hasMoved;
160
+ if (this._sheetDrag && (e == null ? void 0 : e.pointerId) === this._sheetDrag.pointerId) {
161
+ e.preventDefault();
162
+ e.stopPropagation();
163
+ (_b = e.stopImmediatePropagation) == null ? void 0 : _b.call(e);
164
+ try {
165
+ (_c = this.sheetHandleArea) == null ? void 0 : _c.releasePointerCapture(e.pointerId);
166
+ } catch {
167
+ }
168
+ }
169
+ if (hasMoved) {
170
+ this._sheetIgnoreDismissUntil = Date.now() + 350;
171
+ } else {
172
+ this._sheetIgnoreDismissUntil = Date.now() + 500;
173
+ }
174
+ this.endSheetDrag();
175
+ });
176
+ /**
177
+ * Ends mobile bottom sheet resizing from a touch event.
178
+ * @param {TouchEvent} e The touch event.
179
+ */
180
+ __publicField(this, "handleSheetTouchEnd", (e) => {
181
+ var _a;
182
+ if (!this._sheetDrag || this._sheetDrag.pointerId !== "touch") return;
183
+ const hasMoved = this._sheetDrag.hasMoved;
184
+ if (e.type !== "touchcancel") {
185
+ e.preventDefault();
186
+ }
187
+ e.stopPropagation();
188
+ if (e.type !== "touchcancel") {
189
+ (_a = e.stopImmediatePropagation) == null ? void 0 : _a.call(e);
190
+ }
191
+ this._sheetIgnoreDismissUntil = Date.now() + (hasMoved ? 350 : 700);
192
+ this.endSheetDrag();
193
+ });
15
194
  /**
16
195
  * Triggers the event based on the target element.
17
196
  * If the target element is different from the last caller, it refreshes the children by calling the `open` method.
@@ -28,11 +207,19 @@ class SlidingContainer extends WJElement {
28
207
  });
29
208
  this._isOpen = false;
30
209
  this._lastCaller = null;
210
+ this._sheetDrag = null;
211
+ this._sheetIgnoreDismissUntil = 0;
212
+ this._sheetBackdropGesture = null;
213
+ this._sheetBackdropHandledUntil = 0;
214
+ this._hasLockedDocumentScroll = false;
215
+ this._bottomSheetScopeFrame = null;
31
216
  this._resizeObserver = new ResizeObserver((entries) => {
32
217
  for (let entry of entries) {
33
218
  if (entry.contentBoxSize) {
34
219
  if (this.drawingStatus < 3) return;
35
- if (this.screenBreakPoint && window.innerWidth <= this.screenBreakPoint) {
220
+ if (this.isBottomSheet()) {
221
+ this.checkForVariant(this.variant);
222
+ } else if (this.screenBreakPoint && window.innerWidth <= this.screenBreakPoint) {
36
223
  if (this.variant !== "over") {
37
224
  this.variant = "over";
38
225
  } else {
@@ -155,6 +342,34 @@ class SlidingContainer extends WJElement {
155
342
  set screenBreakPoint(value) {
156
343
  this.setAttribute("screen-break-point", value);
157
344
  }
345
+ /**
346
+ * Sets mobile presentation mode.
347
+ * @param {string} value The mobile presentation mode.
348
+ */
349
+ set mobilePresentation(value) {
350
+ this.setAttribute("mobile-presentation", value);
351
+ }
352
+ /**
353
+ * Gets mobile presentation mode.
354
+ * @returns {string|null} The mobile presentation mode.
355
+ */
356
+ get mobilePresentation() {
357
+ return this.getAttribute("mobile-presentation");
358
+ }
359
+ /**
360
+ * Sets the breakpoint for mobile presentation.
361
+ * @param {string} value The mobile breakpoint.
362
+ */
363
+ set mobileBreakPoint(value) {
364
+ this.setAttribute("mobile-break-point", value);
365
+ }
366
+ /**
367
+ * Gets the breakpoint for mobile presentation.
368
+ * @returns {string} The mobile breakpoint.
369
+ */
370
+ get mobileBreakPoint() {
371
+ return this.getAttribute("mobile-break-point") || "768";
372
+ }
158
373
  /**
159
374
  * Sets the duration of the animation by updating the `animation-duration` attribute.
160
375
  * @param {string} value The duration value for the animation, specified in a format
@@ -192,6 +407,97 @@ class SlidingContainer extends WJElement {
192
407
  get hasOpacity() {
193
408
  return this.hasAttribute("has-opacity") ?? false;
194
409
  }
410
+ /**
411
+ * Determines if the bottom sheet should close when the backdrop is clicked.
412
+ * @returns {boolean} True if backdrop dismiss is enabled.
413
+ */
414
+ get backdropDismiss() {
415
+ return this.hasAttribute("backdrop-dismiss") ?? false;
416
+ }
417
+ /**
418
+ * Enables resizing for the mobile bottom sheet.
419
+ * @returns {boolean} True if the sheet can be resized.
420
+ */
421
+ get sheetResizable() {
422
+ return this.hasAttribute("sheet-resizable") ?? false;
423
+ }
424
+ /**
425
+ * Sets resizing for the mobile bottom sheet.
426
+ * @param {boolean|string} value The value to set.
427
+ */
428
+ set sheetResizable(value) {
429
+ this.setAttribute("sheet-resizable", value);
430
+ }
431
+ /**
432
+ * Gets the mobile bottom sheet scope.
433
+ * @returns {string} Either 'viewport', 'container', or 'parent'.
434
+ */
435
+ get sheetScope() {
436
+ return this.getAttribute("sheet-scope") || "viewport";
437
+ }
438
+ /**
439
+ * Sets the mobile bottom sheet scope.
440
+ * @param {string} value The new boundary mode for the mobile sheet.
441
+ */
442
+ set sheetScope(value) {
443
+ this.setAttribute("sheet-scope", value);
444
+ }
445
+ /**
446
+ * Gets the selector used for container-scoped mobile bottom sheets.
447
+ * @returns {string|null} A CSS selector used to find the composed boundary ancestor.
448
+ */
449
+ get sheetBoundary() {
450
+ return this.getAttribute("sheet-boundary");
451
+ }
452
+ /**
453
+ * Sets the selector used for container-scoped mobile bottom sheets.
454
+ * @param {string} value Selector for the boundary element.
455
+ */
456
+ set sheetBoundary(value) {
457
+ this.setAttribute("sheet-boundary", value);
458
+ }
459
+ /**
460
+ * Gets the mobile bottom sheet opening height.
461
+ * @returns {string|null} The opening height.
462
+ */
463
+ get sheetHeight() {
464
+ return this.getAttribute("sheet-height");
465
+ }
466
+ /**
467
+ * Sets the mobile bottom sheet opening height.
468
+ * @param {string} value The opening height.
469
+ */
470
+ set sheetHeight(value) {
471
+ this.setAttribute("sheet-height", value);
472
+ }
473
+ /**
474
+ * Gets the minimum mobile bottom sheet height while resizing.
475
+ * @returns {string|null} The minimum height.
476
+ */
477
+ get sheetMinHeight() {
478
+ return this.getAttribute("sheet-min-height");
479
+ }
480
+ /**
481
+ * Sets the minimum mobile bottom sheet height while resizing.
482
+ * @param {string} value The minimum height.
483
+ */
484
+ set sheetMinHeight(value) {
485
+ this.setAttribute("sheet-min-height", value);
486
+ }
487
+ /**
488
+ * Gets the maximum mobile bottom sheet height while resizing.
489
+ * @returns {string|null} The maximum height.
490
+ */
491
+ get sheetMaxHeight() {
492
+ return this.getAttribute("sheet-max-height");
493
+ }
494
+ /**
495
+ * Sets the maximum mobile bottom sheet height while resizing.
496
+ * @param {string} value The maximum height.
497
+ */
498
+ set sheetMaxHeight(value) {
499
+ this.setAttribute("sheet-max-height", value);
500
+ }
195
501
  /**
196
502
  * Sets the value of the 'add-to-height' attribute.
197
503
  * This attribute is used to modify or adjust the height dynamically.
@@ -220,7 +526,7 @@ class SlidingContainer extends WJElement {
220
526
  * @returns {string[]}
221
527
  */
222
528
  static get observedAttributes() {
223
- return ["max-width", "max-height", "trigger", "direction", "variant", "screen-break-point", "remove-child-after-close", "animation-duration", "animation-easing", "has-opacity"];
529
+ return ["max-width", "max-height", "trigger", "direction", "variant", "screen-break-point", "remove-child-after-close", "animation-duration", "animation-easing", "has-opacity", "mobile-presentation", "mobile-break-point", "backdrop-dismiss", "sheet-resizable", "sheet-scope", "sheet-boundary", "sheet-height", "sheet-min-height", "sheet-max-height"];
224
530
  }
225
531
  /**
226
532
  * Returns the CSS styles for the component.
@@ -244,6 +550,7 @@ class SlidingContainer extends WJElement {
244
550
  var _a, _b;
245
551
  (_a = this.animation) == null ? void 0 : _a.cancel();
246
552
  (_b = this.nativeAnimation) == null ? void 0 : _b.cancel();
553
+ this.endSheetDrag();
247
554
  document.removeEventListener(this.trigger, this.triggerEvent);
248
555
  }
249
556
  /**
@@ -255,44 +562,89 @@ class SlidingContainer extends WJElement {
255
562
  */
256
563
  draw(context, store, params) {
257
564
  let fragment = document.createDocumentFragment();
565
+ const isBottomSheet = this.isBottomSheet();
566
+ let backdrop = document.createElement("div");
567
+ backdrop.setAttribute("part", "backdrop");
568
+ backdrop.classList.add("sliding-container-backdrop");
569
+ if (this._isOpen && isBottomSheet) {
570
+ backdrop.style.opacity = "var(--wje-sliding-container-backdrop-opacity, 1)";
571
+ }
572
+ backdrop.addEventListener("wheel", this.preventBottomSheetScroll, { passive: false });
573
+ backdrop.addEventListener("touchmove", this.preventBottomSheetScroll, { passive: false });
574
+ if (this.backdropDismiss) {
575
+ backdrop.addEventListener("pointerdown", this.handleBackdropPointerStart);
576
+ backdrop.addEventListener("pointermove", this.handleBackdropPointerMove);
577
+ backdrop.addEventListener("pointerup", this.handleBackdropPointerEnd);
578
+ backdrop.addEventListener("pointercancel", this.handleBackdropPointerCancel);
579
+ backdrop.addEventListener("click", (e) => {
580
+ if (this.isEventInsideSheet(e) || Date.now() < this._sheetIgnoreDismissUntil || Date.now() < this._sheetBackdropHandledUntil) {
581
+ e.preventDefault();
582
+ e.stopPropagation();
583
+ return;
584
+ }
585
+ if (e.target === backdrop) {
586
+ this.close(e);
587
+ }
588
+ });
589
+ }
258
590
  let wrapperDiv = document.createElement("div");
259
591
  wrapperDiv.classList.add("sliding-container-wrapper");
260
592
  let transparentDiv = document.createElement("div");
261
593
  transparentDiv.classList.add("sliding-container-transparent");
262
- if (this._isOpen) {
594
+ if (this._isOpen && !isBottomSheet) {
263
595
  transparentDiv.style.width = this.maxWidth;
264
596
  }
265
597
  let native = document.createElement("div");
266
598
  native.setAttribute("part", "sliding-container");
267
599
  native.classList.add("native-sliding-container");
268
- native.style.width = 0;
600
+ native.style.width = isBottomSheet ? "100%" : 0;
269
601
  if (this.hasOpacity) {
270
602
  native.style.opacity = 0;
271
603
  }
272
604
  if (this._isOpen) {
273
- native.style.width = this.maxWidth;
605
+ native.style.width = isBottomSheet ? "100%" : this.maxWidth;
606
+ if (isBottomSheet) {
607
+ native.style.transform = "translateY(0)";
608
+ }
274
609
  if (this.hasOpacity) {
275
610
  native.style.opacity = 1;
276
611
  }
612
+ } else if (isBottomSheet) {
613
+ native.style.transform = "translateY(100%)";
277
614
  }
278
- if (this.direction === "right") {
615
+ if (isBottomSheet) {
616
+ native.style.left = 0;
617
+ native.style.right = 0;
618
+ native.style.bottom = 0;
619
+ native.style.maxHeight = this.maxHeight;
620
+ } else if (this.direction === "right") {
279
621
  native.style.right = 0;
280
622
  } else {
281
623
  native.style.left = 0;
282
624
  }
283
- let slot = document.createElement("slot");
284
625
  const nativeInner = document.createElement("div");
285
626
  nativeInner.classList.add("native-sliding-container-inner");
286
- nativeInner.style.width = this.maxWidth;
627
+ nativeInner.style.width = isBottomSheet ? "100%" : this.maxWidth;
628
+ if (isBottomSheet) {
629
+ nativeInner.style.maxHeight = this.maxHeight;
630
+ }
631
+ let slot = document.createElement("slot");
632
+ this.sheetHandleArea = null;
287
633
  nativeInner.append(slot);
288
634
  nativeInner.append(this.htmlCloseButton());
635
+ if (this.sheetResizable) {
636
+ native.append(this.htmlSheetHandle());
637
+ }
289
638
  native.append(nativeInner);
290
639
  wrapperDiv.append(transparentDiv);
291
640
  wrapperDiv.append(native);
641
+ fragment.append(backdrop);
292
642
  fragment.append(wrapperDiv);
643
+ this.backdropElement = backdrop;
293
644
  this.transparentDiv = transparentDiv;
294
645
  this.wrapperDiv = wrapperDiv;
295
646
  this.nativeElement = native;
647
+ this.nativeInner = nativeInner;
296
648
  return fragment;
297
649
  }
298
650
  /**
@@ -304,11 +656,18 @@ class SlidingContainer extends WJElement {
304
656
  afterDraw() {
305
657
  this.syncAria();
306
658
  document.addEventListener(this.trigger, this.triggerEvent);
307
- if (this.screenBreakPoint && window.innerWidth <= this.screenBreakPoint) {
659
+ if (!this.isBottomSheet() && this.screenBreakPoint && window.innerWidth <= this.screenBreakPoint) {
308
660
  this.variant = "over";
309
661
  }
310
662
  this.checkForVariant(this.variant);
311
663
  }
664
+ /**
665
+ * Returns whether the mobile bottom sheet presentation is active.
666
+ * @returns {boolean}
667
+ */
668
+ isBottomSheet() {
669
+ return this.mobilePresentation === "bottom-sheet" && window.innerWidth <= +this.mobileBreakPoint;
670
+ }
312
671
  /**
313
672
  * Sync ARIA attributes on host.
314
673
  */
@@ -341,6 +700,28 @@ class SlidingContainer extends WJElement {
341
700
  });
342
701
  return closeButton;
343
702
  }
703
+ /**
704
+ * Creates the mobile bottom sheet resize handle.
705
+ * @returns {HTMLElement} The resize handle element.
706
+ */
707
+ htmlSheetHandle() {
708
+ const handleArea = document.createElement("div");
709
+ handleArea.setAttribute("part", "sheet-handle-area");
710
+ handleArea.setAttribute("role", "separator");
711
+ handleArea.setAttribute("aria-orientation", "horizontal");
712
+ handleArea.classList.add("sliding-container-sheet-handle-area");
713
+ const handle = document.createElement("div");
714
+ handle.setAttribute("part", "sheet-handle");
715
+ handle.classList.add("sliding-container-sheet-handle");
716
+ handleArea.append(handle);
717
+ handleArea.addEventListener("pointerdown", this.handleSheetDragStart, { capture: true });
718
+ handleArea.addEventListener("touchstart", this.handleSheetTouchStart, { capture: true, passive: false });
719
+ handleArea.addEventListener("click", this.stopSheetHandleEvent, { capture: true });
720
+ handleArea.addEventListener("mousedown", this.stopSheetHandleEvent, { capture: true });
721
+ handleArea.addEventListener("mouseup", this.stopSheetHandleEvent, { capture: true });
722
+ this.sheetHandleArea = handleArea;
723
+ return handleArea;
724
+ }
344
725
  /**
345
726
  * Retrieves the parent element of the current element.
346
727
  * If the parent element is not found, it attempts to find the root host element.
@@ -353,6 +734,108 @@ class SlidingContainer extends WJElement {
353
734
  }
354
735
  return parentElement;
355
736
  }
737
+ /**
738
+ * Finds the closest element across shadow DOM boundaries.
739
+ * @param {string} selector The selector to match.
740
+ * @returns {Element|null} The matched composed ancestor.
741
+ */
742
+ getClosestComposedElement(selector) {
743
+ var _a;
744
+ let currentElement = this;
745
+ while (currentElement) {
746
+ let matches = false;
747
+ try {
748
+ matches = currentElement instanceof Element && currentElement.matches(selector);
749
+ } catch {
750
+ return null;
751
+ }
752
+ if (matches) {
753
+ return currentElement;
754
+ }
755
+ if (currentElement.parentElement) {
756
+ currentElement = currentElement.parentElement;
757
+ continue;
758
+ }
759
+ const root = (_a = currentElement.getRootNode) == null ? void 0 : _a.call(currentElement);
760
+ currentElement = root instanceof ShadowRoot ? root.host : null;
761
+ }
762
+ return null;
763
+ }
764
+ /**
765
+ * Returns the viewport frame.
766
+ * @returns {{top: number, left: number, right: number, bottom: number, width: number, height: number}}
767
+ */
768
+ getViewportFrame() {
769
+ return {
770
+ top: 0,
771
+ left: 0,
772
+ right: window.innerWidth,
773
+ bottom: window.innerHeight,
774
+ width: window.innerWidth,
775
+ height: window.innerHeight
776
+ };
777
+ }
778
+ /**
779
+ * Returns the element that bounds the mobile bottom sheet.
780
+ * @returns {Element|null} The scope element, or null for viewport scope.
781
+ */
782
+ getBottomSheetScopeElement() {
783
+ if (this.sheetScope === "viewport") return null;
784
+ if (this.sheetScope === "parent") return this.getParentElement();
785
+ if (this.sheetBoundary) return this.getClosestComposedElement(this.sheetBoundary);
786
+ return this.getParentElement();
787
+ }
788
+ /**
789
+ * Returns the frame used by the mobile bottom sheet.
790
+ * @returns {{top: number, left: number, right: number, bottom: number, width: number, height: number}}
791
+ */
792
+ getBottomSheetScopeFrame() {
793
+ const scopeElement = this.getBottomSheetScopeElement();
794
+ if (!scopeElement) return this.getViewportFrame();
795
+ const rect = scopeElement.getBoundingClientRect();
796
+ const top = Math.max(rect.top, 0);
797
+ const left = Math.max(rect.left, 0);
798
+ const right = Math.min(rect.right, window.innerWidth);
799
+ const bottom = Math.min(rect.bottom, window.innerHeight);
800
+ const width = right - left;
801
+ const height = bottom - top;
802
+ if (width <= 0 || height <= 0) {
803
+ return this.getViewportFrame();
804
+ }
805
+ return {
806
+ top,
807
+ left,
808
+ right,
809
+ bottom,
810
+ width,
811
+ height
812
+ };
813
+ }
814
+ /**
815
+ * Applies a fixed frame to a bottom sheet layer.
816
+ * @param {HTMLElement|SlidingContainer} element The element to update.
817
+ * @param {object} frame The frame to apply.
818
+ */
819
+ setBottomSheetLayerFrame(element, frame) {
820
+ element.style.top = frame.top + "px";
821
+ element.style.left = frame.left + "px";
822
+ element.style.right = "auto";
823
+ element.style.bottom = "auto";
824
+ element.style.width = frame.width + "px";
825
+ element.style.height = frame.height + "px";
826
+ }
827
+ /**
828
+ * Removes fixed frame styles from a bottom sheet layer.
829
+ * @param {HTMLElement|SlidingContainer} element The element to reset.
830
+ */
831
+ resetBottomSheetLayerFrame(element) {
832
+ element == null ? void 0 : element.style.removeProperty("top");
833
+ element == null ? void 0 : element.style.removeProperty("left");
834
+ element == null ? void 0 : element.style.removeProperty("right");
835
+ element == null ? void 0 : element.style.removeProperty("bottom");
836
+ element == null ? void 0 : element.style.removeProperty("width");
837
+ element == null ? void 0 : element.style.removeProperty("height");
838
+ }
356
839
  /**
357
840
  * Adjusts the position and dimensions of the current element based on the specified variant.
358
841
  *
@@ -362,6 +845,11 @@ class SlidingContainer extends WJElement {
362
845
  * @returns {void} No value is returned, the method modifies the element's style properties directly.
363
846
  */
364
847
  checkForVariant(variant) {
848
+ if (this.isBottomSheet()) {
849
+ this.setBottomSheetVariant();
850
+ return;
851
+ }
852
+ this.resetBottomSheetVariant();
365
853
  if (variant === "over") {
366
854
  this.style.position = "fixed";
367
855
  let computentStyleOfParent = window.getComputedStyle(this.getParentElement());
@@ -390,6 +878,286 @@ class SlidingContainer extends WJElement {
390
878
  }
391
879
  }
392
880
  }
881
+ /**
882
+ * Applies the mobile bottom sheet layout.
883
+ */
884
+ setBottomSheetVariant() {
885
+ const scopeFrame = this.getBottomSheetScopeFrame();
886
+ this._bottomSheetScopeFrame = scopeFrame;
887
+ this.classList.add("bottom-sheet");
888
+ this.style.position = "fixed";
889
+ this.setBottomSheetLayerFrame(this, scopeFrame);
890
+ this.setBottomSheetLayerFrame(this.backdropElement, scopeFrame);
891
+ this.setBottomSheetLayerFrame(this.wrapperDiv, scopeFrame);
892
+ this.wrapperDiv.style.height = "100%";
893
+ this.transparentDiv.style.width = 0;
894
+ this.nativeElement.style.left = scopeFrame.left + "px";
895
+ this.nativeElement.style.right = "auto";
896
+ this.nativeElement.style.bottom = window.innerHeight - scopeFrame.bottom + "px";
897
+ this.nativeElement.style.top = "auto";
898
+ this.nativeElement.style.width = scopeFrame.width + "px";
899
+ if (this._sheetDrag) {
900
+ this.nativeElement.style.maxHeight = this.getSheetMaxHeightInPixels() + "px";
901
+ } else {
902
+ this.setSheetHeight();
903
+ }
904
+ this.setBottomSheetVisualState(this.classList.contains("open"));
905
+ this.nativeInner.style.width = "100%";
906
+ this.nativeInner.style.maxHeight = this.nativeElement.style.maxHeight;
907
+ }
908
+ /**
909
+ * Removes layout styles managed by the mobile bottom sheet mode.
910
+ */
911
+ resetBottomSheetVariant() {
912
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
913
+ if (!this.classList.contains("bottom-sheet")) return;
914
+ this.classList.remove("bottom-sheet");
915
+ this.style.removeProperty("position");
916
+ this.resetBottomSheetLayerFrame(this);
917
+ this.resetBottomSheetLayerFrame(this.backdropElement);
918
+ this.resetBottomSheetLayerFrame(this.wrapperDiv);
919
+ if (this.transparentDiv) {
920
+ this.transparentDiv.style.width = this._isOpen ? this.maxWidth : 0;
921
+ }
922
+ (_a = this.nativeElement) == null ? void 0 : _a.style.removeProperty("left");
923
+ (_b = this.nativeElement) == null ? void 0 : _b.style.removeProperty("right");
924
+ (_c = this.nativeElement) == null ? void 0 : _c.style.removeProperty("bottom");
925
+ (_d = this.nativeElement) == null ? void 0 : _d.style.removeProperty("top");
926
+ (_e = this.nativeElement) == null ? void 0 : _e.style.removeProperty("height");
927
+ (_f = this.nativeElement) == null ? void 0 : _f.style.removeProperty("max-height");
928
+ (_g = this.nativeElement) == null ? void 0 : _g.style.removeProperty("transform");
929
+ if (this.nativeElement) {
930
+ if (this.direction === "right") {
931
+ this.nativeElement.style.right = 0;
932
+ } else {
933
+ this.nativeElement.style.left = 0;
934
+ }
935
+ this.nativeElement.style.width = this._isOpen ? this.maxWidth : 0;
936
+ }
937
+ (_h = this.nativeInner) == null ? void 0 : _h.style.removeProperty("max-height");
938
+ if (this.nativeInner) {
939
+ this.nativeInner.style.width = this.maxWidth;
940
+ }
941
+ (_i = this.backdropElement) == null ? void 0 : _i.style.removeProperty("opacity");
942
+ this._bottomSheetScopeFrame = null;
943
+ this.endSheetDrag();
944
+ this.unlockDocumentScroll();
945
+ }
946
+ /**
947
+ * Applies the current visual open or closed state to the mobile bottom sheet.
948
+ * @param {boolean} isOpen True when the sheet should be visible.
949
+ */
950
+ setBottomSheetVisualState(isOpen) {
951
+ this.nativeElement.style.transform = isOpen ? "translateY(0)" : "translateY(100%)";
952
+ if (this.hasOpacity) {
953
+ this.nativeElement.style.opacity = isOpen ? 1 : 0;
954
+ }
955
+ this.backdropElement.style.opacity = isOpen ? "var(--wje-sliding-container-backdrop-opacity, 1)" : 0;
956
+ }
957
+ /**
958
+ * Gets the CSS height limit used for the mobile bottom sheet.
959
+ * @returns {string} The CSS max height.
960
+ */
961
+ getSheetMaxHeight() {
962
+ return this.sheetMaxHeight || this.maxHeight;
963
+ }
964
+ /**
965
+ * Applies the configured bottom sheet opening height.
966
+ */
967
+ setSheetHeight() {
968
+ const maxHeightInPixels = this.getSheetMaxHeightInPixels();
969
+ this.nativeElement.style.maxHeight = maxHeightInPixels + "px";
970
+ if (!this.sheetHeight) {
971
+ this.nativeElement.style.removeProperty("height");
972
+ return;
973
+ }
974
+ const minHeight = Math.min(this.getSheetMinHeightInPixels(), maxHeightInPixels);
975
+ const height = this.resolveCssHeight(this.sheetHeight, maxHeightInPixels);
976
+ const clampedHeight = this.clamp(height, minHeight, maxHeightInPixels);
977
+ this.nativeElement.style.height = clampedHeight + "px";
978
+ }
979
+ /**
980
+ * Resolves the sheet minimum height in pixels.
981
+ * @returns {number} The minimum height.
982
+ */
983
+ getSheetMinHeightInPixels() {
984
+ const availableHeight = this.getBottomSheetAvailableHeight();
985
+ return Math.min(
986
+ this.resolveCssHeight(this.sheetMinHeight || "30vh", availableHeight * 0.3),
987
+ availableHeight
988
+ );
989
+ }
990
+ /**
991
+ * Resolves the sheet maximum height in pixels.
992
+ * @returns {number} The maximum height.
993
+ */
994
+ getSheetMaxHeightInPixels() {
995
+ const availableHeight = this.getBottomSheetAvailableHeight();
996
+ return Math.min(
997
+ this.resolveCssHeight(this.getSheetMaxHeight(), availableHeight * 0.9),
998
+ availableHeight
999
+ );
1000
+ }
1001
+ /**
1002
+ * Returns available height for the bottom sheet scope.
1003
+ * @returns {number} Pixel height that can be used inside the current sheet frame.
1004
+ */
1005
+ getBottomSheetAvailableHeight() {
1006
+ var _a;
1007
+ return ((_a = this._bottomSheetScopeFrame) == null ? void 0 : _a.height) || this.getBottomSheetScopeFrame().height || window.innerHeight;
1008
+ }
1009
+ /**
1010
+ * Resolves a CSS height value against the viewport.
1011
+ * @param {string} value The configured sheet height.
1012
+ * @param {number} fallback The fallback height in pixels.
1013
+ * @returns {number} The resolved height.
1014
+ */
1015
+ resolveCssHeight(value, fallback) {
1016
+ if (!value || value === "auto") return fallback;
1017
+ const normalizedValue = `${value}`.trim();
1018
+ const parsedValue = Number.parseFloat(normalizedValue);
1019
+ if (Number.isNaN(parsedValue)) return fallback;
1020
+ if (normalizedValue.endsWith("px")) return parsedValue;
1021
+ if (normalizedValue.endsWith("vh")) return window.innerHeight * parsedValue / 100;
1022
+ if (normalizedValue.endsWith("vw")) return window.innerWidth * parsedValue / 100;
1023
+ if (normalizedValue.endsWith("%")) return window.innerHeight * parsedValue / 100;
1024
+ if (/^-?\d+(\.\d+)?$/.test(normalizedValue)) return parsedValue;
1025
+ return fallback;
1026
+ }
1027
+ /**
1028
+ * Clamps a number between min and max.
1029
+ * @param {number} value The measured height.
1030
+ * @param {number} min The minimum.
1031
+ * @param {number} max The maximum.
1032
+ * @returns {number} The clamped value.
1033
+ */
1034
+ clamp(value, min, max) {
1035
+ return Math.min(Math.max(value, min), max);
1036
+ }
1037
+ /**
1038
+ * Checks whether an event came from the resize handle.
1039
+ * @param {Event} e The event to check.
1040
+ * @returns {boolean} True when the event belongs to the resize handle.
1041
+ */
1042
+ isSheetHandleEvent(e) {
1043
+ if (!(e == null ? void 0 : e.composedPath)) return false;
1044
+ return e.composedPath().includes(this.sheetHandleArea);
1045
+ }
1046
+ /**
1047
+ * Checks whether an event happened inside the visible bottom sheet.
1048
+ * @param {Event} e The event to check.
1049
+ * @returns {boolean} True when the event coordinates are inside the sheet.
1050
+ */
1051
+ isEventInsideSheet(e) {
1052
+ if (!this.nativeElement || typeof (e == null ? void 0 : e.clientX) !== "number" || typeof (e == null ? void 0 : e.clientY) !== "number") return false;
1053
+ const rect = this.nativeElement.getBoundingClientRect();
1054
+ return e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom;
1055
+ }
1056
+ /**
1057
+ * Prevents the page behind the mobile bottom sheet from scrolling.
1058
+ */
1059
+ lockDocumentScroll() {
1060
+ if (!this.isBottomSheet() || this.sheetScope !== "viewport" || this._hasLockedDocumentScroll) return;
1061
+ if (documentScrollLocks === 0) {
1062
+ documentScrollState = {
1063
+ bodyOverflow: document.body.style.overflow,
1064
+ documentOverflow: document.documentElement.style.overflow,
1065
+ bodyOverscrollBehavior: document.body.style.overscrollBehavior,
1066
+ documentOverscrollBehavior: document.documentElement.style.overscrollBehavior,
1067
+ bodyPosition: document.body.style.position,
1068
+ bodyTop: document.body.style.top,
1069
+ bodyLeft: document.body.style.left,
1070
+ bodyRight: document.body.style.right,
1071
+ bodyWidth: document.body.style.width,
1072
+ scrollX: window.scrollX,
1073
+ scrollY: window.scrollY
1074
+ };
1075
+ document.body.style.overflow = "hidden";
1076
+ document.documentElement.style.overflow = "hidden";
1077
+ document.body.style.overscrollBehavior = "none";
1078
+ document.documentElement.style.overscrollBehavior = "none";
1079
+ document.body.style.position = "fixed";
1080
+ document.body.style.top = `-${documentScrollState.scrollY}px`;
1081
+ document.body.style.left = `-${documentScrollState.scrollX}px`;
1082
+ document.body.style.right = "0";
1083
+ document.body.style.width = "100%";
1084
+ }
1085
+ documentScrollLocks++;
1086
+ this._hasLockedDocumentScroll = true;
1087
+ }
1088
+ /**
1089
+ * Restores page scrolling after the mobile bottom sheet is closed.
1090
+ */
1091
+ unlockDocumentScroll() {
1092
+ if (!this._hasLockedDocumentScroll) return;
1093
+ documentScrollLocks = Math.max(documentScrollLocks - 1, 0);
1094
+ this._hasLockedDocumentScroll = false;
1095
+ if (documentScrollLocks > 0 || !documentScrollState) return;
1096
+ document.body.style.overflow = documentScrollState.bodyOverflow;
1097
+ document.documentElement.style.overflow = documentScrollState.documentOverflow;
1098
+ document.body.style.overscrollBehavior = documentScrollState.bodyOverscrollBehavior;
1099
+ document.documentElement.style.overscrollBehavior = documentScrollState.documentOverscrollBehavior;
1100
+ document.body.style.position = documentScrollState.bodyPosition;
1101
+ document.body.style.top = documentScrollState.bodyTop;
1102
+ document.body.style.left = documentScrollState.bodyLeft;
1103
+ document.body.style.right = documentScrollState.bodyRight;
1104
+ document.body.style.width = documentScrollState.bodyWidth;
1105
+ window.scrollTo(documentScrollState.scrollX, documentScrollState.scrollY);
1106
+ documentScrollState = null;
1107
+ }
1108
+ /**
1109
+ * Stores the initial drag state for the mobile bottom sheet.
1110
+ * @param {number|string} pointerId The pointer identifier.
1111
+ * @param {number} startY The starting Y coordinate.
1112
+ */
1113
+ startSheetDrag(pointerId, startY) {
1114
+ var _a, _b;
1115
+ if (this.classList.contains("open")) {
1116
+ this.setBottomSheetVisualState(true);
1117
+ }
1118
+ (_a = this.animation) == null ? void 0 : _a.cancel();
1119
+ (_b = this.nativeAnimation) == null ? void 0 : _b.cancel();
1120
+ this.animation = null;
1121
+ this.nativeAnimation = null;
1122
+ const fallbackHeight = this.resolveCssHeight(this.sheetHeight, window.innerHeight * 0.5);
1123
+ const currentHeight = this.nativeElement.getBoundingClientRect().height || fallbackHeight;
1124
+ this._sheetDrag = {
1125
+ pointerId,
1126
+ startY,
1127
+ startHeight: currentHeight,
1128
+ minHeight: this.getSheetMinHeightInPixels(),
1129
+ maxHeight: this.getSheetMaxHeightInPixels(),
1130
+ hasMoved: false
1131
+ };
1132
+ }
1133
+ /**
1134
+ * Applies a new height while the bottom sheet is being dragged.
1135
+ * @param {number} clientY The current Y coordinate.
1136
+ */
1137
+ updateSheetDrag(clientY) {
1138
+ const distance = this._sheetDrag.startY - clientY;
1139
+ if (Math.abs(distance) > 3) {
1140
+ this._sheetDrag.hasMoved = true;
1141
+ }
1142
+ const height = this.clamp(
1143
+ this._sheetDrag.startHeight + distance,
1144
+ this._sheetDrag.minHeight,
1145
+ this._sheetDrag.maxHeight
1146
+ );
1147
+ this.nativeElement.style.height = height + "px";
1148
+ }
1149
+ /**
1150
+ * Cleans up mobile bottom sheet resizing listeners.
1151
+ */
1152
+ endSheetDrag() {
1153
+ window.removeEventListener("pointermove", this.handleSheetDragMove);
1154
+ window.removeEventListener("pointerup", this.handleSheetDragEnd);
1155
+ window.removeEventListener("pointercancel", this.handleSheetDragEnd);
1156
+ window.removeEventListener("touchmove", this.handleSheetTouchMove);
1157
+ window.removeEventListener("touchend", this.handleSheetTouchEnd);
1158
+ window.removeEventListener("touchcancel", this.handleSheetTouchEnd);
1159
+ this._sheetDrag = null;
1160
+ }
393
1161
  /**
394
1162
  * Executes before the element is opened.
395
1163
  */
@@ -431,6 +1199,9 @@ class SlidingContainer extends WJElement {
431
1199
  direction: "normal",
432
1200
  easing: this.animationEasing
433
1201
  };
1202
+ if (this.isBottomSheet()) {
1203
+ return this.doAnimateBottomSheetTransition(options);
1204
+ }
434
1205
  if (this.animation && ((_b = (_a = this.animation) == null ? void 0 : _a.effect) == null ? void 0 : _b.target) !== this.transparentDiv) {
435
1206
  this.animation.cancel();
436
1207
  this.animation = null;
@@ -500,13 +1271,74 @@ class SlidingContainer extends WJElement {
500
1271
  );
501
1272
  }
502
1273
  }
503
- return new Promise((resolve, reject) => {
1274
+ return new Promise((resolve) => {
504
1275
  this.animation.onfinish = () => {
505
1276
  this._isOpen = !this._isOpen;
506
1277
  resolve();
507
1278
  };
508
1279
  });
509
1280
  }
1281
+ /**
1282
+ * Animates the mobile bottom sheet and its backdrop.
1283
+ * @param {object} options Web Animation options.
1284
+ * @returns {Promise<void>}
1285
+ */
1286
+ doAnimateBottomSheetTransition(options) {
1287
+ var _a, _b, _c, _d;
1288
+ const shouldOpen = !this._isOpen;
1289
+ const closedBackdrop = {
1290
+ opacity: 0
1291
+ };
1292
+ const openBackdrop = {
1293
+ opacity: "var(--wje-sliding-container-backdrop-opacity, 1)"
1294
+ };
1295
+ const closedSheet = {
1296
+ ...this.hasOpacity ? { opacity: 0 } : {},
1297
+ transform: "translateY(100%)"
1298
+ };
1299
+ const openSheet = {
1300
+ ...this.hasOpacity ? { opacity: 1 } : {},
1301
+ transform: "translateY(0)"
1302
+ };
1303
+ if (this.animation && ((_b = (_a = this.animation) == null ? void 0 : _a.effect) == null ? void 0 : _b.target) !== this.backdropElement) {
1304
+ this.animation.cancel();
1305
+ this.animation = null;
1306
+ }
1307
+ if (this.nativeAnimation && ((_d = (_c = this.nativeAnimation) == null ? void 0 : _c.effect) == null ? void 0 : _d.target) !== this.nativeElement) {
1308
+ this.nativeAnimation.cancel();
1309
+ this.nativeAnimation = null;
1310
+ }
1311
+ if (shouldOpen) {
1312
+ if (this.animation && this.nativeAnimation) {
1313
+ this.animation.reverse();
1314
+ this.nativeAnimation.reverse();
1315
+ } else {
1316
+ this.animation = this.backdropElement.animate([closedBackdrop, openBackdrop], options);
1317
+ this.nativeAnimation = this.nativeElement.animate([closedSheet, openSheet], options);
1318
+ }
1319
+ } else {
1320
+ if (this.animation && this.nativeAnimation) {
1321
+ this.animation.reverse();
1322
+ this.nativeAnimation.reverse();
1323
+ } else {
1324
+ this.animation = this.backdropElement.animate([openBackdrop, closedBackdrop], options);
1325
+ this.nativeAnimation = this.nativeElement.animate([openSheet, closedSheet], options);
1326
+ }
1327
+ }
1328
+ return new Promise((resolve) => {
1329
+ let isFinished = false;
1330
+ const finish = () => {
1331
+ if (isFinished) return;
1332
+ isFinished = true;
1333
+ this._isOpen = shouldOpen;
1334
+ this.classList.toggle("open", shouldOpen);
1335
+ this.setBottomSheetVisualState(shouldOpen);
1336
+ resolve();
1337
+ };
1338
+ this.nativeAnimation.onfinish = finish;
1339
+ this.nativeAnimation.oncancel = finish;
1340
+ });
1341
+ }
510
1342
  /**
511
1343
  * Opens the sliding container by performing necessary preparatory and transitional operations.
512
1344
  * @param {Event} e The event that triggered the open operation.
@@ -518,6 +1350,7 @@ class SlidingContainer extends WJElement {
518
1350
  this.classList.add("open");
519
1351
  event.dispatchCustomEvent(this, "wje-sliding-container:beforeOpen");
520
1352
  this.checkForVariant(this.variant);
1353
+ this.lockDocumentScroll();
521
1354
  await this.doAnimateTransition();
522
1355
  this.syncAria();
523
1356
  await Promise.resolve(this.afterOpen(e)).then(() => {
@@ -532,12 +1365,20 @@ class SlidingContainer extends WJElement {
532
1365
  * @returns {Promise<void>} A promise that resolves when the closing operation, including animations and child element removal, is completed.
533
1366
  */
534
1367
  async close(e) {
1368
+ if (this.isBottomSheet() && e instanceof Event && (this.isSheetHandleEvent(e) || e.target === this.backdropElement && Date.now() < this._sheetIgnoreDismissUntil)) {
1369
+ return;
1370
+ }
535
1371
  await Promise.resolve(this.beforeClose(e)).then(async () => {
536
1372
  if (this._isOpen) {
537
1373
  this.classList.remove("open");
538
1374
  event.dispatchCustomEvent(this, "wje-sliding-container:beforeClose");
539
- await this.doAnimateTransition();
1375
+ await this.doAnimateTransition().catch(() => {
1376
+ if (this.isBottomSheet()) {
1377
+ this.setBottomSheetClosedState();
1378
+ }
1379
+ });
540
1380
  this.syncAria();
1381
+ this.unlockDocumentScroll();
541
1382
  await Promise.resolve(this.afterClose(e)).then(() => {
542
1383
  if (this.removeChildAfterClose) {
543
1384
  this.childNodes.forEach((child) => {
@@ -549,6 +1390,14 @@ class SlidingContainer extends WJElement {
549
1390
  }
550
1391
  });
551
1392
  }
1393
+ /**
1394
+ * Forces the closed visual state for the mobile bottom sheet.
1395
+ */
1396
+ setBottomSheetClosedState() {
1397
+ this._isOpen = false;
1398
+ this.classList.remove("open");
1399
+ this.setBottomSheetVisualState(false);
1400
+ }
552
1401
  /**
553
1402
  * Toggles the state between open and closed.
554
1403
  * @param {Event} e The event object triggering the toggle.
@@ -556,9 +1405,9 @@ class SlidingContainer extends WJElement {
556
1405
  */
557
1406
  async toggle(e) {
558
1407
  if (this._isOpen) {
559
- await this.close(event);
1408
+ await this.close(e);
560
1409
  } else {
561
- await this.open(event);
1410
+ await this.open(e);
562
1411
  }
563
1412
  }
564
1413
  /**
@@ -568,6 +1417,8 @@ class SlidingContainer extends WJElement {
568
1417
  */
569
1418
  componentCleanup() {
570
1419
  var _a;
1420
+ this.endSheetDrag();
1421
+ this.unlockDocumentScroll();
571
1422
  (_a = this._resizeObserver) == null ? void 0 : _a.disconnect();
572
1423
  this._resizeObserver = null;
573
1424
  }