@justeattakeaway/pie-modal 0.11.0 → 0.13.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/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +27 -0
- package/README.md +2 -0
- package/dist/index.js +221 -164
- package/dist/react.js +131 -124
- package/dist/types/packages/components/pie-modal/src/defs.d.ts +16 -1
- package/dist/types/packages/components/pie-modal/src/defs.d.ts.map +1 -1
- package/dist/types/packages/components/pie-modal/src/index.d.ts +25 -11
- package/dist/types/packages/components/pie-modal/src/index.d.ts.map +1 -1
- package/dist/types/packages/components/pie-modal/src/react.d.ts +6 -1
- package/dist/types/packages/components/pie-modal/src/react.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/defs.ts +20 -1
- package/src/index.ts +110 -41
- package/src/modal.scss +183 -19
- package/test/component/pie-modal.spec.ts +236 -56
- package/test/visual/pie-modal.spec.ts +50 -0
package/src/modal.scss
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
@use '@justeat/pie-design-tokens/dist/jet.scss' as dt;
|
|
2
2
|
|
|
3
|
+
// TODO - add to CSS lib once created
|
|
4
|
+
*,
|
|
5
|
+
*:before,
|
|
6
|
+
*:after {
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Spin animation for loading state
|
|
11
|
+
@keyframes rotate360 {
|
|
12
|
+
from {
|
|
13
|
+
transform: rotate(0deg);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
to {
|
|
17
|
+
transform: rotate(360deg);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
3
21
|
.c-modal {
|
|
4
22
|
// Custom Property Declarations
|
|
5
23
|
// These are defined here instead of :host to encapsulate them inside Shadow DOM
|
|
@@ -15,6 +33,18 @@
|
|
|
15
33
|
--modal-bg-color: var(--dt-color-container-default);
|
|
16
34
|
--modal-elevation: var(--dt-elevation-04);
|
|
17
35
|
|
|
36
|
+
&:focus-visible {
|
|
37
|
+
outline: none;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&[open] {
|
|
41
|
+
// We only apply this when the modal is open,
|
|
42
|
+
// otherwise it interferes with the native
|
|
43
|
+
// `display: none;` on the dialog element.
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
}
|
|
47
|
+
|
|
18
48
|
border-radius: var(--modal-border-radius);
|
|
19
49
|
border: none;
|
|
20
50
|
box-shadow: var(--modal-elevation);
|
|
@@ -23,31 +53,60 @@
|
|
|
23
53
|
|
|
24
54
|
padding: 0;
|
|
25
55
|
|
|
26
|
-
--modal-
|
|
56
|
+
--modal-margin-none: var(--dt-spacing-none);
|
|
57
|
+
--modal-margin-small: var(--dt-spacing-g);
|
|
58
|
+
--modal-margin-large: var(--dt-spacing-j);
|
|
59
|
+
--modal-margin-block: var(--modal-margin-small);
|
|
60
|
+
|
|
61
|
+
@media (min-width: $breakpoint-wide) {
|
|
62
|
+
--modal-margin-block: var(--modal-margin-large);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// The initial values for these variables apply to the medium-sized modal
|
|
66
|
+
// Other sizes will update the variables as needed
|
|
67
|
+
--modal-block-size: fit-content;
|
|
27
68
|
--modal-inline-size: 75%;
|
|
69
|
+
--modal-max-block-size: calc(100vh - calc(var(--modal-margin-block) * 2));
|
|
70
|
+
--modal-max-inline-size: var(--modal-size-m);
|
|
28
71
|
|
|
29
|
-
|
|
72
|
+
block-size: var(--modal-block-size);
|
|
30
73
|
inline-size: var(--modal-inline-size);
|
|
74
|
+
max-block-size: var(--modal-max-block-size);
|
|
75
|
+
max-inline-size: var(--modal-max-inline-size);
|
|
31
76
|
|
|
32
77
|
&[size='small'] {
|
|
33
78
|
--modal-max-inline-size: var(--modal-size-s);
|
|
79
|
+
|
|
80
|
+
@media (min-width: $breakpoint-wide) {
|
|
81
|
+
--modal-margin-block: var(--modal-margin-large);
|
|
82
|
+
}
|
|
34
83
|
}
|
|
35
84
|
|
|
36
85
|
&[size='medium'] {
|
|
37
86
|
/* Same as default styles */
|
|
38
87
|
&[isfullwidthbelowmid] {
|
|
39
|
-
@media (max-width: $breakpoint-wide) {
|
|
88
|
+
@media (max-width: calc($breakpoint-wide - 1px)) {
|
|
89
|
+
--modal-margin-block: var(--modal-margin-none);
|
|
90
|
+
--modal-border-radius: var(--dt-radius-rounded-none);
|
|
91
|
+
--modal-block-size: 100%;
|
|
40
92
|
--modal-inline-size: 100%;
|
|
93
|
+
|
|
94
|
+
// In this case, the modal must exceed the previous maximum width
|
|
95
|
+
--modal-max-inline-size: 100%;
|
|
41
96
|
}
|
|
42
97
|
}
|
|
43
98
|
}
|
|
44
99
|
|
|
45
100
|
&[size='large'] {
|
|
101
|
+
--modal-inline-size: 75%;
|
|
46
102
|
--modal-max-inline-size: var(--modal-size-l);
|
|
47
|
-
--modal-
|
|
103
|
+
--modal-margin-block: var(--modal-margin-large);
|
|
48
104
|
|
|
49
|
-
@media (
|
|
50
|
-
--modal-
|
|
105
|
+
@media (max-width: calc($breakpoint-wide - 1px)) {
|
|
106
|
+
--modal-margin-block: var(--modal-margin-none);
|
|
107
|
+
--modal-border-radius: var(--dt-radius-rounded-none);
|
|
108
|
+
--modal-block-size: 100%;
|
|
109
|
+
--modal-inline-size: 100%;
|
|
51
110
|
}
|
|
52
111
|
}
|
|
53
112
|
|
|
@@ -57,21 +116,60 @@
|
|
|
57
116
|
background: #{dt.$color-overlay};
|
|
58
117
|
}
|
|
59
118
|
|
|
119
|
+
& .c-modal-footer {
|
|
120
|
+
--modal-button-spacing: var(--dt-spacing-d);
|
|
121
|
+
--modal-footer-padding: var(--dt-spacing-d);
|
|
122
|
+
|
|
123
|
+
display: flex;
|
|
124
|
+
flex-flow: row-reverse;
|
|
125
|
+
flex-wrap: wrap;
|
|
126
|
+
gap: var(--modal-button-spacing);
|
|
127
|
+
padding: var(--modal-footer-padding);
|
|
128
|
+
|
|
129
|
+
@media (min-width: $breakpoint-wide) {
|
|
130
|
+
--modal-footer-padding: var(--dt-spacing-e);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
& .c-modal-header {
|
|
135
|
+
--modal-header-padding: var(--dt-spacing-e);
|
|
136
|
+
|
|
137
|
+
padding-inline: var(--modal-header-padding);
|
|
138
|
+
padding-block: var(--modal-header-padding);
|
|
139
|
+
align-items: center;
|
|
140
|
+
display: flex;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
&[hasbackbutton] .c-modal-header {
|
|
144
|
+
padding-block: var(--dt-spacing-c);
|
|
145
|
+
padding-inline-start: var(--dt-spacing-c);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
&[isdismissible] .c-modal-header {
|
|
149
|
+
justify-content: space-between;
|
|
150
|
+
padding-block: var(--dt-spacing-c);
|
|
151
|
+
padding-inline-end: var(--dt-spacing-c);
|
|
152
|
+
}
|
|
153
|
+
|
|
60
154
|
& .c-modal-heading {
|
|
61
|
-
// Modal header Custom Props
|
|
62
155
|
--modal-header-font-size: calc(var(--dt-font-heading-m-size--wide) * 1px);
|
|
63
156
|
--modal-header-font-line-height: calc(var(--dt-font-heading-m-line-height--wide) * 1px);
|
|
64
157
|
--modal-header-font-weight: var(--dt-font-heading-m-weight);
|
|
65
|
-
--modal-header-padding: var(--dt-spacing-e);
|
|
66
|
-
--modal-header-padding-block-end: var(--dt-spacing-d);
|
|
67
158
|
|
|
68
159
|
font-size: var(--modal-header-font-size);
|
|
69
160
|
line-height: var(--modal-header-font-line-height);
|
|
70
161
|
font-weight: var(--modal-header-font-weight);
|
|
71
|
-
|
|
72
162
|
margin: 0;
|
|
73
|
-
|
|
74
|
-
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Ensure correct padding when there is a back button in front of the heading
|
|
166
|
+
&[hasbackbutton] .c-modal-heading {
|
|
167
|
+
margin-inline-start: var(--dt-spacing-c);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Ensure correct padding when there is a close button behind the heading
|
|
171
|
+
&[isdismissible] .c-modal-heading {
|
|
172
|
+
margin-inline-end: var(--dt-spacing-e);
|
|
75
173
|
}
|
|
76
174
|
|
|
77
175
|
& .c-modal-content {
|
|
@@ -80,22 +178,88 @@
|
|
|
80
178
|
--modal-content-font-weight: var(--dt-font-weight-regular);
|
|
81
179
|
--modal-content-line-height: calc(var(--dt-font-size-16-line-height) * 1px);
|
|
82
180
|
--modal-content-padding: var(--dt-spacing-e);
|
|
83
|
-
--modal-content-padding-block
|
|
181
|
+
--modal-content-padding-block: var(--dt-spacing-a);
|
|
182
|
+
|
|
183
|
+
// Spinner sizes defaults
|
|
184
|
+
--spinner-size: 48px;
|
|
185
|
+
--spinner-border-width: 6px;
|
|
186
|
+
|
|
187
|
+
// Spinner colors - currently set for the primary button styles
|
|
188
|
+
--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);
|
|
189
|
+
--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);
|
|
190
|
+
--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l);
|
|
191
|
+
--spinner-left-color-opacity: 0.35;
|
|
192
|
+
--spinner-left-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), var(--spinner-left-color-opacity));
|
|
193
|
+
--spinner-right-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), 1);
|
|
194
|
+
|
|
195
|
+
// Spinner animations
|
|
196
|
+
--spinner-animation-duration: 1.15s;
|
|
197
|
+
--spinner-animation-timing-function: linear;
|
|
198
|
+
--spinner-animation-iteration-count: infinite;
|
|
199
|
+
|
|
200
|
+
position: relative;
|
|
201
|
+
min-block-size: 60px;
|
|
84
202
|
|
|
85
203
|
font-size: var(--modal-content-font-size);
|
|
86
204
|
line-height: var(--modal-content-line-height);
|
|
87
205
|
font-weight: var(--modal-content-font-weight);
|
|
88
206
|
|
|
89
|
-
padding-block: var(--modal-content-padding-block-start) var(--modal-content-padding);
|
|
90
207
|
padding-inline: var(--modal-content-padding);
|
|
208
|
+
padding-block: var(--modal-content-padding-block);
|
|
209
|
+
|
|
210
|
+
overflow-y: auto;
|
|
211
|
+
|
|
212
|
+
&--scrollable {
|
|
213
|
+
background:
|
|
214
|
+
// Scroll shadow cover
|
|
215
|
+
// A top-to-bottom opacity gradient from transparent to the component background colour
|
|
216
|
+
linear-gradient(to bottom, transparent, var(--dt-color-container-default) 75%) center bottom,
|
|
217
|
+
// Scroll shadow
|
|
218
|
+
linear-gradient(transparent, var(--dt-color-border-strong)) center bottom;
|
|
219
|
+
background-repeat: no-repeat;
|
|
220
|
+
background-size: 100% 48px, 100% 12px;
|
|
221
|
+
|
|
222
|
+
// The shadow cover is an opacity gradient which is attached to the bottom of the scrollable element
|
|
223
|
+
// and scrolls with it, so as you reach the bottom of the content the more opaque portion covers
|
|
224
|
+
// (and therefore hides) the shadow. This gives the effect of the shadow fading away.
|
|
225
|
+
// The shadow itself does not move as you scroll.
|
|
226
|
+
background-attachment: local, scroll;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
&:before {
|
|
230
|
+
content: '';
|
|
91
231
|
|
|
92
|
-
|
|
93
|
-
|
|
232
|
+
// Centre the spinner over the top of the button text
|
|
233
|
+
position: absolute;
|
|
234
|
+
left: 50%;
|
|
235
|
+
top: 50%;
|
|
236
|
+
translate: -50% -50%;
|
|
237
|
+
|
|
238
|
+
height: var(--spinner-size);
|
|
239
|
+
width: var(--spinner-size);
|
|
240
|
+
display: block;
|
|
241
|
+
background-color: transparent;
|
|
242
|
+
border-radius: 50%;
|
|
243
|
+
border-color: var(--spinner-left-color) var(--spinner-right-color) var(--spinner-right-color) var(--spinner-left-color);
|
|
244
|
+
border-width: var(--spinner-border-width);
|
|
245
|
+
border-style: solid;
|
|
246
|
+
will-change: transform;
|
|
247
|
+
opacity: 0;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
&[isLoading] .c-modal-content {
|
|
252
|
+
&:before {
|
|
253
|
+
animation: rotate360 var(--spinner-animation-duration) var(--spinner-animation-timing-function) var(--spinner-animation-iteration-count);
|
|
254
|
+
opacity: 1;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
& .c-modal-contentInner {
|
|
258
|
+
opacity: 0;
|
|
259
|
+
}
|
|
94
260
|
}
|
|
95
261
|
|
|
96
262
|
& .c-modal-closeBtn {
|
|
97
|
-
|
|
98
|
-
inset-inline-end: var(--dt-spacing-d);
|
|
99
|
-
inset-block-start: var(--dt-spacing-d);
|
|
263
|
+
margin-inline-start: auto;
|
|
100
264
|
}
|
|
101
265
|
}
|