@justeattakeaway/pie-modal 0.48.0 → 0.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +51 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +167 -142
- package/dist/react.d.ts +16 -1
- package/package.json +8 -8
- package/src/defs-react.ts +1 -1
- package/src/index.ts +78 -25
- package/src/react.ts +2 -2
package/custom-elements.json
CHANGED
|
@@ -306,6 +306,15 @@
|
|
|
306
306
|
},
|
|
307
307
|
"privacy": "private"
|
|
308
308
|
},
|
|
309
|
+
{
|
|
310
|
+
"kind": "field",
|
|
311
|
+
"name": "_escKeyAbortController",
|
|
312
|
+
"type": {
|
|
313
|
+
"text": "AbortController | null"
|
|
314
|
+
},
|
|
315
|
+
"privacy": "private",
|
|
316
|
+
"default": "null"
|
|
317
|
+
},
|
|
309
318
|
{
|
|
310
319
|
"kind": "field",
|
|
311
320
|
"name": "_modalScrollContainer",
|
|
@@ -315,6 +324,19 @@
|
|
|
315
324
|
"privacy": "private",
|
|
316
325
|
"readonly": true
|
|
317
326
|
},
|
|
327
|
+
{
|
|
328
|
+
"kind": "method",
|
|
329
|
+
"name": "_handleIsDismissibleChanged",
|
|
330
|
+
"privacy": "private",
|
|
331
|
+
"parameters": [
|
|
332
|
+
{
|
|
333
|
+
"name": "changedProperties",
|
|
334
|
+
"type": {
|
|
335
|
+
"text": "PropertyValues<this>"
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
]
|
|
339
|
+
},
|
|
318
340
|
{
|
|
319
341
|
"kind": "method",
|
|
320
342
|
"name": "_handleModalOpened",
|
|
@@ -353,9 +375,26 @@
|
|
|
353
375
|
],
|
|
354
376
|
"description": "Closes the dialog element and re-enables page scrolling"
|
|
355
377
|
},
|
|
378
|
+
{
|
|
379
|
+
"kind": "method",
|
|
380
|
+
"name": "_setupEscKeyListener",
|
|
381
|
+
"privacy": "private",
|
|
382
|
+
"return": {
|
|
383
|
+
"type": {
|
|
384
|
+
"text": "void"
|
|
385
|
+
}
|
|
386
|
+
},
|
|
387
|
+
"description": "Sets up an event listener on the Escape key to prevent dismissing the modal if isDismissible is false"
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"kind": "method",
|
|
391
|
+
"name": "_removeEscKeyEventListener",
|
|
392
|
+
"privacy": "private",
|
|
393
|
+
"description": "Removes any event listeners set up that are listening to keyboard events and nulls the existing AbortController."
|
|
394
|
+
},
|
|
356
395
|
{
|
|
357
396
|
"kind": "field",
|
|
358
|
-
"name": "
|
|
397
|
+
"name": "_preventModalKeyboardDismissal",
|
|
359
398
|
"privacy": "private",
|
|
360
399
|
"description": "Prevents the user from dismissing the dialog via the `cancel`\nevent (ESC key) when `isDismissible` is set to false.",
|
|
361
400
|
"parameters": [
|
|
@@ -532,6 +571,17 @@
|
|
|
532
571
|
},
|
|
533
572
|
"description": "Renders the modal inner content and footer of the modal."
|
|
534
573
|
},
|
|
574
|
+
{
|
|
575
|
+
"kind": "method",
|
|
576
|
+
"name": "renderHeading",
|
|
577
|
+
"privacy": "private",
|
|
578
|
+
"return": {
|
|
579
|
+
"type": {
|
|
580
|
+
"text": "TemplateResult"
|
|
581
|
+
}
|
|
582
|
+
},
|
|
583
|
+
"description": "Renders the modal heading content in the correct heading tag"
|
|
584
|
+
},
|
|
535
585
|
{
|
|
536
586
|
"kind": "field",
|
|
537
587
|
"name": "_handleDialogLightDismiss",
|
package/dist/index.d.ts
CHANGED
|
@@ -170,12 +170,14 @@ export declare class PieModal extends PieModal_base implements ModalProps {
|
|
|
170
170
|
private _dialog;
|
|
171
171
|
private _backButtonClicked;
|
|
172
172
|
private _abortController;
|
|
173
|
+
private _escKeyAbortController;
|
|
173
174
|
private get _modalScrollContainer();
|
|
174
175
|
static styles: CSSResult;
|
|
175
176
|
connectedCallback(): void;
|
|
176
177
|
disconnectedCallback(): void;
|
|
177
178
|
firstUpdated(changedProperties: PropertyValues<this>): Promise<void>;
|
|
178
179
|
updated(changedProperties: PropertyValues<this>): void;
|
|
180
|
+
private _handleIsDismissibleChanged;
|
|
179
181
|
/**
|
|
180
182
|
* Opens the dialog element and disables page scrolling
|
|
181
183
|
*/
|
|
@@ -184,13 +186,21 @@ export declare class PieModal extends PieModal_base implements ModalProps {
|
|
|
184
186
|
* Closes the dialog element and re-enables page scrolling
|
|
185
187
|
*/
|
|
186
188
|
private _handleModalClosed;
|
|
189
|
+
/**
|
|
190
|
+
* Sets up an event listener on the Escape key to prevent dismissing the modal if isDismissible is false
|
|
191
|
+
*/
|
|
192
|
+
private _setupEscKeyListener;
|
|
193
|
+
/**
|
|
194
|
+
* Removes any event listeners set up that are listening to keyboard events and nulls the existing AbortController.
|
|
195
|
+
*/
|
|
196
|
+
private _removeEscKeyEventListener;
|
|
187
197
|
/**
|
|
188
198
|
* Prevents the user from dismissing the dialog via the `cancel`
|
|
189
199
|
* event (ESC key) when `isDismissible` is set to false.
|
|
190
200
|
*
|
|
191
201
|
* @param {Event} event - The event object.
|
|
192
202
|
*/
|
|
193
|
-
private
|
|
203
|
+
private _preventModalKeyboardDismissal;
|
|
194
204
|
private _handleModalOpenStateOnFirstRender;
|
|
195
205
|
private _handleModalOpenStateChanged;
|
|
196
206
|
private _handleActionClick;
|
|
@@ -259,6 +269,11 @@ export declare class PieModal extends PieModal_base implements ModalProps {
|
|
|
259
269
|
* @private
|
|
260
270
|
*/
|
|
261
271
|
private renderModalContentAndFooter;
|
|
272
|
+
/**
|
|
273
|
+
* Renders the modal heading content in the correct heading tag
|
|
274
|
+
* @private
|
|
275
|
+
*/
|
|
276
|
+
private renderHeading;
|
|
262
277
|
render(): TemplateResult;
|
|
263
278
|
/**
|
|
264
279
|
* Dismisses the modal on backdrop click if `isDismissible` is `true`.
|
package/dist/index.js
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
import { LitElement as
|
|
2
|
-
import { html as s, unsafeStatic as
|
|
3
|
-
import { property as d, query as
|
|
4
|
-
import { classMap as
|
|
5
|
-
import { ifDefined as
|
|
1
|
+
import { LitElement as F, unsafeCSS as T, nothing as p } from "lit";
|
|
2
|
+
import { html as s, unsafeStatic as P } from "lit/static-html.js";
|
|
3
|
+
import { property as d, query as K } from "lit/decorators.js";
|
|
4
|
+
import { classMap as B } from "lit/directives/class-map.js";
|
|
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
|
-
import { RtlMixin as
|
|
8
|
+
import { RtlMixin as I, dispatchCustomEvent as h, requiredProperty as N, validPropertyValues as _, defineCustomElement as W } from "@justeattakeaway/pie-webc-core";
|
|
9
9
|
import "@justeattakeaway/pie-icons-webc/dist/IconClose.js";
|
|
10
10
|
import "@justeattakeaway/pie-icons-webc/dist/IconChevronLeft.js";
|
|
11
11
|
import "@justeattakeaway/pie-icons-webc/dist/IconChevronRight.js";
|
|
12
12
|
import "@justeattakeaway/pie-spinner";
|
|
13
|
-
function
|
|
13
|
+
function R(n) {
|
|
14
14
|
if (Array.isArray(n)) {
|
|
15
|
-
for (var
|
|
16
|
-
e
|
|
17
|
-
return
|
|
15
|
+
for (var e = 0, o = Array(n.length); e < n.length; e++)
|
|
16
|
+
o[e] = n[e];
|
|
17
|
+
return o;
|
|
18
18
|
} else
|
|
19
19
|
return Array.from(n);
|
|
20
20
|
}
|
|
21
|
-
var
|
|
21
|
+
var x = !1;
|
|
22
22
|
if (typeof window < "u") {
|
|
23
|
-
var
|
|
23
|
+
var S = {
|
|
24
24
|
get passive() {
|
|
25
|
-
|
|
25
|
+
x = !0;
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
|
-
window.addEventListener("testPassive", null,
|
|
28
|
+
window.addEventListener("testPassive", null, S), window.removeEventListener("testPassive", null, S);
|
|
29
29
|
}
|
|
30
|
-
var
|
|
31
|
-
return m.some(function(
|
|
32
|
-
return !!(
|
|
30
|
+
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 = [], k = !1, M = -1, u = void 0, f = void 0, D = function(e) {
|
|
31
|
+
return m.some(function(o) {
|
|
32
|
+
return !!(o.options.allowTouchMove && o.options.allowTouchMove(e));
|
|
33
33
|
});
|
|
34
|
-
},
|
|
35
|
-
var
|
|
36
|
-
return D(
|
|
37
|
-
},
|
|
34
|
+
}, y = function(e) {
|
|
35
|
+
var o = e || window.event;
|
|
36
|
+
return D(o.target) || o.touches.length > 1 ? !0 : (o.preventDefault && o.preventDefault(), !1);
|
|
37
|
+
}, j = function(e) {
|
|
38
38
|
if (f === void 0) {
|
|
39
|
-
var
|
|
40
|
-
|
|
39
|
+
var o = !!e, t = window.innerWidth - document.documentElement.clientWidth;
|
|
40
|
+
o && t > 0 && (f = document.body.style.paddingRight, document.body.style.paddingRight = t + "px");
|
|
41
41
|
}
|
|
42
42
|
u === void 0 && (u = document.body.style.overflow, document.body.style.overflow = "hidden");
|
|
43
|
-
},
|
|
43
|
+
}, V = function() {
|
|
44
44
|
f !== void 0 && (document.body.style.paddingRight = f, f = void 0), u !== void 0 && (document.body.style.overflow = u, u = void 0);
|
|
45
|
-
},
|
|
46
|
-
return
|
|
47
|
-
},
|
|
48
|
-
var t =
|
|
49
|
-
return D(
|
|
50
|
-
},
|
|
51
|
-
if (!
|
|
45
|
+
}, Y = function(e) {
|
|
46
|
+
return e ? e.scrollHeight - e.scrollTop <= e.clientHeight : !1;
|
|
47
|
+
}, H = function(e, o) {
|
|
48
|
+
var t = e.targetTouches[0].clientY - M;
|
|
49
|
+
return D(e.target) ? !1 : o && o.scrollTop === 0 && t > 0 || Y(o) && t < 0 ? y(e) : (e.stopPropagation(), !0);
|
|
50
|
+
}, q = function(e, o) {
|
|
51
|
+
if (!e) {
|
|
52
52
|
console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.");
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
55
|
if (!m.some(function(i) {
|
|
56
|
-
return i.targetElement ===
|
|
56
|
+
return i.targetElement === e;
|
|
57
57
|
})) {
|
|
58
58
|
var t = {
|
|
59
|
-
targetElement:
|
|
59
|
+
targetElement: e,
|
|
60
60
|
options: {}
|
|
61
61
|
};
|
|
62
|
-
m = [].concat(
|
|
63
|
-
i.targetTouches.length === 1 && (
|
|
64
|
-
},
|
|
65
|
-
i.targetTouches.length === 1 &&
|
|
66
|
-
},
|
|
62
|
+
m = [].concat(R(m), [t]), O ? (e.ontouchstart = function(i) {
|
|
63
|
+
i.targetTouches.length === 1 && (M = i.targetTouches[0].clientY);
|
|
64
|
+
}, e.ontouchmove = function(i) {
|
|
65
|
+
i.targetTouches.length === 1 && H(i, e);
|
|
66
|
+
}, k || (document.addEventListener("touchmove", y, x ? { passive: !1 } : void 0), k = !0)) : j(o);
|
|
67
67
|
}
|
|
68
|
-
},
|
|
69
|
-
if (!
|
|
68
|
+
}, U = function(e) {
|
|
69
|
+
if (!e) {
|
|
70
70
|
console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.");
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
|
-
m = m.filter(function(
|
|
74
|
-
return
|
|
75
|
-
}),
|
|
73
|
+
m = m.filter(function(o) {
|
|
74
|
+
return o.targetElement !== e;
|
|
75
|
+
}), O ? (e.ontouchstart = null, e.ontouchmove = null, k && m.length === 0 && (document.removeEventListener("touchmove", y, x ? { passive: !1 } : void 0), k = !1)) : m.length || V();
|
|
76
76
|
};
|
|
77
|
-
const
|
|
77
|
+
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-04);border-radius:var(--modal-border-radius);border:none;box-shadow:var(--modal-elevation);font-family:var(--modal-font);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 .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:not(:last-child){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"], A = "pie-modal-close", w = "pie-modal-open", L = "pie-modal-back", Z = "pie-modal-leading-action-click", ee = "pie-modal-supporting-action-click", r = {
|
|
78
78
|
hasBackButton: !1,
|
|
79
79
|
hasStackedActions: !1,
|
|
80
80
|
headingLevel: "h2",
|
|
@@ -86,27 +86,27 @@ const Q = '*,*:after,*:before{box-sizing:inherit}dialog{position:absolute;left:0
|
|
|
86
86
|
position: "center",
|
|
87
87
|
size: "medium"
|
|
88
88
|
};
|
|
89
|
-
var
|
|
89
|
+
var oe = Object.defineProperty, l = (n, e, o, t) => {
|
|
90
90
|
for (var i = void 0, c = n.length - 1, g; c >= 0; c--)
|
|
91
|
-
(g = n[c]) && (i = g(
|
|
92
|
-
return i &&
|
|
91
|
+
(g = n[c]) && (i = g(e, o, i) || i);
|
|
92
|
+
return i && oe(e, o, i), i;
|
|
93
93
|
};
|
|
94
|
-
const v = "pie-modal",
|
|
94
|
+
const v = "pie-modal", C = class C extends I(F) {
|
|
95
95
|
constructor() {
|
|
96
|
-
super(...arguments), this.headingLevel = r.headingLevel, this.hasBackButton = r.hasBackButton, this.hasStackedActions = r.hasStackedActions, this.isDismissible = r.isDismissible, this.isFooterPinned = r.isFooterPinned, this.isFullWidthBelowMid = r.isFullWidthBelowMid, this.isLoading = r.isLoading, this.isOpen = r.isOpen, this.position = r.position, this.size = r.size, this._backButtonClicked = !1, this.
|
|
97
|
-
|
|
98
|
-
}, this._handleDialogLightDismiss = (
|
|
96
|
+
super(...arguments), this.headingLevel = r.headingLevel, this.hasBackButton = r.hasBackButton, this.hasStackedActions = r.hasStackedActions, this.isDismissible = r.isDismissible, this.isFooterPinned = r.isFooterPinned, this.isFullWidthBelowMid = r.isFullWidthBelowMid, this.isLoading = r.isLoading, this.isOpen = r.isOpen, this.position = r.position, this.size = r.size, this._backButtonClicked = !1, this._escKeyAbortController = null, this._preventModalKeyboardDismissal = (e) => {
|
|
97
|
+
e.key === "Escape" && e.preventDefault();
|
|
98
|
+
}, this._handleDialogLightDismiss = (e) => {
|
|
99
99
|
if (!this.isDismissible)
|
|
100
100
|
return;
|
|
101
|
-
const
|
|
101
|
+
const o = this._dialog.getBoundingClientRect(), {
|
|
102
102
|
top: t = 0,
|
|
103
103
|
bottom: i = 0,
|
|
104
104
|
left: c = 0,
|
|
105
105
|
right: g = 0
|
|
106
|
-
} =
|
|
106
|
+
} = o || {};
|
|
107
107
|
if (t === 0 && i === 0 && c === 0 && g === 0)
|
|
108
108
|
return;
|
|
109
|
-
(
|
|
109
|
+
(e.clientY < t || e.clientY > i || e.clientX < c || e.clientX > g) && (this.isOpen = !1);
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
get _modalScrollContainer() {
|
|
@@ -114,75 +114,93 @@ const v = "pie-modal", z = class z extends j(I) {
|
|
|
114
114
|
}
|
|
115
115
|
connectedCallback() {
|
|
116
116
|
super.connectedCallback(), this._abortController = new AbortController();
|
|
117
|
-
const { signal:
|
|
118
|
-
this.addEventListener("click", (
|
|
117
|
+
const { signal: e } = this._abortController;
|
|
118
|
+
this.addEventListener("click", (o) => this._handleDialogLightDismiss(o)), this._setupEscKeyListener(), document.addEventListener(w, (o) => this._handleModalOpened(o), { signal: e }), document.addEventListener(A, (o) => this._handleModalClosed(o), { signal: e }), document.addEventListener(L, (o) => this._handleModalClosed(o), { signal: e });
|
|
119
119
|
}
|
|
120
120
|
disconnectedCallback() {
|
|
121
|
-
this._abortController.abort(), this._enableBodyScroll(),
|
|
121
|
+
super.disconnectedCallback(), this._abortController.abort(), this._enableBodyScroll(), this._removeEscKeyEventListener();
|
|
122
122
|
}
|
|
123
|
-
async firstUpdated(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
this.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
this.
|
|
123
|
+
async firstUpdated(e) {
|
|
124
|
+
(await import("./dialog-polyfill.esm-CbjBMXAG.js").then((i) => i.default)).registerDialog(this._dialog);
|
|
125
|
+
const { signal: t } = this._abortController;
|
|
126
|
+
this._dialog.addEventListener("close", () => {
|
|
127
|
+
this.isOpen = !1;
|
|
128
|
+
}, { signal: t }), this._handleModalOpenStateOnFirstRender(e);
|
|
129
|
+
}
|
|
130
|
+
updated(e) {
|
|
131
|
+
this._handleModalOpenStateChanged(e), this._handleIsDismissibleChanged(e);
|
|
132
132
|
}
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
_handleIsDismissibleChanged(e) {
|
|
134
|
+
const o = e.get("isDismissible"), t = this.isDismissible;
|
|
135
|
+
!o && t && this._removeEscKeyEventListener(), o && !t && this._setupEscKeyListener();
|
|
135
136
|
}
|
|
136
137
|
/**
|
|
137
138
|
* Opens the dialog element and disables page scrolling
|
|
138
139
|
*/
|
|
139
|
-
_handleModalOpened(
|
|
140
|
-
const { targetModal:
|
|
141
|
-
if (
|
|
140
|
+
_handleModalOpened(e) {
|
|
141
|
+
const { targetModal: o } = e.detail;
|
|
142
|
+
if (o === this) {
|
|
142
143
|
if (this._disableBodyScroll(), this._dialog.hasAttribute("open") || !this._dialog.isConnected)
|
|
143
144
|
return;
|
|
144
|
-
this._dialog.showModal();
|
|
145
|
+
this._setupEscKeyListener(), this._dialog.showModal();
|
|
145
146
|
}
|
|
146
147
|
}
|
|
147
148
|
/**
|
|
148
149
|
* Closes the dialog element and re-enables page scrolling
|
|
149
150
|
*/
|
|
150
|
-
_handleModalClosed(
|
|
151
|
-
const { targetModal:
|
|
152
|
-
|
|
151
|
+
_handleModalClosed(e) {
|
|
152
|
+
const { targetModal: o } = e.detail;
|
|
153
|
+
o === this && (this._enableBodyScroll(), this._dialog.close(), this._returnFocus(), this._removeEscKeyEventListener());
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Sets up an event listener on the Escape key to prevent dismissing the modal if isDismissible is false
|
|
157
|
+
*/
|
|
158
|
+
_setupEscKeyListener() {
|
|
159
|
+
if (!this._escKeyAbortController && !this.isDismissible) {
|
|
160
|
+
this._escKeyAbortController = new AbortController();
|
|
161
|
+
const { signal: e } = this._escKeyAbortController;
|
|
162
|
+
document.addEventListener("keydown", (o) => this._preventModalKeyboardDismissal(o), { signal: e });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Removes any event listeners set up that are listening to keyboard events and nulls the existing AbortController.
|
|
167
|
+
*/
|
|
168
|
+
_removeEscKeyEventListener() {
|
|
169
|
+
var e;
|
|
170
|
+
(e = this._escKeyAbortController) == null || e.abort(), this._escKeyAbortController = null;
|
|
153
171
|
}
|
|
154
172
|
// Handles the value of the isOpen property on first render of the component
|
|
155
|
-
_handleModalOpenStateOnFirstRender(
|
|
156
|
-
|
|
173
|
+
_handleModalOpenStateOnFirstRender(e) {
|
|
174
|
+
e.get("isOpen") === void 0 && this.isOpen && h(this, w, { targetModal: this });
|
|
157
175
|
}
|
|
158
176
|
// Handles changes to the modal isOpen property by dispatching any appropriate events
|
|
159
|
-
_handleModalOpenStateChanged(
|
|
160
|
-
const
|
|
161
|
-
|
|
177
|
+
_handleModalOpenStateChanged(e) {
|
|
178
|
+
const o = e.get("isOpen");
|
|
179
|
+
o !== void 0 && (o ? this._backButtonClicked ? (this._backButtonClicked = !1, h(this, L, { targetModal: this })) : h(this, A, { targetModal: this }) : h(this, w, { targetModal: this }));
|
|
162
180
|
}
|
|
163
|
-
_handleActionClick(
|
|
164
|
-
|
|
181
|
+
_handleActionClick(e) {
|
|
182
|
+
e === "leading" ? (this._dialog.close("leading"), h(this, Z, { targetModal: this })) : e === "supporting" && (this._dialog.close("supporting"), h(this, ee, { targetModal: this }));
|
|
165
183
|
}
|
|
166
184
|
/**
|
|
167
185
|
* Return focus to the specified element, providing the selector is valid
|
|
168
186
|
* and the chosen element can be found.
|
|
169
187
|
*/
|
|
170
188
|
_returnFocus() {
|
|
171
|
-
var
|
|
172
|
-
const
|
|
173
|
-
|
|
189
|
+
var o, t;
|
|
190
|
+
const e = (o = this.returnFocusAfterCloseSelector) == null ? void 0 : o.trim();
|
|
191
|
+
e && ((t = document.querySelector(e)) == null || t.focus());
|
|
174
192
|
}
|
|
175
193
|
/**
|
|
176
194
|
* Enables body scroll by unlocking the scroll container.
|
|
177
195
|
*/
|
|
178
196
|
_enableBodyScroll() {
|
|
179
|
-
this._modalScrollContainer &&
|
|
197
|
+
this._modalScrollContainer && U(this._modalScrollContainer);
|
|
180
198
|
}
|
|
181
199
|
/**
|
|
182
200
|
* Disables body scroll by locking the scroll container.
|
|
183
201
|
*/
|
|
184
202
|
_disableBodyScroll() {
|
|
185
|
-
this._modalScrollContainer && ("scrollTo" in window && window.scrollTo(0, 0),
|
|
203
|
+
this._modalScrollContainer && ("scrollTo" in window && window.scrollTo(0, 0), q(this._modalScrollContainer));
|
|
186
204
|
}
|
|
187
205
|
/**
|
|
188
206
|
* Template for the close button element. Called within the
|
|
@@ -191,7 +209,7 @@ const v = "pie-modal", z = class z extends j(I) {
|
|
|
191
209
|
* @private
|
|
192
210
|
*/
|
|
193
211
|
renderCloseButton() {
|
|
194
|
-
var
|
|
212
|
+
var e;
|
|
195
213
|
return this.isDismissible ? s`
|
|
196
214
|
<pie-icon-button
|
|
197
215
|
@click="${() => {
|
|
@@ -199,7 +217,7 @@ const v = "pie-modal", z = class z extends j(I) {
|
|
|
199
217
|
}}"
|
|
200
218
|
variant="ghost-secondary"
|
|
201
219
|
class="c-modal-closeBtn"
|
|
202
|
-
aria-label="${((
|
|
220
|
+
aria-label="${((e = this.aria) == null ? void 0 : e.close) || p}"
|
|
203
221
|
data-test-id="modal-close-button">
|
|
204
222
|
<icon-close></icon-close>
|
|
205
223
|
</pie-icon-button>` : p;
|
|
@@ -211,7 +229,7 @@ const v = "pie-modal", z = class z extends j(I) {
|
|
|
211
229
|
* @private
|
|
212
230
|
*/
|
|
213
231
|
renderBackButton() {
|
|
214
|
-
var
|
|
232
|
+
var e;
|
|
215
233
|
return this.hasBackButton ? s`
|
|
216
234
|
<pie-icon-button
|
|
217
235
|
@click="${() => {
|
|
@@ -219,7 +237,7 @@ const v = "pie-modal", z = class z extends j(I) {
|
|
|
219
237
|
}}"
|
|
220
238
|
variant="ghost-secondary"
|
|
221
239
|
class="c-modal-backBtn"
|
|
222
|
-
aria-label="${
|
|
240
|
+
aria-label="${b((e = this.aria) == null ? void 0 : e.back)}"
|
|
223
241
|
data-test-id="modal-back-button">
|
|
224
242
|
${this.isRTL ? s`<icon-chevron-right></icon-chevron-right>` : s`<icon-chevron-left></icon-chevron-left>`}
|
|
225
243
|
</pie-icon-button>
|
|
@@ -235,16 +253,16 @@ const v = "pie-modal", z = class z extends j(I) {
|
|
|
235
253
|
* @private
|
|
236
254
|
*/
|
|
237
255
|
renderLeadingAction() {
|
|
238
|
-
const { ariaLabel:
|
|
239
|
-
return
|
|
256
|
+
const { ariaLabel: e, text: o, variant: t = "primary" } = this.leadingAction || {};
|
|
257
|
+
return o ? s`
|
|
240
258
|
<pie-button
|
|
241
259
|
variant="${t}"
|
|
242
|
-
aria-label="${
|
|
260
|
+
aria-label="${b(e)}"
|
|
243
261
|
type="submit"
|
|
244
262
|
?isFullWidth="${this.hasStackedActions}"
|
|
245
263
|
@click="${() => this._handleActionClick("leading")}"
|
|
246
264
|
data-test-id="modal-leading-action">
|
|
247
|
-
${
|
|
265
|
+
${o}
|
|
248
266
|
</pie-button>
|
|
249
267
|
` : p;
|
|
250
268
|
}
|
|
@@ -260,16 +278,16 @@ const v = "pie-modal", z = class z extends j(I) {
|
|
|
260
278
|
*/
|
|
261
279
|
renderSupportingAction() {
|
|
262
280
|
var i;
|
|
263
|
-
const { ariaLabel:
|
|
264
|
-
return !
|
|
281
|
+
const { ariaLabel: e, text: o, variant: t = "ghost" } = this.supportingAction || {};
|
|
282
|
+
return !o || !((i = this.leadingAction) != null && i.text) ? p : s`
|
|
265
283
|
<pie-button
|
|
266
284
|
variant="${t}"
|
|
267
|
-
aria-label="${
|
|
285
|
+
aria-label="${b(e)}"
|
|
268
286
|
type="reset"
|
|
269
287
|
?isFullWidth="${this.hasStackedActions}"
|
|
270
288
|
@click="${() => this._handleActionClick("supporting")}"
|
|
271
289
|
data-test-id="modal-supporting-action">
|
|
272
|
-
${
|
|
290
|
+
${o}
|
|
273
291
|
</pie-button>
|
|
274
292
|
`;
|
|
275
293
|
}
|
|
@@ -280,15 +298,15 @@ const v = "pie-modal", z = class z extends j(I) {
|
|
|
280
298
|
* @private
|
|
281
299
|
*/
|
|
282
300
|
renderModalFooter() {
|
|
283
|
-
var
|
|
284
|
-
if (!((
|
|
301
|
+
var o, t;
|
|
302
|
+
if (!((o = this.leadingAction) != null && o.text))
|
|
285
303
|
return (t = this.supportingAction) != null && t.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."), p;
|
|
286
|
-
const
|
|
304
|
+
const e = {
|
|
287
305
|
"c-modal-footer": !0,
|
|
288
306
|
"c-modal-footer--stackedActions": this.hasStackedActions
|
|
289
307
|
};
|
|
290
308
|
return s`
|
|
291
|
-
<footer class="${
|
|
309
|
+
<footer class="${B(e)}" data-test-id="pie-modal-footer">
|
|
292
310
|
${this.renderLeadingAction()}
|
|
293
311
|
${this.renderSupportingAction()}
|
|
294
312
|
</footer>`;
|
|
@@ -314,61 +332,68 @@ const v = "pie-modal", z = class z extends j(I) {
|
|
|
314
332
|
</article>
|
|
315
333
|
${this.renderModalFooter()}`;
|
|
316
334
|
}
|
|
335
|
+
/**
|
|
336
|
+
* Renders the modal heading content in the correct heading tag
|
|
337
|
+
* @private
|
|
338
|
+
*/
|
|
339
|
+
renderHeading() {
|
|
340
|
+
const { heading: e, headingLevel: o } = this, t = P(o);
|
|
341
|
+
return s`
|
|
342
|
+
<${t} class="c-modal-heading">
|
|
343
|
+
${e}
|
|
344
|
+
</${t}>
|
|
345
|
+
`;
|
|
346
|
+
}
|
|
317
347
|
render() {
|
|
318
348
|
const {
|
|
319
|
-
aria:
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
size: T
|
|
328
|
-
} = this, B = W(t), E = b && (o == null ? void 0 : o.loading) || void 0, P = {
|
|
349
|
+
aria: e,
|
|
350
|
+
isDismissible: o,
|
|
351
|
+
isFooterPinned: t,
|
|
352
|
+
isFullWidthBelowMid: i,
|
|
353
|
+
isLoading: c,
|
|
354
|
+
position: g,
|
|
355
|
+
size: z
|
|
356
|
+
} = this, $ = c && (e == null ? void 0 : e.loading) || void 0, E = {
|
|
329
357
|
"c-modal": !0,
|
|
330
|
-
[`c-modal--${
|
|
331
|
-
"c-modal--top":
|
|
332
|
-
"c-modal--dismissible":
|
|
333
|
-
"c-modal--loading":
|
|
334
|
-
"c-modal--pinnedFooter":
|
|
335
|
-
"c-modal--fullWidthBelowMid":
|
|
358
|
+
[`c-modal--${z}`]: !0,
|
|
359
|
+
"c-modal--top": g === "top",
|
|
360
|
+
"c-modal--dismissible": o,
|
|
361
|
+
"c-modal--loading": c,
|
|
362
|
+
"c-modal--pinnedFooter": t,
|
|
363
|
+
"c-modal--fullWidthBelowMid": i
|
|
336
364
|
};
|
|
337
365
|
return s`
|
|
338
366
|
<dialog
|
|
339
367
|
id="dialog"
|
|
340
|
-
class="${
|
|
341
|
-
aria-busy="${
|
|
342
|
-
aria-label="${
|
|
368
|
+
class="${B(E)}"
|
|
369
|
+
aria-busy="${c ? "true" : "false"}"
|
|
370
|
+
aria-label="${b($)}"
|
|
343
371
|
data-test-id="pie-modal">
|
|
344
|
-
<header class="c-modal-header"
|
|
345
|
-
data-test-id="modal-header">
|
|
372
|
+
<header class="c-modal-header" data-test-id="modal-header">
|
|
346
373
|
${this.renderBackButton()}
|
|
347
|
-
|
|
348
|
-
${e}
|
|
349
|
-
</${B}>
|
|
374
|
+
${this.renderHeading()}
|
|
350
375
|
${this.renderCloseButton()}
|
|
351
376
|
</header>
|
|
352
377
|
${// We need to wrap the remaining content in a shared scrollable container if the footer is not pinned
|
|
353
|
-
|
|
378
|
+
t ? this.renderModalContentAndFooter() : s`
|
|
354
379
|
<div class="c-modal-scrollContainer">
|
|
355
380
|
${this.renderModalContentAndFooter()}
|
|
356
381
|
</div>`}
|
|
357
382
|
</dialog>`;
|
|
358
383
|
}
|
|
359
384
|
};
|
|
360
|
-
|
|
361
|
-
let a =
|
|
385
|
+
C.styles = T(X);
|
|
386
|
+
let a = C;
|
|
362
387
|
l([
|
|
363
388
|
d({ type: Object })
|
|
364
389
|
], a.prototype, "aria");
|
|
365
390
|
l([
|
|
366
391
|
d({ type: String }),
|
|
367
|
-
|
|
392
|
+
N(v)
|
|
368
393
|
], a.prototype, "heading");
|
|
369
394
|
l([
|
|
370
395
|
d(),
|
|
371
|
-
_(v,
|
|
396
|
+
_(v, G, r.headingLevel)
|
|
372
397
|
], a.prototype, "headingLevel");
|
|
373
398
|
l([
|
|
374
399
|
d({ type: Boolean })
|
|
@@ -396,31 +421,31 @@ l([
|
|
|
396
421
|
], a.prototype, "leadingAction");
|
|
397
422
|
l([
|
|
398
423
|
d(),
|
|
399
|
-
_(v,
|
|
424
|
+
_(v, Q, r.position)
|
|
400
425
|
], a.prototype, "position");
|
|
401
426
|
l([
|
|
402
427
|
d()
|
|
403
428
|
], a.prototype, "returnFocusAfterCloseSelector");
|
|
404
429
|
l([
|
|
405
430
|
d(),
|
|
406
|
-
_(v,
|
|
431
|
+
_(v, J, r.size)
|
|
407
432
|
], a.prototype, "size");
|
|
408
433
|
l([
|
|
409
434
|
d({ type: Object })
|
|
410
435
|
], a.prototype, "supportingAction");
|
|
411
436
|
l([
|
|
412
|
-
|
|
437
|
+
K("dialog")
|
|
413
438
|
], a.prototype, "_dialog");
|
|
414
|
-
|
|
439
|
+
W(v, a);
|
|
415
440
|
export {
|
|
416
441
|
L as ON_MODAL_BACK_EVENT,
|
|
417
442
|
A as ON_MODAL_CLOSE_EVENT,
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
443
|
+
Z as ON_MODAL_LEADING_ACTION_CLICK,
|
|
444
|
+
w as ON_MODAL_OPEN_EVENT,
|
|
445
|
+
ee as ON_MODAL_SUPPORTING_ACTION_CLICK,
|
|
421
446
|
a as PieModal,
|
|
422
447
|
r as defaultProps,
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
448
|
+
G as headingLevels,
|
|
449
|
+
Q as positions,
|
|
450
|
+
J as sizes
|
|
426
451
|
};
|
package/dist/react.d.ts
CHANGED
|
@@ -169,12 +169,14 @@ declare class PieModal_2 extends PieModal_base implements ModalProps {
|
|
|
169
169
|
private _dialog;
|
|
170
170
|
private _backButtonClicked;
|
|
171
171
|
private _abortController;
|
|
172
|
+
private _escKeyAbortController;
|
|
172
173
|
private get _modalScrollContainer();
|
|
173
174
|
static styles: CSSResult;
|
|
174
175
|
connectedCallback(): void;
|
|
175
176
|
disconnectedCallback(): void;
|
|
176
177
|
firstUpdated(changedProperties: PropertyValues<this>): Promise<void>;
|
|
177
178
|
updated(changedProperties: PropertyValues<this>): void;
|
|
179
|
+
private _handleIsDismissibleChanged;
|
|
178
180
|
/**
|
|
179
181
|
* Opens the dialog element and disables page scrolling
|
|
180
182
|
*/
|
|
@@ -183,13 +185,21 @@ declare class PieModal_2 extends PieModal_base implements ModalProps {
|
|
|
183
185
|
* Closes the dialog element and re-enables page scrolling
|
|
184
186
|
*/
|
|
185
187
|
private _handleModalClosed;
|
|
188
|
+
/**
|
|
189
|
+
* Sets up an event listener on the Escape key to prevent dismissing the modal if isDismissible is false
|
|
190
|
+
*/
|
|
191
|
+
private _setupEscKeyListener;
|
|
192
|
+
/**
|
|
193
|
+
* Removes any event listeners set up that are listening to keyboard events and nulls the existing AbortController.
|
|
194
|
+
*/
|
|
195
|
+
private _removeEscKeyEventListener;
|
|
186
196
|
/**
|
|
187
197
|
* Prevents the user from dismissing the dialog via the `cancel`
|
|
188
198
|
* event (ESC key) when `isDismissible` is set to false.
|
|
189
199
|
*
|
|
190
200
|
* @param {Event} event - The event object.
|
|
191
201
|
*/
|
|
192
|
-
private
|
|
202
|
+
private _preventModalKeyboardDismissal;
|
|
193
203
|
private _handleModalOpenStateOnFirstRender;
|
|
194
204
|
private _handleModalOpenStateChanged;
|
|
195
205
|
private _handleActionClick;
|
|
@@ -258,6 +268,11 @@ declare class PieModal_2 extends PieModal_base implements ModalProps {
|
|
|
258
268
|
* @private
|
|
259
269
|
*/
|
|
260
270
|
private renderModalContentAndFooter;
|
|
271
|
+
/**
|
|
272
|
+
* Renders the modal heading content in the correct heading tag
|
|
273
|
+
* @private
|
|
274
|
+
*/
|
|
275
|
+
private renderHeading;
|
|
261
276
|
render(): TemplateResult;
|
|
262
277
|
/**
|
|
263
278
|
* Dismisses the modal on backdrop click if `isDismissible` is `true`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-modal",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.0",
|
|
4
4
|
"description": "PIE design system modal built using web components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"@custom-elements-manifest/analyzer": "0.9.0",
|
|
39
39
|
"@justeat/pie-design-tokens": "6.5.0",
|
|
40
40
|
"@justeattakeaway/pie-components-config": "0.18.0",
|
|
41
|
-
"@justeattakeaway/pie-css": "0.13.
|
|
42
|
-
"@justeattakeaway/pie-wrapper-react": "0.14.
|
|
41
|
+
"@justeattakeaway/pie-css": "0.13.1",
|
|
42
|
+
"@justeattakeaway/pie-wrapper-react": "0.14.2",
|
|
43
43
|
"@types/body-scroll-lock": "3.1.2",
|
|
44
44
|
"cem-plugin-module-file-extensions": "0.0.5"
|
|
45
45
|
},
|
|
@@ -47,11 +47,11 @@
|
|
|
47
47
|
"extends": "../../../package.json"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@justeattakeaway/pie-button": "0.49.
|
|
51
|
-
"@justeattakeaway/pie-icon-button": "0.28.
|
|
52
|
-
"@justeattakeaway/pie-icons-webc": "0.25.
|
|
53
|
-
"@justeattakeaway/pie-spinner": "0.7.
|
|
54
|
-
"@justeattakeaway/pie-webc-core": "0.24.
|
|
50
|
+
"@justeattakeaway/pie-button": "0.49.3",
|
|
51
|
+
"@justeattakeaway/pie-icon-button": "0.28.14",
|
|
52
|
+
"@justeattakeaway/pie-icons-webc": "0.25.3",
|
|
53
|
+
"@justeattakeaway/pie-spinner": "0.7.2",
|
|
54
|
+
"@justeattakeaway/pie-webc-core": "0.24.2",
|
|
55
55
|
"body-scroll-lock": "3.1.5",
|
|
56
56
|
"dialog-polyfill": "0.5.6"
|
|
57
57
|
},
|
package/src/defs-react.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -110,6 +110,10 @@ export class PieModal extends RtlMixin(LitElement) implements ModalProps {
|
|
|
110
110
|
|
|
111
111
|
private _abortController!: AbortController;
|
|
112
112
|
|
|
113
|
+
// We are using a separate controller for this event because it needs
|
|
114
|
+
// to be aborted / reinstantiated on modal open/close
|
|
115
|
+
private _escKeyAbortController: AbortController | null = null;
|
|
116
|
+
|
|
113
117
|
private get _modalScrollContainer (): Element | null {
|
|
114
118
|
return this._dialog.querySelector('.c-modal-scrollContainer');
|
|
115
119
|
}
|
|
@@ -123,39 +127,52 @@ export class PieModal extends RtlMixin(LitElement) implements ModalProps {
|
|
|
123
127
|
const { signal } = this._abortController;
|
|
124
128
|
|
|
125
129
|
this.addEventListener('click', (event) => this._handleDialogLightDismiss(event));
|
|
130
|
+
|
|
131
|
+
this._setupEscKeyListener();
|
|
132
|
+
|
|
126
133
|
document.addEventListener(ON_MODAL_OPEN_EVENT, (event) => this._handleModalOpened(<CustomEvent>event), { signal });
|
|
127
134
|
document.addEventListener(ON_MODAL_CLOSE_EVENT, (event) => this._handleModalClosed(<CustomEvent>event), { signal });
|
|
128
135
|
document.addEventListener(ON_MODAL_BACK_EVENT, (event) => this._handleModalClosed(<CustomEvent>event), { signal });
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
disconnectedCallback (): void {
|
|
132
|
-
|
|
133
|
-
this._abortController.abort();
|
|
139
|
+
super.disconnectedCallback();
|
|
134
140
|
|
|
141
|
+
this._abortController.abort();
|
|
135
142
|
this._enableBodyScroll();
|
|
136
|
-
|
|
143
|
+
this._removeEscKeyEventListener();
|
|
137
144
|
}
|
|
138
145
|
|
|
139
146
|
async firstUpdated (changedProperties: PropertyValues<this>): Promise<void> {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const dialogPolyfill = await import('dialog-polyfill').then((module) => module.default);
|
|
144
|
-
dialogPolyfill.registerDialog(this._dialog);
|
|
145
|
-
const { signal } = this._abortController;
|
|
147
|
+
const dialogPolyfill = await import('dialog-polyfill').then((module) => module.default);
|
|
148
|
+
dialogPolyfill.registerDialog(this._dialog);
|
|
149
|
+
const { signal } = this._abortController;
|
|
146
150
|
|
|
147
|
-
|
|
148
|
-
this.
|
|
149
|
-
|
|
150
|
-
}, { signal });
|
|
151
|
-
}
|
|
151
|
+
this._dialog.addEventListener('close', () => {
|
|
152
|
+
this.isOpen = false;
|
|
153
|
+
}, { signal });
|
|
152
154
|
|
|
153
155
|
this._handleModalOpenStateOnFirstRender(changedProperties);
|
|
154
156
|
}
|
|
155
157
|
|
|
156
158
|
updated (changedProperties: PropertyValues<this>): void {
|
|
157
|
-
super.updated(changedProperties);
|
|
158
159
|
this._handleModalOpenStateChanged(changedProperties);
|
|
160
|
+
this._handleIsDismissibleChanged(changedProperties);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private _handleIsDismissibleChanged (changedProperties: PropertyValues<this>) {
|
|
164
|
+
const oldValue = changedProperties.get('isDismissible');
|
|
165
|
+
const newValue = this.isDismissible;
|
|
166
|
+
|
|
167
|
+
// if the modal is being set to dismissible, remove any esc key listener
|
|
168
|
+
if (!oldValue && newValue) {
|
|
169
|
+
this._removeEscKeyEventListener();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// if the modal is being set to NOT dismissible, add the esc key listener
|
|
173
|
+
if (oldValue && !newValue) {
|
|
174
|
+
this._setupEscKeyListener();
|
|
175
|
+
}
|
|
159
176
|
}
|
|
160
177
|
|
|
161
178
|
/**
|
|
@@ -171,6 +188,8 @@ export class PieModal extends RtlMixin(LitElement) implements ModalProps {
|
|
|
171
188
|
return;
|
|
172
189
|
}
|
|
173
190
|
|
|
191
|
+
this._setupEscKeyListener();
|
|
192
|
+
|
|
174
193
|
// The ::backdrop pseudoelement is only shown if the modal is opened via JS
|
|
175
194
|
this._dialog.showModal();
|
|
176
195
|
}
|
|
@@ -186,17 +205,42 @@ export class PieModal extends RtlMixin(LitElement) implements ModalProps {
|
|
|
186
205
|
this._enableBodyScroll();
|
|
187
206
|
this._dialog.close();
|
|
188
207
|
this._returnFocus();
|
|
208
|
+
this._removeEscKeyEventListener();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Sets up an event listener on the Escape key to prevent dismissing the modal if isDismissible is false
|
|
214
|
+
*/
|
|
215
|
+
private _setupEscKeyListener () : void {
|
|
216
|
+
// AbortControllers are single-use. Meaning if we have already aborted this controller,
|
|
217
|
+
// we need to create a new one for setting up subsequent event listeners.
|
|
218
|
+
// We only perform this if the controller does not exist to prevent multiple listeners being set up
|
|
219
|
+
if (!this._escKeyAbortController && !this.isDismissible) {
|
|
220
|
+
this._escKeyAbortController = new AbortController();
|
|
221
|
+
const { signal } = this._escKeyAbortController;
|
|
222
|
+
|
|
223
|
+
document.addEventListener('keydown', (event: KeyboardEvent) => this._preventModalKeyboardDismissal(event), { signal });
|
|
189
224
|
}
|
|
190
225
|
}
|
|
191
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Removes any event listeners set up that are listening to keyboard events and nulls the existing AbortController.
|
|
229
|
+
*/
|
|
230
|
+
private _removeEscKeyEventListener () {
|
|
231
|
+
this._escKeyAbortController?.abort();
|
|
232
|
+
// This is so we can create a new AbortController for any subsequent event listener setup in the future
|
|
233
|
+
this._escKeyAbortController = null;
|
|
234
|
+
}
|
|
235
|
+
|
|
192
236
|
/**
|
|
193
237
|
* Prevents the user from dismissing the dialog via the `cancel`
|
|
194
238
|
* event (ESC key) when `isDismissible` is set to false.
|
|
195
239
|
*
|
|
196
240
|
* @param {Event} event - The event object.
|
|
197
241
|
*/
|
|
198
|
-
private
|
|
199
|
-
if (
|
|
242
|
+
private _preventModalKeyboardDismissal = (event: KeyboardEvent): void => {
|
|
243
|
+
if (event.key === 'Escape') {
|
|
200
244
|
event.preventDefault();
|
|
201
245
|
}
|
|
202
246
|
};
|
|
@@ -429,11 +473,24 @@ export class PieModal extends RtlMixin(LitElement) implements ModalProps {
|
|
|
429
473
|
${this.renderModalFooter()}`;
|
|
430
474
|
}
|
|
431
475
|
|
|
476
|
+
/**
|
|
477
|
+
* Renders the modal heading content in the correct heading tag
|
|
478
|
+
* @private
|
|
479
|
+
*/
|
|
480
|
+
private renderHeading (): TemplateResult {
|
|
481
|
+
const { heading, headingLevel } = this;
|
|
482
|
+
const headingTag = unsafeStatic(headingLevel);
|
|
483
|
+
|
|
484
|
+
return html`
|
|
485
|
+
<${headingTag} class="c-modal-heading">
|
|
486
|
+
${heading}
|
|
487
|
+
</${headingTag}>
|
|
488
|
+
`;
|
|
489
|
+
}
|
|
490
|
+
|
|
432
491
|
render () {
|
|
433
492
|
const {
|
|
434
493
|
aria,
|
|
435
|
-
heading,
|
|
436
|
-
headingLevel,
|
|
437
494
|
isDismissible,
|
|
438
495
|
isFooterPinned,
|
|
439
496
|
isFullWidthBelowMid,
|
|
@@ -442,7 +499,6 @@ export class PieModal extends RtlMixin(LitElement) implements ModalProps {
|
|
|
442
499
|
size,
|
|
443
500
|
} = this;
|
|
444
501
|
|
|
445
|
-
const headingTag = unsafeStatic(headingLevel);
|
|
446
502
|
const ariaLabel = (isLoading && aria?.loading) || undefined;
|
|
447
503
|
|
|
448
504
|
const modalClasses = {
|
|
@@ -462,12 +518,9 @@ export class PieModal extends RtlMixin(LitElement) implements ModalProps {
|
|
|
462
518
|
aria-busy="${isLoading ? 'true' : 'false'}"
|
|
463
519
|
aria-label="${ifDefined(ariaLabel)}"
|
|
464
520
|
data-test-id="pie-modal">
|
|
465
|
-
<header class="c-modal-header"
|
|
466
|
-
data-test-id="modal-header">
|
|
521
|
+
<header class="c-modal-header" data-test-id="modal-header">
|
|
467
522
|
${this.renderBackButton()}
|
|
468
|
-
|
|
469
|
-
${heading}
|
|
470
|
-
</${headingTag}>
|
|
523
|
+
${this.renderHeading()}
|
|
471
524
|
${this.renderCloseButton()}
|
|
472
525
|
</header>
|
|
473
526
|
${
|
package/src/react.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { createComponent, EventName } from '@lit/react';
|
|
2
|
+
import { createComponent, type EventName } from '@lit/react';
|
|
3
3
|
import { PieModal as PieModalLit } from './index';
|
|
4
|
-
import { ModalProps } from './defs';
|
|
4
|
+
import { type ModalProps } from './defs';
|
|
5
5
|
|
|
6
6
|
export * from './defs';
|
|
7
7
|
|