@justeattakeaway/pie-modal 0.7.0 → 0.9.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.
@@ -1,14 +1,14 @@
1
- [4:04:52 PM] @custom-elements-manifest/analyzer: Created new manifest.
1
+ [13:51:16] @custom-elements-manifest/analyzer: Created new manifest.
2
2
  react wrapper has been added!
3
3
  vite v4.3.9 building for production...
4
4
  transforming...
5
- ✓ 30 modules transformed.
5
+ ✓ 23 modules transformed.
6
6
  rendering chunks...
7
7
  computing gzip size...
8
- dist/index.js 13.55 kB │ gzip: 4.16 kB
8
+ dist/index.js 12.03 kB │ gzip: 3.79 kB
9
9
  dist/react.js 59.04 kB │ gzip: 15.92 kB
10
- 
11
- [vite:dts] Start generate declaration files...
12
- ✓ built in 28.39s
13
- [vite:dts] Declaration files built in 26000ms.
14
- 
10
+
11
+ [vite:dts] Start generate declaration files...
12
+ ✓ built in 4.35s
13
+ [vite:dts] Declaration files built in 3800ms.
14
+
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @justeattakeaway/pie-modal
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [Changed] - Set modal props to public ([#597](https://github.com/justeattakeaway/pie/pull/597)) by [@jamieomaguire](https://github.com/jamieomaguire)
8
+
9
+ ## 0.8.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [Added] - New size prop for pie-modal ([#572](https://github.com/justeattakeaway/pie/pull/572)) by [@xander-marjoram](https://github.com/xander-marjoram)
14
+
15
+ [Added] - Visual regression test for each size
16
+ [Changed] - Modal story to include new size prop
17
+
3
18
  ## 0.7.0
4
19
 
5
20
  ### Minor Changes
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
- import { unsafeCSS as T, LitElement as $, html as w } from "lit";
2
- import { unsafeStatic as D, html as z } from "lit/static-html.js";
3
- import { property as u, query as B } from "lit/decorators.js";
4
- import { property as k } from "lit/decorators/property.js";
5
- var V = Object.defineProperty, R = Object.getOwnPropertyDescriptor, A = (i, e, t, n) => {
6
- for (var o = n > 1 ? void 0 : n ? R(e, t) : e, r = i.length - 1, d; r >= 0; r--)
7
- (d = i[r]) && (o = (n ? d(e, t, o) : d(o)) || o);
8
- return n && o && V(e, t, o), o;
1
+ import { unsafeCSS as C, LitElement as x } from "lit";
2
+ import { unsafeStatic as E, html as L } from "lit/static-html.js";
3
+ import { property as y, query as T } from "lit/decorators.js";
4
+ import { property as $ } from "lit/decorators/property.js";
5
+ var D = Object.defineProperty, B = Object.getOwnPropertyDescriptor, k = (i, e, t, n) => {
6
+ for (var o = n > 1 ? void 0 : n ? B(e, t) : e, d = i.length - 1, a; d >= 0; d--)
7
+ (a = i[d]) && (o = (n ? a(e, t, o) : a(o)) || o);
8
+ return n && o && D(e, t, o), o;
9
9
  };
10
- const W = (i) => {
10
+ const R = (i) => {
11
11
  class e extends i {
12
12
  constructor() {
13
13
  super(...arguments), this.dir = "";
@@ -26,80 +26,37 @@ const W = (i) => {
26
26
  return this.dir === "ltr" ? !1 : this.dir === "rtl" || ((n = window == null ? void 0 : window.getComputedStyle(this)) == null ? void 0 : n.direction) === "rtl";
27
27
  }
28
28
  }
29
- return A([
30
- k({ type: String })
29
+ return k([
30
+ $({ type: String })
31
31
  ], e.prototype, "dir", 2), e;
32
- }, j = (i, e, t) => function(o, r) {
33
- const d = `#${r}`;
34
- Object.defineProperty(o, r, {
32
+ }, S = (i, e, t) => function(o, d) {
33
+ const a = `#${d}`;
34
+ Object.defineProperty(o, d, {
35
35
  get() {
36
- return this[d];
36
+ return this[a];
37
37
  },
38
38
  set(f) {
39
- const h = this[d];
40
- e.includes(f) ? this[d] = f : (console.error(
41
- `<${i}> Invalid value "${f}" provided for property "${r}".`,
39
+ const m = this[a];
40
+ e.includes(f) ? this[a] = f : (console.error(
41
+ `<${i}> Invalid value "${f}" provided for property "${d}".`,
42
42
  `Must be one of: ${e.join(" | ")}.`,
43
43
  `Falling back to default value: "${t}"`
44
- ), this[d] = t), this.requestUpdate(r, h);
44
+ ), this[a] = t), this.requestUpdate(d, m);
45
45
  }
46
46
  });
47
- }, q = (i) => function(t, n) {
47
+ }, A = (i) => function(t, n) {
48
48
  const o = `#${n}`;
49
49
  Object.defineProperty(t, n, {
50
50
  get() {
51
51
  return this[o];
52
52
  },
53
- set(r) {
54
- const d = this[o];
55
- (r == null || typeof r == "string" && r.trim() === "") && console.error(`<${i}> Missing required attribute "${n}"`), this[o] = r, this.requestUpdate(n, d);
53
+ set(d) {
54
+ const a = this[o];
55
+ (d == null || typeof d == "string" && d.trim() === "") && console.error(`<${i}> Missing required attribute "${n}"`), this[o] = d, this.requestUpdate(n, a);
56
56
  }
57
57
  });
58
- }, I = `.c-webComponentTestWrapper{padding-block:var(--dt-spacing-c);padding-inline:var(--dt-spacing-e);font-family:var(--dt-font-interactive-m-family);font-size:calc(var(--dt-font-size-20) * 1px);border:1px solid var(--dt-color-background-dark);display:grid;grid-template-columns:1fr 1fr}.c-webComponentTestWrapper-label{margin-block:var(--dt-spacing-c)}.c-webComponentTestWrapper-slot{padding:var(--dt-spacing-c);border:1px dashed var(--dt-color-background-dark);grid-column:1/3;margin-block-start:var(--dt-spacing-c)}
59
- `;
60
- var F = Object.defineProperty, H = Object.getOwnPropertyDescriptor, E = (i, e, t, n) => {
61
- for (var o = n > 1 ? void 0 : n ? H(e, t) : e, r = i.length - 1, d; r >= 0; r--)
62
- (d = i[r]) && (o = (n ? d(e, t, o) : d(o)) || o);
63
- return n && o && F(e, t, o), o;
64
58
  };
65
- class b extends $ {
66
- constructor() {
67
- super(...arguments), this.propKeyValues = "", this.pageMode = !1;
68
- }
69
- // Renders a string such as 'size: small, isFullWidth: true'
70
- // as HTML such as:
71
- // <p class="c-webComponentTestWrapper-label"><b>size</b>: <code>small</code></p>
72
- // <p class="c-webComponentTestWrapper-label"><b>isFullWidth</b>: <code>true</code></p>
73
- _renderPropKeyValues() {
74
- return this.propKeyValues.split(",").map((e) => {
75
- const [t, n] = e.split(":");
76
- return w`<p class="c-webComponentTestWrapper-label"><b>${t}</b>: <code>${n}</code></p>`;
77
- });
78
- }
79
- render() {
80
- return this.pageMode ? w`
81
- <div>
82
- <slot name="component"></slot>
83
- <slot name="pageMarkup"></slot>
84
- </div>` : w`
85
- <div class="c-webComponentTestWrapper">
86
- ${this._renderPropKeyValues()}
87
- <div class="c-webComponentTestWrapper-slot">
88
- <slot name="component"></slot>
89
- </div>
90
- </div>`;
91
- }
92
- }
93
- b.styles = T(I);
94
- E([
95
- u({ type: String })
96
- ], b.prototype, "propKeyValues", 2);
97
- E([
98
- u({ type: Boolean })
99
- ], b.prototype, "pageMode", 2);
100
- const C = "web-component-test-wrapper";
101
- customElements.get(C) || customElements.define(C, b);
102
- function N(i) {
59
+ function q(i) {
103
60
  if (Array.isArray(i)) {
104
61
  for (var e = 0, t = Array(i.length); e < i.length; e++)
105
62
  t[e] = i[e];
@@ -107,37 +64,37 @@ function N(i) {
107
64
  } else
108
65
  return Array.from(i);
109
66
  }
110
- var P = !1;
67
+ var _ = !1;
111
68
  if (typeof window < "u") {
112
- var M = {
69
+ var z = {
113
70
  get passive() {
114
- P = !0;
71
+ _ = !0;
115
72
  }
116
73
  };
117
- window.addEventListener("testPassive", null, M), window.removeEventListener("testPassive", null, M);
74
+ window.addEventListener("testPassive", null, z), window.removeEventListener("testPassive", null, z);
118
75
  }
119
- var v = typeof window < "u" && window.navigator && window.navigator.platform && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === "MacIntel" && window.navigator.maxTouchPoints > 1), s = [], m = !1, x = -1, c = void 0, a = void 0, p = void 0, L = function(e) {
120
- return s.some(function(t) {
76
+ var p = typeof window < "u" && window.navigator && window.navigator.platform && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === "MacIntel" && window.navigator.maxTouchPoints > 1), r = [], v = !1, P = -1, c = void 0, l = void 0, u = void 0, M = function(e) {
77
+ return r.some(function(t) {
121
78
  return !!(t.options.allowTouchMove && t.options.allowTouchMove(e));
122
79
  });
123
80
  }, g = function(e) {
124
81
  var t = e || window.event;
125
- return L(t.target) || t.touches.length > 1 ? !0 : (t.preventDefault && t.preventDefault(), !1);
126
- }, Y = function(e) {
127
- if (p === void 0) {
82
+ return M(t.target) || t.touches.length > 1 ? !0 : (t.preventDefault && t.preventDefault(), !1);
83
+ }, I = function(e) {
84
+ if (u === void 0) {
128
85
  var t = !!e && e.reserveScrollBarGap === !0, n = window.innerWidth - document.documentElement.clientWidth;
129
86
  if (t && n > 0) {
130
87
  var o = parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right"), 10);
131
- p = document.body.style.paddingRight, document.body.style.paddingRight = o + n + "px";
88
+ u = document.body.style.paddingRight, document.body.style.paddingRight = o + n + "px";
132
89
  }
133
90
  }
134
91
  c === void 0 && (c = document.body.style.overflow, document.body.style.overflow = "hidden");
135
- }, U = function() {
136
- p !== void 0 && (document.body.style.paddingRight = p, p = void 0), c !== void 0 && (document.body.style.overflow = c, c = void 0);
137
- }, X = function() {
92
+ }, V = function() {
93
+ u !== void 0 && (document.body.style.paddingRight = u, u = void 0), c !== void 0 && (document.body.style.overflow = c, c = void 0);
94
+ }, j = function() {
138
95
  return window.requestAnimationFrame(function() {
139
- if (a === void 0) {
140
- a = {
96
+ if (l === void 0) {
97
+ l = {
141
98
  position: document.body.style.position,
142
99
  top: document.body.style.top,
143
100
  left: document.body.style.left
@@ -145,74 +102,74 @@ var v = typeof window < "u" && window.navigator && window.navigator.platform &&
145
102
  var e = window, t = e.scrollY, n = e.scrollX, o = e.innerHeight;
146
103
  document.body.style.position = "fixed", document.body.style.top = -t, document.body.style.left = -n, setTimeout(function() {
147
104
  return window.requestAnimationFrame(function() {
148
- var r = o - window.innerHeight;
149
- r && t >= o && (document.body.style.top = -(t + r));
105
+ var d = o - window.innerHeight;
106
+ d && t >= o && (document.body.style.top = -(t + d));
150
107
  });
151
108
  }, 300);
152
109
  }
153
110
  });
154
- }, K = function() {
155
- if (a !== void 0) {
111
+ }, F = function() {
112
+ if (l !== void 0) {
156
113
  var e = -parseInt(document.body.style.top, 10), t = -parseInt(document.body.style.left, 10);
157
- document.body.style.position = a.position, document.body.style.top = a.top, document.body.style.left = a.left, window.scrollTo(t, e), a = void 0;
114
+ document.body.style.position = l.position, document.body.style.top = l.top, document.body.style.left = l.left, window.scrollTo(t, e), l = void 0;
158
115
  }
159
- }, G = function(e) {
116
+ }, H = function(e) {
160
117
  return e ? e.scrollHeight - e.scrollTop <= e.clientHeight : !1;
161
- }, J = function(e, t) {
162
- var n = e.targetTouches[0].clientY - x;
163
- return L(e.target) ? !1 : t && t.scrollTop === 0 && n > 0 || G(t) && n < 0 ? g(e) : (e.stopPropagation(), !0);
164
- }, Q = function(e, t) {
118
+ }, N = function(e, t) {
119
+ var n = e.targetTouches[0].clientY - P;
120
+ return M(e.target) ? !1 : t && t.scrollTop === 0 && n > 0 || H(t) && n < 0 ? g(e) : (e.stopPropagation(), !0);
121
+ }, Y = function(e, t) {
165
122
  if (!e) {
166
123
  console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.");
167
124
  return;
168
125
  }
169
- if (!s.some(function(o) {
126
+ if (!r.some(function(o) {
170
127
  return o.targetElement === e;
171
128
  })) {
172
129
  var n = {
173
130
  targetElement: e,
174
131
  options: t || {}
175
132
  };
176
- s = [].concat(N(s), [n]), v ? X() : Y(t), v && (e.ontouchstart = function(o) {
177
- o.targetTouches.length === 1 && (x = o.targetTouches[0].clientY);
133
+ r = [].concat(q(r), [n]), p ? j() : I(t), p && (e.ontouchstart = function(o) {
134
+ o.targetTouches.length === 1 && (P = o.targetTouches[0].clientY);
178
135
  }, e.ontouchmove = function(o) {
179
- o.targetTouches.length === 1 && J(o, e);
180
- }, m || (document.addEventListener("touchmove", g, P ? { passive: !1 } : void 0), m = !0));
136
+ o.targetTouches.length === 1 && N(o, e);
137
+ }, v || (document.addEventListener("touchmove", g, _ ? { passive: !1 } : void 0), v = !0));
181
138
  }
182
- }, Z = function(e) {
139
+ }, U = function(e) {
183
140
  if (!e) {
184
141
  console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.");
185
142
  return;
186
143
  }
187
- s = s.filter(function(t) {
144
+ r = r.filter(function(t) {
188
145
  return t.targetElement !== e;
189
- }), v && (e.ontouchstart = null, e.ontouchmove = null, m && s.length === 0 && (document.removeEventListener("touchmove", g, P ? { passive: !1 } : void 0), m = !1)), v ? K() : U();
146
+ }), p && (e.ontouchstart = null, e.ontouchmove = null, v && r.length === 0 && (document.removeEventListener("touchmove", g, _ ? { passive: !1 } : void 0), v = !1)), p ? F() : V();
190
147
  };
191
- const ee = `.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;font-family:var(--modal-font);background-color:var(--modal-bg-color);padding:0;inline-size:var(--modal-size-m);box-shadow:var(--modal-elevation)}.c-modal::backdrop{background:rgba(0,0,0,.5)}.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);--modal-header-font-weight: var(--dt-font-heading-m-weight);--modal-header-padding: var(--dt-spacing-e);--modal-header-padding-block-end: var(--dt-spacing-d);font-size:var(--modal-header-font-size);line-height:var(--modal-header-font-line-height);font-weight:var(--modal-header-font-weight);margin:0;padding-block:var(--modal-header-padding) var(--modal-header-padding-block-end);padding-inline:var(--modal-header-padding)}.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: var(--dt-spacing-e);--modal-content-padding-block-start: var(--dt-spacing-a);font-size:var(--modal-content-font-size);line-height:var(--modal-content-line-height);font-weight:var(--modal-content-font-weight);padding-block:var(--modal-content-padding-block-start) var(--modal-content-padding);padding-inline:var(--modal-content-padding);overflow-y:scroll;max-block-size:300px}.c-modal .c-modal-closeBtn{position:absolute;inset-inline-end:var(--dt-spacing-d);inset-block-start:var(--dt-spacing-d)}
192
- `, te = ["h1", "h2", "h3", "h4", "h5", "h6"], _ = "pie-modal-close", O = "pie-modal-open";
193
- var oe = Object.defineProperty, ne = Object.getOwnPropertyDescriptor, y = (i, e, t, n) => {
194
- for (var o = n > 1 ? void 0 : n ? ne(e, t) : e, r = i.length - 1, d; r >= 0; r--)
195
- (d = i[r]) && (o = (n ? d(e, t, o) : d(o)) || o);
196
- return n && o && oe(e, t, o), o;
148
+ const X = `.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-max-inline-size: var(--modal-size-m);--modal-inline-size: 75%;max-inline-size:var(--modal-max-inline-size);inline-size:var(--modal-inline-size)}.c-modal[size=small]{--modal-max-inline-size: var(--modal-size-s)}.c-modal[size=large]{--modal-max-inline-size: var(--modal-size-l);--modal-inline-size: 100%}@media (min-width: 768px){.c-modal[size=large]{--modal-inline-size: 75%}}.c-modal::backdrop{background:rgba(0,0,0,.5)}.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);--modal-header-font-weight: var(--dt-font-heading-m-weight);--modal-header-padding: var(--dt-spacing-e);--modal-header-padding-block-end: var(--dt-spacing-d);font-size:var(--modal-header-font-size);line-height:var(--modal-header-font-line-height);font-weight:var(--modal-header-font-weight);margin:0;padding-block:var(--modal-header-padding) var(--modal-header-padding-block-end);padding-inline:var(--modal-header-padding)}.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: var(--dt-spacing-e);--modal-content-padding-block-start: var(--dt-spacing-a);font-size:var(--modal-content-font-size);line-height:var(--modal-content-line-height);font-weight:var(--modal-content-font-weight);padding-block:var(--modal-content-padding-block-start) var(--modal-content-padding);padding-inline:var(--modal-content-padding);overflow-y:scroll;max-block-size:300px}.c-modal .c-modal-closeBtn{position:absolute;inset-inline-end:var(--dt-spacing-d);inset-block-start:var(--dt-spacing-d)}
149
+ `, W = ["h1", "h2", "h3", "h4", "h5", "h6"], G = ["small", "medium", "large"], w = "pie-modal-close", O = "pie-modal-open";
150
+ var J = Object.defineProperty, Q = Object.getOwnPropertyDescriptor, h = (i, e, t, n) => {
151
+ for (var o = n > 1 ? void 0 : n ? Q(e, t) : e, d = i.length - 1, a; d >= 0; d--)
152
+ (a = i[d]) && (o = (n ? a(e, t, o) : a(o)) || o);
153
+ return n && o && J(e, t, o), o;
197
154
  };
198
- const S = "pie-modal";
199
- class l extends W($) {
155
+ const b = "pie-modal";
156
+ class s extends R(x) {
200
157
  constructor() {
201
- super(), this.isOpen = !1, this.headingLevel = "h2", this._triggerCloseModal = () => {
158
+ super(), this.isOpen = !1, this.headingLevel = "h2", this.size = "medium", this._triggerCloseModal = () => {
202
159
  this.isOpen = !1;
203
160
  }, this._handleDialogLightDismiss = (e) => {
204
- var h;
205
- const t = (h = this._dialog) == null ? void 0 : h.getBoundingClientRect(), {
161
+ var m;
162
+ const t = (m = this._dialog) == null ? void 0 : m.getBoundingClientRect(), {
206
163
  top: n = 0,
207
164
  bottom: o = 0,
208
- left: r = 0,
209
- right: d = 0
165
+ left: d = 0,
166
+ right: a = 0
210
167
  } = t || {};
211
- if (n === 0 && o === 0 && r === 0 && d === 0)
168
+ if (n === 0 && o === 0 && d === 0 && a === 0)
212
169
  return;
213
- (e.clientY < n || e.clientY > o || e.clientX < r || e.clientX > d) && (this.isOpen = !1);
170
+ (e.clientY < n || e.clientY > o || e.clientX < d || e.clientX > a) && (this.isOpen = !1);
214
171
  }, this._dispatchModalCloseEvent = () => {
215
- const e = new CustomEvent(_, {
172
+ const e = new CustomEvent(w, {
216
173
  bubbles: !0,
217
174
  composed: !0
218
175
  });
@@ -236,20 +193,20 @@ class l extends W($) {
236
193
  */
237
194
  _handleModalOpened() {
238
195
  var e;
239
- Q(this), (e = this._dialog) == null || e.showModal();
196
+ Y(this), (e = this._dialog) == null || e.showModal();
240
197
  }
241
198
  /**
242
199
  * Closes the dialog element and re-enables page scrolling
243
200
  */
244
201
  _handleModalClosed() {
245
202
  var e;
246
- Z(this), (e = this._dialog) == null || e.close();
203
+ U(this), (e = this._dialog) == null || e.close();
247
204
  }
248
205
  connectedCallback() {
249
- super.connectedCallback(), document.addEventListener(O, this._handleModalOpened.bind(this)), document.addEventListener(_, this._handleModalClosed.bind(this));
206
+ super.connectedCallback(), document.addEventListener(O, this._handleModalOpened.bind(this)), document.addEventListener(w, this._handleModalClosed.bind(this));
250
207
  }
251
208
  disconnectedCallback() {
252
- document.removeEventListener(O, this._handleModalOpened.bind(this)), document.removeEventListener(_, this._handleModalClosed.bind(this)), super.disconnectedCallback();
209
+ document.removeEventListener(O, this._handleModalOpened.bind(this)), document.removeEventListener(w, this._handleModalClosed.bind(this)), super.disconnectedCallback();
253
210
  }
254
211
  // Handles the value of the isOpen property on first render of the component
255
212
  _handleModalOpenStateOnFirstRender(e) {
@@ -263,15 +220,19 @@ class l extends W($) {
263
220
  render() {
264
221
  const {
265
222
  heading: e,
266
- headingLevel: t = "h2"
267
- } = this, n = D(t);
268
- return z`
269
- <dialog id="dialog" class="c-modal">
223
+ headingLevel: t = "h2",
224
+ size: n
225
+ } = this, o = E(t);
226
+ return L`
227
+ <dialog
228
+ id="dialog"
229
+ size="${n}"
230
+ class="c-modal">
270
231
  <header>
271
- <${n} class="c-modal-heading">${e}</${n}>
232
+ <${o} class="c-modal-heading">${e}</${o}>
272
233
  <pie-icon-button
273
234
  @click="${this._triggerCloseModal}"
274
- variant="ghost-tertiary"
235
+ variant="ghost-secondary"
275
236
  class="c-modal-closeBtn"></pie-icon-button>
276
237
  </header>
277
238
  <article class="c-modal-content">
@@ -281,23 +242,28 @@ class l extends W($) {
281
242
  `;
282
243
  }
283
244
  }
284
- l.styles = T(ee);
285
- y([
286
- u({ type: Boolean })
287
- ], l.prototype, "isOpen", 2);
288
- y([
289
- u({ type: String }),
290
- q(S)
291
- ], l.prototype, "heading", 2);
292
- y([
293
- u(),
294
- j(S, te, "h2")
295
- ], l.prototype, "headingLevel", 2);
296
- y([
297
- B("dialog")
298
- ], l.prototype, "_dialog", 2);
299
- customElements.define(S, l);
245
+ s.styles = C(X);
246
+ h([
247
+ y({ type: Boolean })
248
+ ], s.prototype, "isOpen", 2);
249
+ h([
250
+ y({ type: String }),
251
+ A(b)
252
+ ], s.prototype, "heading", 2);
253
+ h([
254
+ y(),
255
+ S(b, W, "h2")
256
+ ], s.prototype, "headingLevel", 2);
257
+ h([
258
+ y(),
259
+ S(b, G, "medium")
260
+ ], s.prototype, "size", 2);
261
+ h([
262
+ T("dialog")
263
+ ], s.prototype, "_dialog", 2);
264
+ customElements.define(b, s);
300
265
  export {
301
- l as PieModal,
302
- te as headingLevels
266
+ s as PieModal,
267
+ W as headingLevels,
268
+ G as sizes
303
269
  };
package/dist/react.js CHANGED
File without changes
File without changes
@@ -1,19 +1,22 @@
1
1
  export declare const headingLevels: readonly ["h1", "h2", "h3", "h4", "h5", "h6"];
2
+ export declare const sizes: readonly ["small", "medium", "large"];
2
3
  export interface ModalProps {
3
4
  /**
4
- * (Required) The text to display in the modal's heading.
5
+ * The text to display in the modal's heading.
5
6
  */
6
7
  heading: string;
7
8
  /**
8
- * (Optional) The HTML heading tag to use for the modal's heading. Can be H1-H6.
9
- * @default "h2"
9
+ * The HTML heading tag to use for the modal's heading. Can be h1-h6.
10
10
  */
11
11
  headingLevel: typeof headingLevels[number];
12
12
  /**
13
- * (Optional) When true, the modal will be open.
14
- * @default false
13
+ * When true, the modal will be open.
15
14
  */
16
15
  isOpen: boolean;
16
+ /**
17
+ * The size of the modal; this controls how wide it will appear on the page.
18
+ */
19
+ size: typeof sizes[number];
17
20
  }
18
21
  /**
19
22
  * Event name for when the modal is closed.
@@ -1 +1 @@
1
- {"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../../src/defs.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,+CAAgD,CAAC;AAE3E,MAAM,WAAW,UAAU;IACvB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,YAAY,EAAE,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,mBAAmB,CAAC"}
1
+ {"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../../src/defs.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,+CAAgD,CAAC;AAC3E,eAAO,MAAM,KAAK,uCAAwC,CAAC;AAE3D,MAAM,WAAW,UAAU;IACvB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,YAAY,EAAE,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;OAEG;IACH,IAAI,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,mBAAmB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { LitElement } from 'lit';
2
2
  import type { DependentMap } from '@justeattakeaway/pie-webc-core';
3
- import { ModalProps, headingLevels } from './defs';
4
- export { type ModalProps, headingLevels };
3
+ import { ModalProps, headingLevels, sizes } from './defs';
4
+ export { type ModalProps, headingLevels, sizes };
5
5
  declare const componentSelector = "pie-modal";
6
6
  declare const PieModal_base: (new (...args: any[]) => {
7
7
  dir: string;
@@ -11,6 +11,7 @@ export declare class PieModal extends PieModal_base {
11
11
  isOpen: boolean;
12
12
  heading: string;
13
13
  headingLevel: ModalProps['headingLevel'];
14
+ size: ModalProps['size'];
14
15
  _dialog?: HTMLDialogElement;
15
16
  constructor();
16
17
  firstUpdated(changedProperties: DependentMap<ModalProps>): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAM5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,EACH,UAAU,EAAE,aAAa,EAC5B,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,KAAK,UAAU,EAAE,aAAa,EAAE,CAAC;AAE1C,QAAA,MAAM,iBAAiB,cAAc,CAAC;;;;;AAEtC,qBAAa,QAAS,SAAQ,aAAoB;IAE1C,MAAM,UAAS;IAIf,OAAO,EAAG,MAAM,CAAC;IAIjB,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAQ;IAGhD,OAAO,CAAC,EAAE,iBAAiB,CAAC;;IAOhC,YAAY,CAAE,iBAAiB,EAAE,YAAY,CAAC,UAAU,CAAC,GAAI,IAAI;IAIjE,OAAO,CAAE,iBAAiB,EAAE,YAAY,CAAC,UAAU,CAAC,GAAI,IAAI;IAI5D;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;;OAGG;IACH,OAAO,CAAC,kBAAkB,CAExB;IAEF,iBAAiB,IAAM,IAAI;IAM3B,oBAAoB,IAAM,IAAI;IAO9B,OAAO,CAAC,kCAAkC;IAU1C,OAAO,CAAC,4BAA4B;IAYpC,MAAM;IAwBN;;;OAGG;IACH,OAAO,CAAC,yBAAyB,CAqB/B;IAEF;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB,CAO9B;IAEF;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB,CAO7B;IAGF,MAAM,CAAC,MAAM,0BAAqB;CACrC;AAID,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC;KACjC;CACJ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAM5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,EACH,UAAU,EACV,aAAa,EAGb,KAAK,EACR,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,KAAK,UAAU,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;AAEjD,QAAA,MAAM,iBAAiB,cAAc,CAAC;;;;;AAEtC,qBAAa,QAAS,SAAQ,aAAoB;IAEvC,MAAM,UAAS;IAIf,OAAO,EAAG,MAAM,CAAC;IAIjB,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAQ;IAIhD,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAY;IAGvC,OAAO,CAAC,EAAE,iBAAiB,CAAC;;IAOhC,YAAY,CAAE,iBAAiB,EAAE,YAAY,CAAC,UAAU,CAAC,GAAI,IAAI;IAIjE,OAAO,CAAE,iBAAiB,EAAE,YAAY,CAAC,UAAU,CAAC,GAAI,IAAI;IAI5D;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;;OAGG;IACH,OAAO,CAAC,kBAAkB,CAExB;IAEF,iBAAiB,IAAM,IAAI;IAM3B,oBAAoB,IAAM,IAAI;IAO9B,OAAO,CAAC,kCAAkC;IAU1C,OAAO,CAAC,4BAA4B;IAYpC,MAAM;IA4BN;;;OAGG;IACH,OAAO,CAAC,yBAAyB,CAqB/B;IAEF;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB,CAO9B;IAEF;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB,CAO7B;IAGF,MAAM,CAAC,MAAM,0BAAqB;CACrC;AAID,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC;KACjC;CACJ"}
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-modal",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "PIE design system modal built using web components",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,6 +22,7 @@
22
22
  "license": "Apache-2.0",
23
23
  "devDependencies": {
24
24
  "@justeattakeaway/pie-components-config": "workspace:*",
25
+ "@justeattakeaway/pie-icon-button": "workspace:*",
25
26
  "@justeattakeaway/pie-webc-core": "workspace:*",
26
27
  "@types/body-scroll-lock": "3.1.0"
27
28
  },
package/src/defs.ts CHANGED
@@ -1,20 +1,23 @@
1
1
  export const headingLevels = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;
2
+ export const sizes = ['small', 'medium', 'large'] as const;
2
3
 
3
4
  export interface ModalProps {
4
5
  /**
5
- * (Required) The text to display in the modal's heading.
6
+ * The text to display in the modal's heading.
6
7
  */
7
8
  heading: string;
8
9
  /**
9
- * (Optional) The HTML heading tag to use for the modal's heading. Can be H1-H6.
10
- * @default "h2"
10
+ * The HTML heading tag to use for the modal's heading. Can be h1-h6.
11
11
  */
12
12
  headingLevel: typeof headingLevels[number];
13
13
  /**
14
- * (Optional) When true, the modal will be open.
15
- * @default false
14
+ * When true, the modal will be open.
16
15
  */
17
16
  isOpen: boolean;
17
+ /**
18
+ * The size of the modal; this controls how wide it will appear on the page.
19
+ */
20
+ size: typeof sizes[number];
18
21
  }
19
22
 
20
23
  /**
package/src/index.ts CHANGED
@@ -8,25 +8,33 @@ import type { DependentMap } from '@justeattakeaway/pie-webc-core';
8
8
  import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock';
9
9
  import styles from './modal.scss?inline';
10
10
  import {
11
- ModalProps, headingLevels, ON_MODAL_CLOSE_EVENT, ON_MODAL_OPEN_EVENT,
11
+ ModalProps,
12
+ headingLevels,
13
+ ON_MODAL_CLOSE_EVENT,
14
+ ON_MODAL_OPEN_EVENT,
15
+ sizes,
12
16
  } from './defs';
13
17
 
14
18
  // Valid values available to consumers
15
- export { type ModalProps, headingLevels };
19
+ export { type ModalProps, headingLevels, sizes };
16
20
 
17
21
  const componentSelector = 'pie-modal';
18
22
 
19
23
  export class PieModal extends RtlMixin(LitElement) {
20
24
  @property({ type: Boolean })
21
- isOpen = false;
25
+ public isOpen = false;
22
26
 
23
27
  @property({ type: String })
24
28
  @requiredProperty(componentSelector)
25
- heading!: string;
29
+ public heading!: string;
26
30
 
27
31
  @property()
28
32
  @validPropertyValues(componentSelector, headingLevels, 'h2')
29
- headingLevel: ModalProps['headingLevel'] = 'h2';
33
+ public headingLevel: ModalProps['headingLevel'] = 'h2';
34
+
35
+ @property()
36
+ @validPropertyValues(componentSelector, sizes, 'medium')
37
+ public size: ModalProps['size'] = 'medium';
30
38
 
31
39
  @query('dialog')
32
40
  _dialog?: HTMLDialogElement;
@@ -111,17 +119,21 @@ export class PieModal extends RtlMixin(LitElement) {
111
119
  const {
112
120
  heading,
113
121
  headingLevel = 'h2',
122
+ size,
114
123
  } = this;
115
124
 
116
125
  const headingTag = unsafeStatic(headingLevel);
117
126
 
118
127
  return html`
119
- <dialog id="dialog" class="c-modal">
128
+ <dialog
129
+ id="dialog"
130
+ size="${size}"
131
+ class="c-modal">
120
132
  <header>
121
133
  <${headingTag} class="c-modal-heading">${heading}</${headingTag}>
122
134
  <pie-icon-button
123
135
  @click="${this._triggerCloseModal}"
124
- variant="ghost-tertiary"
136
+ variant="ghost-secondary"
125
137
  class="c-modal-closeBtn"></pie-icon-button>
126
138
  </header>
127
139
  <article class="c-modal-content">
package/src/modal.scss CHANGED
@@ -3,6 +3,8 @@
3
3
  .c-modal {
4
4
  // Custom Property Declarations
5
5
  // These are defined here instead of :host to encapsulate them inside Shadow DOM
6
+ $breakpoint-wide: 768px;
7
+
6
8
  --modal-size-s: 450px;
7
9
  --modal-size-m: 600px;
8
10
  --modal-size-l: 1080px;
@@ -15,13 +17,34 @@
15
17
 
16
18
  border-radius: var(--modal-border-radius);
17
19
  border: none;
20
+ box-shadow: var(--modal-elevation);
18
21
  font-family: var(--modal-font);
19
22
  background-color: var(--modal-bg-color);
20
23
 
21
24
  padding: 0;
22
- inline-size: var(--modal-size-m);
23
25
 
24
- box-shadow: var(--modal-elevation);
26
+ --modal-max-inline-size: var(--modal-size-m);
27
+ --modal-inline-size: 75%;
28
+
29
+ max-inline-size: var(--modal-max-inline-size);
30
+ inline-size: var(--modal-inline-size);
31
+
32
+ &[size='small'] {
33
+ --modal-max-inline-size: var(--modal-size-s);
34
+ }
35
+
36
+ &[size='medium'] {
37
+ /* Same as default styles */
38
+ }
39
+
40
+ &[size='large'] {
41
+ --modal-max-inline-size: var(--modal-size-l);
42
+ --modal-inline-size: 100%;
43
+
44
+ @media (min-width: $breakpoint-wide) {
45
+ --modal-inline-size: 75%;
46
+ }
47
+ }
25
48
 
26
49
  // We need to pull in the token directly here because the
27
50
  // pseudo element `::backdrop` doesn't seem to pick up custom css properties.
@@ -1,7 +1,25 @@
1
1
  import { test, expect } from '@sand4rt/experimental-ct-web';
2
+ import { PieIconButton } from '@justeattakeaway/pie-icon-button';
2
3
  import { PieModal } from '@/index';
3
4
  import { headingLevels } from '@/defs';
4
5
 
6
+ // Mount any components that are used inside of pie-modal so that
7
+ // they have been registered with the browser before the tests run.
8
+ // There is likely a nicer way to do this but this will temporarily
9
+ // unblock tests.
10
+ test.beforeEach(async ({ page, mount }) => {
11
+ await mount(
12
+ PieIconButton,
13
+ {},
14
+ );
15
+
16
+ // Removing the element so it's not present in the tests (but is still registered in the DOM)
17
+ await page.evaluate(() => {
18
+ const element : Element | null = document.querySelector('pie-icon-button');
19
+ element?.remove();
20
+ });
21
+ });
22
+
5
23
  headingLevels.forEach((headingLevel) => test(`should render the correct heading tag based on the value of headingLevel: ${headingLevel}`, async ({ mount }) => {
6
24
  const props = {
7
25
  heading: 'Modal Header',
@@ -30,13 +48,13 @@ headingLevels.forEach((headingLevel) => test(`should render the correct heading
30
48
 
31
49
  test.describe('`Pie Modal is closed`', () => {
32
50
  test.describe('when via the close button click', () => {
33
- test.skip('should dispatch event `pie-modal-close`', async ({ mount, page }) => {
51
+ test('should dispatch event `pie-modal-close`', async ({ mount, page }) => {
34
52
  const messages: string[] = [];
35
53
  await mount(
36
54
  PieModal,
37
55
  {
38
56
  props: {
39
- isOpen: true
57
+ isOpen: true,
40
58
  },
41
59
  on: {
42
60
  click: (event: string) => messages.push(event),
@@ -46,13 +64,12 @@ test.describe('`Pie Modal is closed`', () => {
46
64
 
47
65
  await page.locator('.c-modal-closeBtn').click();
48
66
 
49
-
50
67
  expect(messages).toHaveLength(1);
51
68
  });
52
69
  });
53
70
 
54
71
  test.describe('when via the backdrop click', () => {
55
- test.skip('should dispatch event `pie-modal-close`', async ({ mount, page }) => {
72
+ test('should dispatch event `pie-modal-close`', async ({ mount, page }) => {
56
73
  const messages: string[] = [];
57
74
  await mount(
58
75
  PieModal,
@@ -68,7 +85,6 @@ test.describe('`Pie Modal is closed`', () => {
68
85
 
69
86
  await page.locator('#dialog').click();
70
87
 
71
-
72
88
  expect(messages).toHaveLength(1);
73
89
  });
74
90
  });
@@ -2,49 +2,43 @@ import { test } from '@sand4rt/experimental-ct-web';
2
2
  import percySnapshot from '@percy/playwright';
3
3
  import {
4
4
  WebComponentTestWrapper,
5
- } from '@justeattakeaway/pie-webc-core/src/test-helpers/components/web-component-test-wrapper/WebComponentTestWrapper.ts';
6
- import { WebComponentPropValues } from '@justeattakeaway/pie-webc-core/src/test-helpers/defs';
5
+ } from '@justeattakeaway/pie-webc-testing/src/helpers/components/web-component-test-wrapper/WebComponentTestWrapper.ts';
6
+ import { PieIconButton } from '@justeattakeaway/pie-icon-button';
7
7
  import { PieModal } from '@/index';
8
+ import { ModalProps, sizes } from '@/defs';
8
9
 
9
- const propIsOpenValues = [{ heading: 'Modal Heading', isOpen: true }, { isOpen: false }];
10
+ // Renders a <pie-modal> HTML string with the given prop values
11
+ const renderTestPieModal = ({
12
+ heading = 'This is a modal heading',
13
+ headingLevel = 'h2',
14
+ size = 'medium',
15
+ isOpen = true,
16
+ } : Partial<ModalProps> = {}) => `<pie-modal ${isOpen ? 'isOpen' : ''} heading="${heading}" headingLevel="${headingLevel}" size="${size}"></pie-modal>`;
10
17
 
11
- propIsOpenValues.forEach((props) => test(`should render Modal correctly when prop isOpen is set to ${props.isOpen}`, async ({ page, mount }) => {
18
+ // Creates a <ol> with a large number of <li> nodes for testing page scrolling
19
+ const createTestPageHTML = () => `<ol>
20
+ ${'<li>List item</li>'.repeat(200)}
21
+ </ol>`;
22
+
23
+ // Mount any components that are used inside of pie-modal so that
24
+ // they have been registered with the browser before the tests run.
25
+ // There is likely a nicer way to do this but this will temporarily
26
+ // unblock tests.
27
+ test.beforeEach(async ({ page, mount }) => {
12
28
  await mount(
13
- PieModal,
14
- {
15
- props,
16
- slots: {
17
- default: 'Hello, this is the Pie Modal!',
18
- },
19
- },
29
+ PieIconButton,
30
+ {},
20
31
  );
21
32
 
22
- await percySnapshot(page, `PIE Modal when isOpen is set to ${props.isOpen}`);
23
- }));
24
-
25
- const renderTestPieModal = (propVals: WebComponentPropValues) => `<pie-modal ${propVals.isOpen ? 'isOpen' : ''} heading="${propVals.heading}" headingLevel="${propVals.headingLevel}"></pie-modal>`;
26
-
27
- // Creates a <ul> with a large number of <li> nodes for testing page scrolling
28
- const createTestPageHTML = () : string => {
29
- let list = '<ul>';
30
-
31
- for (let i = 0; i < 200; i++) {
32
- list += `<li>Item ${i}</li>`;
33
- }
34
-
35
- list += '</ul>';
36
-
37
- return list;
38
- };
33
+ // Removing the element so it's not present in the tests (but is still registered in the DOM)
34
+ await page.evaluate(() => {
35
+ const element : Element | null = document.querySelector('pie-icon-button');
36
+ element?.remove();
37
+ });
38
+ });
39
39
 
40
40
  test('Should not be able to scroll when modal is open', async ({ page, mount }) => {
41
- const props: WebComponentPropValues = {
42
- heading: 'I am a Modal!',
43
- headingLevel: 'h2',
44
- isOpen: true,
45
- };
46
-
47
- const modalComponent = renderTestPieModal(props);
41
+ const modalComponent = renderTestPieModal();
48
42
 
49
43
  await mount(
50
44
  WebComponentTestWrapper,
@@ -64,5 +58,33 @@ test('Should not be able to scroll when modal is open', async ({ page, mount })
64
58
 
65
59
  await page.waitForTimeout(3000); // The mouse.wheel function causes scrolling, but doesn't wait for the scroll to finish before returning.
66
60
 
67
- await percySnapshot(page, 'PIE Modal scroll locking');
61
+ await percySnapshot(page, 'Modal - scroll locking');
62
+ });
63
+
64
+ test('should not render when isOpen = false', async ({ page, mount }) => {
65
+ await mount(PieModal, {
66
+ props: {
67
+ heading: 'This is a modal heading',
68
+ headingLevel: 'h2',
69
+ isOpen: false,
70
+ size: 'medium',
71
+ },
72
+ });
73
+
74
+ await percySnapshot(page, 'Modal - isOpen = false');
75
+ });
76
+
77
+ sizes.forEach((size) => {
78
+ test(`should render correctly with size = ${size}`, async ({ page, mount }) => {
79
+ await mount(PieModal, {
80
+ props: {
81
+ heading: 'This is a modal heading',
82
+ headingLevel: 'h2',
83
+ isOpen: true,
84
+ size,
85
+ },
86
+ });
87
+
88
+ await percySnapshot(page, `Modal - size = ${size}`);
89
+ });
68
90
  });