@pine-ds/core 3.29.0 → 3.30.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/form.js +1 -1
- package/components/pds-avatar.js +1 -1
- package/components/pds-checkbox2.js +1 -1
- package/components/pds-combobox.js +2 -2
- package/components/pds-input.js +1 -1
- package/components/pds-modal.js +1 -1
- package/components/pds-multiselect.js +1 -1
- package/components/pds-radio.js +1 -1
- package/components/pds-select.js +1 -1
- package/components/pds-switch.js +1 -1
- package/components/pds-textarea.js +1 -1
- package/dist/cjs/{form-CpM5Z8q7.js → form-MhwfKTuo.js} +11 -7
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/pds-avatar.cjs.entry.js +2 -2
- package/dist/cjs/pds-checkbox.cjs.entry.js +4 -4
- package/dist/cjs/pds-combobox.cjs.entry.js +20 -4
- package/dist/cjs/pds-input.cjs.entry.js +2 -2
- package/dist/cjs/pds-modal.cjs.entry.js +35 -5
- package/dist/cjs/pds-multiselect.cjs.entry.js +5 -5
- package/dist/cjs/pds-radio-group.cjs.entry.js +1 -1
- package/dist/cjs/pds-radio.cjs.entry.js +5 -5
- package/dist/cjs/pds-select.cjs.entry.js +7 -2
- package/dist/cjs/pds-switch.cjs.entry.js +4 -4
- package/dist/cjs/pds-textarea.cjs.entry.js +4 -4
- package/dist/cjs/pine-core.cjs.js +1 -1
- package/dist/collection/components/pds-avatar/pds-avatar.js +3 -2
- package/dist/collection/components/pds-checkbox/pds-checkbox.js +3 -3
- package/dist/collection/components/pds-combobox/pds-combobox.css +32 -0
- package/dist/collection/components/pds-combobox/pds-combobox.js +76 -3
- package/dist/collection/components/pds-combobox/stories/pds-combobox.stories.js +25 -0
- package/dist/collection/components/pds-input/pds-input.js +1 -1
- package/dist/collection/components/pds-modal/pds-modal.js +58 -5
- package/dist/collection/components/pds-modal/stories/pds-modal.stories.js +77 -0
- package/dist/collection/components/pds-multiselect/pds-multiselect.css +2 -2
- package/dist/collection/components/pds-multiselect/pds-multiselect.js +3 -3
- package/dist/collection/components/pds-radio/pds-radio.css +6 -0
- package/dist/collection/components/pds-radio/pds-radio.js +3 -3
- package/dist/collection/components/pds-select/pds-select.js +7 -2
- package/dist/collection/components/pds-switch/pds-switch.js +3 -3
- package/dist/collection/components/pds-textarea/pds-textarea.js +3 -3
- package/dist/collection/utils/form.js +11 -7
- package/dist/docs.json +107 -1
- package/dist/esm/{form-C3xDZBme.js → form-BuRbS7Hp.js} +11 -7
- package/dist/esm/loader.js +1 -1
- package/dist/esm/pds-avatar.entry.js +2 -2
- package/dist/esm/pds-checkbox.entry.js +4 -4
- package/dist/esm/pds-combobox.entry.js +20 -4
- package/dist/esm/pds-input.entry.js +2 -2
- package/dist/esm/pds-modal.entry.js +35 -5
- package/dist/esm/pds-multiselect.entry.js +5 -5
- package/dist/esm/pds-radio-group.entry.js +1 -1
- package/dist/esm/pds-radio.entry.js +5 -5
- package/dist/esm/pds-select.entry.js +7 -2
- package/dist/esm/pds-switch.entry.js +4 -4
- package/dist/esm/pds-textarea.entry.js +4 -4
- package/dist/esm/pine-core.js +1 -1
- package/dist/esm-es5/form-BuRbS7Hp.js +1 -0
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/pds-avatar.entry.js +1 -1
- package/dist/esm-es5/pds-checkbox.entry.js +1 -1
- package/dist/esm-es5/pds-combobox.entry.js +2 -2
- package/dist/esm-es5/pds-input.entry.js +1 -1
- package/dist/esm-es5/pds-modal.entry.js +1 -1
- package/dist/esm-es5/pds-multiselect.entry.js +1 -1
- package/dist/esm-es5/pds-radio-group.entry.js +1 -1
- package/dist/esm-es5/pds-radio.entry.js +1 -1
- package/dist/esm-es5/pds-select.entry.js +1 -1
- package/dist/esm-es5/pds-switch.entry.js +1 -1
- package/dist/esm-es5/pds-textarea.entry.js +1 -1
- package/dist/esm-es5/pine-core.js +1 -1
- package/dist/pine-core/p-1482053d.entry.js +1 -0
- package/dist/pine-core/p-1e87e72a.entry.js +1 -0
- package/dist/pine-core/{p-978b848b.system.entry.js → p-31679dbc.system.entry.js} +1 -1
- package/dist/pine-core/p-3c09f2d4.system.entry.js +1 -0
- package/dist/pine-core/{p-5f4d2c5c.system.entry.js → p-3cece186.system.entry.js} +1 -1
- package/dist/pine-core/p-43268325.system.entry.js +1 -0
- package/dist/pine-core/{p-092a72d2.system.entry.js → p-559042b7.system.entry.js} +1 -1
- package/dist/pine-core/p-5aa59b20.entry.js +2 -0
- package/dist/pine-core/{p-82af7d58.system.entry.js → p-69372e72.system.entry.js} +1 -1
- package/dist/pine-core/p-69e1a82b.system.entry.js +3 -0
- package/dist/pine-core/{p-02977c6f.entry.js → p-7d15be6a.entry.js} +1 -1
- package/dist/pine-core/p-809e0506.entry.js +1 -0
- package/dist/pine-core/{p-ba54470a.system.entry.js → p-86d12f3c.system.entry.js} +1 -1
- package/dist/pine-core/p-B1rytYxP.system.js +1 -1
- package/dist/pine-core/p-BuRbS7Hp.js +1 -0
- package/dist/pine-core/p-BxIzb-Wc.system.js +1 -0
- package/dist/pine-core/p-a07b331a.entry.js +1 -0
- package/dist/pine-core/p-a0edb4ad.entry.js +1 -0
- package/dist/pine-core/p-aa0753e1.entry.js +1 -0
- package/dist/pine-core/p-c625d5ea.system.entry.js +1 -0
- package/dist/pine-core/{p-dc48f603.entry.js → p-caf73216.entry.js} +1 -1
- package/dist/pine-core/{p-e81b4d04.system.entry.js → p-d00f54f0.system.entry.js} +1 -1
- package/dist/pine-core/p-dfa70d20.entry.js +1 -0
- package/dist/pine-core/p-fb17773a.system.entry.js +1 -0
- package/dist/pine-core/p-fef6694d.entry.js +1 -0
- package/dist/pine-core/pine-core.esm.js +1 -1
- package/dist/types/components/pds-avatar/pds-avatar.d.ts +1 -0
- package/dist/types/components/pds-combobox/pds-combobox.d.ts +14 -0
- package/dist/types/components/pds-modal/pds-modal.d.ts +10 -0
- package/dist/types/components/pds-select/pds-select.d.ts +1 -0
- package/dist/types/components.d.ts +38 -0
- package/dist/types/utils/form.d.ts +4 -1
- package/dist/vscode.html-data.json +10909 -0
- package/hydrate/index.js +96 -36
- package/hydrate/index.mjs +96 -36
- package/package.json +2 -2
- package/dist/esm-es5/form-C3xDZBme.js +0 -1
- package/dist/pine-core/p-054f7011.entry.js +0 -1
- package/dist/pine-core/p-0d6daa35.entry.js +0 -1
- package/dist/pine-core/p-2a74b396.entry.js +0 -1
- package/dist/pine-core/p-69e47ffc.system.entry.js +0 -1
- package/dist/pine-core/p-6fb68ad1.entry.js +0 -1
- package/dist/pine-core/p-72a1b563.system.entry.js +0 -1
- package/dist/pine-core/p-7d15b65e.entry.js +0 -1
- package/dist/pine-core/p-902b5790.entry.js +0 -2
- package/dist/pine-core/p-9ba86e34.entry.js +0 -1
- package/dist/pine-core/p-9f041a63.system.entry.js +0 -3
- package/dist/pine-core/p-B1u-QvFn.system.js +0 -1
- package/dist/pine-core/p-C3xDZBme.js +0 -1
- package/dist/pine-core/p-ce715993.entry.js +0 -1
- package/dist/pine-core/p-e0fb06ea.system.entry.js +0 -1
- package/dist/pine-core/p-e4b69d10.entry.js +0 -1
- package/dist/pine-core/p-fb10caff.system.entry.js +0 -1
|
@@ -22,6 +22,16 @@ export class PdsModal {
|
|
|
22
22
|
* @default true
|
|
23
23
|
*/
|
|
24
24
|
this.scrollable = true;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the modal opens outside the browser top layer as a non-modal dialog.
|
|
27
|
+
* When `true` it opens with `dialog.show()` instead of `dialog.showModal()`, so
|
|
28
|
+
* overlays rendered elsewhere in the DOM (file pickers, editor menus) can display
|
|
29
|
+
* above it via `z-index`. The page is not made inert and focus is not trapped in
|
|
30
|
+
* this mode. Read when the modal opens; changing it while the modal is open is
|
|
31
|
+
* not supported.
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
this.disableTopLayer = false;
|
|
25
35
|
/**
|
|
26
36
|
* Stores the list of focusable elements in the modal
|
|
27
37
|
*/
|
|
@@ -43,6 +53,13 @@ export class PdsModal {
|
|
|
43
53
|
return;
|
|
44
54
|
// Handle Escape key to close the modal
|
|
45
55
|
if (e.key === 'Escape') {
|
|
56
|
+
// In non-top-layer mode, focus can move into an overlay stacked above the
|
|
57
|
+
// modal (the reason disableTopLayer exists). If that overlay owns focus,
|
|
58
|
+
// leave Escape to it rather than dismissing this modal out from under it.
|
|
59
|
+
const active = document.activeElement;
|
|
60
|
+
if (this.disableTopLayer && active && active !== document.body && !this.el.contains(active)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
46
63
|
// Always prevent native dialog close behavior
|
|
47
64
|
e.preventDefault();
|
|
48
65
|
// Only close if backdropDismiss is enabled and this is the innermost modal
|
|
@@ -53,6 +70,11 @@ export class PdsModal {
|
|
|
53
70
|
}
|
|
54
71
|
// Handle Tab key for focus trapping
|
|
55
72
|
if (e.key === 'Tab') {
|
|
73
|
+
// In non-top-layer mode the modal is deliberately not focus-isolated: focus
|
|
74
|
+
// must be able to leave it into overlays stacked above (the whole point of
|
|
75
|
+
// disableTopLayer), so do not trap Tab here.
|
|
76
|
+
if (this.disableTopLayer)
|
|
77
|
+
return;
|
|
56
78
|
// If there are no focusable elements, do nothing
|
|
57
79
|
if (this.focusableElements.length === 0)
|
|
58
80
|
return;
|
|
@@ -170,8 +192,16 @@ export class PdsModal {
|
|
|
170
192
|
try {
|
|
171
193
|
// Store the currently focused element to restore focus when modal closes
|
|
172
194
|
this.previousActiveElement = document.activeElement;
|
|
173
|
-
//
|
|
174
|
-
|
|
195
|
+
// showModal() promotes the dialog to the browser top layer (and makes the
|
|
196
|
+
// rest of the page inert), which prevents any overlay outside the dialog
|
|
197
|
+
// from ever painting above it. show() opens a non-modal dialog that stays
|
|
198
|
+
// in the normal stacking context so those overlays can stack above it.
|
|
199
|
+
if (this.disableTopLayer) {
|
|
200
|
+
this.modalRef.show();
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
this.modalRef.showModal();
|
|
204
|
+
}
|
|
175
205
|
this.open = true;
|
|
176
206
|
// Update focusable elements and set initial focus
|
|
177
207
|
// Using a longer timeout to ensure all components are fully rendered
|
|
@@ -233,14 +263,14 @@ export class PdsModal {
|
|
|
233
263
|
return thisZIndex === maxZIndex;
|
|
234
264
|
}
|
|
235
265
|
render() {
|
|
236
|
-
return (h("dialog", { key: '
|
|
266
|
+
return (h("dialog", { key: 'd345ea0a585213fd7879a2fe27071705fbdba79b', class: {
|
|
237
267
|
'pds-modal__backdrop': true,
|
|
238
268
|
'open': this.open
|
|
239
|
-
}, "aria-modal":
|
|
269
|
+
}, "aria-modal": this.disableTopLayer ? 'false' : 'true', "aria-labelledby": `${this.componentId}-heading`, onClick: this.handleBackdropClick }, h("div", { key: '34c9a222d58ffd9736a36ab6848679186167e878', class: {
|
|
240
270
|
'pds-modal': true,
|
|
241
271
|
[`pds-modal--${this.size}`]: true,
|
|
242
272
|
'pds-modal--scrollable': this.scrollable
|
|
243
|
-
}, part: "modal" }, h("slot", { key: '
|
|
273
|
+
}, part: "modal" }, h("slot", { key: '4eef9c3001b6a7c972fa8e49fa3f0b140c7fe7ce' }))));
|
|
244
274
|
}
|
|
245
275
|
static get is() { return "pds-modal"; }
|
|
246
276
|
static get originalStyleUrls() {
|
|
@@ -365,6 +395,29 @@ export class PdsModal {
|
|
|
365
395
|
"reflect": false,
|
|
366
396
|
"attribute": "scrollable",
|
|
367
397
|
"defaultValue": "true"
|
|
398
|
+
},
|
|
399
|
+
"disableTopLayer": {
|
|
400
|
+
"type": "boolean",
|
|
401
|
+
"mutable": false,
|
|
402
|
+
"complexType": {
|
|
403
|
+
"original": "boolean",
|
|
404
|
+
"resolved": "boolean",
|
|
405
|
+
"references": {}
|
|
406
|
+
},
|
|
407
|
+
"required": false,
|
|
408
|
+
"optional": false,
|
|
409
|
+
"docs": {
|
|
410
|
+
"tags": [{
|
|
411
|
+
"name": "default",
|
|
412
|
+
"text": "false"
|
|
413
|
+
}],
|
|
414
|
+
"text": "Whether the modal opens outside the browser top layer as a non-modal dialog.\nWhen `true` it opens with `dialog.show()` instead of `dialog.showModal()`, so\noverlays rendered elsewhere in the DOM (file pickers, editor menus) can display\nabove it via `z-index`. The page is not made inert and focus is not trapped in\nthis mode. Read when the modal opens; changing it while the modal is open is\nnot supported."
|
|
415
|
+
},
|
|
416
|
+
"getter": false,
|
|
417
|
+
"setter": false,
|
|
418
|
+
"reflect": false,
|
|
419
|
+
"attribute": "disable-top-layer",
|
|
420
|
+
"defaultValue": "false"
|
|
368
421
|
}
|
|
369
422
|
};
|
|
370
423
|
}
|
|
@@ -8,6 +8,7 @@ export default {
|
|
|
8
8
|
args: {
|
|
9
9
|
backdropDismiss: true,
|
|
10
10
|
componentId: 'modal-demo',
|
|
11
|
+
disableTopLayer: false,
|
|
11
12
|
open: false,
|
|
12
13
|
scrollable: true,
|
|
13
14
|
size: 'md',
|
|
@@ -26,6 +27,7 @@ const BaseTemplate = (args) => html`
|
|
|
26
27
|
component-id="${args.componentId}"
|
|
27
28
|
size="${args.size}"
|
|
28
29
|
?backdrop-dismiss=${args.backdropDismiss}
|
|
30
|
+
?disable-top-layer=${args.disableTopLayer}
|
|
29
31
|
scrollable="${args.scrollable}"
|
|
30
32
|
?open=${args.open}
|
|
31
33
|
key="${args.scrollable ? 'scrollable' : 'non-scrollable'}"
|
|
@@ -652,3 +654,78 @@ export const CustomBorders = CustomBordersTemplate.bind({});
|
|
|
652
654
|
CustomBorders.args = {
|
|
653
655
|
componentId: 'custom-borders-modal',
|
|
654
656
|
};
|
|
657
|
+
|
|
658
|
+
// Demonstrates `disable-top-layer`: the modal opens as a non-modal dialog
|
|
659
|
+
// (dialog.show()) so an overlay appended to document.body can display above it.
|
|
660
|
+
// With the default top-layer behavior the same overlay would render behind the
|
|
661
|
+
// modal and be unreachable.
|
|
662
|
+
const DisableTopLayerTemplate = (args) => html`
|
|
663
|
+
<div style="padding: 1rem;">
|
|
664
|
+
<pds-button onClick="document.querySelector('#${args.componentId}').open = true">
|
|
665
|
+
Open Modal (disable-top-layer)
|
|
666
|
+
</pds-button>
|
|
667
|
+
|
|
668
|
+
<pds-modal
|
|
669
|
+
id="${args.componentId}"
|
|
670
|
+
component-id="${args.componentId}"
|
|
671
|
+
size="${args.size}"
|
|
672
|
+
?backdrop-dismiss=${args.backdropDismiss}
|
|
673
|
+
?disable-top-layer=${args.disableTopLayer}
|
|
674
|
+
?open=${args.open}
|
|
675
|
+
>
|
|
676
|
+
<pds-modal-header>
|
|
677
|
+
<pds-box direction="column" fit padding="md">
|
|
678
|
+
<pds-box align-items="center" fit justify-content="space-between">
|
|
679
|
+
<pds-text tag="h2" size="h3">Modal Title</pds-text>
|
|
680
|
+
<pds-button
|
|
681
|
+
class="pds-modal__close"
|
|
682
|
+
variant="unstyled"
|
|
683
|
+
icon-only="true"
|
|
684
|
+
onclick="document.querySelector('#${args.componentId}').open = false"
|
|
685
|
+
aria-label="Close modal"
|
|
686
|
+
part="close-button"
|
|
687
|
+
>
|
|
688
|
+
<pds-icon slot="start" name="remove" aria-hidden="true"></pds-icon>
|
|
689
|
+
</pds-button>
|
|
690
|
+
</pds-box>
|
|
691
|
+
</pds-box>
|
|
692
|
+
</pds-modal-header>
|
|
693
|
+
|
|
694
|
+
<pds-modal-content>
|
|
695
|
+
<pds-box fit direction="column" padding-inline-start="md" padding-inline-end="md" gap="sm">
|
|
696
|
+
<p>
|
|
697
|
+
This modal uses <code>disable-top-layer</code>, so it renders in the normal stacking
|
|
698
|
+
context instead of the browser top layer.
|
|
699
|
+
</p>
|
|
700
|
+
<p>
|
|
701
|
+
An overlay appended to <code>document.body</code> with a higher <code>z-index</code> can
|
|
702
|
+
therefore display above it — useful for file pickers, rich-text editor menus, and
|
|
703
|
+
other body-mounted overlays that would otherwise be trapped behind a top-layer dialog.
|
|
704
|
+
</p>
|
|
705
|
+
<pds-button
|
|
706
|
+
variant="secondary"
|
|
707
|
+
onclick="(function(){var o=document.createElement('button');o.type='button';o.textContent='Overlay above the modal — focusable, keyboard-dismissable. Click or press Enter.';o.setAttribute('style','position:fixed;inset:auto 2rem 2rem auto;max-width:20rem;padding:1rem;border:0;text-align:start;border-radius:8px;background:#111;color:#fff;z-index:2147483647;cursor:pointer;box-shadow:0 8px 24px rgba(0,0,0,.4)');var modal=document.querySelector('#${args.componentId}');var remove=function(){o.remove()};o.onclick=remove;o.addEventListener('keydown',function(e){if(e.key==='Escape')remove()});if(modal)modal.addEventListener('pdsModalClose',remove,{once:true});document.body.appendChild(o);o.focus();})()"
|
|
708
|
+
>
|
|
709
|
+
Show overlay above modal
|
|
710
|
+
</pds-button>
|
|
711
|
+
</pds-box>
|
|
712
|
+
</pds-modal-content>
|
|
713
|
+
|
|
714
|
+
<pds-modal-footer>
|
|
715
|
+
<pds-box justify-content="end" fit padding="md" gap="sm">
|
|
716
|
+
<pds-button variant="secondary" onclick="document.querySelector('#${args.componentId}').open = false">
|
|
717
|
+
Close
|
|
718
|
+
</pds-button>
|
|
719
|
+
</pds-box>
|
|
720
|
+
</pds-modal-footer>
|
|
721
|
+
</pds-modal>
|
|
722
|
+
</div>
|
|
723
|
+
`;
|
|
724
|
+
|
|
725
|
+
export const DisableTopLayer = DisableTopLayerTemplate.bind({});
|
|
726
|
+
DisableTopLayer.args = {
|
|
727
|
+
componentId: 'disable-top-layer-modal',
|
|
728
|
+
disableTopLayer: true,
|
|
729
|
+
size: 'md',
|
|
730
|
+
open: false,
|
|
731
|
+
};
|
|
@@ -291,7 +291,7 @@
|
|
|
291
291
|
|
|
292
292
|
.pds-multiselect__helper {
|
|
293
293
|
color: var(--pine-color-text-message);
|
|
294
|
-
font: var(--pine-typography-body-sm);
|
|
294
|
+
font: var(--pine-typography-body-sm-medium);
|
|
295
295
|
margin-block-start: var(--pine-dimension-2xs);
|
|
296
296
|
margin-inline-start: var(--pine-dimension-none);
|
|
297
297
|
}
|
|
@@ -300,7 +300,7 @@
|
|
|
300
300
|
align-items: flex-start;
|
|
301
301
|
color: var(--pine-color-text-message-danger);
|
|
302
302
|
display: flex;
|
|
303
|
-
font: var(--pine-typography-body-sm);
|
|
303
|
+
font: var(--pine-typography-body-sm-medium);
|
|
304
304
|
gap: var(--pine-dimension-2xs);
|
|
305
305
|
margin-block-start: var(--pine-dimension-2xs);
|
|
306
306
|
margin-inline-start: var(--pine-dimension-none);
|
|
@@ -1031,16 +1031,16 @@ export class PdsMultiselect {
|
|
|
1031
1031
|
'pds-multiselect__trigger--invalid': this.invalid || !!this.errorMessage,
|
|
1032
1032
|
'pds-multiselect__trigger--has-value': hasSelections,
|
|
1033
1033
|
'pds-multiselect__trigger--pill-inline': true,
|
|
1034
|
-
}, onClick: this.handleTriggerClick }, this.renderInlinePills(), h("button", { ref: el => (this.triggerEl = el), type: "button", id: this.componentId, part: "pill-toggle", class: "pds-multiselect__pill-toggle", disabled: this.disabled, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-haspopup": "listbox", "aria-labelledby": this.label ? `${this.componentId}-label` : undefined, "aria-required": this.required ? 'true' : undefined, "aria-describedby": assignDescription(this.componentId, this.invalid || !!this.errorMessage, this.
|
|
1034
|
+
}, onClick: this.handleTriggerClick }, this.renderInlinePills(), h("button", { ref: el => (this.triggerEl = el), type: "button", id: this.componentId, part: "pill-toggle", class: "pds-multiselect__pill-toggle", disabled: this.disabled, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-haspopup": "listbox", "aria-labelledby": this.label ? `${this.componentId}-label` : undefined, "aria-required": this.required ? 'true' : undefined, "aria-describedby": assignDescription(this.componentId, this.invalid || !!this.errorMessage, this.helperMessage, this.errorMessage), "aria-invalid": this.invalid || !!this.errorMessage ? 'true' : undefined, onKeyDown: this.handleTriggerKeyDown }, h("pds-icon", { class: "pds-multiselect__icon", icon: enlarge })))) : (h("button", { ref: el => (this.triggerEl = el), type: "button", part: "trigger", class: {
|
|
1035
1035
|
'pds-multiselect__trigger': true,
|
|
1036
1036
|
'pds-multiselect__trigger--open': this.isOpen,
|
|
1037
1037
|
'pds-multiselect__trigger--disabled': this.disabled,
|
|
1038
1038
|
'pds-multiselect__trigger--invalid': this.invalid || !!this.errorMessage,
|
|
1039
1039
|
'pds-multiselect__trigger--has-value': hasSelections,
|
|
1040
|
-
}, id: this.componentId, disabled: this.disabled, "aria-required": this.required ? 'true' : undefined, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-haspopup": "listbox", "aria-describedby": assignDescription(this.componentId, this.invalid || !!this.errorMessage, this.
|
|
1040
|
+
}, id: this.componentId, disabled: this.disabled, "aria-required": this.required ? 'true' : undefined, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-haspopup": "listbox", "aria-describedby": assignDescription(this.componentId, this.invalid || !!this.errorMessage, this.helperMessage, this.errorMessage), "aria-invalid": this.invalid || !!this.errorMessage ? 'true' : undefined, onClick: this.handleTriggerClick, onKeyDown: this.handleTriggerKeyDown }, h("span", { class: {
|
|
1041
1041
|
'pds-multiselect__trigger-text': true,
|
|
1042
1042
|
'pds-multiselect__trigger-text--placeholder': !hasSelections || (this.selectedDisplay === 'pill' && this.pillPosition === 'below'),
|
|
1043
|
-
} }, this.getTriggerText()), h("pds-icon", { class: "pds-multiselect__icon", icon: enlarge }))), this.renderDropdown()), this.selectedDisplay === 'pill' && this.pillPosition === 'below' && this.renderBelowPills(), h("span", { key: '
|
|
1043
|
+
} }, this.getTriggerText()), h("pds-icon", { class: "pds-multiselect__icon", icon: enlarge }))), this.renderDropdown()), this.selectedDisplay === 'pill' && this.pillPosition === 'below' && this.renderBelowPills(), h("span", { key: '199804f5352818d32542864e3a61f7a9364cc2e3', class: "visually-hidden", "aria-live": "polite", "aria-atomic": "true" }, this.removalAnnouncement), this.helperMessage && !(this.errorMessage && this.errorMessage.length > 0) && (h("p", { key: 'e6855ff0aaf18f59dced2df5d636cadb4d47427b', class: "pds-multiselect__helper", id: messageId(this.componentId, 'helper') }, this.helperMessage)), this.errorMessage && (h("p", { key: '29eae23d8db31b9b9c292d5cd1dc5f641613ed32', class: "pds-multiselect__error", id: messageId(this.componentId, 'error') }, h("pds-icon", { key: 'aad6fd945998957cd28ab6eb97c4d80f0a732ea5', icon: danger, size: "small" }), this.errorMessage)), h("div", { key: '7d0d56a1e097cfc0c7396c1957d16014cb071b1e', style: { display: 'none' } }, h("slot", { key: '6e7fc9dbdab3977248439aa5ea14f13e0f45bbc6' })))));
|
|
1044
1044
|
}
|
|
1045
1045
|
static get is() { return "pds-multiselect"; }
|
|
1046
1046
|
static get encapsulation() { return "shadow"; }
|
|
@@ -59,6 +59,9 @@
|
|
|
59
59
|
color: var(--pine-color-text-label-disabled);
|
|
60
60
|
cursor: not-allowed;
|
|
61
61
|
}
|
|
62
|
+
:host(.has-border):has(input:disabled) label::after {
|
|
63
|
+
cursor: not-allowed;
|
|
64
|
+
}
|
|
62
65
|
:host(.has-border).is-invalid .pds-radio__message--error {
|
|
63
66
|
color: var(--pine-color-text-message-danger);
|
|
64
67
|
}
|
|
@@ -255,6 +258,9 @@ label:has(input:disabled) {
|
|
|
255
258
|
color: var(--pine-color-text-label-disabled);
|
|
256
259
|
cursor: not-allowed;
|
|
257
260
|
}
|
|
261
|
+
:host(.has-image).is-disabled label::after {
|
|
262
|
+
cursor: not-allowed;
|
|
263
|
+
}
|
|
258
264
|
:host(.has-image).is-disabled .pds-radio__message {
|
|
259
265
|
color: var(--pine-color-text-label-disabled);
|
|
260
266
|
}
|
|
@@ -80,11 +80,11 @@ export class PdsRadio {
|
|
|
80
80
|
}
|
|
81
81
|
render() {
|
|
82
82
|
const renderLabelAndMessages = () => [
|
|
83
|
-
h("label", { htmlFor: this.componentId, key: `${this.componentId}-label` }, h("input", { key: '
|
|
83
|
+
h("label", { htmlFor: this.componentId, key: `${this.componentId}-label` }, h("input", { key: 'ca6cb85ace418259f13b6be404e125d4c1c3a778', "aria-describedby": assignDescription(this.componentId, this.invalid, this.helperMessage, this.errorMessage), "aria-invalid": this.invalid ? "true" : undefined, type: "radio", id: this.componentId, name: this.name, value: this.value, checked: this.checked, required: this.required, disabled: this.disabled, onChange: this.handleRadioChange, class: this.hasImage() ? 'visually-hidden' : '' }), h("span", { key: '968c3dcc6b3e18a177db0570a9104b4755827a3e', class: this.hideLabel ? 'visually-hidden' : '' }, this.label)),
|
|
84
84
|
this.helperMessage && (h("div", { key: `${this.componentId}-helper`, class: 'pds-radio__message', id: messageId(this.componentId, 'helper') }, this.helperMessage)),
|
|
85
|
-
this.errorMessage && (h("div", { key: `${this.componentId}-error`, class: `pds-radio__message pds-radio__message--error`, id: messageId(this.componentId, 'error'), "aria-live": "assertive" }, h("pds-icon", { key: '
|
|
85
|
+
this.errorMessage && (h("div", { key: `${this.componentId}-error`, class: `pds-radio__message pds-radio__message--error`, id: messageId(this.componentId, 'error'), "aria-live": "assertive" }, h("pds-icon", { key: '2dec1d43ade25a8ff70301fb661174eff5efadeb', icon: danger, size: "small" }), this.errorMessage))
|
|
86
86
|
];
|
|
87
|
-
return (h(Host, { key: '
|
|
87
|
+
return (h(Host, { key: '75563601db01d7db2a4c4e74364c0bb2d57ac9ae', class: this.classNames() }, this.hasImage() && (h("div", { key: '120ca4dd9d3828cda49c0f7539f429e2aaa89329', class: "pds-radio__image-container", part: "image-container" }, h("slot", { key: 'a03496e1acc3799740aa20342408de97991cad68', name: "image", onSlotchange: () => (this._hasImage = this.hasImageSlot()) }))), this.hasImage() ? (h("div", { class: "pds-radio__content-wrapper" }, renderLabelAndMessages())) : (renderLabelAndMessages())));
|
|
88
88
|
}
|
|
89
89
|
static get is() { return "pds-radio"; }
|
|
90
90
|
static get encapsulation() { return "scoped"; }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
|
-
import { isSpecTest, messageId, exposeTypeProperty } from "../../utils/form";
|
|
2
|
+
import { assignDescription, isSpecTest, messageId, exposeTypeProperty } from "../../utils/form";
|
|
3
3
|
import { danger, enlarge } from "@pine-ds/icons/icons";
|
|
4
4
|
/**
|
|
5
5
|
* @slot action - Content to be displayed in the label area, typically for help icons or links
|
|
@@ -140,6 +140,11 @@ export class PdsSelect {
|
|
|
140
140
|
return null;
|
|
141
141
|
return (h("div", { class: "pds-select__message" }, this.getHelperMessage(), this.getErrorMessage()));
|
|
142
142
|
}
|
|
143
|
+
// The field also renders as invalid whenever an error message is present, via
|
|
144
|
+
// `select:has(~ .pds-select__message .pds-select__error-message)` in the styles.
|
|
145
|
+
isInvalid() {
|
|
146
|
+
return Boolean(this.invalid) || Boolean(this.errorMessage);
|
|
147
|
+
}
|
|
143
148
|
classNames() {
|
|
144
149
|
const classNames = [];
|
|
145
150
|
if (this.invalid) {
|
|
@@ -223,7 +228,7 @@ export class PdsSelect {
|
|
|
223
228
|
}
|
|
224
229
|
render() {
|
|
225
230
|
const hasAction = this.el.querySelector('[slot="action"]') !== null;
|
|
226
|
-
return (h(Host, { key: '
|
|
231
|
+
return (h(Host, { key: 'c74f5e86a09bd3fe6e8048ca103ec9aa66a98fc6', "aria-disabled": this.disabled ? 'true' : null, class: this.classNames(), "has-action": hasAction && !this.hideLabel ? 'true' : null }, h("div", { key: '76de23d6b0d9e32fab48e09a8f6ee3211e196115', class: "pds-select" }, !this.hideLabel && (h("div", { key: '1db87074447cbc819e6b06dd89135d018656a471', class: "pds-select__label-wrapper" }, h("label", { key: 'bc28c3b3361a19ee14a1b79edda736340009d87d', htmlFor: this.componentId }, h("span", { key: 'f0828e0e83c7c0d7cf50e08df4b861dad4df9eb9', class: this.hideLabel ? 'visually-hidden' : '' }, this.label)), hasAction && this.renderAction())), h("select", { key: 'd7d254887c976a95ad1f1da2ea540d6d3f986630', "aria-describedby": assignDescription(this.componentId, this.isInvalid(), this.helperMessage, this.errorMessage), "aria-invalid": this.isInvalid() ? 'true' : undefined, "aria-label": this.hideLabel ? this.label : undefined, autocomplete: this.autocomplete || undefined, class: "pds-select__field", disabled: this.disabled, id: this.componentId, multiple: this.multiple, name: this.name, onBlur: this.onBlur, onChange: this.onSelectUpdate, onFocus: this.onFocus, onKeyDown: this.onKeyDown, part: "select", required: this.required, ref: (el) => (this.selectEl = el) }), h("div", { key: '793a84d41bd5e18d64757238704a053b1135a83c', "aria-hidden": "true", class: "hidden", ref: (el) => (this.slotContainer = el) }, h("slot", { key: '27ed9ff31bbf83fcbd2ed8dd2b23b97422b18d25', onSlotchange: this.handleSlotChange })), this.renderMessages(), !this.multiple && h("pds-icon", { key: '43d415eab0fc8a3c02e19848a5622ea43f04256e', "aria-hidden": "true", class: "pds-select__select-icon", icon: enlarge }))));
|
|
227
232
|
}
|
|
228
233
|
static get is() { return "pds-select"; }
|
|
229
234
|
static get encapsulation() { return "shadow"; }
|
|
@@ -82,9 +82,9 @@ export class PdsSwitch {
|
|
|
82
82
|
this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
|
|
83
83
|
}
|
|
84
84
|
render() {
|
|
85
|
-
return (h(Host, { key: '96ee8c40c04e95b461ba2942b740503897a56b27', class: this.switchClassNames(), "aria-disabled": this.disabled ? 'true' : null }, h("label", { key: '441d6854f2c0b02ecf3d874198b3e0636d68c83b', htmlFor: this.componentId }, h("input", Object.assign({ key: '
|
|
86
|
-
h("div", { key: '
|
|
87
|
-
h("div", { key: '
|
|
85
|
+
return (h(Host, { key: '96ee8c40c04e95b461ba2942b740503897a56b27', class: this.switchClassNames(), "aria-disabled": this.disabled ? 'true' : null }, h("label", { key: '441d6854f2c0b02ecf3d874198b3e0636d68c83b', htmlFor: this.componentId }, h("input", Object.assign({ key: 'ed0c344ab46d83faf902571fcd282a605f5cfbec', "aria-describedby": assignDescription(this.componentId, this.invalid, this.helperMessage, this.errorMessage), "aria-invalid": this.invalid ? "true" : undefined, checked: this.checked, class: "pds-switch__input", disabled: this.disabled, id: this.componentId, name: this.name ? this.name : this.componentId, onChange: this.onSwitchUpdate, required: this.required, type: "checkbox", value: this.value }, this.inheritedAttributes)), h("span", { key: 'a2e89156f56d6c921be9b866823bb4b36710b40f', class: this.hideLabel ? 'visually-hidden' : '' }, this.label)), this.helperMessage &&
|
|
86
|
+
h("div", { key: '1465778f0a69d4c87108a80603d123bf0500911d', class: `pds-switch__message`, id: messageId(this.componentId, 'helper') }, this.helperMessage), this.errorMessage &&
|
|
87
|
+
h("div", { key: '2a652c3019f45a060283f98ea97ac83e17d7de33', class: `pds-switch__message pds-switch__message--error`, id: messageId(this.componentId, 'error'), "aria-live": "assertive" }, h("pds-icon", { key: '438895d9ad8799b540ab239ac90bedcb0231d2f0', icon: danger, size: "small" }), this.errorMessage)));
|
|
88
88
|
}
|
|
89
89
|
static get is() { return "pds-switch"; }
|
|
90
90
|
static get encapsulation() { return "shadow"; }
|
|
@@ -302,9 +302,9 @@ export class PdsTextarea {
|
|
|
302
302
|
render() {
|
|
303
303
|
const value = this.getValue();
|
|
304
304
|
return (h(Host, { key: 'd13869d989752c76c80a46ebb0291df2c0546cc2', "aria-disabled": this.disabled ? 'true' : null, "aria-readonly": this.readonly ? 'true' : null, "has-action": this.hasAction && !this.hideLabel ? 'true' : null }, h("div", { key: '19454f642896485dc22bc5dac8b6ed3b4ae5627a', class: "pds-textarea" }, this.label &&
|
|
305
|
-
h("div", { key: 'def9e117ba3667a542e8cec32c2eabfa701c3305', class: "pds-textarea__label-wrapper" }, h("label", { key: '893a1db325ece460c627e72b765289098823e49e', htmlFor: this.componentId }, h("span", { key: 'd047f17441aa81800057d7403af15f6e38c53f6c', class: this.hideLabel ? 'visually-hidden' : '' }, this.label)), !this.hideLabel && this.renderAction()), h("div", { key: '7d0f2fab56fee9b9d9e0facabc7e607cb6bee23b', class: "pds-textarea__field-wrapper" }, h("textarea", Object.assign({ key: '
|
|
306
|
-
h("p", { key: '
|
|
307
|
-
h("p", { key: '
|
|
305
|
+
h("div", { key: 'def9e117ba3667a542e8cec32c2eabfa701c3305', class: "pds-textarea__label-wrapper" }, h("label", { key: '893a1db325ece460c627e72b765289098823e49e', htmlFor: this.componentId }, h("span", { key: 'd047f17441aa81800057d7403af15f6e38c53f6c', class: this.hideLabel ? 'visually-hidden' : '' }, this.label)), !this.hideLabel && this.renderAction()), h("div", { key: '7d0f2fab56fee9b9d9e0facabc7e607cb6bee23b', class: "pds-textarea__field-wrapper" }, h("textarea", Object.assign({ key: '261e6031c61832acde2d595248ccdc8bd5c84768', ref: (el) => this.nativeTextarea = el, "aria-describedby": assignDescription(this.componentId, this.invalid, this.helperMessage, this.errorMessage), "aria-invalid": this.invalid ? "true" : undefined, autocomplete: this.autocomplete, class: this.textareaClassNames(), disabled: this.disabled, id: this.componentId, maxlength: this.maxLength, name: this.name, placeholder: this.placeholder, readOnly: this.readonly, required: this.required, rows: this.rows, onBlur: this.onBlur, onChange: this.onTextareaChange, onFocus: this.onFocus, onInput: this.onInput, onKeyDown: this.onKeyDown }, this.inheritedAttributes), value), this.renderCharacterCounter()), this.helperMessage &&
|
|
306
|
+
h("p", { key: 'de40f9d13bda3d9a224349b7f4ca38194e7adbb5', class: "pds-textarea__helper-message", id: messageId(this.componentId, 'helper') }, this.helperMessage), this.invalid &&
|
|
307
|
+
h("p", { key: '1306917ce521c3ad0d303d255f9e7aefd0e65de7', "aria-live": "assertive", class: "pds-textarea__error-message", id: messageId(this.componentId, 'error') }, h("pds-icon", { key: '1c9e22b9b4bf84f671797bbfb9080bdbdb7619a7', icon: danger, size: "small" }), this.errorMessage))));
|
|
308
308
|
}
|
|
309
309
|
static get is() { return "pds-textarea"; }
|
|
310
310
|
static get encapsulation() { return "shadow"; }
|
|
@@ -6,14 +6,18 @@ export const messageId = (id, messageType) => {
|
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
8
8
|
* Assign aria-description id to relate messages with form element
|
|
9
|
+
*
|
|
10
|
+
* Returns the error message id when invalid, otherwise the helper message id.
|
|
11
|
+
* Pass only messages the component renders — a described id must exist in the DOM.
|
|
9
12
|
*/
|
|
10
|
-
export const assignDescription = (id, invalid, helperMessage) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
export const assignDescription = (id, invalid, helperMessage, errorMessage) => {
|
|
14
|
+
const hasErrorMessage = Boolean(errorMessage);
|
|
15
|
+
const hasHelperMessage = Boolean(helperMessage);
|
|
16
|
+
if (invalid && hasErrorMessage)
|
|
17
|
+
return messageId(id, 'error');
|
|
18
|
+
if (hasHelperMessage)
|
|
19
|
+
return messageId(id, 'helper');
|
|
20
|
+
return undefined;
|
|
17
21
|
};
|
|
18
22
|
/**
|
|
19
23
|
* Updates the `invalid` prop of a form element based on it's values validity
|
package/dist/docs.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"timestamp": "2026-08-
|
|
2
|
+
"timestamp": "2026-08-27T21:56:56",
|
|
3
3
|
"compiler": {
|
|
4
4
|
"name": "@stencil/core",
|
|
5
5
|
"version": "4.43.5",
|
|
@@ -705,6 +705,10 @@
|
|
|
705
705
|
{
|
|
706
706
|
"name": "part",
|
|
707
707
|
"text": "image - The main image element that represents the avatar component."
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
"name": "part",
|
|
711
|
+
"text": "initials - The text element that renders the avatar's initials, for restyling their color."
|
|
708
712
|
}
|
|
709
713
|
],
|
|
710
714
|
"usage": {},
|
|
@@ -1083,6 +1087,10 @@
|
|
|
1083
1087
|
"name": "image",
|
|
1084
1088
|
"docs": "The main image element that represents the avatar component."
|
|
1085
1089
|
},
|
|
1090
|
+
{
|
|
1091
|
+
"name": "initials",
|
|
1092
|
+
"docs": "The text element that renders the avatar's initials, for restyling their color."
|
|
1093
|
+
},
|
|
1086
1094
|
{
|
|
1087
1095
|
"name": "status",
|
|
1088
1096
|
"docs": ""
|
|
@@ -13703,6 +13711,29 @@
|
|
|
13703
13711
|
"getter": false,
|
|
13704
13712
|
"setter": false
|
|
13705
13713
|
},
|
|
13714
|
+
{
|
|
13715
|
+
"name": "errorMessage",
|
|
13716
|
+
"type": "string",
|
|
13717
|
+
"complexType": {
|
|
13718
|
+
"original": "string",
|
|
13719
|
+
"resolved": "string",
|
|
13720
|
+
"references": {}
|
|
13721
|
+
},
|
|
13722
|
+
"mutable": false,
|
|
13723
|
+
"attr": "error-message",
|
|
13724
|
+
"reflectToAttr": false,
|
|
13725
|
+
"docs": "Error message to display.",
|
|
13726
|
+
"docsTags": [],
|
|
13727
|
+
"values": [
|
|
13728
|
+
{
|
|
13729
|
+
"type": "string"
|
|
13730
|
+
}
|
|
13731
|
+
],
|
|
13732
|
+
"optional": true,
|
|
13733
|
+
"required": false,
|
|
13734
|
+
"getter": false,
|
|
13735
|
+
"setter": false
|
|
13736
|
+
},
|
|
13706
13737
|
{
|
|
13707
13738
|
"name": "fetchTimeout",
|
|
13708
13739
|
"type": "number",
|
|
@@ -13761,6 +13792,29 @@
|
|
|
13761
13792
|
"getter": false,
|
|
13762
13793
|
"setter": false
|
|
13763
13794
|
},
|
|
13795
|
+
{
|
|
13796
|
+
"name": "helperMessage",
|
|
13797
|
+
"type": "string",
|
|
13798
|
+
"complexType": {
|
|
13799
|
+
"original": "string",
|
|
13800
|
+
"resolved": "string",
|
|
13801
|
+
"references": {}
|
|
13802
|
+
},
|
|
13803
|
+
"mutable": false,
|
|
13804
|
+
"attr": "helper-message",
|
|
13805
|
+
"reflectToAttr": false,
|
|
13806
|
+
"docs": "Helper message to display below the combobox.",
|
|
13807
|
+
"docsTags": [],
|
|
13808
|
+
"values": [
|
|
13809
|
+
{
|
|
13810
|
+
"type": "string"
|
|
13811
|
+
}
|
|
13812
|
+
],
|
|
13813
|
+
"optional": true,
|
|
13814
|
+
"required": false,
|
|
13815
|
+
"getter": false,
|
|
13816
|
+
"setter": false
|
|
13817
|
+
},
|
|
13764
13818
|
{
|
|
13765
13819
|
"name": "hideLabel",
|
|
13766
13820
|
"type": "boolean",
|
|
@@ -13790,6 +13844,29 @@
|
|
|
13790
13844
|
"getter": false,
|
|
13791
13845
|
"setter": false
|
|
13792
13846
|
},
|
|
13847
|
+
{
|
|
13848
|
+
"name": "invalid",
|
|
13849
|
+
"type": "boolean",
|
|
13850
|
+
"complexType": {
|
|
13851
|
+
"original": "boolean",
|
|
13852
|
+
"resolved": "boolean",
|
|
13853
|
+
"references": {}
|
|
13854
|
+
},
|
|
13855
|
+
"mutable": false,
|
|
13856
|
+
"attr": "invalid",
|
|
13857
|
+
"reflectToAttr": false,
|
|
13858
|
+
"docs": "If true, the combobox is in an invalid state.",
|
|
13859
|
+
"docsTags": [],
|
|
13860
|
+
"values": [
|
|
13861
|
+
{
|
|
13862
|
+
"type": "boolean"
|
|
13863
|
+
}
|
|
13864
|
+
],
|
|
13865
|
+
"optional": true,
|
|
13866
|
+
"required": false,
|
|
13867
|
+
"getter": false,
|
|
13868
|
+
"setter": false
|
|
13869
|
+
},
|
|
13793
13870
|
{
|
|
13794
13871
|
"name": "label",
|
|
13795
13872
|
"type": "string",
|
|
@@ -17383,6 +17460,35 @@
|
|
|
17383
17460
|
"getter": false,
|
|
17384
17461
|
"setter": false
|
|
17385
17462
|
},
|
|
17463
|
+
{
|
|
17464
|
+
"name": "disableTopLayer",
|
|
17465
|
+
"type": "boolean",
|
|
17466
|
+
"complexType": {
|
|
17467
|
+
"original": "boolean",
|
|
17468
|
+
"resolved": "boolean",
|
|
17469
|
+
"references": {}
|
|
17470
|
+
},
|
|
17471
|
+
"mutable": false,
|
|
17472
|
+
"attr": "disable-top-layer",
|
|
17473
|
+
"reflectToAttr": false,
|
|
17474
|
+
"docs": "Whether the modal opens outside the browser top layer as a non-modal dialog.\nWhen `true` it opens with `dialog.show()` instead of `dialog.showModal()`, so\noverlays rendered elsewhere in the DOM (file pickers, editor menus) can display\nabove it via `z-index`. The page is not made inert and focus is not trapped in\nthis mode. Read when the modal opens; changing it while the modal is open is\nnot supported.",
|
|
17475
|
+
"docsTags": [
|
|
17476
|
+
{
|
|
17477
|
+
"name": "default",
|
|
17478
|
+
"text": "false"
|
|
17479
|
+
}
|
|
17480
|
+
],
|
|
17481
|
+
"default": "false",
|
|
17482
|
+
"values": [
|
|
17483
|
+
{
|
|
17484
|
+
"type": "boolean"
|
|
17485
|
+
}
|
|
17486
|
+
],
|
|
17487
|
+
"optional": false,
|
|
17488
|
+
"required": false,
|
|
17489
|
+
"getter": false,
|
|
17490
|
+
"setter": false
|
|
17491
|
+
},
|
|
17386
17492
|
{
|
|
17387
17493
|
"name": "open",
|
|
17388
17494
|
"type": "boolean",
|
|
@@ -6,14 +6,18 @@ const messageId = (id, messageType) => {
|
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
8
8
|
* Assign aria-description id to relate messages with form element
|
|
9
|
+
*
|
|
10
|
+
* Returns the error message id when invalid, otherwise the helper message id.
|
|
11
|
+
* Pass only messages the component renders — a described id must exist in the DOM.
|
|
9
12
|
*/
|
|
10
|
-
const assignDescription = (id, invalid, helperMessage) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const assignDescription = (id, invalid, helperMessage, errorMessage) => {
|
|
14
|
+
const hasErrorMessage = Boolean(errorMessage);
|
|
15
|
+
const hasHelperMessage = Boolean(helperMessage);
|
|
16
|
+
if (invalid && hasErrorMessage)
|
|
17
|
+
return messageId(id, 'error');
|
|
18
|
+
if (hasHelperMessage)
|
|
19
|
+
return messageId(id, 'helper');
|
|
20
|
+
return undefined;
|
|
17
21
|
};
|
|
18
22
|
/**
|
|
19
23
|
* Updates the `invalid` prop of a form element based on it's values validity
|