@justeattakeaway/pie-modal 0.14.0 → 0.17.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/.eslintignore +5 -0
- package/.turbo/turbo-build.log +5 -5
- package/CHANGELOG.md +45 -0
- package/README.md +31 -17
- package/dist/index.js +1442 -204
- package/dist/types/packages/components/pie-modal/src/defs.d.ts +46 -25
- 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 +26 -10
- package/dist/types/packages/components/pie-modal/src/index.d.ts.map +1 -1
- package/package.json +6 -1
- package/playwright/index.ts +1 -1
- package/playwright-lit-visual.config.ts +0 -1
- package/playwright-lit.config.ts +1 -2
- package/src/defs.ts +57 -30
- package/src/index.ts +132 -57
- package/src/modal.scss +45 -2
- package/test/component/pie-modal.spec.ts +163 -0
- package/test/visual/pie-modal.spec.ts +200 -26
- package/tsconfig.json +1 -1
package/src/modal.scss
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
@use '@justeat/pie-design-tokens/dist/jet.scss' as dt;
|
|
2
|
+
@use 'dialog-polyfill/dist/dialog-polyfill.css';
|
|
2
3
|
|
|
3
4
|
// TODO - add to CSS lib once created
|
|
4
5
|
*,
|
|
@@ -33,6 +34,12 @@
|
|
|
33
34
|
--modal-bg-color: var(--dt-color-container-default);
|
|
34
35
|
--modal-elevation: var(--dt-elevation-04);
|
|
35
36
|
|
|
37
|
+
// TODO: This should be moved into global CSS typography setting
|
|
38
|
+
// This should be imported by consuming apps and set on the application body
|
|
39
|
+
text-rendering: optimizelegibility;
|
|
40
|
+
-webkit-font-smoothing: antialiased;
|
|
41
|
+
-moz-font-smoothing: antialiased;
|
|
42
|
+
|
|
36
43
|
&:focus-visible {
|
|
37
44
|
outline: none;
|
|
38
45
|
}
|
|
@@ -44,6 +51,7 @@
|
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
53
|
|
|
54
|
+
|
|
47
55
|
&[open] {
|
|
48
56
|
// We only apply this when the modal is open,
|
|
49
57
|
// otherwise it interferes with the native
|
|
@@ -148,6 +156,17 @@
|
|
|
148
156
|
}
|
|
149
157
|
}
|
|
150
158
|
|
|
159
|
+
// When hasStackedActions is set
|
|
160
|
+
// change the direction of the footer flex container so buttons are full width of modal
|
|
161
|
+
&[hasstackedactions] {
|
|
162
|
+
& .c-modal-footer {
|
|
163
|
+
// TODO: Move breakpoint sizes into shared CSS component utilities
|
|
164
|
+
@media (max-width: calc($breakpoint-wide - 1px)) {
|
|
165
|
+
flex-direction: column;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
151
170
|
& .c-modal-header {
|
|
152
171
|
padding-inline: var(--dt-spacing-d);
|
|
153
172
|
padding-block: 14px; // This is deliberately not a custom property
|
|
@@ -222,6 +241,32 @@
|
|
|
222
241
|
grid-area: close;
|
|
223
242
|
}
|
|
224
243
|
|
|
244
|
+
&[isfooterpinned] .c-modal-content,
|
|
245
|
+
& .c-modal-scrollContainer {
|
|
246
|
+
overflow-y: auto;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
& .c-modal-scrollContainer {
|
|
250
|
+
// These are the shadows used to indicate scrolling above and below content
|
|
251
|
+
--bg-scroll-start: linear-gradient(var(--dt-color-container-default) 30%, rgba(255, 255, 255, 0));
|
|
252
|
+
--bg-scroll-end: linear-gradient(rgba(255, 255, 255, 0), var(--dt-color-container-default) 70%) 0 100%;
|
|
253
|
+
--bg-scroll-top: radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0));
|
|
254
|
+
--bg-scroll-bottom: radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0)) 0 100%;
|
|
255
|
+
|
|
256
|
+
// Sizes of the scroll shadows
|
|
257
|
+
--bg-size-scroll-start: 100% 40px;
|
|
258
|
+
--bg-size-scroll-end: 100% 40px;
|
|
259
|
+
--bg-size-scroll-top: 100% 16px;
|
|
260
|
+
--bg-size-scroll-bottom: 100% 16px;
|
|
261
|
+
|
|
262
|
+
background: var(--bg-scroll-start), var(--bg-scroll-end), var(--bg-scroll-top), var(--bg-scroll-bottom);
|
|
263
|
+
background-repeat: no-repeat;
|
|
264
|
+
background-color: var(--dt-color-container-default);
|
|
265
|
+
background-size: var(--bg-size-scroll-start), var(--bg-size-scroll-end), var(--bg-size-scroll-top), var(--bg-size-scroll-bottom);
|
|
266
|
+
|
|
267
|
+
background-attachment: local, local, scroll, scroll;
|
|
268
|
+
}
|
|
269
|
+
|
|
225
270
|
& .c-modal-content {
|
|
226
271
|
// Modal content Custom Props
|
|
227
272
|
--modal-content-font-size: calc(var(--dt-font-size-16) * 1px);
|
|
@@ -257,8 +302,6 @@
|
|
|
257
302
|
padding-inline: var(--modal-content-padding);
|
|
258
303
|
padding-block: var(--modal-content-padding-block);
|
|
259
304
|
|
|
260
|
-
overflow-y: auto;
|
|
261
|
-
|
|
262
305
|
&--scrollable {
|
|
263
306
|
background:
|
|
264
307
|
// Scroll shadow cover
|
|
@@ -612,6 +612,11 @@ test.describe('actions', () => {
|
|
|
612
612
|
variant: 'primary',
|
|
613
613
|
ariaLabel: 'Descriptive message',
|
|
614
614
|
},
|
|
615
|
+
supportingAction: {
|
|
616
|
+
text: 'Cancel',
|
|
617
|
+
variant: 'ghost',
|
|
618
|
+
ariaLabel: 'Descriptive message',
|
|
619
|
+
},
|
|
615
620
|
},
|
|
616
621
|
});
|
|
617
622
|
|
|
@@ -635,6 +640,11 @@ test.describe('actions', () => {
|
|
|
635
640
|
variant: 'primary',
|
|
636
641
|
ariaLabel: 'Descriptive message',
|
|
637
642
|
},
|
|
643
|
+
supportingAction: {
|
|
644
|
+
text: 'Cancel',
|
|
645
|
+
variant: 'ghost',
|
|
646
|
+
ariaLabel: 'Descriptive message',
|
|
647
|
+
},
|
|
638
648
|
},
|
|
639
649
|
});
|
|
640
650
|
|
|
@@ -651,3 +661,156 @@ test.describe('actions', () => {
|
|
|
651
661
|
});
|
|
652
662
|
});
|
|
653
663
|
});
|
|
664
|
+
|
|
665
|
+
test.describe('Props: `aria`', () => {
|
|
666
|
+
test.describe('when aria exist', () => {
|
|
667
|
+
test('should render component elements with the correct aria-labels', async ({ mount }) => {
|
|
668
|
+
// Arrange
|
|
669
|
+
const component = await mount(PieModal, {
|
|
670
|
+
props: {
|
|
671
|
+
isOpen: true,
|
|
672
|
+
isDismissible: true,
|
|
673
|
+
isLoading: true,
|
|
674
|
+
hasBackButton: true,
|
|
675
|
+
aria: {
|
|
676
|
+
close: 'Close label info',
|
|
677
|
+
back: 'Back label info',
|
|
678
|
+
loading: 'Loading label info',
|
|
679
|
+
},
|
|
680
|
+
},
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
// Act
|
|
684
|
+
// Close button
|
|
685
|
+
const closeButton = await component.locator(closeButtonSelector);
|
|
686
|
+
const ariaCloseLabel = await closeButton.getAttribute('aria-label');
|
|
687
|
+
|
|
688
|
+
// Back button
|
|
689
|
+
const backButton = await component.locator(backButtonSelector);
|
|
690
|
+
const ariaBackLabel = await backButton.getAttribute('aria-label');
|
|
691
|
+
|
|
692
|
+
// Assert
|
|
693
|
+
await expect(ariaCloseLabel).toBe('Close label info');
|
|
694
|
+
await expect(ariaBackLabel).toBe('Back label info');
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
test.describe('when modal `isloading` is true', () => {
|
|
698
|
+
test('should render component with the correct aria values: `aria-label` & `aria-busy`', async ({ mount }) => {
|
|
699
|
+
// Arrange
|
|
700
|
+
const component = await mount(PieModal, {
|
|
701
|
+
props: {
|
|
702
|
+
isOpen: true,
|
|
703
|
+
isLoading: true,
|
|
704
|
+
aria: {
|
|
705
|
+
loading: 'Loading label info',
|
|
706
|
+
},
|
|
707
|
+
},
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
// Loading state
|
|
711
|
+
const pieModalComponent = await component.locator(componentSelector);
|
|
712
|
+
const ariaLoadingLabel = await pieModalComponent.getAttribute('aria-label');
|
|
713
|
+
const ariaLoadingBusy = await pieModalComponent.getAttribute('aria-busy');
|
|
714
|
+
|
|
715
|
+
// Assert
|
|
716
|
+
await expect(ariaLoadingLabel).toBe('Loading label info');
|
|
717
|
+
await expect(ariaLoadingBusy).toBe('true');
|
|
718
|
+
});
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
test.describe('when modal `isLoading` is dynamically changing from `isLoading: true` to `isLoading: false`', () => {
|
|
722
|
+
test('should dynamically add, remove, and update `arial-label` & `aria-busy` labels', async ({ mount }) => {
|
|
723
|
+
// Arrange
|
|
724
|
+
const component = await mount(PieModal, {
|
|
725
|
+
props: {
|
|
726
|
+
isOpen: true,
|
|
727
|
+
isLoading: true,
|
|
728
|
+
aria: {
|
|
729
|
+
loading: 'Loading label info',
|
|
730
|
+
},
|
|
731
|
+
},
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
const pieModalComponent = await component.locator(componentSelector);
|
|
735
|
+
let ariaLoadingLabel = await pieModalComponent.getAttribute('aria-label');
|
|
736
|
+
let ariaLoadingBusy = await pieModalComponent.getAttribute('aria-busy');
|
|
737
|
+
|
|
738
|
+
// Assert: When `isLoading: true`
|
|
739
|
+
await expect(ariaLoadingLabel).toBe('Loading label info');
|
|
740
|
+
await expect(ariaLoadingBusy).toBe('true');
|
|
741
|
+
|
|
742
|
+
await component.update({ props: { isLoading: false } });
|
|
743
|
+
|
|
744
|
+
ariaLoadingLabel = await pieModalComponent.getAttribute('aria-label');
|
|
745
|
+
ariaLoadingBusy = await pieModalComponent.getAttribute('aria-busy');
|
|
746
|
+
|
|
747
|
+
// Assert: When `isLoading: false`
|
|
748
|
+
await expect(ariaLoadingLabel).toBeNull();
|
|
749
|
+
await expect(ariaLoadingBusy).toBe('false');
|
|
750
|
+
});
|
|
751
|
+
});
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
test.describe('when aria does not exist', () => {
|
|
755
|
+
test('should not render the aria-labels', async ({ mount }) => {
|
|
756
|
+
// Arrange
|
|
757
|
+
const component = await mount(PieModal, {
|
|
758
|
+
props: {
|
|
759
|
+
isOpen: true,
|
|
760
|
+
isDismissible: true,
|
|
761
|
+
hasBackButton: true,
|
|
762
|
+
},
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
// Act
|
|
766
|
+
// Close button
|
|
767
|
+
const closeButton = await component.locator(closeButtonSelector);
|
|
768
|
+
const ariaCloseLabel = await closeButton.getAttribute('aria-label');
|
|
769
|
+
|
|
770
|
+
// Back button
|
|
771
|
+
const backButton = await component.locator(backButtonSelector);
|
|
772
|
+
const ariaBackLabel = await backButton.getAttribute('aria-label');
|
|
773
|
+
|
|
774
|
+
// Assert
|
|
775
|
+
await expect(ariaCloseLabel).toBe(null);
|
|
776
|
+
await expect(ariaBackLabel).toBe(null);
|
|
777
|
+
});
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
test.describe('when modal `isloading` is false', () => {
|
|
781
|
+
test('should not render aria-label', async ({ mount }) => {
|
|
782
|
+
// Arrange
|
|
783
|
+
const component = await mount(PieModal, {
|
|
784
|
+
props: {
|
|
785
|
+
isOpen: true,
|
|
786
|
+
isLoading: false,
|
|
787
|
+
},
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
// Loading state
|
|
791
|
+
const pieModalComponent = await component.locator(componentSelector);
|
|
792
|
+
const ariaLoadingLabel = await pieModalComponent.getAttribute('aria-label');
|
|
793
|
+
|
|
794
|
+
// Assert
|
|
795
|
+
await expect(ariaLoadingLabel).toBe(null);
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
test('should set `aria-busy` to `false`', async ({ mount }) => {
|
|
799
|
+
// Arrange
|
|
800
|
+
const component = await mount(PieModal, {
|
|
801
|
+
props: {
|
|
802
|
+
isOpen: true,
|
|
803
|
+
isLoading: false,
|
|
804
|
+
},
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
// Loading state
|
|
808
|
+
const pieModalComponent = await component.locator(componentSelector);
|
|
809
|
+
const ariaLoadingBusy = await pieModalComponent.getAttribute('aria-busy');
|
|
810
|
+
|
|
811
|
+
// Assert
|
|
812
|
+
await expect(ariaLoadingBusy).toBe('false');
|
|
813
|
+
});
|
|
814
|
+
});
|
|
815
|
+
});
|
|
816
|
+
|
|
@@ -75,25 +75,25 @@ test.describe('Prop: `isFullWidthBelowMid`', () => {
|
|
|
75
75
|
|
|
76
76
|
test.describe('when false', () => {
|
|
77
77
|
(['small', 'medium'] as Array<ModalProps['size']>)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
78
|
+
.forEach((size) => {
|
|
79
|
+
test(`should not be full width for a modal with size = ${size}`, async ({ page, mount }) => {
|
|
80
|
+
await mount(PieModal, {
|
|
81
|
+
props: {
|
|
82
|
+
heading: 'This is a modal heading',
|
|
83
|
+
isFullWidthBelowMid: false,
|
|
84
|
+
isOpen: true,
|
|
85
|
+
size,
|
|
86
|
+
leadingAction: {
|
|
87
|
+
text: 'Confirm',
|
|
88
|
+
variant: 'primary',
|
|
89
|
+
ariaLabel: 'Confirmation text',
|
|
90
|
+
},
|
|
91
|
+
} as ModalProps,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
await percySnapshot(page, `Modal - isFullWidthBelowMid = false, size = ${size}`);
|
|
92
95
|
});
|
|
93
|
-
|
|
94
|
-
await percySnapshot(page, `Modal - isFullWidthBelowMid = false, size = ${size}`);
|
|
95
96
|
});
|
|
96
|
-
});
|
|
97
97
|
});
|
|
98
98
|
});
|
|
99
99
|
|
|
@@ -231,8 +231,6 @@ test.describe('Prop: `leadingAction`', () => {
|
|
|
231
231
|
await mount(PieModal, {
|
|
232
232
|
props: {
|
|
233
233
|
heading: 'This is a modal heading',
|
|
234
|
-
hasBackButton: true,
|
|
235
|
-
isDismissible: true,
|
|
236
234
|
isOpen: true,
|
|
237
235
|
leadingAction: {
|
|
238
236
|
text: 'Confirm',
|
|
@@ -251,8 +249,6 @@ test.describe('Prop: `leadingAction`', () => {
|
|
|
251
249
|
await mount(PieModal, {
|
|
252
250
|
props: {
|
|
253
251
|
heading: 'This is a modal heading',
|
|
254
|
-
hasBackButton: true,
|
|
255
|
-
isDismissible: true,
|
|
256
252
|
isOpen: true,
|
|
257
253
|
leadingAction: {
|
|
258
254
|
text: 'Confirm',
|
|
@@ -269,8 +265,6 @@ test.describe('Prop: `leadingAction`', () => {
|
|
|
269
265
|
await mount(PieModal, {
|
|
270
266
|
props: {
|
|
271
267
|
heading: 'This is a modal heading',
|
|
272
|
-
hasBackButton: true,
|
|
273
|
-
isDismissible: true,
|
|
274
268
|
isOpen: true,
|
|
275
269
|
leadingAction: {
|
|
276
270
|
text: '',
|
|
@@ -287,8 +281,6 @@ test.describe('Prop: `leadingAction`', () => {
|
|
|
287
281
|
await mount(PieModal, {
|
|
288
282
|
props: {
|
|
289
283
|
heading: 'This is a modal heading',
|
|
290
|
-
hasBackButton: true,
|
|
291
|
-
isDismissible: true,
|
|
292
284
|
isOpen: true,
|
|
293
285
|
} as ModalProps,
|
|
294
286
|
});
|
|
@@ -298,7 +290,111 @@ test.describe('Prop: `leadingAction`', () => {
|
|
|
298
290
|
});
|
|
299
291
|
});
|
|
300
292
|
|
|
301
|
-
test.describe('`
|
|
293
|
+
test.describe('Prop: `supportingAction`', () => {
|
|
294
|
+
test.describe('when `leadingAction` prop exists', () => {
|
|
295
|
+
test('should display `supportingAction` correctly', async ({ mount, page }) => {
|
|
296
|
+
await mount(PieModal, {
|
|
297
|
+
props: {
|
|
298
|
+
heading: 'This is a modal heading',
|
|
299
|
+
isOpen: true,
|
|
300
|
+
leadingAction: {
|
|
301
|
+
text: 'Confirm',
|
|
302
|
+
variant: 'primary',
|
|
303
|
+
ariaLabel: 'Confirmation text',
|
|
304
|
+
},
|
|
305
|
+
supportingAction: {
|
|
306
|
+
text: 'Cancel',
|
|
307
|
+
variant: 'ghost',
|
|
308
|
+
ariaLabel: 'Cancellation text',
|
|
309
|
+
},
|
|
310
|
+
} as ModalProps,
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
await percySnapshot(page, 'Modal displays supportingAction alongside leadingAction');
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
test.describe('when prop is provided but the optional child properties of `supportingAction` are not provided', () => {
|
|
317
|
+
test('should fall back to default property', async ({ mount, page }) => {
|
|
318
|
+
await mount(PieModal, {
|
|
319
|
+
props: {
|
|
320
|
+
heading: 'This is a modal heading',
|
|
321
|
+
isOpen: true,
|
|
322
|
+
leadingAction: {
|
|
323
|
+
text: 'Confirm',
|
|
324
|
+
variant: 'primary',
|
|
325
|
+
ariaLabel: 'Confirmation text',
|
|
326
|
+
},
|
|
327
|
+
supportingAction: {
|
|
328
|
+
text: 'Cancel',
|
|
329
|
+
ariaLabel: 'Confirmation text',
|
|
330
|
+
},
|
|
331
|
+
} as ModalProps,
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
await percySnapshot(page, 'Modal falls back to default variant property `ghost`');
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
test.describe('when `supportingAction` prop is provided but the `text` child property of `supportingAction` is empty', () => {
|
|
339
|
+
test('should not render supportingAction markup', async ({ mount, page }) => {
|
|
340
|
+
await mount(PieModal, {
|
|
341
|
+
props: {
|
|
342
|
+
heading: 'This is a modal heading',
|
|
343
|
+
isOpen: true,
|
|
344
|
+
leadingAction: {
|
|
345
|
+
text: 'Confirm',
|
|
346
|
+
variant: 'primary',
|
|
347
|
+
ariaLabel: 'Confirmation text',
|
|
348
|
+
},
|
|
349
|
+
supportingAction: {
|
|
350
|
+
text: '',
|
|
351
|
+
},
|
|
352
|
+
} as ModalProps,
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
await percySnapshot(page, 'Modal will not render `supportingAction` button when `text` is empty');
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
test.describe('when `supportingAction` is not supplied', () => {
|
|
360
|
+
test('should not render supportingAction markup', async ({ mount, page }) => {
|
|
361
|
+
await mount(PieModal, {
|
|
362
|
+
props: {
|
|
363
|
+
heading: 'This is a modal heading',
|
|
364
|
+
isOpen: true,
|
|
365
|
+
leadingAction: {
|
|
366
|
+
text: 'Confirm',
|
|
367
|
+
variant: 'primary',
|
|
368
|
+
ariaLabel: 'Confirmation text',
|
|
369
|
+
},
|
|
370
|
+
} as ModalProps,
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
await percySnapshot(page, 'Modal will not render `supportingAction` when it is not supplied');
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
test.describe('when `leadingAction` prop does not exist and `supportingAction` is supplied', () => {
|
|
379
|
+
test('should not render supportingAction markup', async ({ mount, page }) => {
|
|
380
|
+
await mount(PieModal, {
|
|
381
|
+
props: {
|
|
382
|
+
heading: 'This is a modal heading',
|
|
383
|
+
isOpen: true,
|
|
384
|
+
supportingAction: {
|
|
385
|
+
text: 'Cancel',
|
|
386
|
+
variant: 'ghost',
|
|
387
|
+
ariaLabel: 'Cancellation text',
|
|
388
|
+
},
|
|
389
|
+
} as ModalProps,
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
await percySnapshot(page, 'Modal will not render `supportingAction` when `leadingAction` is not supplied');
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
test.describe('Prop: `position`', () => {
|
|
302
398
|
positions.forEach((position) => {
|
|
303
399
|
test(`should be positioned in the correct part of the page when position is: ${position}`, async ({ mount, page }) => {
|
|
304
400
|
await mount(PieModal, {
|
|
@@ -318,3 +414,81 @@ test.describe('`position`', () => {
|
|
|
318
414
|
});
|
|
319
415
|
});
|
|
320
416
|
});
|
|
417
|
+
|
|
418
|
+
test.describe('Prop: `isFooterPinned`', () => {
|
|
419
|
+
[true, false].forEach((isFooterPinned) => {
|
|
420
|
+
test(`when isFooterPinned is: ${isFooterPinned}`, async ({ mount, page }) => {
|
|
421
|
+
await mount(PieModal, {
|
|
422
|
+
props: {
|
|
423
|
+
heading: 'This is a modal heading',
|
|
424
|
+
isOpen: true,
|
|
425
|
+
isFooterPinned,
|
|
426
|
+
leadingAction: {
|
|
427
|
+
text: 'Confirm',
|
|
428
|
+
variant: 'primary',
|
|
429
|
+
ariaLabel: 'Confirmation text',
|
|
430
|
+
},
|
|
431
|
+
} as ModalProps,
|
|
432
|
+
slots: {
|
|
433
|
+
default: `Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti fugit id exercitationem repellendus in magni
|
|
434
|
+
quis obcaecati laboriosam est vero, perspiciatis ratione porro dolore repudiandae ea numquam! Ipsa, fugiat aut.Lorem ipsum dolor
|
|
435
|
+
sit amet consectetur adipisicing elit. Deleniti fugit id exercitationem repellendus in magni quis obcaecati laboriosam est vero,
|
|
436
|
+
perspiciatis ratione porro dolore repudiandae ea numquam! Ipsa, fugiat aut.Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
|
437
|
+
|
|
438
|
+
Deleniti fugit id exercitationem repellendus in magni quis obcaecati laboriosam est vero, perspiciatis ratione porro dolore
|
|
439
|
+
repudiandae ea numquam! Ipsa, fugiat aut. Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti fugit id exercitationem repellendus
|
|
440
|
+
in magni quis obcaecati laboriosam est vero, perspiciatis ratione porro dolore repudiandae ea numquam! Ipsa, fugiat aut.Lorem ipsum dolor sit amet
|
|
441
|
+
consectetur adipisicing elit. Deleniti fugit id exercitationem repellendus in magni quis obcaecati laboriosam est vero, perspiciatis ratione
|
|
442
|
+
porro dolore repudiandae ea numquam! Ipsa, fugiat aut.Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti fugit id
|
|
443
|
+
exercitationem repellendus in magni quis obcaecati laboriosam est vero,
|
|
444
|
+
perspiciatis ratione porro dolore repudiandae ea numquam! Ipsa, fugiat aut.
|
|
445
|
+
|
|
446
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti fugit id exercitationem repellendus in magni
|
|
447
|
+
quis obcaecati laboriosam est vero, perspiciatis ratione porro dolore repudiandae ea numquam! Ipsa, fugiat aut.Lorem ipsum dolor
|
|
448
|
+
sit amet consectetur adipisicing elit. Deleniti fugit id exercitationem repellendus in magni quis obcaecati laboriosam est vero,
|
|
449
|
+
perspiciatis ratione porro dolore repudiandae ea numquam! Ipsa, fugiat aut.Lorem ipsum dolor sit amet consectetur adipisicing elit.
|
|
450
|
+
|
|
451
|
+
Deleniti fugit id exercitationem repellendus in magni quis obcaecati laboriosam est vero, perspiciatis ratione porro dolore
|
|
452
|
+
repudiandae ea numquam! Ipsa, fugiat aut. Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti fugit id exercitationem repellendus
|
|
453
|
+
in magni quis obcaecati laboriosam est vero, perspiciatis ratione porro dolore repudiandae ea numquam! Ipsa, fugiat aut.Lorem ipsum dolor sit amet
|
|
454
|
+
consectetur adipisicing elit. Deleniti fugit id exercitationem repellendus in magni quis obcaecati laboriosam est vero, perspiciatis ratione
|
|
455
|
+
porro dolore repudiandae ea numquam! Ipsa, fugiat aut.Lorem ipsum dolor sit amet consectetur adipisicing elit. Deleniti fugit id
|
|
456
|
+
exercitationem repellendus in magni quis obcaecati laboriosam est vero,
|
|
457
|
+
perspiciatis ratione porro dolore repudiandae ea numquam! Ipsa, fugiat aut.`,
|
|
458
|
+
},
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
await percySnapshot(page, `Modal isFooterPinned: ${isFooterPinned}`);
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
test.describe('Prop: `hasStackedActions`', () => {
|
|
467
|
+
test.describe('when true', () => {
|
|
468
|
+
(['small', 'medium', 'large'] as Array<ModalProps['size']>)
|
|
469
|
+
.forEach((size) => {
|
|
470
|
+
test(`should display actions full width (at narrow viewports – with leading action on top) for a modal with size = ${size}`, async ({ page, mount }) => {
|
|
471
|
+
await mount(PieModal, {
|
|
472
|
+
props: {
|
|
473
|
+
heading: 'This is a modal heading',
|
|
474
|
+
hasStackedActions: true,
|
|
475
|
+
isOpen: true,
|
|
476
|
+
size,
|
|
477
|
+
leadingAction: {
|
|
478
|
+
text: 'Confirm',
|
|
479
|
+
variant: 'primary',
|
|
480
|
+
ariaLabel: 'Confirmation text',
|
|
481
|
+
},
|
|
482
|
+
supportingAction: {
|
|
483
|
+
text: 'Cancel',
|
|
484
|
+
variant: 'ghost',
|
|
485
|
+
ariaLabel: 'Cancel and close modal',
|
|
486
|
+
},
|
|
487
|
+
} as ModalProps,
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
await percySnapshot(page, `Modal - hasStackedActions = true, size = ${size}`);
|
|
491
|
+
});
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
});
|
package/tsconfig.json
CHANGED