@justeattakeaway/pie-modal 1.9.1 → 1.10.1
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/custom-elements.json +9 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +97 -96
- package/dist/react.d.ts +1 -0
- package/package.json +6 -6
- package/src/index.ts +11 -4
- package/src/modal.scss +1 -1
package/custom-elements.json
CHANGED
|
@@ -282,6 +282,15 @@
|
|
|
282
282
|
},
|
|
283
283
|
"privacy": "private"
|
|
284
284
|
},
|
|
285
|
+
{
|
|
286
|
+
"kind": "field",
|
|
287
|
+
"name": "_scrollableContainer",
|
|
288
|
+
"type": {
|
|
289
|
+
"text": "HTMLElement | null"
|
|
290
|
+
},
|
|
291
|
+
"privacy": "private",
|
|
292
|
+
"default": "null"
|
|
293
|
+
},
|
|
285
294
|
{
|
|
286
295
|
"kind": "field",
|
|
287
296
|
"name": "_backButtonClicked",
|
package/dist/index.d.ts
CHANGED
|
@@ -170,6 +170,7 @@ export declare class PieModal extends PieModal_base implements ModalProps {
|
|
|
170
170
|
size: "medium" | "large" | "small";
|
|
171
171
|
supportingAction: ModalProps['supportingAction'];
|
|
172
172
|
private _dialog;
|
|
173
|
+
private _scrollableContainer;
|
|
173
174
|
private _backButtonClicked;
|
|
174
175
|
private _abortController;
|
|
175
176
|
private _escKeyAbortController;
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { LitElement as F, nothing as g, unsafeCSS as P } from "lit";
|
|
|
2
2
|
import { html as r, unsafeStatic as T } from "lit/static-html.js";
|
|
3
3
|
import { property as d, query as K } from "lit/decorators.js";
|
|
4
4
|
import { classMap as B } from "lit/directives/class-map.js";
|
|
5
|
-
import { ifDefined as
|
|
5
|
+
import { ifDefined as b } from "lit/directives/if-defined.js";
|
|
6
6
|
import "@justeattakeaway/pie-button";
|
|
7
7
|
import "@justeattakeaway/pie-icon-button";
|
|
8
8
|
import { RtlMixin as I, dispatchCustomEvent as h, requiredProperty as N, validPropertyValues as C, safeCustomElement as W } from "@justeattakeaway/pie-webc-core";
|
|
@@ -15,15 +15,15 @@ const k = class k extends F {
|
|
|
15
15
|
this.getAttribute("v") || this.setAttribute("v", k.v);
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
|
-
k.v = "1.
|
|
18
|
+
k.v = "1.10.1";
|
|
19
19
|
let x = k;
|
|
20
|
-
function R(
|
|
21
|
-
if (Array.isArray(
|
|
22
|
-
for (var
|
|
23
|
-
t[
|
|
20
|
+
function R(e) {
|
|
21
|
+
if (Array.isArray(e)) {
|
|
22
|
+
for (var o = 0, t = Array(e.length); o < e.length; o++)
|
|
23
|
+
t[o] = e[o];
|
|
24
24
|
return t;
|
|
25
25
|
} else
|
|
26
|
-
return Array.from(
|
|
26
|
+
return Array.from(e);
|
|
27
27
|
}
|
|
28
28
|
var z = !1;
|
|
29
29
|
if (typeof window < "u") {
|
|
@@ -34,14 +34,14 @@ if (typeof window < "u") {
|
|
|
34
34
|
};
|
|
35
35
|
window.addEventListener("testPassive", null, A), window.removeEventListener("testPassive", null, A);
|
|
36
36
|
}
|
|
37
|
-
var O = typeof window < "u" && window.navigator && window.navigator.platform && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === "MacIntel" && window.navigator.maxTouchPoints > 1), m = [],
|
|
37
|
+
var O = typeof window < "u" && window.navigator && window.navigator.platform && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === "MacIntel" && window.navigator.maxTouchPoints > 1), m = [], v = !1, M = -1, u = void 0, f = void 0, D = function(o) {
|
|
38
38
|
return m.some(function(t) {
|
|
39
|
-
return !!(t.options.allowTouchMove && t.options.allowTouchMove(
|
|
39
|
+
return !!(t.options.allowTouchMove && t.options.allowTouchMove(o));
|
|
40
40
|
});
|
|
41
|
-
}, y = function(
|
|
42
|
-
var t =
|
|
41
|
+
}, y = function(o) {
|
|
42
|
+
var t = o || window.event;
|
|
43
43
|
return D(t.target) || t.touches.length > 1 ? !0 : (t.preventDefault && t.preventDefault(), !1);
|
|
44
|
-
}, j = function(
|
|
44
|
+
}, j = function(o) {
|
|
45
45
|
if (f === void 0) {
|
|
46
46
|
var t = !1, i = window.innerWidth - document.documentElement.clientWidth;
|
|
47
47
|
t && i > 0 && (f = document.body.style.paddingRight, document.body.style.paddingRight = i + "px");
|
|
@@ -49,39 +49,39 @@ var O = typeof window < "u" && window.navigator && window.navigator.platform &&
|
|
|
49
49
|
u === void 0 && (u = document.body.style.overflow, document.body.style.overflow = "hidden");
|
|
50
50
|
}, V = function() {
|
|
51
51
|
f !== void 0 && (document.body.style.paddingRight = f, f = void 0), u !== void 0 && (document.body.style.overflow = u, u = void 0);
|
|
52
|
-
}, Y = function(
|
|
53
|
-
return
|
|
54
|
-
}, H = function(
|
|
55
|
-
var i =
|
|
56
|
-
return D(
|
|
57
|
-
}, q = function(
|
|
58
|
-
if (!
|
|
52
|
+
}, Y = function(o) {
|
|
53
|
+
return o ? o.scrollHeight - o.scrollTop <= o.clientHeight : !1;
|
|
54
|
+
}, H = function(o, t) {
|
|
55
|
+
var i = o.targetTouches[0].clientY - M;
|
|
56
|
+
return D(o.target) ? !1 : t && t.scrollTop === 0 && i > 0 || Y(t) && i < 0 ? y(o) : (o.stopPropagation(), !0);
|
|
57
|
+
}, q = function(o, t) {
|
|
58
|
+
if (!o) {
|
|
59
59
|
console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.");
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
62
|
if (!m.some(function(a) {
|
|
63
|
-
return a.targetElement ===
|
|
63
|
+
return a.targetElement === o;
|
|
64
64
|
})) {
|
|
65
65
|
var i = {
|
|
66
|
-
targetElement:
|
|
66
|
+
targetElement: o,
|
|
67
67
|
options: {}
|
|
68
68
|
};
|
|
69
|
-
m = [].concat(R(m), [i]), O ? (
|
|
69
|
+
m = [].concat(R(m), [i]), O ? (o.ontouchstart = function(a) {
|
|
70
70
|
a.targetTouches.length === 1 && (M = a.targetTouches[0].clientY);
|
|
71
|
-
},
|
|
72
|
-
a.targetTouches.length === 1 && H(a,
|
|
73
|
-
},
|
|
71
|
+
}, o.ontouchmove = function(a) {
|
|
72
|
+
a.targetTouches.length === 1 && H(a, o);
|
|
73
|
+
}, v || (document.addEventListener("touchmove", y, z ? { passive: !1 } : void 0), v = !0)) : j();
|
|
74
74
|
}
|
|
75
|
-
}, U = function(
|
|
76
|
-
if (!
|
|
75
|
+
}, U = function(o) {
|
|
76
|
+
if (!o) {
|
|
77
77
|
console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.");
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
80
|
m = m.filter(function(t) {
|
|
81
|
-
return t.targetElement !==
|
|
82
|
-
}), O ? (
|
|
81
|
+
return t.targetElement !== o;
|
|
82
|
+
}), O ? (o.ontouchstart = null, o.ontouchmove = null, v && m.length === 0 && (document.removeEventListener("touchmove", y, z ? { passive: !1 } : void 0), v = !1)) : m.length || V();
|
|
83
83
|
};
|
|
84
|
-
const X = '*,*:after,*:before{box-sizing:inherit}dialog{position:absolute;left:0;right:0;width:-moz-fit-content;width:-webkit-fit-content;width:fit-content;height:-moz-fit-content;height:-webkit-fit-content;height:fit-content;margin:auto;border:solid;padding:1em;background:#fff;color:#000;display:block}dialog:not([open]){display:none}dialog+.backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000001a}._dialog_overlay{position:fixed;top:0;right:0;bottom:0;left:0}dialog.fixed{position:fixed;top:50%;transform:translateY(-50%)}.c-modal{--modal-size-s: 450px;--modal-size-m: 600px;--modal-size-l: 1080px;--modal-border-radius: var(--dt-radius-rounded-d);--modal-font: var(--dt-font-interactive-l-family);--modal-bg-color: var(--dt-color-container-default);--modal-elevation: var(--dt-elevation-
|
|
84
|
+
const X = '*,*:after,*:before{box-sizing:inherit}dialog{position:absolute;left:0;right:0;width:-moz-fit-content;width:-webkit-fit-content;width:fit-content;height:-moz-fit-content;height:-webkit-fit-content;height:fit-content;margin:auto;border:solid;padding:1em;background:#fff;color:#000;display:block}dialog:not([open]){display:none}dialog+.backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000001a}._dialog_overlay{position:fixed;top:0;right:0;bottom:0;left:0}dialog.fixed{position:fixed;top:50%;transform:translateY(-50%)}.c-modal{--modal-size-s: 450px;--modal-size-m: 600px;--modal-size-l: 1080px;--modal-border-radius: var(--dt-radius-rounded-d);--modal-font: var(--dt-font-interactive-l-family);--modal-bg-color: var(--dt-color-container-default);--modal-elevation: var(--dt-elevation-below-20);position:fixed;top:0;border-radius:var(--modal-border-radius);border:none;box-shadow:var(--modal-elevation);font-family:var(--modal-font);color:var(--dt-color-content-default);background-color:var(--modal-bg-color);padding:0;--modal-margin-none: var(--dt-spacing-none);--modal-margin-small: var(--dt-spacing-g);--modal-margin-large: var(--dt-spacing-j);--modal-margin-block: var(--modal-margin-small);--modal-block-size: fit-content;--modal-inline-size: 75%;--modal-max-block-size: calc(100vh - calc(var(--modal-margin-block) * 2));--modal-max-inline-size: var(--modal-size-m);block-size:var(--modal-block-size);inline-size:var(--modal-inline-size);max-block-size:var(--modal-max-block-size);max-inline-size:var(--modal-max-inline-size)}.c-modal:focus-visible{outline:none}@media (max-width: 767px){.c-modal pie-icon-button{--btn-dimension: 40px}}.c-modal[open]{display:flex;flex-direction:column}@media (min-width: 769px){.c-modal{--modal-margin-block: var(--modal-margin-large)}}.c-modal.c-modal--small{--modal-max-inline-size: var(--modal-size-s)}@media (min-width: 769px){.c-modal.c-modal--small{--modal-margin-block: var(--modal-margin-large)}}.c-modal.c-modal--large{--modal-inline-size: 75%;--modal-max-inline-size: var(--modal-size-l);--modal-margin-block: var(--modal-margin-large)}@media (max-width: 767px){.c-modal.c-modal--large,.c-modal.c-modal--medium.c-modal--fullWidthBelowMid{--modal-margin-block: var(--modal-margin-none);--modal-border-radius: var(--dt-radius-rounded-none);--modal-block-size: 100%;--modal-inline-size: 100%;--modal-max-inline-size: 100%}.c-modal.c-modal--large>.c-modal-scrollContainer,.c-modal.c-modal--medium.c-modal--fullWidthBelowMid>.c-modal-scrollContainer{block-size:100%}}.c-modal.c-modal--top{margin-block-start:var(--dt-spacing-j);max-block-size:calc(100% - var(--dt-spacing-j) * 2)}@media (max-width: 767px){.c-modal.c-modal--top.c-modal--large,.c-modal.c-modal--top.c-modal--fullWidthBelowMid.c-modal--medium{margin-block-start:var(--dt-spacing-none);max-block-size:100%}}.c-modal::backdrop{background:var(--dt-color-overlay)}@supports (hanging-punctuation: first) and (font: -apple-system-body) and (-webkit-appearance: none){.c-modal::backdrop{background:#0000008c}}.c-modal .c-modal-footer{--modal-button-spacing: var(--dt-spacing-d);--modal-footer-padding: var(--dt-spacing-d);display:flex;flex-flow:row-reverse;flex-wrap:wrap;gap:var(--modal-button-spacing);padding:var(--modal-footer-padding)}@media (min-width: 769px){.c-modal .c-modal-footer{--modal-footer-padding: var(--dt-spacing-e)}}@media (max-width: 767px){.c-modal .c-modal-footer.c-modal-footer--stackedActions{flex-direction:column}}.c-modal ::slotted([slot=footer]){display:flex;width:100%}.c-modal .c-modal-header{display:grid;grid-template-areas:"back heading close";grid-template-columns:minmax(0,max-content) minmax(0,1fr) minmax(0,max-content);align-items:start}.c-modal .c-modal-heading{--modal-header-font-size: calc(var(--dt-font-heading-m-size--narrow) * 1px);--modal-header-font-line-height: calc(var(--dt-font-heading-m-line-height--narrow) * 1px);--modal-header-font-weight: var(--dt-font-heading-m-weight);font-size:var(--modal-header-font-size);line-height:var(--modal-header-font-line-height);font-weight:var(--modal-header-font-weight);margin:0;grid-area:heading;margin-inline-start:var(--dt-spacing-d);margin-inline-end:var(--dt-spacing-d);margin-block:14px}@media (min-width: 769px){.c-modal .c-modal-heading{--modal-header-font-size: calc(var(--dt-font-heading-m-size--wide) * 1px);--modal-header-font-line-height: calc(var(--dt-font-heading-m-line-height--wide) * 1px);margin-inline-start:var(--dt-spacing-e);margin-inline-end:var(--dt-spacing-e);margin-block:20px}}.c-modal .c-modal-backBtn+.c-modal-heading{margin-inline-start:var(--dt-spacing-b)}@media (min-width: 769px){.c-modal .c-modal-backBtn+.c-modal-heading{margin-inline-start:var(--dt-spacing-c)}}.c-modal.c-modal--dismissible .c-modal-heading{margin-inline-end:var(--dt-spacing-d)}@media (min-width: 769px){.c-modal.c-modal--dismissible .c-modal-heading{margin-inline-end:var(--dt-spacing-e)}}.c-modal .c-modal-backBtn{grid-area:back;margin-block-start:var(--dt-spacing-b);margin-block-end:var(--dt-spacing-b);margin-inline-start:var(--dt-spacing-b);margin-inline-end:var(--dt-spacing-none)}@media (min-width: 769px){.c-modal .c-modal-backBtn{margin-block-start:var(--dt-spacing-c);margin-block-end:var(--dt-spacing-c);margin-inline-start:var(--dt-spacing-c);margin-inline-end:var(--dt-spacing-none)}}.c-modal .c-modal-closeBtn{grid-area:close;margin-block-start:var(--dt-spacing-b);margin-block-end:var(--dt-spacing-b);margin-inline-start:var(--dt-spacing-none);margin-inline-end:var(--dt-spacing-b)}@media (min-width: 769px){.c-modal .c-modal-closeBtn{margin-block-start:var(--dt-spacing-c);margin-block-end:var(--dt-spacing-c);margin-inline-start:var(--dt-spacing-none);margin-inline-end:var(--dt-spacing-c)}}.c-modal .c-modal-content{--modal-content-font-size: calc(var(--dt-font-size-16) * 1px);--modal-content-font-weight: var(--dt-font-weight-regular);--modal-content-line-height: calc(var(--dt-font-size-16-line-height) * 1px);--modal-content-padding-block: var(--dt-spacing-a);--modal-content-padding-inline: var(--dt-spacing-d);--modal-content-padding-block-end: var(--dt-spacing-e);--modal-content-min-block-size: var(--dt-spacing-j);position:relative;min-block-size:calc(var(--modal-content-min-block-size) + var(--modal-content-padding-block) + var(--modal-content-padding-block-end));font-size:var(--modal-content-font-size);line-height:var(--modal-content-line-height);font-weight:var(--modal-content-font-weight);padding-inline-start:var(--modal-content-padding-inline);padding-inline-end:var(--modal-content-padding-inline);padding-block-start:var(--modal-content-padding-block);padding-block-end:var(--modal-content-padding-block-end);flex-grow:1}@media (min-width: 769px){.c-modal .c-modal-content{--modal-content-padding-inline: var(--dt-spacing-e)}}.c-modal .c-modal-content:has(+slot>footer){padding-block-end:var(--modal-content-padding-block);min-block-size:var(--modal-content-min-block-size)}.c-modal .c-modal-content--scrollable{background:linear-gradient(to bottom,transparent,var(--dt-color-container-default) 75%) center bottom,linear-gradient(transparent,var(--dt-color-border-strong)) center bottom;background-repeat:no-repeat;background-size:100% 48px,100% 12px;background-attachment:local,scroll}.c-modal>.c-modal-scrollContainer{display:flex;flex-direction:column;overflow-y:auto;--bg-scroll-end: linear-gradient(rgba(255, 255, 255, 0), var(--dt-color-container-default) 70%) 0 100%;--bg-scroll-bottom: radial-gradient(farthest-corner at 50% 100%, rgba(0, 0, 0, .3), rgba(0, 0, 0, 0)) 0 100%;--bg-size-scroll-end: 100% 40px;--bg-size-scroll-bottom: 100% 8px;background:var(--bg-scroll-end),var(--bg-scroll-bottom);background-repeat:no-repeat;background-size:var(--bg-size-scroll-end),var(--bg-size-scroll-bottom);background-attachment:local,scroll}.c-modal>.c-modal-scrollContainer .c-modal-content{flex-shrink:0}.c-modal.c-modal--pinnedFooter .c-modal-content{overflow-y:auto}.c-modal.c-modal--loading .c-modal-content pie-spinner{position:absolute;left:50%;top:calc(50% - (var(--modal-content-padding-block-end) - var(--modal-content-padding-block)) / 2);transform:translate(-50%,-50%)}.c-modal.c-modal--loading .c-modal-content .c-modal-contentInner{display:none}.c-modal.c-modal--loading .c-modal-content:not(:last-child) pie-spinner{top:50%}@supports not (aspect-ratio: 1/1){.c-modal .c-modal-scrollContainer{background:none}}', G = ["h1", "h2", "h3", "h4", "h5", "h6"], J = ["small", "medium", "large"], Q = ["top", "center"], S = "pie-modal-close", _ = "pie-modal-open", L = "pie-modal-back", Z = "pie-modal-leading-action-click", ee = "pie-modal-supporting-action-click", s = {
|
|
85
85
|
hasBackButton: !1,
|
|
86
86
|
hasStackedActions: !1,
|
|
87
87
|
headingLevel: "h2",
|
|
@@ -93,61 +93,62 @@ const X = '*,*:after,*:before{box-sizing:inherit}dialog{position:absolute;left:0
|
|
|
93
93
|
position: "center",
|
|
94
94
|
size: "medium"
|
|
95
95
|
};
|
|
96
|
-
var oe = Object.defineProperty, te = Object.getOwnPropertyDescriptor, l = (
|
|
97
|
-
for (var a = i > 1 ? void 0 : i ? te(
|
|
98
|
-
(p =
|
|
99
|
-
return i && a && oe(
|
|
96
|
+
var oe = Object.defineProperty, te = Object.getOwnPropertyDescriptor, l = (e, o, t, i) => {
|
|
97
|
+
for (var a = i > 1 ? void 0 : i ? te(o, t) : o, c = e.length - 1, p; c >= 0; c--)
|
|
98
|
+
(p = e[c]) && (a = (i ? p(o, t, a) : p(a)) || a);
|
|
99
|
+
return i && a && oe(o, t, a), a;
|
|
100
100
|
};
|
|
101
101
|
const w = "pie-modal";
|
|
102
102
|
let n = class extends I(x) {
|
|
103
103
|
constructor() {
|
|
104
|
-
super(...arguments), this.headingLevel = s.headingLevel, this.hasBackButton = s.hasBackButton, this.hasStackedActions = s.hasStackedActions, this.isDismissible = s.isDismissible, this.isFooterPinned = s.isFooterPinned, this.isFullWidthBelowMid = s.isFullWidthBelowMid, this.isLoading = s.isLoading, this.isOpen = s.isOpen, this.position = s.position, this.size = s.size, this._backButtonClicked = !1, this._escKeyAbortController = null, this._preventModalKeyboardDismissal = (
|
|
105
|
-
|
|
106
|
-
}, this._handleDialogLightDismiss = (
|
|
107
|
-
if (!this.isDismissible ||
|
|
104
|
+
super(...arguments), this.headingLevel = s.headingLevel, this.hasBackButton = s.hasBackButton, this.hasStackedActions = s.hasStackedActions, this.isDismissible = s.isDismissible, this.isFooterPinned = s.isFooterPinned, this.isFullWidthBelowMid = s.isFullWidthBelowMid, this.isLoading = s.isLoading, this.isOpen = s.isOpen, this.position = s.position, this.size = s.size, this._scrollableContainer = null, this._backButtonClicked = !1, this._escKeyAbortController = null, this._preventModalKeyboardDismissal = (e) => {
|
|
105
|
+
e.key === "Escape" && e.preventDefault();
|
|
106
|
+
}, this._handleDialogLightDismiss = (e) => {
|
|
107
|
+
if (!this.isDismissible || e.target !== e.currentTarget)
|
|
108
108
|
return;
|
|
109
|
-
const
|
|
109
|
+
const o = this._dialog.getBoundingClientRect(), {
|
|
110
110
|
top: t = 0,
|
|
111
111
|
bottom: i = 0,
|
|
112
112
|
left: a = 0,
|
|
113
113
|
right: c = 0
|
|
114
|
-
} =
|
|
114
|
+
} = o || {};
|
|
115
115
|
if (t === 0 && i === 0 && a === 0 && c === 0)
|
|
116
116
|
return;
|
|
117
|
-
(
|
|
117
|
+
(e.clientY < t || e.clientY > i || e.clientX < a || e.clientX > c) && (this.isOpen = !1);
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
get _modalScrollContainer() {
|
|
121
|
-
|
|
121
|
+
var e;
|
|
122
|
+
return this._scrollableContainer || (this._scrollableContainer = (e = this._dialog) == null ? void 0 : e.querySelector(".c-modal-scrollContainer")), this._scrollableContainer;
|
|
122
123
|
}
|
|
123
124
|
connectedCallback() {
|
|
124
125
|
super.connectedCallback(), this._abortController = new AbortController();
|
|
125
|
-
const { signal:
|
|
126
|
-
this.addEventListener("click", (
|
|
126
|
+
const { signal: e } = this._abortController;
|
|
127
|
+
this.addEventListener("click", (o) => this._handleDialogLightDismiss(o)), this._setupEscKeyListener(), document.addEventListener(_, (o) => this._handleModalOpened(o), { signal: e }), document.addEventListener(S, (o) => this._handleModalClosed(o), { signal: e }), document.addEventListener(L, (o) => this._handleModalClosed(o), { signal: e });
|
|
127
128
|
}
|
|
128
129
|
disconnectedCallback() {
|
|
129
130
|
super.disconnectedCallback(), this._abortController.abort(), this._enableBodyScroll(), this._removeEscKeyEventListener();
|
|
130
131
|
}
|
|
131
|
-
async firstUpdated(
|
|
132
|
+
async firstUpdated(e) {
|
|
132
133
|
(await import("./dialog-polyfill.esm-CbjBMXAG.js").then((i) => i.default)).registerDialog(this._dialog);
|
|
133
134
|
const { signal: t } = this._abortController;
|
|
134
135
|
this._dialog.addEventListener("close", () => {
|
|
135
136
|
this.isOpen = !1;
|
|
136
|
-
}, { signal: t }), this._handleModalOpenStateOnFirstRender(
|
|
137
|
+
}, { signal: t }), this._handleModalOpenStateOnFirstRender(e);
|
|
137
138
|
}
|
|
138
|
-
updated(
|
|
139
|
-
this._handleModalOpenStateChanged(
|
|
139
|
+
updated(e) {
|
|
140
|
+
this._handleModalOpenStateChanged(e), this._handleIsDismissibleChanged(e);
|
|
140
141
|
}
|
|
141
|
-
_handleIsDismissibleChanged(
|
|
142
|
-
const
|
|
143
|
-
!
|
|
142
|
+
_handleIsDismissibleChanged(e) {
|
|
143
|
+
const o = e.get("isDismissible"), t = this.isDismissible;
|
|
144
|
+
!o && t && this._removeEscKeyEventListener(), o && !t && this._setupEscKeyListener();
|
|
144
145
|
}
|
|
145
146
|
/**
|
|
146
147
|
* Opens the dialog element and disables page scrolling
|
|
147
148
|
*/
|
|
148
|
-
_handleModalOpened(
|
|
149
|
-
const { targetModal:
|
|
150
|
-
if (
|
|
149
|
+
_handleModalOpened(e) {
|
|
150
|
+
const { targetModal: o } = e.detail;
|
|
151
|
+
if (o === this) {
|
|
151
152
|
if (this._dialog.hasAttribute("open") || !this._dialog.isConnected)
|
|
152
153
|
return;
|
|
153
154
|
this._dialog.showModal(), requestAnimationFrame(() => {
|
|
@@ -158,9 +159,9 @@ let n = class extends I(x) {
|
|
|
158
159
|
/**
|
|
159
160
|
* Closes the dialog element and re-enables page scrolling
|
|
160
161
|
*/
|
|
161
|
-
_handleModalClosed(
|
|
162
|
-
const { targetModal:
|
|
163
|
-
|
|
162
|
+
_handleModalClosed(e) {
|
|
163
|
+
const { targetModal: o } = e.detail;
|
|
164
|
+
o === this && (this._enableBodyScroll(), this._dialog.close(), this._returnFocus(), this._removeEscKeyEventListener());
|
|
164
165
|
}
|
|
165
166
|
/**
|
|
166
167
|
* Sets up an event listener on the Escape key to prevent dismissing the modal if isDismissible is false
|
|
@@ -168,43 +169,43 @@ let n = class extends I(x) {
|
|
|
168
169
|
_setupEscKeyListener() {
|
|
169
170
|
if (!this._escKeyAbortController && !this.isDismissible) {
|
|
170
171
|
this._escKeyAbortController = new AbortController();
|
|
171
|
-
const { signal:
|
|
172
|
-
document.addEventListener("keydown", (
|
|
172
|
+
const { signal: e } = this._escKeyAbortController;
|
|
173
|
+
document.addEventListener("keydown", (o) => this._preventModalKeyboardDismissal(o), { signal: e });
|
|
173
174
|
}
|
|
174
175
|
}
|
|
175
176
|
/**
|
|
176
177
|
* Removes any event listeners set up that are listening to keyboard events and nulls the existing AbortController.
|
|
177
178
|
*/
|
|
178
179
|
_removeEscKeyEventListener() {
|
|
179
|
-
var
|
|
180
|
-
(
|
|
180
|
+
var e;
|
|
181
|
+
(e = this._escKeyAbortController) == null || e.abort(), this._escKeyAbortController = null;
|
|
181
182
|
}
|
|
182
183
|
// Handles the value of the isOpen property on first render of the component
|
|
183
|
-
_handleModalOpenStateOnFirstRender(
|
|
184
|
-
|
|
184
|
+
_handleModalOpenStateOnFirstRender(e) {
|
|
185
|
+
e.get("isOpen") === void 0 && this.isOpen && h(this, _, { targetModal: this });
|
|
185
186
|
}
|
|
186
187
|
// Handles changes to the modal isOpen property by dispatching any appropriate events
|
|
187
|
-
_handleModalOpenStateChanged(
|
|
188
|
-
const
|
|
189
|
-
|
|
188
|
+
_handleModalOpenStateChanged(e) {
|
|
189
|
+
const o = e.get("isOpen");
|
|
190
|
+
o !== void 0 && (o ? this._backButtonClicked ? (this._backButtonClicked = !1, h(this, L, { targetModal: this })) : h(this, S, { targetModal: this }) : h(this, _, { targetModal: this }));
|
|
190
191
|
}
|
|
191
|
-
_handleActionClick(
|
|
192
|
-
|
|
192
|
+
_handleActionClick(e) {
|
|
193
|
+
e === "leading" ? (this._dialog.close("leading"), h(this, Z, { targetModal: this })) : e === "supporting" && (this._dialog.close("supporting"), h(this, ee, { targetModal: this }));
|
|
193
194
|
}
|
|
194
195
|
/**
|
|
195
196
|
* Return focus to the specified element, providing the selector is valid
|
|
196
197
|
* and the chosen element can be found.
|
|
197
198
|
*/
|
|
198
199
|
_returnFocus() {
|
|
199
|
-
var
|
|
200
|
-
const
|
|
201
|
-
|
|
200
|
+
var o, t;
|
|
201
|
+
const e = (o = this.returnFocusAfterCloseSelector) == null ? void 0 : o.trim();
|
|
202
|
+
e && ((t = document.querySelector(e)) == null || t.focus());
|
|
202
203
|
}
|
|
203
204
|
/**
|
|
204
205
|
* Enables body scroll by unlocking the scroll container.
|
|
205
206
|
*/
|
|
206
207
|
_enableBodyScroll() {
|
|
207
|
-
this.
|
|
208
|
+
this._scrollableContainer && U(this._scrollableContainer);
|
|
208
209
|
}
|
|
209
210
|
/**
|
|
210
211
|
* Disables body scroll by locking the scroll container.
|
|
@@ -219,7 +220,7 @@ let n = class extends I(x) {
|
|
|
219
220
|
* @private
|
|
220
221
|
*/
|
|
221
222
|
renderCloseButton() {
|
|
222
|
-
var
|
|
223
|
+
var e;
|
|
223
224
|
return this.isDismissible ? r`
|
|
224
225
|
<pie-icon-button
|
|
225
226
|
@click="${() => {
|
|
@@ -227,7 +228,7 @@ let n = class extends I(x) {
|
|
|
227
228
|
}}"
|
|
228
229
|
variant="ghost-secondary"
|
|
229
230
|
class="c-modal-closeBtn"
|
|
230
|
-
aria-label="${((
|
|
231
|
+
aria-label="${((e = this.aria) == null ? void 0 : e.close) || g}"
|
|
231
232
|
data-test-id="modal-close-button">
|
|
232
233
|
<icon-close></icon-close>
|
|
233
234
|
</pie-icon-button>` : g;
|
|
@@ -239,7 +240,7 @@ let n = class extends I(x) {
|
|
|
239
240
|
* @private
|
|
240
241
|
*/
|
|
241
242
|
renderBackButton() {
|
|
242
|
-
var
|
|
243
|
+
var e;
|
|
243
244
|
return this.hasBackButton ? r`
|
|
244
245
|
<pie-icon-button
|
|
245
246
|
@click="${() => {
|
|
@@ -247,7 +248,7 @@ let n = class extends I(x) {
|
|
|
247
248
|
}}"
|
|
248
249
|
variant="ghost-secondary"
|
|
249
250
|
class="c-modal-backBtn"
|
|
250
|
-
aria-label="${
|
|
251
|
+
aria-label="${b((e = this.aria) == null ? void 0 : e.back)}"
|
|
251
252
|
data-test-id="modal-back-button">
|
|
252
253
|
${this.isRTL ? r`<icon-chevron-right></icon-chevron-right>` : r`<icon-chevron-left></icon-chevron-left>`}
|
|
253
254
|
</pie-icon-button>
|
|
@@ -263,16 +264,16 @@ let n = class extends I(x) {
|
|
|
263
264
|
* @private
|
|
264
265
|
*/
|
|
265
266
|
renderLeadingAction() {
|
|
266
|
-
const { ariaLabel:
|
|
267
|
-
return
|
|
267
|
+
const { ariaLabel: e, text: o, variant: t = "primary" } = this.leadingAction || {};
|
|
268
|
+
return o ? r`
|
|
268
269
|
<pie-button
|
|
269
270
|
variant="${t}"
|
|
270
|
-
aria-label="${
|
|
271
|
+
aria-label="${b(e)}"
|
|
271
272
|
type="submit"
|
|
272
273
|
?isFullWidth="${this.hasStackedActions}"
|
|
273
274
|
@click="${() => this._handleActionClick("leading")}"
|
|
274
275
|
data-test-id="modal-leading-action">
|
|
275
|
-
${
|
|
276
|
+
${o}
|
|
276
277
|
</pie-button>
|
|
277
278
|
` : g;
|
|
278
279
|
}
|
|
@@ -288,16 +289,16 @@ let n = class extends I(x) {
|
|
|
288
289
|
*/
|
|
289
290
|
renderSupportingAction() {
|
|
290
291
|
var i;
|
|
291
|
-
const { ariaLabel:
|
|
292
|
-
return !
|
|
292
|
+
const { ariaLabel: e, text: o, variant: t = "ghost" } = this.supportingAction || {};
|
|
293
|
+
return !o || !((i = this.leadingAction) != null && i.text) ? g : r`
|
|
293
294
|
<pie-button
|
|
294
295
|
variant="${t}"
|
|
295
|
-
aria-label="${
|
|
296
|
+
aria-label="${b(e)}"
|
|
296
297
|
type="reset"
|
|
297
298
|
?isFullWidth="${this.hasStackedActions}"
|
|
298
299
|
@click="${() => this._handleActionClick("supporting")}"
|
|
299
300
|
data-test-id="modal-supporting-action">
|
|
300
|
-
${
|
|
301
|
+
${o}
|
|
301
302
|
</pie-button>
|
|
302
303
|
`;
|
|
303
304
|
}
|
|
@@ -309,13 +310,13 @@ let n = class extends I(x) {
|
|
|
309
310
|
*/
|
|
310
311
|
renderModalFooter() {
|
|
311
312
|
var i, a;
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
const
|
|
313
|
+
const e = (i = this.leadingAction) == null ? void 0 : i.text;
|
|
314
|
+
e || (a = this.supportingAction) != null && a.text && console.warn("You cannot have a supporting action without a leading action. If you only need one button then use a leading action instead.");
|
|
315
|
+
const o = {
|
|
315
316
|
"c-modal-footer": !0,
|
|
316
317
|
"c-modal-footer--stackedActions": this.hasStackedActions
|
|
317
|
-
}, t =
|
|
318
|
-
<footer class="${B(
|
|
318
|
+
}, t = e ? r`
|
|
319
|
+
<footer class="${B(o)}" data-test-id="pie-modal-footer">
|
|
319
320
|
${this.renderLeadingAction()}
|
|
320
321
|
${this.renderSupportingAction()}
|
|
321
322
|
</footer>` : g;
|
|
@@ -350,27 +351,27 @@ let n = class extends I(x) {
|
|
|
350
351
|
* @private
|
|
351
352
|
*/
|
|
352
353
|
renderHeading() {
|
|
353
|
-
const { heading:
|
|
354
|
+
const { heading: e, headingLevel: o } = this, t = T(o);
|
|
354
355
|
return r`
|
|
355
356
|
<${t} class="c-modal-heading">
|
|
356
|
-
${
|
|
357
|
+
${e}
|
|
357
358
|
</${t}>
|
|
358
359
|
`;
|
|
359
360
|
}
|
|
360
361
|
render() {
|
|
361
362
|
const {
|
|
362
|
-
aria:
|
|
363
|
-
isDismissible:
|
|
363
|
+
aria: e,
|
|
364
|
+
isDismissible: o,
|
|
364
365
|
isFooterPinned: t,
|
|
365
366
|
isFullWidthBelowMid: i,
|
|
366
367
|
isLoading: a,
|
|
367
368
|
position: c,
|
|
368
369
|
size: p
|
|
369
|
-
} = this, $ = a && (
|
|
370
|
+
} = this, $ = a && (e == null ? void 0 : e.loading) || void 0, E = {
|
|
370
371
|
"c-modal": !0,
|
|
371
372
|
[`c-modal--${p}`]: !0,
|
|
372
373
|
"c-modal--top": c === "top",
|
|
373
|
-
"c-modal--dismissible":
|
|
374
|
+
"c-modal--dismissible": o,
|
|
374
375
|
"c-modal--loading": a,
|
|
375
376
|
"c-modal--pinnedFooter": t,
|
|
376
377
|
"c-modal--fullWidthBelowMid": i
|
|
@@ -380,7 +381,7 @@ let n = class extends I(x) {
|
|
|
380
381
|
id="dialog"
|
|
381
382
|
class="${B(E)}"
|
|
382
383
|
aria-busy="${a ? "true" : "false"}"
|
|
383
|
-
aria-label="${
|
|
384
|
+
aria-label="${b($)}"
|
|
384
385
|
data-test-id="pie-modal">
|
|
385
386
|
<header class="c-modal-header" data-test-id="modal-header">
|
|
386
387
|
${this.renderBackButton()}
|
package/dist/react.d.ts
CHANGED
|
@@ -169,6 +169,7 @@ declare class PieModal_2 extends PieModal_base implements ModalProps {
|
|
|
169
169
|
size: "medium" | "large" | "small";
|
|
170
170
|
supportingAction: ModalProps['supportingAction'];
|
|
171
171
|
private _dialog;
|
|
172
|
+
private _scrollableContainer;
|
|
172
173
|
private _backButtonClicked;
|
|
173
174
|
private _abortController;
|
|
174
175
|
private _escKeyAbortController;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-modal",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "PIE design system modal built using web components",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
"license": "Apache-2.0",
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@custom-elements-manifest/analyzer": "0.9.0",
|
|
42
|
-
"@justeat/pie-design-tokens": "7.
|
|
42
|
+
"@justeat/pie-design-tokens": "7.2.0",
|
|
43
43
|
"@justeattakeaway/pie-button": "1.6.6",
|
|
44
44
|
"@justeattakeaway/pie-components-config": "0.21.0",
|
|
45
|
-
"@justeattakeaway/pie-css": "0.
|
|
45
|
+
"@justeattakeaway/pie-css": "0.19.0",
|
|
46
46
|
"@justeattakeaway/pie-monorepo-utils": "0.6.0",
|
|
47
|
-
"@justeattakeaway/pie-text-input": "0.28.
|
|
47
|
+
"@justeattakeaway/pie-text-input": "0.28.11",
|
|
48
48
|
"@justeattakeaway/pie-wrapper-react": "0.14.3",
|
|
49
49
|
"@types/body-scroll-lock": "3.1.2",
|
|
50
50
|
"cem-plugin-module-file-extensions": "0.0.5"
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@justeattakeaway/pie-button": "1.6.6",
|
|
57
|
-
"@justeattakeaway/pie-icon-button": "2.0.
|
|
58
|
-
"@justeattakeaway/pie-icons-webc": "1.14.
|
|
57
|
+
"@justeattakeaway/pie-icon-button": "2.0.5",
|
|
58
|
+
"@justeattakeaway/pie-icons-webc": "1.14.1",
|
|
59
59
|
"@justeattakeaway/pie-spinner": "1.2.4",
|
|
60
60
|
"@justeattakeaway/pie-webc-core": "1.0.0",
|
|
61
61
|
"body-scroll-lock": "3.1.5",
|
package/src/index.ts
CHANGED
|
@@ -110,6 +110,8 @@ export class PieModal extends RtlMixin(PieElement) implements ModalProps {
|
|
|
110
110
|
@query('dialog')
|
|
111
111
|
private _dialog!: HTMLDialogElement;
|
|
112
112
|
|
|
113
|
+
private _scrollableContainer: HTMLElement | null = null;
|
|
114
|
+
|
|
113
115
|
private _backButtonClicked = false;
|
|
114
116
|
|
|
115
117
|
private _abortController!: AbortController;
|
|
@@ -119,7 +121,12 @@ export class PieModal extends RtlMixin(PieElement) implements ModalProps {
|
|
|
119
121
|
private _escKeyAbortController: AbortController | null = null;
|
|
120
122
|
|
|
121
123
|
private get _modalScrollContainer (): Element | null {
|
|
122
|
-
|
|
124
|
+
// Cache the scrollable container to avoid race conditions where it has been removed during disconnectedCallback
|
|
125
|
+
if (!this._scrollableContainer) {
|
|
126
|
+
this._scrollableContainer = this._dialog?.querySelector<HTMLElement>('.c-modal-scrollContainer');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return this._scrollableContainer;
|
|
123
130
|
}
|
|
124
131
|
|
|
125
132
|
// Renders a `CSSResult` generated from SCSS by Vite
|
|
@@ -200,7 +207,7 @@ export class PieModal extends RtlMixin(PieElement) implements ModalProps {
|
|
|
200
207
|
1. Use requestAnimationFrame to defer non-blocking operations.
|
|
201
208
|
2. Batch non-blocking updates inside requestAnimationFrame
|
|
202
209
|
3. Call `showModal()` first and defer `_disableBodyScroll` & `_setupEscKeyListener`
|
|
203
|
-
|
|
210
|
+
to the next `task`.
|
|
204
211
|
*/
|
|
205
212
|
requestAnimationFrame(() => {
|
|
206
213
|
// Read styles before writing them to avoid forced layout recalculations (layout trashing).
|
|
@@ -319,8 +326,8 @@ export class PieModal extends RtlMixin(PieElement) implements ModalProps {
|
|
|
319
326
|
* Enables body scroll by unlocking the scroll container.
|
|
320
327
|
*/
|
|
321
328
|
private _enableBodyScroll (): void {
|
|
322
|
-
if (this.
|
|
323
|
-
enableBodyScroll(this.
|
|
329
|
+
if (this._scrollableContainer) {
|
|
330
|
+
enableBodyScroll(this._scrollableContainer);
|
|
324
331
|
}
|
|
325
332
|
}
|
|
326
333
|
|
package/src/modal.scss
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
--modal-border-radius: var(--dt-radius-rounded-d);
|
|
15
15
|
--modal-font: var(--dt-font-interactive-l-family);
|
|
16
16
|
--modal-bg-color: var(--dt-color-container-default);
|
|
17
|
-
--modal-elevation: var(--dt-elevation-
|
|
17
|
+
--modal-elevation: var(--dt-elevation-below-20);
|
|
18
18
|
|
|
19
19
|
&:focus-visible {
|
|
20
20
|
outline: none;
|