@pine-ds/core 4.6.0 → 4.7.1
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/pds-box2.js +1 -1
- package/components/pds-checkbox2.js +1 -1
- package/components/pds-chip2.js +1 -1
- package/components/pds-combobox.js +1 -1
- package/components/pds-copytext.js +1 -1
- package/components/pds-drawer.js +1 -1
- package/components/pds-dropdown-menu-item.js +1 -1
- package/components/pds-dropdown-menu.js +1 -1
- package/components/pds-modal2.js +1 -1
- package/components/pds-multiselect.js +1 -1
- package/components/pds-popover.js +1 -1
- package/components/pds-radio.js +1 -1
- package/components/pds-row.js +1 -1
- package/components/pds-switch.js +1 -1
- package/components/pds-table-cell2.js +1 -1
- package/components/pds-text2.js +1 -1
- package/components/truncation-tooltip.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/pds-box.cjs.entry.js +96 -96
- package/dist/cjs/pds-checkbox.cjs.entry.js +16 -4
- package/dist/cjs/pds-chip.cjs.entry.js +34 -9
- package/dist/cjs/pds-combobox.cjs.entry.js +47 -4
- package/dist/cjs/pds-copytext.cjs.entry.js +7 -2
- package/dist/cjs/pds-drawer.cjs.entry.js +23 -10
- package/dist/cjs/pds-dropdown-menu-item.cjs.entry.js +2 -2
- package/dist/cjs/pds-dropdown-menu.cjs.entry.js +9 -5
- package/dist/cjs/pds-modal.cjs.entry.js +175 -49
- package/dist/cjs/pds-multiselect.cjs.entry.js +40 -9
- package/dist/cjs/pds-popover.cjs.entry.js +170 -26
- package/dist/cjs/pds-radio.cjs.entry.js +1 -1
- package/dist/cjs/pds-row.cjs.entry.js +7 -7
- package/dist/cjs/pds-switch.cjs.entry.js +15 -3
- package/dist/cjs/pds-table-cell.cjs.entry.js +24 -4
- package/dist/cjs/pds-text.cjs.entry.js +17 -9
- package/dist/cjs/pine-core.cjs.js +1 -1
- package/dist/cjs/{truncation-tooltip-CYgQfBLt.js → truncation-tooltip-DO9xli2e.js} +7 -7
- package/dist/collection/components/pds-box/pds-box.js +96 -96
- package/dist/collection/components/pds-checkbox/pds-checkbox.css +4 -0
- package/dist/collection/components/pds-checkbox/pds-checkbox.js +15 -3
- package/dist/collection/components/pds-chip/pds-chip.js +33 -8
- package/dist/collection/components/pds-chip/stories/pds-chip.stories.js +17 -0
- package/dist/collection/components/pds-combobox/pds-combobox.js +48 -5
- package/dist/collection/components/pds-combobox/stories/pds-combobox.stories.js +1 -1
- package/dist/collection/components/pds-copytext/pds-copytext.js +6 -1
- package/dist/collection/components/pds-drawer/pds-drawer.css +4 -1
- package/dist/collection/components/pds-drawer/pds-drawer.js +54 -17
- package/dist/collection/components/pds-drawer/stories/pds-drawer.stories.js +6 -1
- package/dist/collection/components/pds-dropdown-menu/pds-dropdown-menu-item/pds-dropdown-menu-item.js +2 -2
- package/dist/collection/components/pds-dropdown-menu/pds-dropdown-menu.js +15 -5
- package/dist/collection/components/pds-modal/pds-modal.js +180 -50
- package/dist/collection/components/pds-multiselect/pds-multiselect.css +4 -0
- package/dist/collection/components/pds-multiselect/pds-multiselect.js +42 -11
- package/dist/collection/components/pds-popover/pds-popover.js +171 -27
- package/dist/collection/components/pds-radio/pds-radio.css +6 -0
- package/dist/collection/components/pds-row/pds-row.js +7 -7
- package/dist/collection/components/pds-switch/pds-switch.js +15 -3
- package/dist/collection/components/pds-table/pds-table-cell/pds-table-cell.js +23 -3
- package/dist/collection/components/pds-text/pds-text.js +16 -8
- package/dist/collection/utils/truncation-tooltip.js +7 -7
- package/dist/docs.json +48 -9
- package/dist/esm/loader.js +1 -1
- package/dist/esm/pds-box.entry.js +96 -96
- package/dist/esm/pds-checkbox.entry.js +16 -4
- package/dist/esm/pds-chip.entry.js +34 -9
- package/dist/esm/pds-combobox.entry.js +47 -4
- package/dist/esm/pds-copytext.entry.js +7 -2
- package/dist/esm/pds-drawer.entry.js +23 -10
- package/dist/esm/pds-dropdown-menu-item.entry.js +2 -2
- package/dist/esm/pds-dropdown-menu.entry.js +9 -5
- package/dist/esm/pds-modal.entry.js +175 -49
- package/dist/esm/pds-multiselect.entry.js +40 -9
- package/dist/esm/pds-popover.entry.js +171 -27
- package/dist/esm/pds-radio.entry.js +1 -1
- package/dist/esm/pds-row.entry.js +7 -7
- package/dist/esm/pds-switch.entry.js +15 -3
- package/dist/esm/pds-table-cell.entry.js +24 -4
- package/dist/esm/pds-text.entry.js +17 -9
- package/dist/esm/pine-core.js +1 -1
- package/dist/esm/{truncation-tooltip-_902ENWC.js → truncation-tooltip-DRXsdKk1.js} +7 -7
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/pds-box.entry.js +1 -1
- package/dist/esm-es5/pds-checkbox.entry.js +1 -1
- package/dist/esm-es5/pds-chip.entry.js +1 -1
- package/dist/esm-es5/pds-combobox.entry.js +1 -1
- package/dist/esm-es5/pds-copytext.entry.js +1 -1
- package/dist/esm-es5/pds-drawer.entry.js +1 -1
- package/dist/esm-es5/pds-dropdown-menu-item.entry.js +1 -1
- package/dist/esm-es5/pds-dropdown-menu.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-popover.entry.js +1 -1
- package/dist/esm-es5/pds-radio.entry.js +1 -1
- package/dist/esm-es5/pds-row.entry.js +1 -1
- package/dist/esm-es5/pds-switch.entry.js +1 -1
- package/dist/esm-es5/pds-table-cell.entry.js +1 -1
- package/dist/esm-es5/pds-text.entry.js +1 -1
- package/dist/esm-es5/pine-core.js +1 -1
- package/dist/esm-es5/truncation-tooltip-DRXsdKk1.js +1 -0
- package/dist/pine-core/{p-9af131d6.system.entry.js → p-11d98408.system.entry.js} +1 -1
- package/dist/pine-core/p-153ba77b.entry.js +1 -0
- package/dist/pine-core/p-355e4cf9.entry.js +1 -0
- package/dist/pine-core/p-4435fff6.system.entry.js +1 -0
- package/dist/pine-core/p-576cf904.system.entry.js +1 -0
- package/dist/pine-core/{p-4f94b4f1.system.entry.js → p-645a482b.system.entry.js} +1 -1
- package/dist/pine-core/{p-4fa63723.system.entry.js → p-6d603d16.system.entry.js} +1 -1
- package/dist/pine-core/p-74a05bcc.entry.js +1 -0
- package/dist/pine-core/p-7fa66cad.entry.js +1 -0
- package/dist/pine-core/p-80a698ae.entry.js +1 -0
- package/dist/pine-core/{p-bf7ee3b7.system.entry.js → p-80e6f3a0.system.entry.js} +1 -1
- package/dist/pine-core/p-88ff1604.entry.js +1 -0
- package/dist/pine-core/p-92ae6082.entry.js +1 -0
- package/dist/pine-core/{p-6eec23a7.system.entry.js → p-97d0b89e.system.entry.js} +1 -1
- package/dist/pine-core/p-993d1043.entry.js +1 -0
- package/dist/pine-core/p-CuSNnuFu.system.js +1 -1
- package/dist/pine-core/p-JtdHT_W5.js +1 -0
- package/dist/pine-core/p-a787b34a.system.entry.js +1 -0
- package/dist/pine-core/p-a939b471.entry.js +1 -0
- package/dist/pine-core/p-aa032a5e.system.entry.js +1 -0
- package/dist/pine-core/{p-646afbca.system.entry.js → p-b60ac7eb.system.entry.js} +1 -1
- package/dist/pine-core/p-bb73ad66.entry.js +2 -0
- package/dist/pine-core/p-bd26a5e8.entry.js +1 -0
- package/dist/pine-core/p-bf5887e8.system.entry.js +1 -0
- package/dist/pine-core/p-c36b490e.entry.js +1 -0
- package/dist/pine-core/p-c81d8ac8.entry.js +1 -0
- package/dist/pine-core/p-ca0a8f5c.entry.js +1 -0
- package/dist/pine-core/p-ca0d48e8.entry.js +1 -0
- package/dist/pine-core/p-cfc52b95.system.entry.js +1 -0
- package/dist/pine-core/{p-ba1f65c2.system.entry.js → p-d8570b4b.system.entry.js} +1 -1
- package/dist/pine-core/{p-9e0f920a.system.entry.js → p-e7a95a49.system.entry.js} +1 -1
- package/dist/pine-core/p-e803f629.system.entry.js +1 -0
- package/dist/pine-core/{p-df539c42.system.entry.js → p-e836f3ec.system.entry.js} +2 -2
- package/dist/pine-core/{p-b8e8a4ce.entry.js → p-f474d7de.entry.js} +1 -1
- package/dist/pine-core/{p-CBu9UrXr.system.js → p-qhdoK1Jp.system.js} +1 -1
- package/dist/pine-core/pine-core.esm.js +1 -1
- package/dist/types/components/pds-checkbox/pds-checkbox.d.ts +4 -0
- package/dist/types/components/pds-combobox/pds-combobox.d.ts +7 -1
- package/dist/types/components/pds-drawer/pds-drawer.d.ts +21 -9
- package/dist/types/components/pds-dropdown-menu/pds-dropdown-menu.d.ts +1 -0
- package/dist/types/components/pds-modal/pds-modal.d.ts +16 -3
- package/dist/types/components/pds-multiselect/pds-multiselect.d.ts +10 -3
- package/dist/types/components/pds-popover/pds-popover.d.ts +31 -1
- package/dist/types/components/pds-switch/pds-switch.d.ts +4 -0
- package/dist/types/components/pds-table/pds-table-cell/pds-table-cell.d.ts +3 -0
- package/dist/types/components/pds-text/pds-text.d.ts +1 -0
- package/dist/types/components.d.ts +47 -32
- package/dist/types/utils/truncation-tooltip.d.ts +15 -2
- package/dist/vscode.html-data.json +11 -4
- package/hydrate/index.js +698 -253
- package/hydrate/index.mjs +698 -253
- package/package.json +2 -2
- package/dist/esm-es5/truncation-tooltip-_902ENWC.js +0 -1
- package/dist/pine-core/p-01c9b8f3.entry.js +0 -1
- package/dist/pine-core/p-258d5e83.entry.js +0 -1
- package/dist/pine-core/p-3c27088f.system.entry.js +0 -1
- package/dist/pine-core/p-4849fda7.entry.js +0 -1
- package/dist/pine-core/p-4de8f333.entry.js +0 -1
- package/dist/pine-core/p-550c2fd3.entry.js +0 -1
- package/dist/pine-core/p-6bf853c9.entry.js +0 -1
- package/dist/pine-core/p-6d3610f9.entry.js +0 -1
- package/dist/pine-core/p-73eb47fa.entry.js +0 -1
- package/dist/pine-core/p-7f367db4.system.entry.js +0 -1
- package/dist/pine-core/p-84e9b7da.entry.js +0 -1
- package/dist/pine-core/p-9a0083dd.system.entry.js +0 -1
- package/dist/pine-core/p-CnM3cCof.js +0 -1
- package/dist/pine-core/p-a3735199.entry.js +0 -1
- package/dist/pine-core/p-a85a6ab9.system.entry.js +0 -1
- package/dist/pine-core/p-cf08a6dd.system.entry.js +0 -1
- package/dist/pine-core/p-da103a54.system.entry.js +0 -1
- package/dist/pine-core/p-e800a2b1.entry.js +0 -1
- package/dist/pine-core/p-eb5465ce.entry.js +0 -1
- package/dist/pine-core/p-ec5428fb.entry.js +0 -1
- package/dist/pine-core/p-ed4b979e.entry.js +0 -1
- package/dist/pine-core/p-f1f17940.entry.js +0 -2
- package/dist/pine-core/p-f25e4731.system.entry.js +0 -1
|
@@ -249,9 +249,13 @@
|
|
|
249
249
|
transition: background 0.15s;
|
|
250
250
|
}
|
|
251
251
|
.pds-multiselect__option pds-checkbox {
|
|
252
|
+
min-width: var(--pine-dimension-none);
|
|
252
253
|
pointer-events: none;
|
|
253
254
|
width: 100%;
|
|
254
255
|
}
|
|
256
|
+
.pds-multiselect__option pds-chip {
|
|
257
|
+
pointer-events: auto;
|
|
258
|
+
}
|
|
255
259
|
.pds-multiselect__option:hover:not(.pds-multiselect__option--disabled), .pds-multiselect__option.pds-multiselect__option--highlighted:not(.pds-multiselect__option--disabled) {
|
|
256
260
|
background: var(--pine-color-background-muted);
|
|
257
261
|
}
|
|
@@ -345,6 +345,11 @@ export class PdsMultiselect {
|
|
|
345
345
|
e.preventDefault(); // Prevent focus change
|
|
346
346
|
this.toggleOption(option);
|
|
347
347
|
};
|
|
348
|
+
// mousedown already toggled the option. Without this, a click on the chip reaches the
|
|
349
|
+
// checkbox through its label and toggles it a second time.
|
|
350
|
+
this.handleOptionClick = (e) => {
|
|
351
|
+
e.preventDefault();
|
|
352
|
+
};
|
|
348
353
|
this.handleOptionMouseEnter = (index, option) => () => {
|
|
349
354
|
if (option.disabled)
|
|
350
355
|
return;
|
|
@@ -403,6 +408,18 @@ export class PdsMultiselect {
|
|
|
403
408
|
this.internals = this.el.attachInternals();
|
|
404
409
|
}
|
|
405
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* Form Associated Custom Elements API: Called when the form is disabled
|
|
413
|
+
*/
|
|
414
|
+
formDisabledCallback(disabled) {
|
|
415
|
+
// Also fires when this element's own `disabled` attribute is merely present, even as the
|
|
416
|
+
// literal string "false" (a consumer's or React's attribute serialization can write that) —
|
|
417
|
+
// the platform treats any value as disabled, independent of fieldset state. A real disabled
|
|
418
|
+
// fieldset ancestor confirms this is genuinely that, not this element's own attribute.
|
|
419
|
+
if (disabled && !this.el.closest('fieldset[disabled]'))
|
|
420
|
+
return;
|
|
421
|
+
this.disabled = disabled;
|
|
422
|
+
}
|
|
406
423
|
componentWillLoad() {
|
|
407
424
|
this.originalSearchEmitter = this.pdsMultiselectSearch;
|
|
408
425
|
this.syncSelectedItems();
|
|
@@ -501,8 +518,20 @@ export class PdsMultiselect {
|
|
|
501
518
|
var _a;
|
|
502
519
|
(_a = this.slottedTriggerEl) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-expanded', String(this.isOpen));
|
|
503
520
|
}
|
|
504
|
-
disabledChanged() {
|
|
521
|
+
disabledChanged(disabled) {
|
|
522
|
+
var _a, _b;
|
|
505
523
|
this.syncSlottedTrigger();
|
|
524
|
+
// A disabled control can't stay open, or its options could still be toggled.
|
|
525
|
+
if (!disabled || !this.isOpen)
|
|
526
|
+
return;
|
|
527
|
+
const activeElement = document.activeElement;
|
|
528
|
+
const focusInside = !!(((_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.contains(activeElement)) || this.el.contains(activeElement));
|
|
529
|
+
this.closeDropdown();
|
|
530
|
+
// A disabled built-in trigger can't take focus back (falls to <body>, as natively); a slotted
|
|
531
|
+
// trigger without its own disabled property only gets aria-disabled and stays focusable, so
|
|
532
|
+
// focus would otherwise stay stranded on the closed panel's former content.
|
|
533
|
+
if (focusInside)
|
|
534
|
+
(_b = this.activeTriggerEl) === null || _b === void 0 ? void 0 : _b.focus();
|
|
506
535
|
}
|
|
507
536
|
/**
|
|
508
537
|
* Sets focus on the trigger button.
|
|
@@ -512,7 +541,8 @@ export class PdsMultiselect {
|
|
|
512
541
|
(_a = this.activeTriggerEl) === null || _a === void 0 ? void 0 : _a.focus();
|
|
513
542
|
}
|
|
514
543
|
/**
|
|
515
|
-
* Clears all selected values and resets the component.
|
|
544
|
+
* Clears all selected values and resets the component. Works while disabled too, as setting a
|
|
545
|
+
* native control's value from script does.
|
|
516
546
|
*/
|
|
517
547
|
async clear() {
|
|
518
548
|
const hadValues = this.value.length > 0 || this.searchQuery !== '';
|
|
@@ -535,11 +565,12 @@ export class PdsMultiselect {
|
|
|
535
565
|
}
|
|
536
566
|
/**
|
|
537
567
|
* Handle global keyboard events for accessibility.
|
|
538
|
-
* Closes dropdown on Escape key press regardless of focus location.
|
|
568
|
+
* Closes dropdown on Escape key press regardless of focus location. Taken in document's capture
|
|
569
|
+
* phase, before a modal around the multiselect hears it on document and closes too.
|
|
539
570
|
*/
|
|
540
571
|
handleWindowKeyDown(event) {
|
|
541
572
|
var _a;
|
|
542
|
-
if (!this.isOpen)
|
|
573
|
+
if (!this.isOpen || event.defaultPrevented)
|
|
543
574
|
return;
|
|
544
575
|
if (event.key === 'Escape') {
|
|
545
576
|
event.preventDefault();
|
|
@@ -1147,7 +1178,7 @@ export class PdsMultiselect {
|
|
|
1147
1178
|
'pds-multiselect__option--selected': isSelected,
|
|
1148
1179
|
'pds-multiselect__option--create': isCreateOption,
|
|
1149
1180
|
'pds-multiselect__option--disabled': isDisabled || isCreateDisabled,
|
|
1150
|
-
}, role: "option", "aria-selected": isSelected ? 'true' : 'false', "aria-disabled": isDisabled || isCreateDisabled ? 'true' : undefined, "aria-label": isCreateOption ? formatMessage(this.createOptionAriaLabel, { text: option.text }) : undefined, "aria-describedby": hasAction ? `${optionId}-action-description` : undefined, "data-index": index, onMouseDown: this.handleOptionMouseDown(option), onMouseEnter: this.handleOptionMouseEnter(index, option) }, isCreateOption ? (h("pds-box", { class: "pds-multiselect__create-option", "align-items": "center", gap: "xs" }, h("pds-icon", { name: "add", size: "small" }), h("pds-text", null, formatMessage(this.createOptionLabel, { text: option.text })))) : (h("pds-checkbox", { componentId: `${this.componentId}-checkbox-${index}`, checked: isSelected, label: option.text, disabled: isDisabled, style: { pointerEvents: 'none' } }, this.optionDisplay === 'chip' && (h("pds-chip", { slot: "label", sentiment: "subtle", dot: !!option.dotColor, "dot-color": option.dotColor }, option.text)))), hasAction && this.renderOptionAction(option, optionId, isHighlighted)));
|
|
1181
|
+
}, role: "option", "aria-selected": isSelected ? 'true' : 'false', "aria-disabled": isDisabled || isCreateDisabled ? 'true' : undefined, "aria-label": isCreateOption ? formatMessage(this.createOptionAriaLabel, { text: option.text }) : undefined, "aria-describedby": hasAction ? `${optionId}-action-description` : undefined, "data-index": index, onMouseDown: this.handleOptionMouseDown(option), onClick: this.handleOptionClick, onMouseEnter: this.handleOptionMouseEnter(index, option) }, isCreateOption ? (h("pds-box", { class: "pds-multiselect__create-option", "align-items": "center", gap: "xs" }, h("pds-icon", { name: "add", size: "small" }), h("pds-text", null, formatMessage(this.createOptionLabel, { text: option.text })))) : (h("pds-checkbox", { componentId: `${this.componentId}-checkbox-${index}`, checked: isSelected, label: option.text, disabled: isDisabled, style: { pointerEvents: 'none' } }, this.optionDisplay === 'chip' && (h("pds-chip", { slot: "label", sentiment: "subtle", dot: !!option.dotColor, "dot-color": option.dotColor, "max-width": "100%" }, option.text)))), hasAction && this.renderOptionAction(option, optionId, isHighlighted)));
|
|
1151
1182
|
}
|
|
1152
1183
|
renderOptionAction(option, optionId, isHighlighted) {
|
|
1153
1184
|
var _a;
|
|
@@ -1229,10 +1260,10 @@ export class PdsMultiselect {
|
|
|
1229
1260
|
}
|
|
1230
1261
|
render() {
|
|
1231
1262
|
const hasSelections = this.selectedItems.length > 0;
|
|
1232
|
-
return (h(Host, { key: '
|
|
1263
|
+
return (h(Host, { key: 'a7806379c53598d41af91be63ee5bd300cc87755', "aria-disabled": this.disabled ? 'true' : null }, h("div", { key: '0213d40953f1735b84c038e0e0afd1bc289d45ad', class: "pds-multiselect", onFocusout: this.handleContainerFocusOut }, this.label && (h("label", { key: 'fa91c2337cdc9f5dea62173aeaa6b56e118a1316', id: `${this.componentId}-label`, htmlFor: this.componentId, class: {
|
|
1233
1264
|
'pds-multiselect__label': true,
|
|
1234
1265
|
'visually-hidden': this.hideLabel,
|
|
1235
|
-
} }, this.label)), h("div", { key: '
|
|
1266
|
+
} }, this.label)), h("div", { key: '54209b3edfb3583ab1bcecd2b1df973955abfcc3', class: "pds-multiselect__wrapper", ref: el => (this.containerEl = el), style: { width: this.triggerWidth } }, this.slottedTriggerEl ? (h("slot", { name: "trigger" })) : this.selectedDisplay === 'pill' && this.pillPosition === 'inline' ? (h("div", { ref: el => (this.pillInlineTriggerEl = el || undefined), part: "trigger", class: {
|
|
1236
1267
|
'pds-multiselect__trigger': true,
|
|
1237
1268
|
'pds-multiselect__trigger--open': this.isOpen,
|
|
1238
1269
|
'pds-multiselect__trigger--disabled': this.disabled,
|
|
@@ -1248,7 +1279,7 @@ export class PdsMultiselect {
|
|
|
1248
1279
|
}, 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: {
|
|
1249
1280
|
'pds-multiselect__trigger-text': true,
|
|
1250
1281
|
'pds-multiselect__trigger-text--placeholder': !hasSelections || (this.selectedDisplay === 'pill' && this.pillPosition === 'below'),
|
|
1251
|
-
} }, this.getTriggerText()), h("pds-icon", { "aria-hidden": "true", class: "pds-multiselect__icon", icon: enlarge }))), this.renderDropdown()), this.selectedDisplay === 'pill' && this.pillPosition === 'below' && this.renderBelowPills(), h("span", { key: '
|
|
1282
|
+
} }, this.getTriggerText()), h("pds-icon", { "aria-hidden": "true", class: "pds-multiselect__icon", icon: enlarge }))), this.renderDropdown()), this.selectedDisplay === 'pill' && this.pillPosition === 'below' && this.renderBelowPills(), h("span", { key: 'e3c1bb5c484d851b332e994cd2a528ae95cbfc4d', class: "visually-hidden", "aria-live": "polite", "aria-atomic": "true" }, this.removalAnnouncement), this.helperMessage && !(this.errorMessage && this.errorMessage.length > 0) && (h("p", { key: '2009f6487118252ef1ec14170ddd0c6853ad279f', class: "pds-multiselect__helper", id: messageId(this.componentId, 'helper') }, this.helperMessage)), this.errorMessage && (h("p", { key: 'c740f4845ff0c1ccff4633810c1d9d92fb2e8a78', class: "pds-multiselect__error", id: messageId(this.componentId, 'error') }, h("pds-icon", { key: 'b2406ab3b0957a440593b4b986c98476258349be', icon: danger, size: "small" }), this.errorMessage)), h("div", { key: '6d2db6563864c71ab92ed9a8d4133efca23b1c55', style: { display: 'none' } }, h("slot", { key: '2af0e0a7e2410b9850fd15ef524fb388c32dc320' })))));
|
|
1252
1283
|
}
|
|
1253
1284
|
static get is() { return "pds-multiselect"; }
|
|
1254
1285
|
static get encapsulation() { return "shadow"; }
|
|
@@ -2439,7 +2470,7 @@ export class PdsMultiselect {
|
|
|
2439
2470
|
"return": "Promise<void>"
|
|
2440
2471
|
},
|
|
2441
2472
|
"docs": {
|
|
2442
|
-
"text": "Clears all selected values and resets the component.",
|
|
2473
|
+
"text": "Clears all selected values and resets the component. Works while disabled too, as setting a\nnative control's value from script does.",
|
|
2443
2474
|
"tags": []
|
|
2444
2475
|
}
|
|
2445
2476
|
},
|
|
@@ -2488,8 +2519,8 @@ export class PdsMultiselect {
|
|
|
2488
2519
|
return [{
|
|
2489
2520
|
"name": "keydown",
|
|
2490
2521
|
"method": "handleWindowKeyDown",
|
|
2491
|
-
"target": "
|
|
2492
|
-
"capture":
|
|
2522
|
+
"target": "document",
|
|
2523
|
+
"capture": true,
|
|
2493
2524
|
"passive": false
|
|
2494
2525
|
}];
|
|
2495
2526
|
}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
|
-
import { containsComposed } from "../../utils/closest";
|
|
2
|
+
import { closest, containsComposed } from "../../utils/closest";
|
|
3
3
|
import { restoreReflectedDefault } from "../../utils/reflected-attribute-default";
|
|
4
4
|
import { setAttributesIfChanged } from "../../utils/attributes";
|
|
5
5
|
import { cssEscape } from "../../utils/css";
|
|
6
6
|
import { limitRestores } from "../../utils/keep-hydrated";
|
|
7
|
+
/** Open auto popovers, in the order they opened: Escape goes to the last one it applies to. */
|
|
8
|
+
const openAutoPopovers = [];
|
|
9
|
+
/** The focused element, followed down through shadow roots to the control that has focus. */
|
|
10
|
+
function deepActiveElement() {
|
|
11
|
+
var _a;
|
|
12
|
+
let active = document.activeElement;
|
|
13
|
+
while ((_a = active === null || active === void 0 ? void 0 : active.shadowRoot) === null || _a === void 0 ? void 0 : _a.activeElement)
|
|
14
|
+
active = active.shadowRoot.activeElement;
|
|
15
|
+
return active;
|
|
16
|
+
}
|
|
7
17
|
/**
|
|
8
18
|
* @slot trigger - The trigger element for the popover
|
|
9
19
|
* @slot (default) - The content to display inside the popover
|
|
@@ -36,7 +46,7 @@ export class PdsPopover {
|
|
|
36
46
|
*/
|
|
37
47
|
this.triggerObserver = null;
|
|
38
48
|
/**
|
|
39
|
-
* Portal element
|
|
49
|
+
* Portal element: in document.body, or in the open dialog the popover is in
|
|
40
50
|
*/
|
|
41
51
|
this.portalEl = null;
|
|
42
52
|
/**
|
|
@@ -132,6 +142,26 @@ export class PdsPopover {
|
|
|
132
142
|
break;
|
|
133
143
|
}
|
|
134
144
|
};
|
|
145
|
+
/** The focus style copied into a shadow root the panel opened in, which `document.head` can't reach. */
|
|
146
|
+
this.shadowFocusStyle = null;
|
|
147
|
+
/** The dialog the panel was opened in, closed along with it. */
|
|
148
|
+
this.watchedDialog = null;
|
|
149
|
+
this.onDialogClose = () => {
|
|
150
|
+
this.hide();
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Inside a dialog, the panel can sit in a form that wraps the dialog, which a body portal never
|
|
154
|
+
* did. A submit from the panel (a button in it, or Enter in a field in it) is stopped, so the
|
|
155
|
+
* panel behaves as it does in the body.
|
|
156
|
+
*/
|
|
157
|
+
this.handleSubmitFromPanel = (event) => {
|
|
158
|
+
if (!this.portalEl || !containsComposed(event.target, this.portalEl))
|
|
159
|
+
return;
|
|
160
|
+
if (containsComposed(this.portalEl, event.submitter) || containsComposed(this.portalEl, deepActiveElement())) {
|
|
161
|
+
event.preventDefault();
|
|
162
|
+
event.stopPropagation();
|
|
163
|
+
}
|
|
164
|
+
};
|
|
135
165
|
}
|
|
136
166
|
restorePlacementDefault(newValue) {
|
|
137
167
|
this.placement = restoreReflectedDefault(this.el, 'placement', newValue, 'right');
|
|
@@ -194,19 +224,23 @@ export class PdsPopover {
|
|
|
194
224
|
(_a = this.triggerEl) === null || _a === void 0 ? void 0 : _a.addEventListener('click', this.handleTriggerClick);
|
|
195
225
|
this.observeTrigger();
|
|
196
226
|
this.linkTriggerToPortal();
|
|
197
|
-
// Still open after a move: the trigger moved, so the portal follows it
|
|
227
|
+
// Still open after a move: the trigger moved, so the portal follows it, into the dialog it
|
|
228
|
+
// is in now, if any.
|
|
198
229
|
if (this.active) {
|
|
230
|
+
this.placePortal();
|
|
199
231
|
requestAnimationFrame(() => this.handlePopoverPositioning());
|
|
200
232
|
}
|
|
201
233
|
}
|
|
202
234
|
disconnectedCallback() {
|
|
203
235
|
var _a;
|
|
204
236
|
// Moved in one operation (a DOM morph, or a framework reparenting it), the popover is
|
|
205
|
-
// already back in the page. Its portal is
|
|
206
|
-
// where it was.
|
|
237
|
+
// already back in the page. Its portal is outside the popover, so it stays open, with focus
|
|
238
|
+
// where it was; connectedCallback moves it to follow the popover.
|
|
207
239
|
if (this.el.isConnected)
|
|
208
240
|
return;
|
|
209
241
|
this.isComponentMounted = false;
|
|
242
|
+
this.unwatchDialogClose();
|
|
243
|
+
this.forgetOpen();
|
|
210
244
|
// Open, the content sits in the portal; put it back before the portal goes. Only listeners on
|
|
211
245
|
// the popover itself hear the close event now, but those are the ones mirroring its state.
|
|
212
246
|
if (this.active) {
|
|
@@ -227,6 +261,7 @@ export class PdsPopover {
|
|
|
227
261
|
// Clean up all event listeners
|
|
228
262
|
this.removeLightDismissListeners();
|
|
229
263
|
this.removeScrollAndResizeListeners();
|
|
264
|
+
document.removeEventListener('submit', this.handleSubmitFromPanel, true);
|
|
230
265
|
// Clear any pending debounce timers
|
|
231
266
|
this.clearDebounceTimers();
|
|
232
267
|
// Remove portal from DOM
|
|
@@ -271,9 +306,6 @@ export class PdsPopover {
|
|
|
271
306
|
else {
|
|
272
307
|
this.portalEl.id = `${this.componentId}-portal`;
|
|
273
308
|
}
|
|
274
|
-
// Add accessibility attributes for screen readers
|
|
275
|
-
// Note: Native Popover API doesn't add a specific role, keeping semantic HTML
|
|
276
|
-
this.portalEl.setAttribute('aria-modal', 'false'); // Not a modal, can interact with rest of page
|
|
277
309
|
// Append to body
|
|
278
310
|
document.body.appendChild(this.portalEl);
|
|
279
311
|
// Add global focus styles to match Pine design system
|
|
@@ -357,7 +389,27 @@ export class PdsPopover {
|
|
|
357
389
|
// Clear tracking array
|
|
358
390
|
this.movedNodes = [];
|
|
359
391
|
}
|
|
392
|
+
copyFocusStylesInto(root) {
|
|
393
|
+
var _a, _b, _c;
|
|
394
|
+
// Outside a shadow root the document's own style applies, so drop a copy left in one.
|
|
395
|
+
if (!(root instanceof ShadowRoot)) {
|
|
396
|
+
(_a = this.shadowFocusStyle) === null || _a === void 0 ? void 0 : _a.remove();
|
|
397
|
+
this.shadowFocusStyle = null;
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (((_b = this.shadowFocusStyle) === null || _b === void 0 ? void 0 : _b.parentNode) === root || !this.portalEl)
|
|
401
|
+
return;
|
|
402
|
+
const source = document.querySelector(`style[data-pds-popover-focus="${cssEscape(this.portalEl.id)}"]`);
|
|
403
|
+
if (!source)
|
|
404
|
+
return;
|
|
405
|
+
(_c = this.shadowFocusStyle) === null || _c === void 0 ? void 0 : _c.remove();
|
|
406
|
+
this.shadowFocusStyle = source.cloneNode(true);
|
|
407
|
+
root.appendChild(this.shadowFocusStyle);
|
|
408
|
+
}
|
|
360
409
|
removePortal() {
|
|
410
|
+
var _a;
|
|
411
|
+
(_a = this.shadowFocusStyle) === null || _a === void 0 ? void 0 : _a.remove();
|
|
412
|
+
this.shadowFocusStyle = null;
|
|
361
413
|
if (this.portalEl) {
|
|
362
414
|
// Remove the portal element from DOM
|
|
363
415
|
if (this.portalEl.parentNode) {
|
|
@@ -382,9 +434,13 @@ export class PdsPopover {
|
|
|
382
434
|
// Record open timestamp to prevent immediate close from opening click
|
|
383
435
|
this.openTimestamp = Date.now();
|
|
384
436
|
this.linkTriggerToPortal();
|
|
437
|
+
this.placePortal();
|
|
385
438
|
// Update portal content with latest slot content
|
|
386
439
|
this.updatePortalContent();
|
|
387
|
-
// Show portal
|
|
440
|
+
// Show portal. The attribute tells a modal around it that this popover takes Escape first; only
|
|
441
|
+
// an auto popover listens for Escape.
|
|
442
|
+
if (this.popoverType === 'auto')
|
|
443
|
+
this.portalEl.setAttribute('data-pds-popover-open', '');
|
|
388
444
|
this.portalEl.style.display = 'block';
|
|
389
445
|
this.portalEl.style.opacity = '1';
|
|
390
446
|
this.portalEl.style.visibility = 'visible';
|
|
@@ -396,8 +452,10 @@ export class PdsPopover {
|
|
|
396
452
|
});
|
|
397
453
|
// Add scroll and resize listeners for repositioning (always)
|
|
398
454
|
this.addScrollAndResizeListeners();
|
|
455
|
+
document.addEventListener('submit', this.handleSubmitFromPanel, true);
|
|
399
456
|
// Add document listeners for light dismiss and escape key (auto type only)
|
|
400
457
|
if (this.popoverType === 'auto') {
|
|
458
|
+
openAutoPopovers.push(this);
|
|
401
459
|
this.addLightDismissListeners();
|
|
402
460
|
}
|
|
403
461
|
// Emit open event
|
|
@@ -413,12 +471,16 @@ export class PdsPopover {
|
|
|
413
471
|
if (!this.active || !this.portalEl)
|
|
414
472
|
return;
|
|
415
473
|
this.active = false;
|
|
416
|
-
|
|
417
|
-
|
|
474
|
+
this.unwatchDialogClose();
|
|
475
|
+
// Restoring the content drops its focus to the body, so check where focus is first. In a
|
|
476
|
+
// shadow root, document.activeElement is only its host.
|
|
477
|
+
const focusWasInside = containsComposed(this.portalEl, deepActiveElement());
|
|
418
478
|
this.linkTriggerToPortal();
|
|
419
479
|
// Restore content back to original slot positions
|
|
420
480
|
this.restorePortalContent();
|
|
421
|
-
// Hide portal
|
|
481
|
+
// Hide portal. The dark-mode border set in a shadow root is worked out again on the next open.
|
|
482
|
+
this.portalEl.style.border = '';
|
|
483
|
+
this.portalEl.removeAttribute('data-pds-popover-open');
|
|
422
484
|
this.portalEl.style.display = 'none';
|
|
423
485
|
this.portalEl.style.opacity = '0';
|
|
424
486
|
this.portalEl.style.visibility = 'hidden';
|
|
@@ -428,8 +490,10 @@ export class PdsPopover {
|
|
|
428
490
|
this.returnFocusToTrigger();
|
|
429
491
|
}
|
|
430
492
|
// Remove all listeners
|
|
493
|
+
this.forgetOpen();
|
|
431
494
|
this.removeLightDismissListeners();
|
|
432
495
|
this.removeScrollAndResizeListeners();
|
|
496
|
+
document.removeEventListener('submit', this.handleSubmitFromPanel, true);
|
|
433
497
|
// Clear any pending timers
|
|
434
498
|
this.clearDebounceTimers();
|
|
435
499
|
// Emit close event
|
|
@@ -449,6 +513,59 @@ export class PdsPopover {
|
|
|
449
513
|
this.show();
|
|
450
514
|
}
|
|
451
515
|
}
|
|
516
|
+
/**
|
|
517
|
+
* Puts the panel where it shows above everything around the popover. In an open dialog, it goes
|
|
518
|
+
* inside it: a modal dialog sits in the top layer above the body and makes the rest of the page
|
|
519
|
+
* inert, and a non-modal one sits above it by z-index. Right after the popover, it's next in the
|
|
520
|
+
* Tab order. In another component's slot, though, it would have no slot to render in, and in a
|
|
521
|
+
* form its buttons would submit it, so there it goes at the end of the dialog.
|
|
522
|
+
*/
|
|
523
|
+
placePortal() {
|
|
524
|
+
var _a, _b;
|
|
525
|
+
if (!this.portalEl)
|
|
526
|
+
return;
|
|
527
|
+
const dialog = closest('dialog[open]', this.el);
|
|
528
|
+
if (!dialog) {
|
|
529
|
+
this.unwatchDialogClose();
|
|
530
|
+
this.portalEl.style.border = '';
|
|
531
|
+
if (this.portalEl.parentElement !== document.body)
|
|
532
|
+
document.body.appendChild(this.portalEl);
|
|
533
|
+
this.copyFocusStylesInto(document);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
const form = closest('form', this.el);
|
|
537
|
+
const besidePopover = !((_a = this.el.parentElement) === null || _a === void 0 ? void 0 : _a.shadowRoot) && !(form && containsComposed(dialog, form));
|
|
538
|
+
if (besidePopover) {
|
|
539
|
+
if (this.el.nextElementSibling !== this.portalEl)
|
|
540
|
+
(_b = this.el.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(this.portalEl, this.el.nextSibling);
|
|
541
|
+
}
|
|
542
|
+
else if (this.portalEl.parentNode !== dialog) {
|
|
543
|
+
dialog.appendChild(this.portalEl);
|
|
544
|
+
}
|
|
545
|
+
this.watchDialogClose(dialog);
|
|
546
|
+
const root = this.portalEl.getRootNode();
|
|
547
|
+
this.copyFocusStylesInto(root);
|
|
548
|
+
// In a shadow root, the copied dark-mode rule can't see a [data-theme="dark"] on the page.
|
|
549
|
+
this.portalEl.style.border = root instanceof ShadowRoot && closest('[data-theme="dark"]', this.el) ? 'var(--pine-border)' : '';
|
|
550
|
+
}
|
|
551
|
+
forgetOpen() {
|
|
552
|
+
const index = openAutoPopovers.indexOf(this);
|
|
553
|
+
if (index >= 0)
|
|
554
|
+
openAutoPopovers.splice(index, 1);
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Whether an Escape is this popover's. One from a dialog the popover isn't in belongs to that
|
|
558
|
+
* dialog when it's above it: a top-layer dialog or a pds-modal. A plain non-modal dialog inside
|
|
559
|
+
* the popover's modal doesn't close on Escape, so the popover takes it.
|
|
560
|
+
*/
|
|
561
|
+
takesEscapeFrom(event) {
|
|
562
|
+
var _a, _b;
|
|
563
|
+
const origin = ((_b = (_a = event.composedPath) === null || _a === void 0 ? void 0 : _a.call(event)[0]) !== null && _b !== void 0 ? _b : event.target);
|
|
564
|
+
const dialog = closest('dialog[open]', origin);
|
|
565
|
+
if (!dialog || containsComposed(dialog, this.portalEl))
|
|
566
|
+
return true;
|
|
567
|
+
return !(dialog.classList.contains('pds-modal__backdrop') || dialog.matches(':modal'));
|
|
568
|
+
}
|
|
452
569
|
/**
|
|
453
570
|
* Adds light dismiss listeners (click outside and escape key)
|
|
454
571
|
*/
|
|
@@ -457,6 +574,19 @@ export class PdsPopover {
|
|
|
457
574
|
document.addEventListener('click', this.boundClickOutsideHandler, true);
|
|
458
575
|
document.addEventListener('keydown', this.boundEscapeKeyHandler);
|
|
459
576
|
}
|
|
577
|
+
/** Closes the popover when the dialog it opened in closes, so it isn't left open inside. */
|
|
578
|
+
watchDialogClose(dialog) {
|
|
579
|
+
if (this.watchedDialog === dialog)
|
|
580
|
+
return;
|
|
581
|
+
this.unwatchDialogClose();
|
|
582
|
+
this.watchedDialog = dialog;
|
|
583
|
+
dialog.addEventListener('close', this.onDialogClose);
|
|
584
|
+
}
|
|
585
|
+
unwatchDialogClose() {
|
|
586
|
+
var _a;
|
|
587
|
+
(_a = this.watchedDialog) === null || _a === void 0 ? void 0 : _a.removeEventListener('close', this.onDialogClose);
|
|
588
|
+
this.watchedDialog = null;
|
|
589
|
+
}
|
|
460
590
|
/**
|
|
461
591
|
* Removes light dismiss listeners
|
|
462
592
|
*/
|
|
@@ -482,7 +612,7 @@ export class PdsPopover {
|
|
|
482
612
|
* Handles clicks outside the popover for light dismiss (auto type only)
|
|
483
613
|
*/
|
|
484
614
|
handleClickOutside(event) {
|
|
485
|
-
var _a, _b
|
|
615
|
+
var _a, _b;
|
|
486
616
|
// Ignore events that occurred at or before the popover opened
|
|
487
617
|
// This prevents the opening click from immediately closing the popover
|
|
488
618
|
// Convert event.timeStamp (DOMHighResTimeStamp from performance.now()) to epoch time
|
|
@@ -493,16 +623,18 @@ export class PdsPopover {
|
|
|
493
623
|
if (eventTime <= this.openTimestamp) {
|
|
494
624
|
return;
|
|
495
625
|
}
|
|
496
|
-
|
|
626
|
+
// In a shadow root, event.target is only its host.
|
|
627
|
+
const target = ((_b = (_a = event.composedPath) === null || _a === void 0 ? void 0 : _a.call(event)[0]) !== null && _b !== void 0 ? _b : event.target);
|
|
497
628
|
// A datepicker's calendar is portaled to the body: a click in the calendar of a datepicker
|
|
498
|
-
// inside this popover, in its content or its trigger, isn't outside it.
|
|
499
|
-
|
|
629
|
+
// inside this popover, in its content or its trigger, isn't outside it. The target can be
|
|
630
|
+
// inside the calendar's shadow root, so look up across it.
|
|
631
|
+
const calendar = closest('.pds-datepicker-calendar-portal', target);
|
|
500
632
|
const owner = calendar === null || calendar === void 0 ? void 0 : calendar.pdsDatepicker;
|
|
501
633
|
if (owner && (containsComposed(this.portalEl, owner) || containsComposed(this.triggerEl, owner)))
|
|
502
634
|
return;
|
|
503
635
|
// Check if click is outside both the popover portal and the trigger
|
|
504
|
-
const clickedInsidePopover = (
|
|
505
|
-
const clickedInsideTrigger = (
|
|
636
|
+
const clickedInsidePopover = containsComposed(this.portalEl, target);
|
|
637
|
+
const clickedInsideTrigger = containsComposed(this.triggerEl, target);
|
|
506
638
|
if (!clickedInsidePopover && !clickedInsideTrigger) {
|
|
507
639
|
this.hide();
|
|
508
640
|
}
|
|
@@ -523,14 +655,19 @@ export class PdsPopover {
|
|
|
523
655
|
* Mirrors native Popover API: Escape closes and returns focus to trigger
|
|
524
656
|
*/
|
|
525
657
|
handleEscapeKey(event) {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
658
|
+
// A control inside that closes on Escape (a datepicker, a combobox) has handled it already.
|
|
659
|
+
if (event.key !== 'Escape' || event.defaultPrevented)
|
|
660
|
+
return;
|
|
661
|
+
// Like the native Popover API, Escape closes only the top popover: the last one opened that
|
|
662
|
+
// it applies to. Every open popover hears it, so each checks whether it's that one.
|
|
663
|
+
const top = [...openAutoPopovers].reverse().find(popover => popover.takesEscapeFrom(event));
|
|
664
|
+
if (top !== this)
|
|
665
|
+
return;
|
|
666
|
+
// Take the key, so the dialog or modal around it doesn't close too.
|
|
667
|
+
event.preventDefault();
|
|
668
|
+
event.stopPropagation();
|
|
669
|
+
// Close popover and return focus to trigger
|
|
670
|
+
this.hide();
|
|
534
671
|
}
|
|
535
672
|
/**
|
|
536
673
|
* Handles scroll events to reposition the popover (debounced for performance)
|
|
@@ -635,13 +772,20 @@ export class PdsPopover {
|
|
|
635
772
|
}
|
|
636
773
|
this.portalEl.style.top = `${top}px`;
|
|
637
774
|
this.portalEl.style.left = `${left}px`;
|
|
775
|
+
// `position: fixed` measures from the viewport unless an ancestor becomes its containing block,
|
|
776
|
+
// as a modal dialog does with its backdrop filter. Shift by however far it landed from the spot.
|
|
777
|
+
const placed = this.portalEl.getBoundingClientRect();
|
|
778
|
+
if (Math.abs(placed.top - top) > 0.5 || Math.abs(placed.left - left) > 0.5) {
|
|
779
|
+
this.portalEl.style.top = `${2 * top - placed.top}px`;
|
|
780
|
+
this.portalEl.style.left = `${2 * left - placed.left}px`;
|
|
781
|
+
}
|
|
638
782
|
// Reset the repositioning guard after a short delay
|
|
639
783
|
setTimeout(() => {
|
|
640
784
|
this.isRepositioning = false;
|
|
641
785
|
}, 16); // ~1 frame at 60fps
|
|
642
786
|
}
|
|
643
787
|
render() {
|
|
644
|
-
return (h(Host, { key: '
|
|
788
|
+
return (h(Host, { key: 'da8a0c715df1199231b1265085f3f9ae0234032d', id: this.componentId }, h("span", { key: 'f35023492399420829cec2e88556462f5ac1663e', class: "pds-popover__trigger-wrapper" }, h("slot", { key: '38ebe92eebb87665467b3f92ff94dc8095450063', name: "trigger", onSlotchange: this.handleTriggerSlotChange })), h("div", { key: '8917930f4520544d14bbd68b4c7936dd60af19e3', class: "pds-popover__content-slot-wrapper" }, h("slot", { key: '28d3f9112256edd95721a79a7072a9e35a3712bf', onSlotchange: this.handleContentSlotChange }))));
|
|
645
789
|
}
|
|
646
790
|
static get is() { return "pds-popover"; }
|
|
647
791
|
static get encapsulation() { return "shadow"; }
|
|
@@ -181,6 +181,7 @@ label:has(input:disabled) {
|
|
|
181
181
|
column-gap: var(--pine-dimension-xs);
|
|
182
182
|
display: flex;
|
|
183
183
|
flex: 1;
|
|
184
|
+
flex-direction: row;
|
|
184
185
|
padding: var(--pine-dimension-md);
|
|
185
186
|
}
|
|
186
187
|
@media (max-width: 767px) {
|
|
@@ -235,6 +236,11 @@ label:has(input:disabled) {
|
|
|
235
236
|
object-fit: cover;
|
|
236
237
|
width: 100%;
|
|
237
238
|
}
|
|
239
|
+
:host(.has-image) .pds-radio__content-wrapper {
|
|
240
|
+
flex: 1;
|
|
241
|
+
min-width: 0;
|
|
242
|
+
overflow-wrap: anywhere;
|
|
243
|
+
}
|
|
238
244
|
:host(.has-image) .pds-radio__message {
|
|
239
245
|
grid-area: message;
|
|
240
246
|
margin-block-start: 0;
|
|
@@ -51,23 +51,23 @@ export class PdsRow {
|
|
|
51
51
|
}
|
|
52
52
|
render() {
|
|
53
53
|
const rowClasses = `
|
|
54
|
-
${this.alignItems
|
|
54
|
+
${this.alignItems != null && this.alignItems.trim() !== '' ? `pds-align-items-${this.alignItems}` : ''}
|
|
55
55
|
${this.border ? 'pds-row--border' : ''}
|
|
56
|
-
${this.justifyContent
|
|
56
|
+
${this.justifyContent != null && this.justifyContent.trim() !== '' ? `pds-justify-content-${this.justifyContent}` : ''}
|
|
57
57
|
${this.noWrap ? 'pds-row--no-wrap' : ''}
|
|
58
58
|
`;
|
|
59
59
|
const rowInlineStyles = Object.assign(Object.assign(Object.assign(Object.assign({}, (this.colGap && {
|
|
60
|
-
'--row-gap-x': this.colGap
|
|
61
|
-
'--row-gap-y': this.colGap
|
|
60
|
+
'--row-gap-x': this.colGap != null && this.colGap.trim() !== '' ? this.colGapMap[this.colGap] : '',
|
|
61
|
+
'--row-gap-y': this.colGap != null && this.colGap.trim() !== '' ? this.colGapMap[this.colGap] : '',
|
|
62
62
|
})), (this.colGapBlock && {
|
|
63
|
-
'--row-gap-y': this.colGapBlock
|
|
63
|
+
'--row-gap-y': this.colGapBlock != null && this.colGapBlock.trim() !== '' ? this.colGapMap[this.colGapBlock] : '',
|
|
64
64
|
})), (this.colGapInline && {
|
|
65
|
-
'--row-gap-x': this.colGapInline
|
|
65
|
+
'--row-gap-x': this.colGapInline != null && this.colGapInline.trim() !== '' ? this.colGapMap[this.colGapInline] : '',
|
|
66
66
|
})), (this.minHeight && {
|
|
67
67
|
'min-height': this.minHeight,
|
|
68
68
|
}));
|
|
69
69
|
this.hostKeeper.record(`pds-row ${rowClasses}`, rowInlineStyles);
|
|
70
|
-
return h(Host, { key: '
|
|
70
|
+
return h(Host, { key: '452882c1105868f5d392e7cb165311b1abc4a243', class: `pds-row ${rowClasses}`, style: rowInlineStyles });
|
|
71
71
|
}
|
|
72
72
|
static get is() { return "pds-row"; }
|
|
73
73
|
static get originalStyleUrls() {
|
|
@@ -93,6 +93,18 @@ export class PdsSwitch {
|
|
|
93
93
|
this.checked = state === (this.value || 'on');
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Form Associated Custom Elements API: Called when the form is disabled
|
|
98
|
+
*/
|
|
99
|
+
formDisabledCallback(disabled) {
|
|
100
|
+
// Also fires when this element's own `disabled` attribute is merely present, even as the
|
|
101
|
+
// literal string "false" (a consumer's or React's attribute serialization can write that) —
|
|
102
|
+
// the platform treats any value as disabled, independent of fieldset state. A real disabled
|
|
103
|
+
// fieldset ancestor confirms this is genuinely that, not this element's own attribute.
|
|
104
|
+
if (disabled && !this.el.closest('fieldset[disabled]'))
|
|
105
|
+
return;
|
|
106
|
+
this.disabled = disabled;
|
|
107
|
+
}
|
|
96
108
|
componentWillLoad() {
|
|
97
109
|
this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
|
|
98
110
|
this.updateHasLabelSlot();
|
|
@@ -101,9 +113,9 @@ export class PdsSwitch {
|
|
|
101
113
|
const hostClass = this.switchClassNames();
|
|
102
114
|
const ariaDisabled = this.disabled ? 'true' : null;
|
|
103
115
|
this.hostKeeper.record(hostClass, {}, { 'aria-disabled': ariaDisabled });
|
|
104
|
-
return (h(Host, { key: '
|
|
105
|
-
h("div", { key: '
|
|
106
|
-
h("div", { key: '
|
|
116
|
+
return (h(Host, { key: 'b8bd2870be101081aa8a65cdee45397bc4c21435', class: hostClass, "aria-disabled": ariaDisabled }, h("label", { key: '1e223f22f7fc6c576098353ad67dc11500def8b4', htmlFor: this.componentId }, h("input", Object.assign({ key: 'edf59869e165a65b97465ea9de06f7ea82fbc9a6', "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: '1c252b9455471069f8c6ea6c13f2e88c99308b41', class: this.hideLabel ? 'visually-hidden' : '' }, h("slot", { key: 'ce0d471918bd3018f5e55d0d1e6c5c2247790f81', name: "label", onSlotchange: this.updateHasLabelSlot }), !this.hasLabelSlot && this.label)), this.helperMessage &&
|
|
117
|
+
h("div", { key: '64874b15403f1f42344715ac34febdfb8d94042a', class: `pds-switch__message`, id: messageId(this.componentId, 'helper') }, this.helperMessage), this.errorMessage &&
|
|
118
|
+
h("div", { key: '560ea486859124bb0ac2f75ab4bd34b0bca7efbc', class: `pds-switch__message pds-switch__message--error`, id: messageId(this.componentId, 'error'), "aria-live": "assertive" }, h("pds-icon", { key: 'f49caaba976579eb5588e442499595c7dba7ceff', icon: danger, size: "small" }), this.errorMessage)));
|
|
107
119
|
}
|
|
108
120
|
static get is() { return "pds-switch"; }
|
|
109
121
|
static get encapsulation() { return "shadow"; }
|
|
@@ -6,6 +6,7 @@ export class PdsTableCell {
|
|
|
6
6
|
this.scrollContainer = null;
|
|
7
7
|
this.setupRetries = 0;
|
|
8
8
|
this.truncationCleanup = null;
|
|
9
|
+
this.hasLoaded = false;
|
|
9
10
|
/**
|
|
10
11
|
* Determines if the table is currently scrolling.
|
|
11
12
|
* @defaultValue false
|
|
@@ -31,8 +32,23 @@ export class PdsTableCell {
|
|
|
31
32
|
componentWillRender() {
|
|
32
33
|
this.tableRef = this.hostElement.closest('pds-table');
|
|
33
34
|
}
|
|
35
|
+
// Fires again each time the cell is moved (a sort re-appends every row), unlike componentDidLoad,
|
|
36
|
+
// so it re-binds what disconnectedCallback tore down. The tooltip binds to the host, which exists before load.
|
|
37
|
+
connectedCallback() {
|
|
38
|
+
if (!this.hasLoaded)
|
|
39
|
+
return;
|
|
40
|
+
this.tableRef = this.hostElement.closest('pds-table');
|
|
41
|
+
this.cleanupScrollListener();
|
|
42
|
+
if (this.needsScrollShadow) {
|
|
43
|
+
this.setupScrollListener();
|
|
44
|
+
}
|
|
45
|
+
if (this.truncate) {
|
|
46
|
+
this.initTruncationTooltip();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
34
49
|
componentDidLoad() {
|
|
35
|
-
|
|
50
|
+
this.hasLoaded = true;
|
|
51
|
+
if (this.needsScrollShadow) {
|
|
36
52
|
// For responsive tables with fixed columns, set up scroll detection
|
|
37
53
|
// This enables the first column to show a shadow when the table is scrolled horizontally
|
|
38
54
|
this.setupScrollListener();
|
|
@@ -45,6 +61,10 @@ export class PdsTableCell {
|
|
|
45
61
|
this.cleanupScrollListener();
|
|
46
62
|
this.destroyTruncationTooltip();
|
|
47
63
|
}
|
|
64
|
+
get needsScrollShadow() {
|
|
65
|
+
var _a;
|
|
66
|
+
return Boolean(((_a = this.tableRef) === null || _a === void 0 ? void 0 : _a.responsive) && this.tableRef.fixedColumn);
|
|
67
|
+
}
|
|
48
68
|
setupScrollListener() {
|
|
49
69
|
var _a;
|
|
50
70
|
if (!this.tableRef)
|
|
@@ -123,11 +143,11 @@ export class PdsTableCell {
|
|
|
123
143
|
return classNames.join(' ');
|
|
124
144
|
}
|
|
125
145
|
render() {
|
|
126
|
-
return (h(Host, { key: '
|
|
146
|
+
return (h(Host, { key: 'de70a1002cc46e204f87349069b86ca43aa2129a', class: this.classNames(), role: "gridcell", part: "cell", style: this.tableRef &&
|
|
127
147
|
this.tableRef.fixedColumn &&
|
|
128
148
|
this.tableRef.selectable
|
|
129
149
|
? { '--fixed-cell-position': '40px' }
|
|
130
|
-
: {} }, h("slot", { key: '
|
|
150
|
+
: {} }, h("slot", { key: '5e2b3308291e480323d7a1ac0575035758fb3695' })));
|
|
131
151
|
}
|
|
132
152
|
static get is() { return "pds-table-cell"; }
|
|
133
153
|
static get encapsulation() { return "shadow"; }
|