@pine-ds/core 3.5.2 → 3.6.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/components/mock-pds-modal.js +9 -4
- package/components/mock-pds-modal.js.map +1 -1
- package/components/pds-box2.js +132 -2
- package/components/pds-box2.js.map +1 -1
- package/components/pds-button2.js +51 -2
- package/components/pds-button2.js.map +1 -1
- package/components/pds-modal-content.js +128 -11
- package/components/pds-modal-content.js.map +1 -1
- package/components/pds-modal.js +13 -3
- package/components/pds-modal.js.map +1 -1
- package/components/pds-textarea.js +111 -7
- package/components/pds-textarea.js.map +1 -1
- package/components/pds-toast.js +3 -3
- package/components/pds-tooltip.js +2 -2
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/mock-pds-modal.cjs.entry.js +8 -4
- package/dist/cjs/mock-pds-modal.cjs.entry.js.map +1 -1
- package/dist/cjs/mock-pds-modal.entry.cjs.js.map +1 -1
- package/dist/cjs/pds-box.cjs.entry.js +67 -2
- package/dist/cjs/pds-box.cjs.entry.js.map +1 -1
- package/dist/cjs/pds-box.entry.cjs.js.map +1 -1
- package/dist/cjs/pds-button.cjs.entry.js +50 -1
- package/dist/cjs/pds-button.cjs.entry.js.map +1 -1
- package/dist/cjs/pds-button.entry.cjs.js.map +1 -1
- package/dist/cjs/pds-modal-content.cjs.entry.js +128 -11
- package/dist/cjs/pds-modal-content.cjs.entry.js.map +1 -1
- package/dist/cjs/pds-modal-content.entry.cjs.js.map +1 -1
- package/dist/cjs/pds-modal.cjs.entry.js +12 -3
- package/dist/cjs/pds-modal.cjs.entry.js.map +1 -1
- package/dist/cjs/pds-modal.entry.cjs.js.map +1 -1
- package/dist/cjs/pds-textarea.cjs.entry.js +108 -6
- package/dist/cjs/pds-textarea.cjs.entry.js.map +1 -1
- package/dist/cjs/pds-textarea.entry.cjs.js.map +1 -1
- package/dist/cjs/pds-toast.cjs.entry.js +3 -3
- package/dist/cjs/pds-tooltip.cjs.entry.js +2 -2
- package/dist/cjs/pine-core.cjs.js +1 -1
- package/dist/collection/components/pds-box/pds-box.css +1325 -0
- package/dist/collection/components/pds-box/pds-box.js +1913 -148
- package/dist/collection/components/pds-box/pds-box.js.map +1 -1
- package/dist/collection/components/pds-button/pds-button.js +59 -1
- package/dist/collection/components/pds-button/pds-button.js.map +1 -1
- package/dist/collection/components/pds-modal/pds-modal-content/pds-modal-content.css +4 -6
- package/dist/collection/components/pds-modal/pds-modal-content/pds-modal-content.js +128 -11
- package/dist/collection/components/pds-modal/pds-modal-content/pds-modal-content.js.map +1 -1
- package/dist/collection/components/pds-modal/pds-modal.css +42 -1
- package/dist/collection/components/pds-modal/pds-modal.js +34 -2
- package/dist/collection/components/pds-modal/pds-modal.js.map +1 -1
- package/dist/collection/components/pds-modal/stories/pds-modal.stories.js +245 -0
- package/dist/collection/components/pds-modal/test/mock-pds-modal.js +30 -3
- package/dist/collection/components/pds-modal/test/mock-pds-modal.js.map +1 -1
- package/dist/collection/components/pds-textarea/pds-textarea.css +51 -11
- package/dist/collection/components/pds-textarea/pds-textarea.js +127 -4
- package/dist/collection/components/pds-textarea/pds-textarea.js.map +1 -1
- package/dist/collection/components/pds-textarea/stories/pds-textarea.stories.js +13 -0
- package/dist/collection/components/pds-toast/pds-toast.js +3 -3
- package/dist/collection/components/pds-tooltip/pds-tooltip.js +2 -2
- package/dist/docs.json +3988 -380
- package/dist/esm/loader.js +1 -1
- package/dist/esm/mock-pds-modal.entry.js +8 -4
- package/dist/esm/mock-pds-modal.entry.js.map +1 -1
- package/dist/esm/pds-box.entry.js +67 -2
- package/dist/esm/pds-box.entry.js.map +1 -1
- package/dist/esm/pds-button.entry.js +50 -1
- package/dist/esm/pds-button.entry.js.map +1 -1
- package/dist/esm/pds-modal-content.entry.js +128 -11
- package/dist/esm/pds-modal-content.entry.js.map +1 -1
- package/dist/esm/pds-modal.entry.js +12 -3
- package/dist/esm/pds-modal.entry.js.map +1 -1
- package/dist/esm/pds-textarea.entry.js +108 -6
- package/dist/esm/pds-textarea.entry.js.map +1 -1
- package/dist/esm/pds-toast.entry.js +3 -3
- package/dist/esm/pds-tooltip.entry.js +2 -2
- package/dist/esm/pine-core.js +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/mock-pds-modal.entry.js +1 -1
- package/dist/esm-es5/mock-pds-modal.entry.js.map +1 -1
- package/dist/esm-es5/pds-box.entry.js +1 -1
- package/dist/esm-es5/pds-box.entry.js.map +1 -1
- package/dist/esm-es5/pds-button.entry.js +1 -1
- package/dist/esm-es5/pds-button.entry.js.map +1 -1
- package/dist/esm-es5/pds-modal-content.entry.js +1 -1
- package/dist/esm-es5/pds-modal-content.entry.js.map +1 -1
- package/dist/esm-es5/pds-modal.entry.js +1 -1
- package/dist/esm-es5/pds-modal.entry.js.map +1 -1
- package/dist/esm-es5/pds-textarea.entry.js +1 -1
- package/dist/esm-es5/pds-textarea.entry.js.map +1 -1
- package/dist/esm-es5/pds-toast.entry.js +1 -1
- package/dist/esm-es5/pds-tooltip.entry.js +1 -1
- package/dist/esm-es5/pine-core.js +1 -1
- package/dist/pine-core/mock-pds-modal.entry.esm.js.map +1 -1
- package/dist/pine-core/p-318fd0cf.entry.js +2 -0
- package/dist/pine-core/p-318fd0cf.entry.js.map +1 -0
- package/dist/pine-core/{p-c4d6fe50.system.entry.js → p-346561a6.system.entry.js} +2 -2
- package/dist/pine-core/p-346561a6.system.entry.js.map +1 -0
- package/dist/pine-core/p-3gYSFJIn.system.js.map +1 -0
- package/dist/pine-core/{p-IG5YumI3.system.js.map → p-3pEJO0vO.system.js.map} +1 -1
- package/dist/pine-core/p-41d1b164.entry.js +2 -0
- package/dist/pine-core/p-41d1b164.entry.js.map +1 -0
- package/dist/pine-core/{p-02326ac3.entry.js → p-4c81420c.entry.js} +2 -2
- package/dist/pine-core/p-52cb152b.system.entry.js +2 -0
- package/dist/pine-core/p-52cb152b.system.entry.js.map +1 -0
- package/dist/pine-core/p-540cfd70.entry.js +2 -0
- package/dist/pine-core/p-540cfd70.entry.js.map +1 -0
- package/dist/pine-core/{p-11d4036e.entry.js → p-5f5b19f4.entry.js} +2 -2
- package/dist/pine-core/p-6d4d4705.system.entry.js +2 -0
- package/dist/pine-core/p-6d4d4705.system.entry.js.map +1 -0
- package/dist/pine-core/{p-68b5665a.entry.js → p-84949a12.entry.js} +2 -2
- package/dist/pine-core/p-84949a12.entry.js.map +1 -0
- package/dist/pine-core/{p-7a95a90f.system.entry.js → p-8726c99d.system.entry.js} +2 -2
- package/dist/pine-core/{p-2kXtbFXu.system.js.map → p-BZoPY2dP.system.js.map} +1 -1
- package/dist/pine-core/p-C0zqu7Gr.system.js.map +1 -0
- package/dist/pine-core/p-CHJgq_z7.system.js.map +1 -0
- package/dist/pine-core/p-Co5XZmTN.system.js.map +1 -0
- package/dist/pine-core/p-Czoq9yJM.system.js.map +1 -0
- package/dist/pine-core/p-De9tROL-.system.js +1 -1
- package/dist/pine-core/p-WkrM7Vv0.system.js.map +1 -0
- package/dist/pine-core/p-a9895385.system.entry.js +2 -0
- package/dist/pine-core/p-a9895385.system.entry.js.map +1 -0
- package/dist/pine-core/p-c0df3222.entry.js +2 -0
- package/dist/pine-core/p-c0df3222.entry.js.map +1 -0
- package/dist/pine-core/{p-884b9ae6.system.entry.js → p-d8d8fe07.system.entry.js} +2 -2
- package/dist/pine-core/p-dc19ce6c.system.entry.js +2 -0
- package/dist/pine-core/p-dc19ce6c.system.entry.js.map +1 -0
- package/dist/pine-core/p-e08f492a.entry.js +2 -0
- package/dist/pine-core/p-e08f492a.entry.js.map +1 -0
- package/dist/pine-core/p-fcb39155.system.entry.js +2 -0
- package/dist/pine-core/p-fcb39155.system.entry.js.map +1 -0
- package/dist/pine-core/pds-box.entry.esm.js.map +1 -1
- package/dist/pine-core/pds-button.entry.esm.js.map +1 -1
- package/dist/pine-core/pds-modal-content.entry.esm.js.map +1 -1
- package/dist/pine-core/pds-modal.entry.esm.js.map +1 -1
- package/dist/pine-core/pds-textarea.entry.esm.js.map +1 -1
- package/dist/pine-core/pine-core.esm.js +1 -1
- package/dist/types/components/pds-box/pds-box.d.ts +315 -0
- package/dist/types/components/pds-button/pds-button.d.ts +4 -0
- package/dist/types/components/pds-modal/pds-modal-content/pds-modal-content.d.ts +18 -1
- package/dist/types/components/pds-modal/pds-modal.d.ts +5 -0
- package/dist/types/components/pds-modal/test/mock-pds-modal.d.ts +5 -0
- package/dist/types/components/pds-textarea/pds-textarea.d.ts +20 -0
- package/dist/types/components.d.ts +660 -2
- package/hydrate/index.js +448 -34
- package/hydrate/index.mjs +448 -34
- package/package.json +2 -2
- package/dist/pine-core/p-007b61e9.system.entry.js +0 -2
- package/dist/pine-core/p-007b61e9.system.entry.js.map +0 -1
- package/dist/pine-core/p-0485aa93.system.entry.js +0 -2
- package/dist/pine-core/p-0485aa93.system.entry.js.map +0 -1
- package/dist/pine-core/p-2186e5d4.system.entry.js +0 -2
- package/dist/pine-core/p-2186e5d4.system.entry.js.map +0 -1
- package/dist/pine-core/p-54061a33.entry.js +0 -2
- package/dist/pine-core/p-54061a33.entry.js.map +0 -1
- package/dist/pine-core/p-68b5665a.entry.js.map +0 -1
- package/dist/pine-core/p-96a89cd5.system.entry.js +0 -2
- package/dist/pine-core/p-96a89cd5.system.entry.js.map +0 -1
- package/dist/pine-core/p-Bv5PJxD8.system.js.map +0 -1
- package/dist/pine-core/p-CD_nPb2F.system.js.map +0 -1
- package/dist/pine-core/p-DJekRkSL.system.js.map +0 -1
- package/dist/pine-core/p-DNYl_6t_.system.js.map +0 -1
- package/dist/pine-core/p-Dt10r3RZ.system.js.map +0 -1
- package/dist/pine-core/p-IIl2cTlj.system.js.map +0 -1
- package/dist/pine-core/p-a24c46e4.entry.js +0 -2
- package/dist/pine-core/p-a24c46e4.entry.js.map +0 -1
- package/dist/pine-core/p-c4d6fe50.system.entry.js.map +0 -1
- package/dist/pine-core/p-c6badcf8.entry.js +0 -2
- package/dist/pine-core/p-c6badcf8.entry.js.map +0 -1
- package/dist/pine-core/p-d714f68f.system.entry.js +0 -2
- package/dist/pine-core/p-d714f68f.system.entry.js.map +0 -1
- package/dist/pine-core/p-e5ca5b8e.entry.js +0 -2
- package/dist/pine-core/p-e5ca5b8e.entry.js.map +0 -1
- package/dist/pine-core/p-fb4058e6.entry.js +0 -2
- package/dist/pine-core/p-fb4058e6.entry.js.map +0 -1
- /package/dist/pine-core/{p-02326ac3.entry.js.map → p-4c81420c.entry.js.map} +0 -0
- /package/dist/pine-core/{p-11d4036e.entry.js.map → p-5f5b19f4.entry.js.map} +0 -0
- /package/dist/pine-core/{p-7a95a90f.system.entry.js.map → p-8726c99d.system.entry.js.map} +0 -0
- /package/dist/pine-core/{p-884b9ae6.system.entry.js.map → p-d8d8fe07.system.entry.js.map} +0 -0
|
@@ -40,18 +40,36 @@ pds-modal .pds-modal__backdrop {
|
|
|
40
40
|
display: flex;
|
|
41
41
|
flex-direction: column;
|
|
42
42
|
margin: var(--pine-dimension-md);
|
|
43
|
-
max-height:
|
|
43
|
+
max-height: none;
|
|
44
44
|
width: 100%;
|
|
45
45
|
}
|
|
46
|
+
.pds-modal.pds-modal--scrollable {
|
|
47
|
+
max-height: calc(100vh - (5vh + 96px));
|
|
48
|
+
}
|
|
49
|
+
@supports (height: 100dvh) {
|
|
50
|
+
.pds-modal.pds-modal--scrollable {
|
|
51
|
+
max-height: calc(100dvh - (5dvh + 96px));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
46
54
|
@media (min-width: 992px) {
|
|
47
55
|
.pds-modal {
|
|
48
56
|
margin-block-start: 6vh;
|
|
49
57
|
}
|
|
58
|
+
@supports (height: 100dvh) {
|
|
59
|
+
.pds-modal {
|
|
60
|
+
margin-block-start: 6dvh;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
50
63
|
}
|
|
51
64
|
@media (min-width: 1200px) {
|
|
52
65
|
.pds-modal {
|
|
53
66
|
margin-block-start: 8vh;
|
|
54
67
|
}
|
|
68
|
+
@supports (height: 100dvh) {
|
|
69
|
+
.pds-modal {
|
|
70
|
+
margin-block-start: 8dvh;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
55
73
|
}
|
|
56
74
|
|
|
57
75
|
.pds-modal--sm {
|
|
@@ -73,7 +91,30 @@ pds-modal .pds-modal__backdrop {
|
|
|
73
91
|
max-height: 100vh;
|
|
74
92
|
max-width: 100%;
|
|
75
93
|
}
|
|
94
|
+
@supports (height: 100dvh) {
|
|
95
|
+
.pds-modal--fullscreen {
|
|
96
|
+
max-height: 100dvh;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
.pds-modal--fullscreen.pds-modal--scrollable {
|
|
100
|
+
max-height: 100vh;
|
|
101
|
+
}
|
|
102
|
+
@supports (height: 100dvh) {
|
|
103
|
+
.pds-modal--fullscreen.pds-modal--scrollable {
|
|
104
|
+
max-height: 100dvh;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
76
107
|
|
|
77
108
|
.pds-modal--fullscreen .pds-modal-content {
|
|
78
109
|
flex: 1;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.pds-modal--scrollable pds-modal-content {
|
|
113
|
+
border-block-end: 1px solid transparent;
|
|
114
|
+
border-block-start: 1px solid transparent;
|
|
115
|
+
overflow-y: auto;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.pds-modal:not(.pds-modal--scrollable) pds-modal-content {
|
|
119
|
+
overflow-y: visible;
|
|
79
120
|
}
|
|
@@ -17,6 +17,11 @@ export class PdsModal {
|
|
|
17
17
|
* @default 'md'
|
|
18
18
|
*/
|
|
19
19
|
this.size = 'md';
|
|
20
|
+
/**
|
|
21
|
+
* Whether the modal content should be scrollable
|
|
22
|
+
* @default true
|
|
23
|
+
*/
|
|
24
|
+
this.scrollable = true;
|
|
20
25
|
/**
|
|
21
26
|
* Stores the list of focusable elements in the modal
|
|
22
27
|
*/
|
|
@@ -227,10 +232,14 @@ export class PdsModal {
|
|
|
227
232
|
return thisZIndex === maxZIndex;
|
|
228
233
|
}
|
|
229
234
|
render() {
|
|
230
|
-
return (h("dialog", { key: '
|
|
235
|
+
return (h("dialog", { key: '57daacecb0d85c643c1fe17b98046dcc98f982cb', class: {
|
|
231
236
|
'pds-modal__backdrop': true,
|
|
232
237
|
'open': this.open
|
|
233
|
-
}, "aria-modal": "true", "aria-labelledby": `${this.componentId}-heading`, onClick: this.handleBackdropClick }, h("div", { key: '
|
|
238
|
+
}, "aria-modal": "true", "aria-labelledby": `${this.componentId}-heading`, onClick: this.handleBackdropClick }, h("div", { key: '9fe239071cb2679dd626bc3cf8fd94abe9c1bee0', class: {
|
|
239
|
+
'pds-modal': true,
|
|
240
|
+
[`pds-modal--${this.size}`]: true,
|
|
241
|
+
'pds-modal--scrollable': this.scrollable
|
|
242
|
+
} }, h("slot", { key: '59edffec7f550550a03ce2100eb3aeb2be99902b' }))));
|
|
234
243
|
}
|
|
235
244
|
static get is() { return "pds-modal"; }
|
|
236
245
|
static get originalStyleUrls() {
|
|
@@ -332,6 +341,29 @@ export class PdsModal {
|
|
|
332
341
|
"attribute": "size",
|
|
333
342
|
"reflect": false,
|
|
334
343
|
"defaultValue": "'md'"
|
|
344
|
+
},
|
|
345
|
+
"scrollable": {
|
|
346
|
+
"type": "boolean",
|
|
347
|
+
"mutable": false,
|
|
348
|
+
"complexType": {
|
|
349
|
+
"original": "boolean",
|
|
350
|
+
"resolved": "boolean",
|
|
351
|
+
"references": {}
|
|
352
|
+
},
|
|
353
|
+
"required": false,
|
|
354
|
+
"optional": false,
|
|
355
|
+
"docs": {
|
|
356
|
+
"tags": [{
|
|
357
|
+
"name": "default",
|
|
358
|
+
"text": "true"
|
|
359
|
+
}],
|
|
360
|
+
"text": "Whether the modal content should be scrollable"
|
|
361
|
+
},
|
|
362
|
+
"getter": false,
|
|
363
|
+
"setter": false,
|
|
364
|
+
"attribute": "scrollable",
|
|
365
|
+
"reflect": false,
|
|
366
|
+
"defaultValue": "true"
|
|
335
367
|
}
|
|
336
368
|
};
|
|
337
369
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pds-modal.js","sourceRoot":"","sources":["../../../src/components/pds-modal/pds-modal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Element, Event, EventEmitter, h, Method, Prop, State, Watch } from '@stencil/core';\n\n@Component({\n tag: 'pds-modal',\n styleUrl: 'pds-modal.scss',\n shadow: false\n})\nexport class PdsModal {\n private modalRef: HTMLDialogElement;\n private previousActiveElement: HTMLElement;\n private focusableElements: HTMLElement[] = [];\n\n @Element() el: HTMLPdsModalElement;\n\n /**\n * Whether the modal can be dismissed by clicking the backdrop\n * @default true\n */\n @Prop() backdropDismiss = true;\n\n /**\n * A unique identifier used for the underlying component `id` attribute.\n */\n @Prop() componentId: string;\n\n /**\n * Whether the modal is open\n * @default false\n */\n @Prop({ mutable: true }) open = false;\n\n /**\n * The size of the modal\n * @default 'md'\n */\n @Prop() size: 'sm' | 'md' | 'lg' | 'fullscreen' = 'md';\n\n // Modal content is always scrollable by default\n\n /**\n * Emitted when the modal is opened\n */\n @Event() pdsModalOpen: EventEmitter<void>;\n\n /**\n * Emitted when the modal is closed\n */\n @Event() pdsModalClose: EventEmitter<void>;\n\n /**\n * Stores the list of focusable elements in the modal\n */\n @State() focusableElementsArray: HTMLElement[] = [];\n\n componentDidLoad() {\n this.modalRef = this.el.querySelector('.pds-modal__backdrop') as HTMLDialogElement;\n // Add keyboard event listener\n document.addEventListener('keydown', this.handleKeyDown);\n }\n\n disconnectedCallback() {\n // Clean up event listener\n document.removeEventListener('keydown', this.handleKeyDown);\n }\n\n @Watch('open')\n handleOpenChange(newValue: boolean) {\n if (newValue) {\n this.showModal();\n } else {\n this.hideModal();\n }\n }\n\n /**\n * Updates the list of focusable elements in the modal\n */\n private updateFocusableElements() {\n if (!this.modalRef) return;\n\n // Get all focusable elements within the modal\n const selector = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n 'pds-button:not([disabled])',\n 'pds-link:not([disabled])',\n 'pds-input:not([disabled])',\n 'pds-checkbox:not([disabled])',\n 'pds-radio:not([disabled])',\n 'pds-switch:not([disabled])',\n 'pds-select:not([disabled])',\n ].join(',');\n\n this.focusableElements = Array.from(\n this.modalRef.querySelectorAll(selector)\n ) as HTMLElement[];\n\n // Filter out elements with display: none or visibility: hidden\n this.focusableElements = this.focusableElements.filter(el => {\n const style = window.getComputedStyle(el);\n return style.display !== 'none' && style.visibility !== 'hidden';\n });\n }\n\n /**\n * Sets focus to the first focusable element in the modal\n */\n private setInitialFocus() {\n if (this.focusableElements.length === 0) return;\n\n // Focus the first focusable element\n const firstElement = this.focusableElements[0];\n\n // For web components, we need to ensure they're properly focused\n this.focusElement(firstElement);\n }\n\n /**\n * Helper method to focus an element, with special handling for web components\n */\n private focusElement(element: HTMLElement) {\n if (!element) return;\n\n try {\n // Try standard focus first\n element.focus();\n\n // Check if focus worked\n setTimeout(() => {\n if (document.activeElement !== element) {\n // For web components, try to find a focusable element inside\n if (element.shadowRoot) {\n const focusableInShadow = element.shadowRoot.querySelector(\n 'button, [tabindex], input, a[href]'\n ) as HTMLElement;\n\n if (focusableInShadow) {\n focusableInShadow.focus();\n }\n }\n }\n }, 0);\n } catch (error) {\n console.error('Error focusing element:', error);\n }\n }\n\n /**\n * Opens the modal\n */\n @Method()\n async showModal() {\n if (this.modalRef) {\n try {\n // Store the currently focused element to restore focus when modal closes\n this.previousActiveElement = document.activeElement as HTMLElement;\n\n // Use native dialog showModal method which makes the rest of the page inert\n this.modalRef.showModal();\n this.open = true;\n\n // Update focusable elements and set initial focus\n // Using a longer timeout to ensure all components are fully rendered\n setTimeout(() => {\n this.updateFocusableElements();\n this.setInitialFocus();\n this.pdsModalOpen.emit();\n }, 100);\n } catch (error) {\n console.error('Failed to show modal:', error);\n }\n }\n }\n\n /**\n * Closes the modal\n */\n @Method()\n async hideModal() {\n if (this.modalRef) {\n try {\n this.modalRef.close();\n this.open = false;\n\n // Restore focus to the element that was focused before the modal was opened\n if (this.previousActiveElement && typeof this.previousActiveElement.focus === 'function') {\n this.previousActiveElement.focus();\n }\n\n this.pdsModalClose.emit();\n } catch (error) {\n console.error('Failed to hide modal:', error);\n }\n }\n }\n\n private handleBackdropClick = (e: MouseEvent) => {\n if (!this.backdropDismiss || !this.open) return;\n\n if ((e.target as HTMLElement).classList.contains('pds-modal__backdrop')) {\n e.stopPropagation();\n\n // Only close if this is the innermost modal\n if (this.isInnermostModal()) {\n this.hideModal();\n }\n }\n };\n\n /**\n * Gets the z-index of a modal's backdrop element\n */\n private getBackdropZIndex(modal: Element): number {\n const backdrop = modal.querySelector('.pds-modal__backdrop');\n return backdrop ? parseInt(getComputedStyle(backdrop).zIndex, 10) : -1;\n }\n\n /**\n * Checks if this modal is the innermost (highest z-index) modal\n */\n private isInnermostModal(): boolean {\n // Find all open modals\n const openModals = Array.from(document.querySelectorAll('pds-modal')).filter(\n modal => modal.open\n );\n\n if (openModals.length === 0) return false;\n\n // Get this modal's backdrop element\n const thisBackdrop = this.el.querySelector('.pds-modal__backdrop');\n if (!thisBackdrop) return false;\n\n // Get computed z-index of all open modal backdrops\n const modalZIndexes = openModals.map(modal => this.getBackdropZIndex(modal));\n\n // Get the highest z-index\n const maxZIndex = Math.max(...modalZIndexes);\n\n // Check if this modal's backdrop has the highest z-index\n const thisZIndex = this.getBackdropZIndex(this.el);\n return thisZIndex === maxZIndex;\n }\n\n private handleKeyDown = (e: KeyboardEvent) => {\n // If the modal is not open, don't handle any keyboard events\n if (!this.open) return;\n\n // Handle Escape key to close the modal\n if (e.key === 'Escape') {\n // Only close if this is the innermost modal\n if (this.isInnermostModal()) {\n e.preventDefault();\n this.hideModal();\n }\n return;\n }\n\n // Handle Tab key for focus trapping\n if (e.key === 'Tab') {\n // If there are no focusable elements, do nothing\n if (this.focusableElements.length === 0) return;\n\n // Get the first and last focusable elements\n const firstFocusableElement = this.focusableElements[0];\n const lastFocusableElement = this.focusableElements[this.focusableElements.length - 1];\n\n // Get the current active element\n const activeElement = document.activeElement;\n\n // Check if we need to wrap focus\n const isFirstElement = activeElement === firstFocusableElement ||\n firstFocusableElement.contains(activeElement as Node);\n\n const isLastElement = activeElement === lastFocusableElement ||\n lastFocusableElement.contains(activeElement as Node);\n\n // If shift + tab is pressed and focus is on the first element, move to the last element\n if (e.shiftKey && isFirstElement) {\n e.preventDefault();\n this.focusElement(lastFocusableElement);\n }\n // If tab is pressed and focus is on the last element, move to the first element\n else if (!e.shiftKey && isLastElement) {\n e.preventDefault();\n this.focusElement(firstFocusableElement);\n }\n }\n };\n\n render() {\n return (\n <dialog\n class={{\n 'pds-modal__backdrop': true,\n 'open': this.open\n }}\n aria-modal=\"true\"\n aria-labelledby={`${this.componentId}-heading`}\n onClick={this.handleBackdropClick}\n >\n <div\n class={`pds-modal pds-modal--${this.size} pds-modal--scrollable`}\n >\n <slot></slot>\n </div>\n </dialog>\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pds-modal.js","sourceRoot":"","sources":["../../../src/components/pds-modal/pds-modal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Element, Event, EventEmitter, h, Method, Prop, State, Watch } from '@stencil/core';\n\n@Component({\n tag: 'pds-modal',\n styleUrl: 'pds-modal.scss',\n shadow: false\n})\nexport class PdsModal {\n private modalRef: HTMLDialogElement;\n private previousActiveElement: HTMLElement;\n private focusableElements: HTMLElement[] = [];\n\n @Element() el: HTMLPdsModalElement;\n\n /**\n * Whether the modal can be dismissed by clicking the backdrop\n * @default true\n */\n @Prop() backdropDismiss = true;\n\n /**\n * A unique identifier used for the underlying component `id` attribute.\n */\n @Prop() componentId: string;\n\n /**\n * Whether the modal is open\n * @default false\n */\n @Prop({ mutable: true }) open = false;\n\n /**\n * The size of the modal\n * @default 'md'\n */\n @Prop() size: 'sm' | 'md' | 'lg' | 'fullscreen' = 'md';\n\n /**\n * Whether the modal content should be scrollable\n * @default true\n */\n @Prop() scrollable = true;\n\n /**\n * Emitted when the modal is opened\n */\n @Event() pdsModalOpen: EventEmitter<void>;\n\n /**\n * Emitted when the modal is closed\n */\n @Event() pdsModalClose: EventEmitter<void>;\n\n /**\n * Stores the list of focusable elements in the modal\n */\n @State() focusableElementsArray: HTMLElement[] = [];\n\n componentDidLoad() {\n this.modalRef = this.el.querySelector('.pds-modal__backdrop') as HTMLDialogElement;\n // Add keyboard event listener\n document.addEventListener('keydown', this.handleKeyDown);\n }\n\n disconnectedCallback() {\n // Clean up event listener\n document.removeEventListener('keydown', this.handleKeyDown);\n }\n\n @Watch('open')\n handleOpenChange(newValue: boolean) {\n if (newValue) {\n this.showModal();\n } else {\n this.hideModal();\n }\n }\n\n /**\n * Updates the list of focusable elements in the modal\n */\n private updateFocusableElements() {\n if (!this.modalRef) return;\n\n // Get all focusable elements within the modal\n const selector = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n 'pds-button:not([disabled])',\n 'pds-link:not([disabled])',\n 'pds-input:not([disabled])',\n 'pds-checkbox:not([disabled])',\n 'pds-radio:not([disabled])',\n 'pds-switch:not([disabled])',\n 'pds-select:not([disabled])',\n ].join(',');\n\n this.focusableElements = Array.from(\n this.modalRef.querySelectorAll(selector)\n ) as HTMLElement[];\n\n // Filter out elements with display: none or visibility: hidden\n this.focusableElements = this.focusableElements.filter(el => {\n const style = window.getComputedStyle(el);\n return style.display !== 'none' && style.visibility !== 'hidden';\n });\n }\n\n /**\n * Sets focus to the first focusable element in the modal\n */\n private setInitialFocus() {\n if (this.focusableElements.length === 0) return;\n\n // Focus the first focusable element\n const firstElement = this.focusableElements[0];\n\n // For web components, we need to ensure they're properly focused\n this.focusElement(firstElement);\n }\n\n /**\n * Helper method to focus an element, with special handling for web components\n */\n private focusElement(element: HTMLElement) {\n if (!element) return;\n\n try {\n // Try standard focus first\n element.focus();\n\n // Check if focus worked\n setTimeout(() => {\n if (document.activeElement !== element) {\n // For web components, try to find a focusable element inside\n if (element.shadowRoot) {\n const focusableInShadow = element.shadowRoot.querySelector(\n 'button, [tabindex], input, a[href]'\n ) as HTMLElement;\n\n if (focusableInShadow) {\n focusableInShadow.focus();\n }\n }\n }\n }, 0);\n } catch (error) {\n console.error('Error focusing element:', error);\n }\n }\n\n /**\n * Opens the modal\n */\n @Method()\n async showModal() {\n if (this.modalRef) {\n try {\n // Store the currently focused element to restore focus when modal closes\n this.previousActiveElement = document.activeElement as HTMLElement;\n\n // Use native dialog showModal method which makes the rest of the page inert\n this.modalRef.showModal();\n this.open = true;\n\n // Update focusable elements and set initial focus\n // Using a longer timeout to ensure all components are fully rendered\n setTimeout(() => {\n this.updateFocusableElements();\n this.setInitialFocus();\n this.pdsModalOpen.emit();\n }, 100);\n } catch (error) {\n console.error('Failed to show modal:', error);\n }\n }\n }\n\n /**\n * Closes the modal\n */\n @Method()\n async hideModal() {\n if (this.modalRef) {\n try {\n this.modalRef.close();\n this.open = false;\n\n // Restore focus to the element that was focused before the modal was opened\n if (this.previousActiveElement && typeof this.previousActiveElement.focus === 'function') {\n this.previousActiveElement.focus();\n }\n\n this.pdsModalClose.emit();\n } catch (error) {\n console.error('Failed to hide modal:', error);\n }\n }\n }\n\n private handleBackdropClick = (e: MouseEvent) => {\n if (!this.backdropDismiss || !this.open) return;\n\n if ((e.target as HTMLElement).classList.contains('pds-modal__backdrop')) {\n e.stopPropagation();\n\n // Only close if this is the innermost modal\n if (this.isInnermostModal()) {\n this.hideModal();\n }\n }\n };\n\n /**\n * Gets the z-index of a modal's backdrop element\n */\n private getBackdropZIndex(modal: Element): number {\n const backdrop = modal.querySelector('.pds-modal__backdrop');\n return backdrop ? parseInt(getComputedStyle(backdrop).zIndex, 10) : -1;\n }\n\n /**\n * Checks if this modal is the innermost (highest z-index) modal\n */\n private isInnermostModal(): boolean {\n // Find all open modals\n const openModals = Array.from(document.querySelectorAll('pds-modal')).filter(\n modal => modal.open\n );\n\n if (openModals.length === 0) return false;\n\n // Get this modal's backdrop element\n const thisBackdrop = this.el.querySelector('.pds-modal__backdrop');\n if (!thisBackdrop) return false;\n\n // Get computed z-index of all open modal backdrops\n const modalZIndexes = openModals.map(modal => this.getBackdropZIndex(modal));\n\n // Get the highest z-index\n const maxZIndex = Math.max(...modalZIndexes);\n\n // Check if this modal's backdrop has the highest z-index\n const thisZIndex = this.getBackdropZIndex(this.el);\n return thisZIndex === maxZIndex;\n }\n\n private handleKeyDown = (e: KeyboardEvent) => {\n // If the modal is not open, don't handle any keyboard events\n if (!this.open) return;\n\n // Handle Escape key to close the modal\n if (e.key === 'Escape') {\n // Only close if this is the innermost modal\n if (this.isInnermostModal()) {\n e.preventDefault();\n this.hideModal();\n }\n return;\n }\n\n // Handle Tab key for focus trapping\n if (e.key === 'Tab') {\n // If there are no focusable elements, do nothing\n if (this.focusableElements.length === 0) return;\n\n // Get the first and last focusable elements\n const firstFocusableElement = this.focusableElements[0];\n const lastFocusableElement = this.focusableElements[this.focusableElements.length - 1];\n\n // Get the current active element\n const activeElement = document.activeElement;\n\n // Check if we need to wrap focus\n const isFirstElement = activeElement === firstFocusableElement ||\n firstFocusableElement.contains(activeElement as Node);\n\n const isLastElement = activeElement === lastFocusableElement ||\n lastFocusableElement.contains(activeElement as Node);\n\n // If shift + tab is pressed and focus is on the first element, move to the last element\n if (e.shiftKey && isFirstElement) {\n e.preventDefault();\n this.focusElement(lastFocusableElement);\n }\n // If tab is pressed and focus is on the last element, move to the first element\n else if (!e.shiftKey && isLastElement) {\n e.preventDefault();\n this.focusElement(firstFocusableElement);\n }\n }\n };\n\n render() {\n return (\n <dialog\n class={{\n 'pds-modal__backdrop': true,\n 'open': this.open\n }}\n aria-modal=\"true\"\n aria-labelledby={`${this.componentId}-heading`}\n onClick={this.handleBackdropClick}\n >\n <div\n class={{\n 'pds-modal': true,\n [`pds-modal--${this.size}`]: true,\n 'pds-modal--scrollable': this.scrollable\n }}\n >\n <slot></slot>\n </div>\n </dialog>\n );\n }\n}\n"]}
|
|
@@ -11,6 +11,7 @@ export default {
|
|
|
11
11
|
backdropDismiss: true,
|
|
12
12
|
componentId: 'modal-demo',
|
|
13
13
|
open: false,
|
|
14
|
+
scrollable: true,
|
|
14
15
|
size: 'md',
|
|
15
16
|
},
|
|
16
17
|
parameters: {
|
|
@@ -31,7 +32,9 @@ const BaseTemplate = (args) => html`
|
|
|
31
32
|
component-id="${args.componentId}"
|
|
32
33
|
size="${args.size}"
|
|
33
34
|
?backdrop-dismiss=${args.backdropDismiss}
|
|
35
|
+
scrollable="${args.scrollable}"
|
|
34
36
|
?open=${args.open}
|
|
37
|
+
key="${args.scrollable ? 'scrollable' : 'non-scrollable'}"
|
|
35
38
|
>
|
|
36
39
|
<pds-modal-header>
|
|
37
40
|
<pds-box direction="column" fit padding="md">
|
|
@@ -413,3 +416,245 @@ Fullscreen.args = {
|
|
|
413
416
|
componentId: 'fullscreen-modal',
|
|
414
417
|
open: false,
|
|
415
418
|
};
|
|
419
|
+
|
|
420
|
+
const NonScrollableTemplate = (args) => html`
|
|
421
|
+
<div style="padding: 1rem;">
|
|
422
|
+
<pds-button id="show-modal" onClick="document.querySelector('#${args.componentId}').open = true">
|
|
423
|
+
Open Non-Scrollable Modal
|
|
424
|
+
</pds-button>
|
|
425
|
+
|
|
426
|
+
<pds-modal
|
|
427
|
+
id="${args.componentId}"
|
|
428
|
+
component-id="${args.componentId}"
|
|
429
|
+
size="${args.size}"
|
|
430
|
+
?backdrop-dismiss=${args.backdropDismiss}
|
|
431
|
+
scrollable="${args.scrollable}"
|
|
432
|
+
?open=${args.open}
|
|
433
|
+
key="${args.scrollable ? 'scrollable' : 'non-scrollable'}"
|
|
434
|
+
>
|
|
435
|
+
<pds-modal-header>
|
|
436
|
+
<pds-box direction="column" fit padding="md">
|
|
437
|
+
<pds-box
|
|
438
|
+
align-items="center"
|
|
439
|
+
fit
|
|
440
|
+
justify-content="space-between"
|
|
441
|
+
>
|
|
442
|
+
<pds-text tag="h2" size="h3">Non-Scrollable Modal</pds-text>
|
|
443
|
+
<pds-button
|
|
444
|
+
class="pds-modal__close"
|
|
445
|
+
variant="unstyled"
|
|
446
|
+
icon-only="true"
|
|
447
|
+
onclick="document.querySelector('#${args.componentId}').open = false"
|
|
448
|
+
aria-label="Close modal"
|
|
449
|
+
part="close-button"
|
|
450
|
+
>
|
|
451
|
+
<pds-icon slot="start" name="remove" aria-hidden="true"></pds-icon>
|
|
452
|
+
</pds-button>
|
|
453
|
+
</pds-box>
|
|
454
|
+
<pds-box>
|
|
455
|
+
<pds-text tag="p" size="md">Content overflow is handled naturally</pds-text>
|
|
456
|
+
</pds-box>
|
|
457
|
+
</pds-box>
|
|
458
|
+
</pds-modal-header>
|
|
459
|
+
<pds-modal-content>
|
|
460
|
+
<pds-box direction="column" padding-inline-start="md" padding-inline-end="md">
|
|
461
|
+
<p>This modal has scrollable=false, so content will overflow naturally.</p>
|
|
462
|
+
<p>Use this when you want to control overflow behavior differently.</p>
|
|
463
|
+
<p>This is ideal for modals with fixed-height content or custom overflow handling.</p>
|
|
464
|
+
<p>This modal has scrollable=false, so content will overflow naturally.</p>
|
|
465
|
+
<p>Use this when you want to control overflow behavior differently.</p>
|
|
466
|
+
<p>This is ideal for modals with fixed-height content or custom overflow handling.</p>
|
|
467
|
+
<p>This modal has scrollable=false, so content will overflow naturally.</p>
|
|
468
|
+
<p>Use this when you want to control overflow behavior differently.</p>
|
|
469
|
+
<p>This modal has scrollable=false, so content will overflow naturally.</p>
|
|
470
|
+
<p>Use this when you want to control overflow behavior differently.</p>
|
|
471
|
+
<p>This is ideal for modals with fixed-height content or custom overflow handling.</p>
|
|
472
|
+
<p>This modal has scrollable=false, so content will overflow naturally.</p>
|
|
473
|
+
<p>Use this when you want to control overflow behavior differently.</p>
|
|
474
|
+
<p>This is ideal for modals with fixed-height content or custom overflow handling.</p>
|
|
475
|
+
<p>This modal has scrollable=false, so content will overflow naturally.</p>
|
|
476
|
+
<p>Use this when you want to control overflow behavior differently.</p>
|
|
477
|
+
<p>This is ideal for modals with fixed-height content or custom overflow handling.</p>
|
|
478
|
+
</pds-box>
|
|
479
|
+
</pds-modal-content>
|
|
480
|
+
|
|
481
|
+
<pds-modal-footer>
|
|
482
|
+
<pds-box
|
|
483
|
+
justify-content="space-between"
|
|
484
|
+
fit
|
|
485
|
+
padding="md"
|
|
486
|
+
>
|
|
487
|
+
<pds-button variant="unstyled" onclick="document.querySelector('#${args.componentId}').open = false">Close</pds-button>
|
|
488
|
+
<pds-box gap="sm" justify-content="end">
|
|
489
|
+
<pds-button
|
|
490
|
+
variant="secondary"
|
|
491
|
+
onclick="document.querySelector('#${args.componentId}').open = false"
|
|
492
|
+
>
|
|
493
|
+
Cancel
|
|
494
|
+
</pds-button>
|
|
495
|
+
<pds-button variant="primary">Confirm</pds-button>
|
|
496
|
+
</pds-box>
|
|
497
|
+
</pds-box>
|
|
498
|
+
</pds-modal-footer>
|
|
499
|
+
</pds-modal>
|
|
500
|
+
</div>
|
|
501
|
+
`;
|
|
502
|
+
|
|
503
|
+
export const NonScrollable = NonScrollableTemplate.bind({});
|
|
504
|
+
NonScrollable.args = {
|
|
505
|
+
size: 'md',
|
|
506
|
+
componentId: 'non-scrollable-modal',
|
|
507
|
+
scrollable: false,
|
|
508
|
+
open: false,
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
const CustomBordersTemplate = () => html`
|
|
512
|
+
<div style="padding: 1rem;">
|
|
513
|
+
<pds-box gap="sm" direction="column">
|
|
514
|
+
<pds-text tag="h3" size="h4">Border Examples</pds-text>
|
|
515
|
+
<pds-box gap="sm" wrap>
|
|
516
|
+
<pds-button id="show-modal-none" onClick="document.querySelector('#border-none-modal').open = true">
|
|
517
|
+
border="none"
|
|
518
|
+
</pds-button>
|
|
519
|
+
<pds-button id="show-modal-top" onClick="document.querySelector('#border-top-modal').open = true">
|
|
520
|
+
border="top"
|
|
521
|
+
</pds-button>
|
|
522
|
+
<pds-button id="show-modal-bottom" onClick="document.querySelector('#border-bottom-modal').open = true">
|
|
523
|
+
border="bottom"
|
|
524
|
+
</pds-button>
|
|
525
|
+
<pds-button id="show-modal-both" onClick="document.querySelector('#border-both-modal').open = true">
|
|
526
|
+
border="both"
|
|
527
|
+
</pds-button>
|
|
528
|
+
</pds-box>
|
|
529
|
+
</pds-box>
|
|
530
|
+
|
|
531
|
+
<!-- Border None Modal -->
|
|
532
|
+
<pds-modal id="border-none-modal" component-id="border-none-modal" size="sm">
|
|
533
|
+
<pds-modal-header>
|
|
534
|
+
<pds-box direction="column" fit padding="md">
|
|
535
|
+
<pds-box align-items="center" fit justify-content="space-between">
|
|
536
|
+
<pds-text tag="h2" size="h3">No Borders</pds-text>
|
|
537
|
+
<pds-button
|
|
538
|
+
class="pds-modal__close"
|
|
539
|
+
variant="unstyled"
|
|
540
|
+
icon-only="true"
|
|
541
|
+
onclick="document.querySelector('#border-none-modal').open = false"
|
|
542
|
+
aria-label="Close modal"
|
|
543
|
+
>
|
|
544
|
+
<pds-icon slot="start" name="remove" aria-hidden="true"></pds-icon>
|
|
545
|
+
</pds-button>
|
|
546
|
+
</pds-box>
|
|
547
|
+
</pds-box>
|
|
548
|
+
</pds-modal-header>
|
|
549
|
+
<pds-modal-content border="none">
|
|
550
|
+
<pds-box fit direction="column" padding-inline-start="md" padding-inline-end="md">
|
|
551
|
+
<p>This modal content has <code>border="none"</code></p>
|
|
552
|
+
<p>No borders will be shown regardless of content length or scroll position.</p>
|
|
553
|
+
</pds-box>
|
|
554
|
+
</pds-modal-content>
|
|
555
|
+
<pds-modal-footer>
|
|
556
|
+
<pds-box fit justify-content="end" padding="md" gap="sm">
|
|
557
|
+
<pds-button onclick="document.querySelector('#border-none-modal').open = false">Close</pds-button>
|
|
558
|
+
</pds-box>
|
|
559
|
+
</pds-modal-footer>
|
|
560
|
+
</pds-modal>
|
|
561
|
+
|
|
562
|
+
<!-- Border Top Modal -->
|
|
563
|
+
<pds-modal id="border-top-modal" component-id="border-top-modal" size="sm">
|
|
564
|
+
<pds-modal-header>
|
|
565
|
+
<pds-box direction="column" fit padding="md">
|
|
566
|
+
<pds-box align-items="center" fit justify-content="space-between">
|
|
567
|
+
<pds-text tag="h2" size="h3">Top Border Only</pds-text>
|
|
568
|
+
<pds-button
|
|
569
|
+
class="pds-modal__close"
|
|
570
|
+
variant="unstyled"
|
|
571
|
+
icon-only="true"
|
|
572
|
+
onclick="document.querySelector('#border-top-modal').open = false"
|
|
573
|
+
aria-label="Close modal"
|
|
574
|
+
>
|
|
575
|
+
<pds-icon slot="start" name="remove" aria-hidden="true"></pds-icon>
|
|
576
|
+
</pds-button>
|
|
577
|
+
</pds-box>
|
|
578
|
+
</pds-box>
|
|
579
|
+
</pds-modal-header>
|
|
580
|
+
<pds-modal-content border="top">
|
|
581
|
+
<pds-box fit direction="column" padding-inline-start="md" padding-inline-end="md">
|
|
582
|
+
<p>This modal content has <code>border="top"</code></p>
|
|
583
|
+
<p>Only the top border is visible, indicating there's content above.</p>
|
|
584
|
+
</pds-box>
|
|
585
|
+
</pds-modal-content>
|
|
586
|
+
<pds-modal-footer>
|
|
587
|
+
<pds-box fit justify-content="end" padding="md" gap="sm">
|
|
588
|
+
<pds-button onclick="document.querySelector('#border-top-modal').open = false">Close</pds-button>
|
|
589
|
+
</pds-box>
|
|
590
|
+
</pds-modal-footer>
|
|
591
|
+
</pds-modal>
|
|
592
|
+
|
|
593
|
+
<!-- Border Bottom Modal -->
|
|
594
|
+
<pds-modal id="border-bottom-modal" component-id="border-bottom-modal" size="sm">
|
|
595
|
+
<pds-modal-header>
|
|
596
|
+
<pds-box direction="column" fit padding="md">
|
|
597
|
+
<pds-box align-items="center" fit justify-content="space-between">
|
|
598
|
+
<pds-text tag="h2" size="h3">Bottom Border Only</pds-text>
|
|
599
|
+
<pds-button
|
|
600
|
+
class="pds-modal__close"
|
|
601
|
+
variant="unstyled"
|
|
602
|
+
icon-only="true"
|
|
603
|
+
onclick="document.querySelector('#border-bottom-modal').open = false"
|
|
604
|
+
aria-label="Close modal"
|
|
605
|
+
>
|
|
606
|
+
<pds-icon slot="start" name="remove" aria-hidden="true"></pds-icon>
|
|
607
|
+
</pds-button>
|
|
608
|
+
</pds-box>
|
|
609
|
+
</pds-box>
|
|
610
|
+
</pds-modal-header>
|
|
611
|
+
<pds-modal-content border="bottom">
|
|
612
|
+
<pds-box fit direction="column" padding-inline-start="md" padding-inline-end="md">
|
|
613
|
+
<p>This modal content has <code>border="bottom"</code></p>
|
|
614
|
+
<p>Only the bottom border is visible, indicating there's content below.</p>
|
|
615
|
+
</pds-box>
|
|
616
|
+
</pds-modal-content>
|
|
617
|
+
<pds-modal-footer>
|
|
618
|
+
<pds-box fit justify-content="end" padding="md" gap="sm">
|
|
619
|
+
<pds-button onclick="document.querySelector('#border-bottom-modal').open = false">Close</pds-button>
|
|
620
|
+
</pds-box>
|
|
621
|
+
</pds-modal-footer>
|
|
622
|
+
</pds-modal>
|
|
623
|
+
|
|
624
|
+
<!-- Border Both Modal -->
|
|
625
|
+
<pds-modal id="border-both-modal" component-id="border-both-modal" size="sm">
|
|
626
|
+
<pds-modal-header>
|
|
627
|
+
<pds-box direction="column" fit padding="md">
|
|
628
|
+
<pds-box align-items="center" fit justify-content="space-between">
|
|
629
|
+
<pds-text tag="h2" size="h3">Both Borders</pds-text>
|
|
630
|
+
<pds-button
|
|
631
|
+
class="pds-modal__close"
|
|
632
|
+
variant="unstyled"
|
|
633
|
+
icon-only="true"
|
|
634
|
+
onclick="document.querySelector('#border-both-modal').open = false"
|
|
635
|
+
aria-label="Close modal"
|
|
636
|
+
>
|
|
637
|
+
<pds-icon slot="start" name="remove" aria-hidden="true"></pds-icon>
|
|
638
|
+
</pds-button>
|
|
639
|
+
</pds-box>
|
|
640
|
+
</pds-box>
|
|
641
|
+
</pds-modal-header>
|
|
642
|
+
<pds-modal-content border="both">
|
|
643
|
+
<pds-box fit direction="column" padding-inline-start="md" padding-inline-end="md">
|
|
644
|
+
<p>This modal content has <code>border="both"</code></p>
|
|
645
|
+
<p>Both top and bottom borders are visible, indicating content above and below.</p>
|
|
646
|
+
</pds-box>
|
|
647
|
+
</pds-modal-content>
|
|
648
|
+
<pds-modal-footer>
|
|
649
|
+
<pds-box fit justify-content="end" padding="md" gap="sm">
|
|
650
|
+
<pds-button onclick="document.querySelector('#border-both-modal').open = false">Close</pds-button>
|
|
651
|
+
</pds-box>
|
|
652
|
+
</pds-modal-footer>
|
|
653
|
+
</pds-modal>
|
|
654
|
+
</div>
|
|
655
|
+
`;
|
|
656
|
+
|
|
657
|
+
export const CustomBorders = CustomBordersTemplate.bind({});
|
|
658
|
+
CustomBorders.args = {
|
|
659
|
+
componentId: 'custom-borders-modal',
|
|
660
|
+
};
|
|
@@ -9,7 +9,11 @@ export class MockPdsModal {
|
|
|
9
9
|
* The size of the modal
|
|
10
10
|
*/
|
|
11
11
|
this.size = 'md';
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Whether the modal content should be scrollable
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
this.scrollable = true;
|
|
13
17
|
/**
|
|
14
18
|
* Whether the modal can be dismissed by clicking the backdrop
|
|
15
19
|
*/
|
|
@@ -63,13 +67,13 @@ export class MockPdsModal {
|
|
|
63
67
|
const modalClasses = {
|
|
64
68
|
'pds-modal': true,
|
|
65
69
|
[`pds-modal--${this.size}`]: true,
|
|
66
|
-
'pds-modal--scrollable':
|
|
70
|
+
'pds-modal--scrollable': this.scrollable
|
|
67
71
|
};
|
|
68
72
|
const backdropClasses = {
|
|
69
73
|
'pds-modal__backdrop': true,
|
|
70
74
|
'open': this.open,
|
|
71
75
|
};
|
|
72
|
-
return (h("div", { key: '
|
|
76
|
+
return (h("div", { key: '0fccdb57d79f636ec3b5782943ddd76fbc9ce171', class: backdropClasses }, h("div", { key: '341963284bfbcd1f99df53e346ed3257b00dbeb2', class: modalClasses, role: "dialog", "aria-modal": "true", "aria-labelledby": this.componentId ? `${this.componentId}-heading` : null }, h("div", { key: '8ff526d8c2d8c0696f9fff107928cf9cb59dbdad', class: "pds-modal__header" }, h("slot", { key: '8746d9cb026e70b293be00f71ffa2939d80947ee', name: "header" })), h("div", { key: '48b98256d3114016de8279012e2c496726f766ba', class: "pds-modal-content" }, h("slot", { key: '49ff7217a2c8d59c56751c850c4372329e263e7b' })), h("div", { key: 'd46d11d288bff5a4539d0cb4b2c7ea2111687ebf', class: "pds-modal__footer" }, h("slot", { key: '549d4f33a78db562b5afce77cc108cc22f474a0d', name: "footer" })))));
|
|
73
77
|
}
|
|
74
78
|
static get is() { return "mock-pds-modal"; }
|
|
75
79
|
static get originalStyleUrls() {
|
|
@@ -123,6 +127,29 @@ export class MockPdsModal {
|
|
|
123
127
|
"reflect": false,
|
|
124
128
|
"defaultValue": "'md'"
|
|
125
129
|
},
|
|
130
|
+
"scrollable": {
|
|
131
|
+
"type": "boolean",
|
|
132
|
+
"mutable": false,
|
|
133
|
+
"complexType": {
|
|
134
|
+
"original": "boolean",
|
|
135
|
+
"resolved": "boolean",
|
|
136
|
+
"references": {}
|
|
137
|
+
},
|
|
138
|
+
"required": false,
|
|
139
|
+
"optional": false,
|
|
140
|
+
"docs": {
|
|
141
|
+
"tags": [{
|
|
142
|
+
"name": "default",
|
|
143
|
+
"text": "true"
|
|
144
|
+
}],
|
|
145
|
+
"text": "Whether the modal content should be scrollable"
|
|
146
|
+
},
|
|
147
|
+
"getter": false,
|
|
148
|
+
"setter": false,
|
|
149
|
+
"attribute": "scrollable",
|
|
150
|
+
"reflect": false,
|
|
151
|
+
"defaultValue": "true"
|
|
152
|
+
},
|
|
126
153
|
"backdropDismiss": {
|
|
127
154
|
"type": "boolean",
|
|
128
155
|
"mutable": false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock-pds-modal.js","sourceRoot":"","sources":["../../../../src/components/pds-modal/test/mock-pds-modal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAgB,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAWzF;;;GAGG;AAMH,MAAM,OAAO,YAAY;IALzB;QAaE;;WAEG;QACK,SAAI,GAAsC,IAAI,CAAC;QAEvD,
|
|
1
|
+
{"version":3,"file":"mock-pds-modal.js","sourceRoot":"","sources":["../../../../src/components/pds-modal/test/mock-pds-modal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAgB,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAWzF;;;GAGG;AAMH,MAAM,OAAO,YAAY;IALzB;QAaE;;WAEG;QACK,SAAI,GAAsC,IAAI,CAAC;QAEvD;;;WAGG;QACK,eAAU,GAAG,IAAI,CAAC;QAE1B;;WAEG;QACK,oBAAe,GAAG,IAAI,CAAC;QAE/B,+FAA+F;QAE/F;;WAEG;QACsB,SAAI,GAAG,KAAK,CAAC;KAkGvC;IA/EC;;OAEG;IAEH,KAAK,CAAC,SAAS;QACb,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IAEH,KAAK,CAAC,SAAS;QACb,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,iEAAiE;IACjE,mBAAmB,CAAC,KAAiB;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;QAC/D,2EAA2E;QAC3E,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;YAC/D,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,iEAAiE;IACjE,aAAa,CAAC,KAAoB;QAChC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACjD,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAED,gBAAgB;QACd,0DAA0D;IAC5D,CAAC;IAED,MAAM;QACJ,MAAM,YAAY,GAAG;YACnB,WAAW,EAAE,IAAI;YACjB,CAAC,cAAc,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI;YACjC,uBAAuB,EAAE,IAAI,CAAC,UAAU;SACzC,CAAC;QAEF,MAAM,eAAe,GAAG;YACtB,qBAAqB,EAAE,IAAI;YAC3B,MAAM,EAAE,IAAI,CAAC,IAAI;SAClB,CAAC;QAEF,OAAO,CACL,4DAAK,KAAK,EAAE,eAAe;YACzB,4DACE,KAAK,EAAE,YAAY,EACnB,IAAI,EAAC,QAAQ,gBACF,MAAM,qBACA,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,UAAU,CAAC,CAAC,CAAC,IAAI;gBAExE,4DAAK,KAAK,EAAC,mBAAmB;oBAC5B,6DAAM,IAAI,EAAC,QAAQ,GAAQ,CACvB;gBACN,4DAAK,KAAK,EAAC,mBAAmB;oBAC5B,8DAAa,CACT;gBACN,4DAAK,KAAK,EAAC,mBAAmB;oBAC5B,6DAAM,IAAI,EAAC,QAAQ,GAAQ,CACvB,CACF,CACF,CACP,CAAC;IACJ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACF","sourcesContent":["import { Component, Prop, Event, EventEmitter, Method, Element, h } from '@stencil/core';\n\n// Define the element interface for the mock component\ninterface HTMLMockPdsModalElement extends HTMLElement {\n open: boolean;\n showModal: () => Promise<void>;\n hideModal: () => Promise<void>;\n handleBackdropClick: (event: MouseEvent) => void;\n handleKeyDown: (event: KeyboardEvent) => void;\n}\n\n/**\n * Mock PdsModal component for testing purposes\n * This component mimics the real PdsModal but without using the Popover API\n */\n@Component({\n tag: 'mock-pds-modal',\n styleUrl: '../pds-modal.scss',\n shadow: false,\n})\nexport class MockPdsModal {\n @Element() el!: HTMLMockPdsModalElement;\n\n /**\n * The ID of the modal component\n */\n @Prop() componentId?: string;\n\n /**\n * The size of the modal\n */\n @Prop() size: 'sm' | 'md' | 'lg' | 'fullscreen' = 'md';\n\n /**\n * Whether the modal content should be scrollable\n * @default true\n */\n @Prop() scrollable = true;\n\n /**\n * Whether the modal can be dismissed by clicking the backdrop\n */\n @Prop() backdropDismiss = true;\n\n // Native dialog element always closes on Escape key press, so no closeOnEsc property is needed\n\n /**\n * Whether the modal is open\n */\n @Prop({ mutable: true }) open = false;\n\n // No need for modalRef in the mock implementation\n\n /**\n * Event emitted when the modal is opened\n */\n @Event() pdsModalOpen: EventEmitter;\n\n /**\n * Event emitted when the modal is closed\n */\n @Event() pdsModalClose: EventEmitter;\n\n /**\n * Event emitted when the backdrop is clicked\n */\n @Event() pdsModalBackdropClick: EventEmitter;\n\n /**\n * Shows the modal\n */\n @Method()\n async showModal() {\n this.open = true;\n this.pdsModalOpen.emit();\n }\n\n /**\n * Hides the modal\n */\n @Method()\n async hideModal() {\n this.open = false;\n this.pdsModalClose.emit();\n }\n\n /**\n * Listen for click events on the backdrop\n */\n // Using direct method instead of @Listen to avoid ESLint warning\n handleBackdropClick(event: MouseEvent) {\n const backdrop = this.el.querySelector('.pds-modal__backdrop');\n // Check if the click was directly on the backdrop (not on a child element)\n if (event.target === backdrop && this.backdropDismiss === true) {\n this.pdsModalBackdropClick.emit();\n this.hideModal();\n }\n }\n\n /**\n * Listen for keydown events to handle Escape key\n * Native dialog element always closes on Escape key press\n */\n // Using direct method instead of @Listen to avoid ESLint warning\n handleKeyDown(event: KeyboardEvent) {\n if (event.key === 'Escape' && this.open === true) {\n this.hideModal();\n }\n }\n\n componentDidLoad() {\n // No need to do anything in componentDidLoad for the mock\n }\n\n render() {\n const modalClasses = {\n 'pds-modal': true,\n [`pds-modal--${this.size}`]: true,\n 'pds-modal--scrollable': this.scrollable\n };\n\n const backdropClasses = {\n 'pds-modal__backdrop': true,\n 'open': this.open,\n };\n\n return (\n <div class={backdropClasses}>\n <div\n class={modalClasses}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={this.componentId ? `${this.componentId}-heading` : null}\n >\n <div class=\"pds-modal__header\">\n <slot name=\"header\"></slot>\n </div>\n <div class=\"pds-modal-content\">\n <slot></slot>\n </div>\n <div class=\"pds-modal__footer\">\n <slot name=\"footer\"></slot>\n </div>\n </div>\n </div>\n );\n }\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
:host {
|
|
2
|
-
display: inline;
|
|
2
|
+
display: inline-block;
|
|
3
|
+
width: 100%;
|
|
3
4
|
}
|
|
4
5
|
|
|
5
6
|
:host([aria-readonly=true]) textarea {
|
|
@@ -34,13 +35,42 @@ label {
|
|
|
34
35
|
margin-block-end: 0;
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
.pds-textarea__helper-message {
|
|
39
|
+
color: var(--pine-color-text-message);
|
|
40
|
+
font: var(--pine-typography-body-sm-medium);
|
|
41
|
+
margin-block-start: var(--pine-dimension-2xs);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.pds-textarea__error-message {
|
|
45
|
+
align-items: center;
|
|
46
|
+
color: var(--pine-color-text-message-danger);
|
|
47
|
+
display: flex;
|
|
48
|
+
font: var(--pine-typography-body-sm-medium);
|
|
49
|
+
gap: var(--pine-dimension-2xs);
|
|
50
|
+
margin-block-start: var(--pine-dimension-2xs);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.pds-textarea__field-wrapper {
|
|
54
|
+
display: inline-block;
|
|
55
|
+
position: relative;
|
|
56
|
+
width: 100%;
|
|
57
|
+
}
|
|
58
|
+
|
|
37
59
|
.pds-textarea__field {
|
|
38
60
|
background-color: var(--pine-color-background-container);
|
|
39
61
|
border: var(--pine-border);
|
|
40
62
|
border-radius: calc(var(--pine-dimension-xs) * 1.25);
|
|
63
|
+
box-sizing: border-box;
|
|
41
64
|
font: var(--pine-typography-body);
|
|
42
65
|
letter-spacing: var(--pine-letter-spacing);
|
|
66
|
+
min-height: calc(var(--pine-dimension-xl) * 2);
|
|
67
|
+
min-width: calc(var(--pine-dimension-xl) * 2);
|
|
43
68
|
padding: var(--pine-dimension-xs) var(--pine-dimension-sm);
|
|
69
|
+
resize: both;
|
|
70
|
+
width: 100%;
|
|
71
|
+
}
|
|
72
|
+
:host([max-length]) .pds-textarea__field {
|
|
73
|
+
padding-bottom: calc(var(--pine-dimension-xs) + var(--pine-dimension-md));
|
|
44
74
|
}
|
|
45
75
|
.pds-textarea__field:hover:not(:disabled, .is-invalid) {
|
|
46
76
|
border: var(--pine-border-hover);
|
|
@@ -65,18 +95,28 @@ label {
|
|
|
65
95
|
outline-color: var(--pine-color-focus-ring-danger);
|
|
66
96
|
}
|
|
67
97
|
|
|
68
|
-
.pds-
|
|
69
|
-
|
|
70
|
-
|
|
98
|
+
.pds-textarea__character-counter {
|
|
99
|
+
background: color-mix(in srgb, var(--pine-color-background-container) 80%, transparent);
|
|
100
|
+
border-radius: calc(var(--pine-dimension-2xs) * 0.5);
|
|
101
|
+
color: var(--pine-color-text-readonly);
|
|
71
102
|
font: var(--pine-typography-body-sm-medium);
|
|
72
|
-
|
|
103
|
+
padding: calc(var(--pine-dimension-2xs) * 0.5) var(--pine-dimension-2xs);
|
|
104
|
+
pointer-events: none;
|
|
105
|
+
position: absolute;
|
|
106
|
+
user-select: none;
|
|
107
|
+
white-space: nowrap;
|
|
108
|
+
z-index: 2;
|
|
73
109
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
110
|
+
:host([aria-disabled=true]) .pds-textarea__character-counter {
|
|
111
|
+
background-color: var(--pine-color-background-container-disabled);
|
|
112
|
+
color: var(--pine-color-text-disabled);
|
|
113
|
+
}
|
|
114
|
+
:host([aria-readonly=true]) .pds-textarea__character-counter {
|
|
115
|
+
background-color: var(--pine-color-background-container-disabled);
|
|
116
|
+
color: var(--pine-color-text-readonly);
|
|
117
|
+
}
|
|
118
|
+
.pds-textarea__field.is-invalid ~ .pds-textarea__character-counter {
|
|
119
|
+
background-color: var(--pine-input-color-background-danger);
|
|
80
120
|
}
|
|
81
121
|
|
|
82
122
|
.visually-hidden {
|