@justeattakeaway/pie-modal 0.34.1 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +4 -0
- package/dist/index.js +94 -73
- package/package.json +2 -2
- package/src/index.ts +39 -25
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,10 @@ export declare const headingLevels: readonly ["h1", "h2", "h3", "h4", "h5", "h6"
|
|
|
29
29
|
|
|
30
30
|
export declare type ModalActionType = 'leading' | 'supporting';
|
|
31
31
|
|
|
32
|
+
export declare interface ModalEventDetail {
|
|
33
|
+
targetModal: PieModal;
|
|
34
|
+
}
|
|
35
|
+
|
|
32
36
|
export declare type ModalProps = {
|
|
33
37
|
/**
|
|
34
38
|
* The ARIA labels used for the modal close and back buttons, as well as loading state.
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LitElement as P, nothing as
|
|
2
|
-
import { html as
|
|
1
|
+
import { LitElement as P, nothing as s, unsafeCSS as T } from "lit";
|
|
2
|
+
import { html as m, unsafeStatic as F } from "lit/static-html.js";
|
|
3
3
|
import { property as d, query as N } from "lit/decorators.js";
|
|
4
4
|
import "@justeattakeaway/pie-button";
|
|
5
5
|
import "@justeattakeaway/pie-icon-button";
|
|
@@ -25,26 +25,26 @@ if (typeof window < "u") {
|
|
|
25
25
|
};
|
|
26
26
|
window.addEventListener("testPassive", null, A), window.removeEventListener("testPassive", null, A);
|
|
27
27
|
}
|
|
28
|
-
var B = typeof window < "u" && window.navigator && window.navigator.platform && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === "MacIntel" && window.navigator.maxTouchPoints > 1), p = [],
|
|
28
|
+
var B = typeof window < "u" && window.navigator && window.navigator.platform && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === "MacIntel" && window.navigator.maxTouchPoints > 1), p = [], k = !1, S = -1, h = void 0, u = void 0, L = function(e) {
|
|
29
29
|
return p.some(function(o) {
|
|
30
30
|
return !!(o.options.allowTouchMove && o.options.allowTouchMove(e));
|
|
31
31
|
});
|
|
32
|
-
},
|
|
32
|
+
}, w = function(e) {
|
|
33
33
|
var o = e || window.event;
|
|
34
34
|
return L(o.target) || o.touches.length > 1 ? !0 : (o.preventDefault && o.preventDefault(), !1);
|
|
35
35
|
}, Y = function(e) {
|
|
36
|
-
if (
|
|
36
|
+
if (u === void 0) {
|
|
37
37
|
var o = !!e && e.reserveScrollBarGap === !0, i = window.innerWidth - document.documentElement.clientWidth;
|
|
38
|
-
o && i > 0 && (
|
|
38
|
+
o && i > 0 && (u = document.body.style.paddingRight, document.body.style.paddingRight = i + "px");
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
h === void 0 && (h = document.body.style.overflow, document.body.style.overflow = "hidden");
|
|
41
41
|
}, V = function() {
|
|
42
|
-
|
|
42
|
+
u !== void 0 && (document.body.style.paddingRight = u, u = void 0), h !== void 0 && (document.body.style.overflow = h, h = void 0);
|
|
43
43
|
}, q = function(e) {
|
|
44
44
|
return e ? e.scrollHeight - e.scrollTop <= e.clientHeight : !1;
|
|
45
45
|
}, H = function(e, o) {
|
|
46
46
|
var i = e.targetTouches[0].clientY - S;
|
|
47
|
-
return L(e.target) ? !1 : o && o.scrollTop === 0 && i > 0 || q(o) && i < 0 ?
|
|
47
|
+
return L(e.target) ? !1 : o && o.scrollTop === 0 && i > 0 || q(o) && i < 0 ? w(e) : (e.stopPropagation(), !0);
|
|
48
48
|
}, U = function(e, o) {
|
|
49
49
|
if (!e) {
|
|
50
50
|
console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.");
|
|
@@ -61,7 +61,7 @@ var B = typeof window < "u" && window.navigator && window.navigator.platform &&
|
|
|
61
61
|
t.targetTouches.length === 1 && (S = t.targetTouches[0].clientY);
|
|
62
62
|
}, e.ontouchmove = function(t) {
|
|
63
63
|
t.targetTouches.length === 1 && H(t, e);
|
|
64
|
-
},
|
|
64
|
+
}, k || (document.addEventListener("touchmove", w, C ? { passive: !1 } : void 0), k = !0)) : Y(o);
|
|
65
65
|
}
|
|
66
66
|
}, K = function(e) {
|
|
67
67
|
if (!e) {
|
|
@@ -70,46 +70,40 @@ var B = typeof window < "u" && window.navigator && window.navigator.platform &&
|
|
|
70
70
|
}
|
|
71
71
|
p = p.filter(function(o) {
|
|
72
72
|
return o.targetElement !== e;
|
|
73
|
-
}), B ? (e.ontouchstart = null, e.ontouchmove = null,
|
|
73
|
+
}), B ? (e.ontouchstart = null, e.ontouchmove = null, k && p.length === 0 && (document.removeEventListener("touchmove", w, C ? { passive: !1 } : void 0), k = !1)) : p.length || V();
|
|
74
74
|
};
|
|
75
75
|
const G = `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:white;color:#000;display:block}dialog:not([open]){display:none}dialog+.backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(0,0,0,.1)}._dialog_overlay{position:fixed;top:0;right:0;bottom:0;left:0}dialog.fixed{position:fixed;top:50%;transform:translateY(-50%)}*,*:before,*:after{box-sizing:border-box}.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-m-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: 768px){.c-modal{--modal-margin-block: var(--modal-margin-large)}}.c-modal[size=small]{--modal-max-inline-size: var(--modal-size-s)}@media (min-width: 768px){.c-modal[size=small]{--modal-margin-block: var(--modal-margin-large)}}@media (max-width: 767px){.c-modal[size=medium][isfullwidthbelowmid]{--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[size=medium][isfullwidthbelowmid]>.c-modal-scrollContainer{block-size:100%}}.c-modal[size=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[size=large]{--modal-margin-block: var(--modal-margin-none);--modal-border-radius: var(--dt-radius-rounded-none);--modal-block-size: 100%;--modal-inline-size: 100%}}.c-modal[position=top]{margin-block-start:var(--dt-spacing-j);max-block-size:calc(100% - var(--dt-spacing-j) * 2)}@media (max-width: 767px){.c-modal[position=top][size=large],.c-modal[position=top][isfullwidthbelowmid][size=medium]{margin-block-start:var(--dt-spacing-none);max-block-size:100%}}.c-modal::backdrop{background:rgba(0,0,0,.55)}.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: 768px){.c-modal .c-modal-footer{--modal-footer-padding: var(--dt-spacing-e)}}@media (max-width: 767px){.c-modal[hasstackedactions] .c-modal-footer{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:var(--dt-spacing-d);margin-block:14px}@media (min-width: 768px){.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:var(--dt-spacing-e);margin-block:20px}}.c-modal[hasbackbutton] .c-modal-heading{margin-inline-start:var(--dt-spacing-b)}@media (min-width: 768px){.c-modal[hasbackbutton] .c-modal-heading{margin-inline-start:var(--dt-spacing-c)}}.c-modal[isdismissible] .c-modal-heading{margin-inline-end:var(--dt-spacing-d)}@media (min-width: 768px){.c-modal[isdismissible] .c-modal-heading{margin-inline-end:var(--dt-spacing-e)}}.c-modal .c-modal-backBtn{grid-area:back;margin-block:var(--dt-spacing-b);margin-inline:var(--dt-spacing-b) var(--dt-spacing-none)}@media (min-width: 768px){.c-modal .c-modal-backBtn{margin-block:var(--dt-spacing-c);margin-inline:var(--dt-spacing-c) var(--dt-spacing-none)}}.c-modal .c-modal-closeBtn{grid-area:close;margin-block:var(--dt-spacing-b);margin-inline:var(--dt-spacing-none) var(--dt-spacing-b)}@media (min-width: 768px){.c-modal .c-modal-closeBtn{margin-block:var(--dt-spacing-c);margin-inline:var(--dt-spacing-none) 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);position:relative;min-block-size:var(--dt-spacing-j);font-size:var(--modal-content-font-size);line-height:var(--modal-content-line-height);font-weight:var(--modal-content-font-weight);padding-inline:var(--modal-content-padding-inline);padding-block:var(--modal-content-padding-block);flex-grow:1}@media (min-width: 768px){.c-modal .c-modal-content{--modal-content-padding-inline: var(--dt-spacing-e)}}.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;block-size:auto;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[isfooterpinned] .c-modal-content{overflow-y:auto}.c-modal[isLoading] .c-modal-content pie-spinner{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}.c-modal[isLoading] .c-modal-content .c-modal-contentInner{display:none}@supports not (aspect-ratio: 1/1){.c-modal .c-modal-scrollContainer{background:none}}
|
|
76
|
-
`, X = ["h1", "h2", "h3", "h4", "h5", "h6"], J = ["small", "medium", "large"], Q = ["top", "center"], x = "pie-modal-close",
|
|
76
|
+
`, X = ["h1", "h2", "h3", "h4", "h5", "h6"], J = ["small", "medium", "large"], Q = ["top", "center"], x = "pie-modal-close", b = "pie-modal-open", _ = "pie-modal-back", Z = "pie-modal-leading-action-click", ee = "pie-modal-supporting-action-click";
|
|
77
77
|
var oe = Object.defineProperty, ie = Object.getOwnPropertyDescriptor, l = (n, e, o, i) => {
|
|
78
|
-
for (var t = i > 1 ? void 0 : i ? ie(e, o) : e,
|
|
79
|
-
(
|
|
78
|
+
for (var t = i > 1 ? void 0 : i ? ie(e, o) : e, r = n.length - 1, c; r >= 0; r--)
|
|
79
|
+
(c = n[r]) && (t = (i ? c(e, o, t) : c(t)) || t);
|
|
80
80
|
return i && t && oe(e, o, t), t;
|
|
81
81
|
};
|
|
82
|
-
const
|
|
82
|
+
const f = "pie-modal";
|
|
83
83
|
class a extends I(P) {
|
|
84
84
|
constructor() {
|
|
85
85
|
super(...arguments), this.headingLevel = "h2", this.hasBackButton = !1, this.hasStackedActions = !1, this.isDismissible = !1, this.isFooterPinned = !0, this.isFullWidthBelowMid = !1, this.isLoading = !1, this.isOpen = !1, this.position = "center", this.size = "medium", this._backButtonClicked = !1, this._handleDialogCancelEvent = (e) => {
|
|
86
86
|
this.isDismissible || e.preventDefault();
|
|
87
87
|
}, this._handleDialogLightDismiss = (e) => {
|
|
88
|
-
var
|
|
88
|
+
var v;
|
|
89
89
|
if (!this.isDismissible)
|
|
90
90
|
return;
|
|
91
|
-
const o = (
|
|
91
|
+
const o = (v = this._dialog) == null ? void 0 : v.getBoundingClientRect(), {
|
|
92
92
|
top: i = 0,
|
|
93
93
|
bottom: t = 0,
|
|
94
|
-
left:
|
|
95
|
-
right:
|
|
94
|
+
left: r = 0,
|
|
95
|
+
right: c = 0
|
|
96
96
|
} = o || {};
|
|
97
|
-
if (i === 0 && t === 0 &&
|
|
97
|
+
if (i === 0 && t === 0 && r === 0 && c === 0)
|
|
98
98
|
return;
|
|
99
|
-
(e.clientY < i || e.clientY > t || e.clientX <
|
|
100
|
-
}, this._dispatchModalCustomEvent = (e) => {
|
|
101
|
-
const o = new CustomEvent(e, {
|
|
102
|
-
bubbles: !0,
|
|
103
|
-
composed: !0
|
|
104
|
-
});
|
|
105
|
-
this.dispatchEvent(o);
|
|
99
|
+
(e.clientY < i || e.clientY > t || e.clientX < r || e.clientX > c) && (this.isOpen = !1);
|
|
106
100
|
};
|
|
107
101
|
}
|
|
108
102
|
connectedCallback() {
|
|
109
|
-
super.connectedCallback(), this.addEventListener("click", (e) => this._handleDialogLightDismiss(e)), document.addEventListener(
|
|
103
|
+
super.connectedCallback(), this.addEventListener("click", (e) => this._handleDialogLightDismiss(e)), document.addEventListener(b, (e) => this._handleModalOpened(e)), document.addEventListener(x, (e) => this._handleModalClosed(e)), document.addEventListener(_, (e) => this._handleModalClosed(e));
|
|
110
104
|
}
|
|
111
105
|
disconnectedCallback() {
|
|
112
|
-
document.removeEventListener(
|
|
106
|
+
document.removeEventListener(b, (e) => this._handleModalOpened(e)), document.removeEventListener(x, (e) => this._handleModalClosed(e)), document.removeEventListener(_, (e) => this._handleModalClosed(e)), super.disconnectedCallback();
|
|
113
107
|
}
|
|
114
108
|
async firstUpdated(e) {
|
|
115
109
|
super.firstUpdated(e), this._dialog && ((await import("./dialog-polyfill.esm-29edb142.js").then((i) => i.default)).registerDialog(this._dialog), this._dialog.addEventListener("cancel", (i) => this._handleDialogCancelEvent(i)), this._dialog.addEventListener("close", () => {
|
|
@@ -122,27 +116,35 @@ class a extends I(P) {
|
|
|
122
116
|
/**
|
|
123
117
|
* Opens the dialog element and disables page scrolling
|
|
124
118
|
*/
|
|
125
|
-
_handleModalOpened() {
|
|
126
|
-
var
|
|
127
|
-
const
|
|
128
|
-
|
|
119
|
+
_handleModalOpened(e) {
|
|
120
|
+
var i, t, r, c;
|
|
121
|
+
const { targetModal: o } = e.detail;
|
|
122
|
+
if (o === this) {
|
|
123
|
+
const g = (i = this._dialog) == null ? void 0 : i.querySelector(".c-modal-scrollContainer");
|
|
124
|
+
if (g && U(g), (t = this._dialog) != null && t.hasAttribute("open") || !((r = this._dialog) != null && r.isConnected))
|
|
125
|
+
return;
|
|
126
|
+
(c = this._dialog) == null || c.showModal();
|
|
127
|
+
}
|
|
129
128
|
}
|
|
130
129
|
/**
|
|
131
130
|
* Closes the dialog element and re-enables page scrolling
|
|
132
131
|
*/
|
|
133
|
-
_handleModalClosed() {
|
|
134
|
-
var
|
|
135
|
-
const
|
|
136
|
-
|
|
132
|
+
_handleModalClosed(e) {
|
|
133
|
+
var i, t;
|
|
134
|
+
const { targetModal: o } = e.detail;
|
|
135
|
+
if (o === this) {
|
|
136
|
+
const r = (i = this._dialog) == null ? void 0 : i.querySelector(".c-modal-scrollContainer");
|
|
137
|
+
r && K(r), (t = this._dialog) == null || t.close(), this._returnFocus();
|
|
138
|
+
}
|
|
137
139
|
}
|
|
138
140
|
// Handles the value of the isOpen property on first render of the component
|
|
139
141
|
_handleModalOpenStateOnFirstRender(e) {
|
|
140
|
-
e.get("isOpen") === void 0 && this.isOpen && this._dispatchModalCustomEvent(
|
|
142
|
+
e.get("isOpen") === void 0 && this.isOpen && this._dispatchModalCustomEvent(b);
|
|
141
143
|
}
|
|
142
144
|
// Handles changes to the modal isOpen property by dispatching any appropriate events
|
|
143
145
|
_handleModalOpenStateChanged(e) {
|
|
144
146
|
const o = e.get("isOpen");
|
|
145
|
-
o !== void 0 && (o ? this._backButtonClicked ? (this._backButtonClicked = !1, this._dispatchModalCustomEvent(_)) : this._dispatchModalCustomEvent(x) : this._dispatchModalCustomEvent(
|
|
147
|
+
o !== void 0 && (o ? this._backButtonClicked ? (this._backButtonClicked = !1, this._dispatchModalCustomEvent(_)) : this._dispatchModalCustomEvent(x) : this._dispatchModalCustomEvent(b));
|
|
146
148
|
}
|
|
147
149
|
_handleActionClick(e) {
|
|
148
150
|
var o, i;
|
|
@@ -165,14 +167,14 @@ class a extends I(P) {
|
|
|
165
167
|
*/
|
|
166
168
|
renderCloseButton() {
|
|
167
169
|
var e;
|
|
168
|
-
return
|
|
170
|
+
return m`
|
|
169
171
|
<pie-icon-button
|
|
170
172
|
@click="${() => {
|
|
171
173
|
this.isOpen = !1;
|
|
172
174
|
}}"
|
|
173
175
|
variant="ghost-secondary"
|
|
174
176
|
class="c-modal-closeBtn"
|
|
175
|
-
aria-label="${((e = this.aria) == null ? void 0 : e.close) ||
|
|
177
|
+
aria-label="${((e = this.aria) == null ? void 0 : e.close) || s}"
|
|
176
178
|
data-test-id="modal-close-button">
|
|
177
179
|
<icon-close></icon-close>
|
|
178
180
|
</pie-icon-button>`;
|
|
@@ -185,16 +187,16 @@ class a extends I(P) {
|
|
|
185
187
|
*/
|
|
186
188
|
renderBackButton() {
|
|
187
189
|
var e;
|
|
188
|
-
return
|
|
190
|
+
return m`
|
|
189
191
|
<pie-icon-button
|
|
190
192
|
@click="${() => {
|
|
191
193
|
this._backButtonClicked = !0, this.isOpen = !1;
|
|
192
194
|
}}"
|
|
193
195
|
variant="ghost-secondary"
|
|
194
196
|
class="c-modal-backBtn"
|
|
195
|
-
aria-label="${((e = this.aria) == null ? void 0 : e.back) ||
|
|
197
|
+
aria-label="${((e = this.aria) == null ? void 0 : e.back) || s}"
|
|
196
198
|
data-test-id="modal-back-button">
|
|
197
|
-
${this.isRTL ?
|
|
199
|
+
${this.isRTL ? m`<icon-chevron-right></icon-chevron-right>` : m`<icon-chevron-left></icon-chevron-left>`}
|
|
198
200
|
</pie-icon-button>
|
|
199
201
|
`;
|
|
200
202
|
}
|
|
@@ -209,17 +211,17 @@ class a extends I(P) {
|
|
|
209
211
|
*/
|
|
210
212
|
renderLeadingAction() {
|
|
211
213
|
const { text: e, variant: o = "primary", ariaLabel: i } = this.leadingAction;
|
|
212
|
-
return e ?
|
|
214
|
+
return e ? m`
|
|
213
215
|
<pie-button
|
|
214
216
|
variant="${o}"
|
|
215
|
-
aria-label="${i ||
|
|
217
|
+
aria-label="${i || s}"
|
|
216
218
|
type="submit"
|
|
217
219
|
?isFullWidth="${this.hasStackedActions}"
|
|
218
220
|
@click="${() => this._handleActionClick("leading")}"
|
|
219
221
|
data-test-id="modal-leading-action">
|
|
220
222
|
${e}
|
|
221
223
|
</pie-button>
|
|
222
|
-
` :
|
|
224
|
+
` : s;
|
|
223
225
|
}
|
|
224
226
|
/**
|
|
225
227
|
* Render supportingAction button depending on prop availability.
|
|
@@ -234,33 +236,33 @@ class a extends I(P) {
|
|
|
234
236
|
*/
|
|
235
237
|
renderSupportingAction() {
|
|
236
238
|
const { text: e, variant: o = "ghost", ariaLabel: i } = this.supportingAction;
|
|
237
|
-
return e ? this.leadingAction ?
|
|
239
|
+
return e ? this.leadingAction ? m`
|
|
238
240
|
<pie-button
|
|
239
241
|
variant="${o}"
|
|
240
|
-
aria-label="${i ||
|
|
242
|
+
aria-label="${i || s}"
|
|
241
243
|
type="reset"
|
|
242
244
|
?isFullWidth="${this.hasStackedActions}"
|
|
243
245
|
@click="${() => this._handleActionClick("supporting")}"
|
|
244
246
|
data-test-id="modal-supporting-action">
|
|
245
247
|
${e}
|
|
246
248
|
</pie-button>
|
|
247
|
-
` : (console.warn("Use `leadingAction` instead of `supportingAction`. `supportingAction` is being ignored."),
|
|
249
|
+
` : (console.warn("Use `leadingAction` instead of `supportingAction`. `supportingAction` is being ignored."), s) : s;
|
|
248
250
|
}
|
|
249
251
|
/**
|
|
250
252
|
* Renders the modal inner content and footer of the modal.
|
|
251
253
|
* @private
|
|
252
254
|
*/
|
|
253
255
|
renderModalContentAndFooter() {
|
|
254
|
-
return
|
|
256
|
+
return m`
|
|
255
257
|
<article class="c-modal-scrollContainer c-modal-content c-modal-content--scrollable">
|
|
256
258
|
<div class="c-modal-contentInner">
|
|
257
259
|
<slot></slot>
|
|
258
260
|
</div>
|
|
259
|
-
${this.isLoading ?
|
|
261
|
+
${this.isLoading ? m`<pie-spinner size="xlarge" variant="secondary"></pie-spinner>` : s}
|
|
260
262
|
</article>
|
|
261
263
|
<footer class="c-modal-footer">
|
|
262
|
-
${this.leadingAction ? this.renderLeadingAction() :
|
|
263
|
-
${this.supportingAction ? this.renderSupportingAction() :
|
|
264
|
+
${this.leadingAction ? this.renderLeadingAction() : s}
|
|
265
|
+
${this.supportingAction ? this.renderSupportingAction() : s}
|
|
264
266
|
</footer>`;
|
|
265
267
|
}
|
|
266
268
|
render() {
|
|
@@ -269,17 +271,17 @@ class a extends I(P) {
|
|
|
269
271
|
hasBackButton: o,
|
|
270
272
|
hasStackedActions: i,
|
|
271
273
|
heading: t,
|
|
272
|
-
headingLevel:
|
|
273
|
-
isDismissible:
|
|
274
|
-
isFooterPinned:
|
|
275
|
-
isFullWidthBelowMid:
|
|
274
|
+
headingLevel: r = "h2",
|
|
275
|
+
isDismissible: c,
|
|
276
|
+
isFooterPinned: g,
|
|
277
|
+
isFullWidthBelowMid: v,
|
|
276
278
|
isLoading: y,
|
|
277
279
|
leadingAction: M,
|
|
278
280
|
position: $,
|
|
279
281
|
size: E,
|
|
280
282
|
supportingAction: D
|
|
281
|
-
} = this, O = F(
|
|
282
|
-
return
|
|
283
|
+
} = this, O = F(r);
|
|
284
|
+
return m`
|
|
283
285
|
<dialog
|
|
284
286
|
id="dialog"
|
|
285
287
|
class="c-modal"
|
|
@@ -288,28 +290,47 @@ class a extends I(P) {
|
|
|
288
290
|
?hasActions=${M || D}
|
|
289
291
|
?hasBackButton=${o}
|
|
290
292
|
?hasStackedActions=${i}
|
|
291
|
-
?isDismissible=${
|
|
292
|
-
?isFooterPinned=${
|
|
293
|
-
?isFullWidthBelowMid=${
|
|
293
|
+
?isDismissible=${c}
|
|
294
|
+
?isFooterPinned=${g}
|
|
295
|
+
?isFullWidthBelowMid=${v}
|
|
294
296
|
?isLoading=${y}
|
|
295
297
|
aria-busy="${y ? "true" : "false"}"
|
|
296
|
-
aria-label="${y && (e == null ? void 0 : e.loading) ||
|
|
298
|
+
aria-label="${y && (e == null ? void 0 : e.loading) || s}"
|
|
297
299
|
data-test-id="pie-modal">
|
|
298
300
|
<header class="c-modal-header">
|
|
299
|
-
${o ? this.renderBackButton() :
|
|
301
|
+
${o ? this.renderBackButton() : s}
|
|
300
302
|
<${O} class="c-modal-heading">
|
|
301
303
|
${t}
|
|
302
304
|
</${O}>
|
|
303
|
-
${
|
|
305
|
+
${c ? this.renderCloseButton() : s}
|
|
304
306
|
</header>
|
|
305
307
|
${// We need to wrap the remaining content in a shared scrollable container if the footer is not pinned
|
|
306
|
-
|
|
308
|
+
g ? this.renderModalContentAndFooter() : m`
|
|
307
309
|
<div class="c-modal-scrollContainer">
|
|
308
310
|
${this.renderModalContentAndFooter()}
|
|
309
311
|
</div>
|
|
310
312
|
`}
|
|
311
313
|
</dialog>`;
|
|
312
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* Note: We should aim to have a shareable event helper system to allow
|
|
317
|
+
* us to share this across components in-future.
|
|
318
|
+
*
|
|
319
|
+
* Dispatch a custom event.
|
|
320
|
+
*
|
|
321
|
+
* To be used whenever we have behavioural events we want to
|
|
322
|
+
* bubble up through the modal.
|
|
323
|
+
*
|
|
324
|
+
* @param {string} eventType
|
|
325
|
+
*/
|
|
326
|
+
_dispatchModalCustomEvent(e) {
|
|
327
|
+
const o = new CustomEvent(e, {
|
|
328
|
+
bubbles: !0,
|
|
329
|
+
composed: !0,
|
|
330
|
+
detail: { targetModal: this }
|
|
331
|
+
});
|
|
332
|
+
this.dispatchEvent(o);
|
|
333
|
+
}
|
|
313
334
|
}
|
|
314
335
|
a.styles = T(G);
|
|
315
336
|
l([
|
|
@@ -317,11 +338,11 @@ l([
|
|
|
317
338
|
], a.prototype, "aria", 2);
|
|
318
339
|
l([
|
|
319
340
|
d({ type: String }),
|
|
320
|
-
R(
|
|
341
|
+
R(f)
|
|
321
342
|
], a.prototype, "heading", 2);
|
|
322
343
|
l([
|
|
323
344
|
d(),
|
|
324
|
-
z(
|
|
345
|
+
z(f, X, "h2")
|
|
325
346
|
], a.prototype, "headingLevel", 2);
|
|
326
347
|
l([
|
|
327
348
|
d({ type: Boolean })
|
|
@@ -349,14 +370,14 @@ l([
|
|
|
349
370
|
], a.prototype, "leadingAction", 2);
|
|
350
371
|
l([
|
|
351
372
|
d(),
|
|
352
|
-
z(
|
|
373
|
+
z(f, Q, "center")
|
|
353
374
|
], a.prototype, "position", 2);
|
|
354
375
|
l([
|
|
355
376
|
d()
|
|
356
377
|
], a.prototype, "returnFocusAfterCloseSelector", 2);
|
|
357
378
|
l([
|
|
358
379
|
d(),
|
|
359
|
-
z(
|
|
380
|
+
z(f, J, "medium")
|
|
360
381
|
], a.prototype, "size", 2);
|
|
361
382
|
l([
|
|
362
383
|
d({ type: Object })
|
|
@@ -364,12 +385,12 @@ l([
|
|
|
364
385
|
l([
|
|
365
386
|
N("dialog")
|
|
366
387
|
], a.prototype, "_dialog", 2);
|
|
367
|
-
j(
|
|
388
|
+
j(f, a);
|
|
368
389
|
export {
|
|
369
390
|
_ as ON_MODAL_BACK_EVENT,
|
|
370
391
|
x as ON_MODAL_CLOSE_EVENT,
|
|
371
392
|
Z as ON_MODAL_LEADING_ACTION_CLICK,
|
|
372
|
-
|
|
393
|
+
b as ON_MODAL_OPEN_EVENT,
|
|
373
394
|
ee as ON_MODAL_SUPPORTING_ACTION_CLICK,
|
|
374
395
|
a as PieModal,
|
|
375
396
|
X as headingLevels,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-modal",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "PIE design system modal built using web components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@justeattakeaway/pie-button": "0.40.1",
|
|
40
|
-
"@justeattakeaway/pie-icon-button": "0.
|
|
40
|
+
"@justeattakeaway/pie-icon-button": "0.24.0",
|
|
41
41
|
"@justeattakeaway/pie-icons-webc": "0.12.0",
|
|
42
42
|
"@justeattakeaway/pie-spinner": "0.3.1",
|
|
43
43
|
"@justeattakeaway/pie-webc-core": "0.13.0",
|
package/src/index.ts
CHANGED
|
@@ -36,6 +36,10 @@ export * from './defs';
|
|
|
36
36
|
|
|
37
37
|
const componentSelector = 'pie-modal';
|
|
38
38
|
|
|
39
|
+
export interface ModalEventDetail {
|
|
40
|
+
targetModal: PieModal;
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
/**
|
|
40
44
|
* @tagname pie-modal
|
|
41
45
|
* @event {CustomEvent} pie-modal-open - when the modal is opened.
|
|
@@ -105,15 +109,15 @@ export class PieModal extends RtlMixin(LitElement) implements ModalProps {
|
|
|
105
109
|
connectedCallback () : void {
|
|
106
110
|
super.connectedCallback();
|
|
107
111
|
this.addEventListener('click', (event) => this._handleDialogLightDismiss(event));
|
|
108
|
-
document.addEventListener(ON_MODAL_OPEN_EVENT, this._handleModalOpened
|
|
109
|
-
document.addEventListener(ON_MODAL_CLOSE_EVENT, this._handleModalClosed
|
|
110
|
-
document.addEventListener(ON_MODAL_BACK_EVENT, this._handleModalClosed
|
|
112
|
+
document.addEventListener(ON_MODAL_OPEN_EVENT, (event) => this._handleModalOpened(<CustomEvent>event));
|
|
113
|
+
document.addEventListener(ON_MODAL_CLOSE_EVENT, (event) => this._handleModalClosed(<CustomEvent>event));
|
|
114
|
+
document.addEventListener(ON_MODAL_BACK_EVENT, (event) => this._handleModalClosed(<CustomEvent>event));
|
|
111
115
|
}
|
|
112
116
|
|
|
113
117
|
disconnectedCallback () : void {
|
|
114
|
-
document.removeEventListener(ON_MODAL_OPEN_EVENT, this._handleModalOpened
|
|
115
|
-
document.removeEventListener(ON_MODAL_CLOSE_EVENT, this._handleModalClosed
|
|
116
|
-
document.removeEventListener(ON_MODAL_BACK_EVENT, this._handleModalClosed
|
|
118
|
+
document.removeEventListener(ON_MODAL_OPEN_EVENT, (event) => this._handleModalOpened(<CustomEvent>event));
|
|
119
|
+
document.removeEventListener(ON_MODAL_CLOSE_EVENT, (event) => this._handleModalClosed(<CustomEvent>event));
|
|
120
|
+
document.removeEventListener(ON_MODAL_BACK_EVENT, (event) => this._handleModalClosed(<CustomEvent>event));
|
|
117
121
|
super.disconnectedCallback();
|
|
118
122
|
}
|
|
119
123
|
|
|
@@ -140,32 +144,41 @@ export class PieModal extends RtlMixin(LitElement) implements ModalProps {
|
|
|
140
144
|
/**
|
|
141
145
|
* Opens the dialog element and disables page scrolling
|
|
142
146
|
*/
|
|
143
|
-
private _handleModalOpened ()
|
|
144
|
-
const
|
|
147
|
+
private _handleModalOpened (event: CustomEvent): void {
|
|
148
|
+
const { targetModal } = event.detail;
|
|
145
149
|
|
|
146
|
-
if (
|
|
147
|
-
|
|
148
|
-
}
|
|
150
|
+
if (targetModal === this) {
|
|
151
|
+
const modalScrollContainer = this._dialog?.querySelector('.c-modal-scrollContainer');
|
|
149
152
|
|
|
150
|
-
|
|
151
|
-
|
|
153
|
+
if (modalScrollContainer) {
|
|
154
|
+
disableBodyScroll(modalScrollContainer);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (this._dialog?.hasAttribute('open') || !this._dialog?.isConnected) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// The ::backdrop pseudoelement is only shown if the modal is opened via JS
|
|
162
|
+
this._dialog?.showModal();
|
|
152
163
|
}
|
|
153
|
-
// The ::backdrop pseudoelement is only shown if the modal is opened via JS
|
|
154
|
-
this._dialog?.showModal();
|
|
155
164
|
}
|
|
156
165
|
|
|
157
166
|
/**
|
|
158
167
|
* Closes the dialog element and re-enables page scrolling
|
|
159
168
|
*/
|
|
160
|
-
private _handleModalClosed ()
|
|
161
|
-
const
|
|
169
|
+
private _handleModalClosed (event: CustomEvent): void {
|
|
170
|
+
const { targetModal } = event.detail;
|
|
162
171
|
|
|
163
|
-
if (
|
|
164
|
-
|
|
165
|
-
|
|
172
|
+
if (targetModal === this) {
|
|
173
|
+
const modalScrollContainer = this._dialog?.querySelector('.c-modal-scrollContainer');
|
|
174
|
+
|
|
175
|
+
if (modalScrollContainer) {
|
|
176
|
+
enableBodyScroll(modalScrollContainer);
|
|
177
|
+
}
|
|
166
178
|
|
|
167
|
-
|
|
168
|
-
|
|
179
|
+
this._dialog?.close();
|
|
180
|
+
this._returnFocus();
|
|
181
|
+
}
|
|
169
182
|
}
|
|
170
183
|
|
|
171
184
|
/**
|
|
@@ -448,14 +461,15 @@ export class PieModal extends RtlMixin(LitElement) implements ModalProps {
|
|
|
448
461
|
*
|
|
449
462
|
* @param {string} eventType
|
|
450
463
|
*/
|
|
451
|
-
private _dispatchModalCustomEvent
|
|
452
|
-
const event = new CustomEvent(eventType, {
|
|
464
|
+
private _dispatchModalCustomEvent (eventType: string): void {
|
|
465
|
+
const event = new CustomEvent<ModalEventDetail>(eventType, {
|
|
453
466
|
bubbles: true,
|
|
454
467
|
composed: true,
|
|
468
|
+
detail: { targetModal: this },
|
|
455
469
|
});
|
|
456
470
|
|
|
457
471
|
this.dispatchEvent(event);
|
|
458
|
-
}
|
|
472
|
+
}
|
|
459
473
|
}
|
|
460
474
|
|
|
461
475
|
defineCustomElement(componentSelector, PieModal);
|