@pine-ds/core 4.7.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.
Files changed (136) hide show
  1. package/components/pds-box2.js +1 -1
  2. package/components/pds-checkbox2.js +1 -1
  3. package/components/pds-chip2.js +1 -1
  4. package/components/pds-combobox.js +1 -1
  5. package/components/pds-copytext.js +1 -1
  6. package/components/pds-dropdown-menu-item.js +1 -1
  7. package/components/pds-modal2.js +1 -1
  8. package/components/pds-multiselect.js +1 -1
  9. package/components/pds-radio.js +1 -1
  10. package/components/pds-row.js +1 -1
  11. package/components/pds-switch.js +1 -1
  12. package/components/pds-table-cell2.js +1 -1
  13. package/components/pds-text2.js +1 -1
  14. package/components/truncation-tooltip.js +1 -1
  15. package/dist/cjs/pds-box.cjs.entry.js +96 -96
  16. package/dist/cjs/pds-checkbox.cjs.entry.js +16 -4
  17. package/dist/cjs/pds-chip.cjs.entry.js +34 -9
  18. package/dist/cjs/pds-combobox.cjs.entry.js +16 -3
  19. package/dist/cjs/pds-copytext.cjs.entry.js +7 -2
  20. package/dist/cjs/pds-dropdown-menu-item.cjs.entry.js +2 -2
  21. package/dist/cjs/pds-modal.cjs.entry.js +62 -21
  22. package/dist/cjs/pds-multiselect.cjs.entry.js +37 -7
  23. package/dist/cjs/pds-radio.cjs.entry.js +1 -1
  24. package/dist/cjs/pds-row.cjs.entry.js +7 -7
  25. package/dist/cjs/pds-switch.cjs.entry.js +15 -3
  26. package/dist/cjs/pds-table-cell.cjs.entry.js +24 -4
  27. package/dist/cjs/pds-text.cjs.entry.js +17 -9
  28. package/dist/cjs/{truncation-tooltip-CYgQfBLt.js → truncation-tooltip-DO9xli2e.js} +7 -7
  29. package/dist/collection/components/pds-box/pds-box.js +96 -96
  30. package/dist/collection/components/pds-checkbox/pds-checkbox.css +4 -0
  31. package/dist/collection/components/pds-checkbox/pds-checkbox.js +15 -3
  32. package/dist/collection/components/pds-chip/pds-chip.js +33 -8
  33. package/dist/collection/components/pds-chip/stories/pds-chip.stories.js +17 -0
  34. package/dist/collection/components/pds-combobox/pds-combobox.js +17 -4
  35. package/dist/collection/components/pds-combobox/stories/pds-combobox.stories.js +1 -1
  36. package/dist/collection/components/pds-copytext/pds-copytext.js +6 -1
  37. package/dist/collection/components/pds-dropdown-menu/pds-dropdown-menu-item/pds-dropdown-menu-item.js +2 -2
  38. package/dist/collection/components/pds-modal/pds-modal.js +66 -21
  39. package/dist/collection/components/pds-multiselect/pds-multiselect.css +4 -0
  40. package/dist/collection/components/pds-multiselect/pds-multiselect.js +37 -7
  41. package/dist/collection/components/pds-radio/pds-radio.css +6 -0
  42. package/dist/collection/components/pds-row/pds-row.js +7 -7
  43. package/dist/collection/components/pds-switch/pds-switch.js +15 -3
  44. package/dist/collection/components/pds-table/pds-table-cell/pds-table-cell.js +23 -3
  45. package/dist/collection/components/pds-text/pds-text.js +16 -8
  46. package/dist/collection/utils/truncation-tooltip.js +7 -7
  47. package/dist/docs.json +7 -3
  48. package/dist/esm/pds-box.entry.js +96 -96
  49. package/dist/esm/pds-checkbox.entry.js +16 -4
  50. package/dist/esm/pds-chip.entry.js +34 -9
  51. package/dist/esm/pds-combobox.entry.js +16 -3
  52. package/dist/esm/pds-copytext.entry.js +7 -2
  53. package/dist/esm/pds-dropdown-menu-item.entry.js +2 -2
  54. package/dist/esm/pds-modal.entry.js +62 -21
  55. package/dist/esm/pds-multiselect.entry.js +37 -7
  56. package/dist/esm/pds-radio.entry.js +1 -1
  57. package/dist/esm/pds-row.entry.js +7 -7
  58. package/dist/esm/pds-switch.entry.js +15 -3
  59. package/dist/esm/pds-table-cell.entry.js +24 -4
  60. package/dist/esm/pds-text.entry.js +17 -9
  61. package/dist/esm/{truncation-tooltip-_902ENWC.js → truncation-tooltip-DRXsdKk1.js} +7 -7
  62. package/dist/esm-es5/pds-box.entry.js +1 -1
  63. package/dist/esm-es5/pds-checkbox.entry.js +1 -1
  64. package/dist/esm-es5/pds-chip.entry.js +1 -1
  65. package/dist/esm-es5/pds-combobox.entry.js +1 -1
  66. package/dist/esm-es5/pds-copytext.entry.js +1 -1
  67. package/dist/esm-es5/pds-dropdown-menu-item.entry.js +1 -1
  68. package/dist/esm-es5/pds-modal.entry.js +1 -1
  69. package/dist/esm-es5/pds-multiselect.entry.js +1 -1
  70. package/dist/esm-es5/pds-radio.entry.js +1 -1
  71. package/dist/esm-es5/pds-row.entry.js +1 -1
  72. package/dist/esm-es5/pds-switch.entry.js +1 -1
  73. package/dist/esm-es5/pds-table-cell.entry.js +1 -1
  74. package/dist/esm-es5/pds-text.entry.js +1 -1
  75. package/dist/esm-es5/truncation-tooltip-DRXsdKk1.js +1 -0
  76. package/dist/pine-core/{p-9af131d6.system.entry.js → p-11d98408.system.entry.js} +1 -1
  77. package/dist/pine-core/p-355e4cf9.entry.js +1 -0
  78. package/dist/pine-core/p-4435fff6.system.entry.js +1 -0
  79. package/dist/pine-core/p-576cf904.system.entry.js +1 -0
  80. package/dist/pine-core/{p-4f94b4f1.system.entry.js → p-645a482b.system.entry.js} +1 -1
  81. package/dist/pine-core/{p-4fa63723.system.entry.js → p-6d603d16.system.entry.js} +1 -1
  82. package/dist/pine-core/p-7fa66cad.entry.js +1 -0
  83. package/dist/pine-core/p-80a698ae.entry.js +1 -0
  84. package/dist/pine-core/{p-bf7ee3b7.system.entry.js → p-80e6f3a0.system.entry.js} +1 -1
  85. package/dist/pine-core/p-88ff1604.entry.js +1 -0
  86. package/dist/pine-core/{p-6eec23a7.system.entry.js → p-97d0b89e.system.entry.js} +1 -1
  87. package/dist/pine-core/p-993d1043.entry.js +1 -0
  88. package/dist/pine-core/p-CuSNnuFu.system.js +1 -1
  89. package/dist/pine-core/p-JtdHT_W5.js +1 -0
  90. package/dist/pine-core/p-a939b471.entry.js +1 -0
  91. package/dist/pine-core/p-aa032a5e.system.entry.js +1 -0
  92. package/dist/pine-core/p-bb73ad66.entry.js +2 -0
  93. package/dist/pine-core/p-bd26a5e8.entry.js +1 -0
  94. package/dist/pine-core/p-c36b490e.entry.js +1 -0
  95. package/dist/pine-core/p-c81d8ac8.entry.js +1 -0
  96. package/dist/pine-core/p-ca0a8f5c.entry.js +1 -0
  97. package/dist/pine-core/p-ca0d48e8.entry.js +1 -0
  98. package/dist/pine-core/p-cfc52b95.system.entry.js +1 -0
  99. package/dist/pine-core/{p-ba1f65c2.system.entry.js → p-d8570b4b.system.entry.js} +1 -1
  100. package/dist/pine-core/{p-9e0f920a.system.entry.js → p-e7a95a49.system.entry.js} +1 -1
  101. package/dist/pine-core/p-e803f629.system.entry.js +1 -0
  102. package/dist/pine-core/{p-5a10784e.system.entry.js → p-e836f3ec.system.entry.js} +2 -2
  103. package/dist/pine-core/{p-b8e8a4ce.entry.js → p-f474d7de.entry.js} +1 -1
  104. package/dist/pine-core/{p-CBu9UrXr.system.js → p-qhdoK1Jp.system.js} +1 -1
  105. package/dist/pine-core/pine-core.esm.js +1 -1
  106. package/dist/types/components/pds-checkbox/pds-checkbox.d.ts +4 -0
  107. package/dist/types/components/pds-combobox/pds-combobox.d.ts +6 -1
  108. package/dist/types/components/pds-modal/pds-modal.d.ts +6 -0
  109. package/dist/types/components/pds-multiselect/pds-multiselect.d.ts +8 -2
  110. package/dist/types/components/pds-switch/pds-switch.d.ts +4 -0
  111. package/dist/types/components/pds-table/pds-table-cell/pds-table-cell.d.ts +3 -0
  112. package/dist/types/components/pds-text/pds-text.d.ts +1 -0
  113. package/dist/types/components.d.ts +2 -2
  114. package/dist/types/utils/truncation-tooltip.d.ts +15 -2
  115. package/hydrate/index.js +337 -171
  116. package/hydrate/index.mjs +337 -171
  117. package/package.json +2 -2
  118. package/dist/esm-es5/truncation-tooltip-_902ENWC.js +0 -1
  119. package/dist/pine-core/p-21fe6ee1.system.entry.js +0 -1
  120. package/dist/pine-core/p-24fbbb74.system.entry.js +0 -1
  121. package/dist/pine-core/p-258d5e83.entry.js +0 -1
  122. package/dist/pine-core/p-4849fda7.entry.js +0 -1
  123. package/dist/pine-core/p-4de8f333.entry.js +0 -1
  124. package/dist/pine-core/p-550c2fd3.entry.js +0 -1
  125. package/dist/pine-core/p-6bf853c9.entry.js +0 -1
  126. package/dist/pine-core/p-6d3610f9.entry.js +0 -1
  127. package/dist/pine-core/p-84e9b7da.entry.js +0 -1
  128. package/dist/pine-core/p-945fb0b1.entry.js +0 -1
  129. package/dist/pine-core/p-CnM3cCof.js +0 -1
  130. package/dist/pine-core/p-a0344e30.entry.js +0 -2
  131. package/dist/pine-core/p-a85a6ab9.system.entry.js +0 -1
  132. package/dist/pine-core/p-cf08a6dd.system.entry.js +0 -1
  133. package/dist/pine-core/p-e21ff692.entry.js +0 -1
  134. package/dist/pine-core/p-e800a2b1.entry.js +0 -1
  135. package/dist/pine-core/p-eb5465ce.entry.js +0 -1
  136. package/dist/pine-core/p-f25e4731.system.entry.js +0 -1
@@ -72,6 +72,20 @@ function oneRadioPerGroup(elements) {
72
72
  const stops = new Set(groups.map((radios) => { var _a; return (_a = radios.find((radio) => radio.checked)) !== null && _a !== void 0 ? _a : radios[0]; }));
73
73
  return elements.filter((el) => groupedRadio(el) === null || stops.has(el));
74
74
  }
75
+ /** The controls Tab reaches in `root`, in order: visible ones, and one radio per group. */
76
+ function tabbableIn(root) {
77
+ const found = [];
78
+ collectTabbable(root, found);
79
+ // checkVisibility() also drops an element inside a hidden ancestor, whose own computed
80
+ // display isn't none; such an element can't take focus.
81
+ const visible = found.filter(el => {
82
+ if (typeof el.checkVisibility === 'function')
83
+ return el.checkVisibility({ checkVisibilityCSS: true });
84
+ const style = window.getComputedStyle(el);
85
+ return style.display !== 'none' && style.visibility !== 'hidden';
86
+ });
87
+ return oneRadioPerGroup(visible);
88
+ }
75
89
  /** Whether `node` is `ancestor` or inside it, crossing shadow roots, which `Node.contains` doesn't. */
76
90
  function containsComposed(ancestor, node) {
77
91
  for (let current = node; current; current = current instanceof ShadowRoot ? current.host : current.parentNode) {
@@ -355,17 +369,7 @@ export class PdsModal {
355
369
  updateFocusableElements() {
356
370
  if (!this.modalRef)
357
371
  return;
358
- this.focusableElements = [];
359
- collectTabbable(this.modalRef, this.focusableElements);
360
- // checkVisibility() also drops an element inside a hidden ancestor, whose own computed
361
- // display isn't none; such an element can't take focus, so it can't anchor the trap.
362
- this.focusableElements = this.focusableElements.filter(el => {
363
- if (typeof el.checkVisibility === 'function')
364
- return el.checkVisibility({ checkVisibilityCSS: true });
365
- const style = window.getComputedStyle(el);
366
- return style.display !== 'none' && style.visibility !== 'hidden';
367
- });
368
- this.focusableElements = oneRadioPerGroup(this.focusableElements);
372
+ this.focusableElements = tabbableIn(this.modalRef);
369
373
  }
370
374
  /**
371
375
  * Sets focus to the first focusable element in the modal
@@ -389,10 +393,13 @@ export class PdsModal {
389
393
  * Opens the modal
390
394
  */
391
395
  async showModal() {
396
+ var _a;
392
397
  if (this.modalRef) {
393
398
  try {
394
- // Store the currently focused element to restore focus when modal closes
395
- this.previousActiveElement = document.activeElement;
399
+ // Store the currently focused element to restore focus when modal closes. Showing an open
400
+ // modal again (the open watcher does) would record a control inside it instead.
401
+ if (!this.modalRef.open)
402
+ this.previousActiveElement = document.activeElement;
396
403
  // showModal() promotes the dialog to the browser top layer (and makes the
397
404
  // rest of the page inert), which prevents any overlay outside the dialog
398
405
  // from ever painting above it. show() opens a non-modal dialog that stays
@@ -409,9 +416,20 @@ export class PdsModal {
409
416
  openModals.set(this.el, ++openSequence);
410
417
  // Update focusable elements and set initial focus
411
418
  // Using a longer timeout to ensure all components are fully rendered
419
+ const openedAs = (_a = openModals.get(this.el)) !== null && _a !== void 0 ? _a : 0;
412
420
  setTimeout(() => {
413
421
  var _a, _b;
414
422
  this.updateFocusableElements();
423
+ // A modal opened above this one in the meantime has focus; don't take it back. Not this
424
+ // modal itself (moving it gives it a new place), and not a disableTopLayer modal outside
425
+ // it while this one is in the top layer, which sits below it.
426
+ const openedAbove = Array.from(openModals).some(([modal, sequence]) => sequence > openedAs &&
427
+ modal !== this.el &&
428
+ (containsComposed(this.el, modal) || !modal.disableTopLayer || this.disableTopLayer));
429
+ if (openedAbove) {
430
+ this.pdsModalOpen.emit();
431
+ return;
432
+ }
415
433
  if (this.disableInitialFocus) {
416
434
  // show()/showModal() also move focus into the dialog natively (the
417
435
  // HTML spec's "dialog focusing steps") — that native step isn't
@@ -455,6 +473,7 @@ export class PdsModal {
455
473
  * Closes the modal
456
474
  */
457
475
  async hideModal() {
476
+ var _a;
458
477
  if (this.modalRef) {
459
478
  try {
460
479
  // Capture before close(): with the async task queue, a prop change
@@ -470,11 +489,18 @@ export class PdsModal {
470
489
  this.modalRef.close();
471
490
  this.open = false;
472
491
  openModals.delete(this.el);
473
- // Restore focus to the element that was focused before the modal was opened
474
- if (!focusAlreadyMovedElsewhere &&
475
- this.previousActiveElement &&
476
- typeof this.previousActiveElement.focus === 'function') {
477
- this.previousActiveElement.focus();
492
+ // Restore focus to the element that was focused before the modal was opened. If that's
493
+ // gone or can't take focus (disabled, hidden, or nothing), fall back to the open modal now
494
+ // on top, so focus doesn't land on an inert page behind it.
495
+ if (!focusAlreadyMovedElsewhere) {
496
+ const previous = this.previousActiveElement;
497
+ if (previous && previous !== document.body && previous.isConnected)
498
+ (_a = previous.focus) === null || _a === void 0 ? void 0 : _a.call(previous);
499
+ const active = deepActiveElement();
500
+ // document.body isn't a real restore target — it's just where focus lands when nothing
501
+ // was focused before opening, so landing back there never counts as a successful restore.
502
+ if (!previous || previous === document.body || !containsComposed(previous, active) || containsComposed(this.el, active))
503
+ this.focusTopModal();
478
504
  }
479
505
  this.pdsModalClose.emit();
480
506
  }
@@ -483,6 +509,21 @@ export class PdsModal {
483
509
  }
484
510
  }
485
511
  }
512
+ /**
513
+ * Focuses the first control of the open modal now on top, when the page behind it is inert: that
514
+ * modal is in the top layer (or paints there inside a top-layer one), or it wraps this one. A
515
+ * non-modal one over an interactive page, like a drawer, is left alone.
516
+ */
517
+ focusTopModal() {
518
+ var _a;
519
+ const top = this.innermostOpenModal();
520
+ const dialog = top === null || top === void 0 ? void 0 : top.querySelector('.pds-modal__backdrop');
521
+ if (!dialog)
522
+ return;
523
+ if (!closest('dialog:modal', dialog) && !containsComposed(top, this.el))
524
+ return;
525
+ (_a = tabbableIn(dialog).find(el => !containsComposed(this.el, el))) === null || _a === void 0 ? void 0 : _a.focus();
526
+ }
486
527
  /**
487
528
  * Gets the z-index of a modal's backdrop element
488
529
  */
@@ -604,14 +645,14 @@ export class PdsModal {
604
645
  }
605
646
  render() {
606
647
  const [sizeClass = 'md', customSize] = this.resolveSize();
607
- return (h("dialog", { key: '0633d4e8a7cb81f2f9280e754564960a00a4d60b', class: {
648
+ return (h("dialog", { key: '0b187f36910a859afe57b891f1ebffd1d2d49ab7', class: {
608
649
  'pds-modal__backdrop': true,
609
650
  'open': this.open
610
- }, "aria-modal": this.disableTopLayer ? 'false' : 'true', "aria-labelledby": `${this.componentId}-heading`, onClick: this.handleBackdropClick, onCancel: this.handleCancel }, h("div", { key: '466f8a3476cf066817554f47ec7d3a0e3ab10b89', class: {
651
+ }, "aria-modal": this.disableTopLayer ? 'false' : 'true', "aria-labelledby": `${this.componentId}-heading`, onClick: this.handleBackdropClick, onCancel: this.handleCancel }, h("div", { key: 'f5e652d4dae0e7c272b37b63eb9c65f04c69536a', class: {
611
652
  'pds-modal': true,
612
653
  [`pds-modal--${sizeClass}`]: true,
613
654
  'pds-modal--scrollable': this.scrollable
614
- }, style: customSize !== undefined ? { '--pds-modal-max-width': customSize } : undefined, part: "modal" }, h("slot", { key: '01ca45c96540416216a1082bad52b137720f0f4d' }))));
655
+ }, style: customSize !== undefined ? { '--pds-modal-max-width': customSize } : undefined, part: "modal" }, h("slot", { key: 'a954e1694741f78230599c476b270079797a263e' }))));
615
656
  }
616
657
  static get is() { return "pds-modal"; }
617
658
  static get originalStyleUrls() {
@@ -848,6 +889,10 @@ export class PdsModal {
848
889
  "HTMLElement": {
849
890
  "location": "global",
850
891
  "id": "global::HTMLElement"
892
+ },
893
+ "HTMLPdsModalElement": {
894
+ "location": "global",
895
+ "id": "global::HTMLPdsModalElement"
851
896
  }
852
897
  },
853
898
  "return": "Promise<void>"
@@ -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 !== '';
@@ -1148,7 +1178,7 @@ export class PdsMultiselect {
1148
1178
  'pds-multiselect__option--selected': isSelected,
1149
1179
  'pds-multiselect__option--create': isCreateOption,
1150
1180
  'pds-multiselect__option--disabled': isDisabled || isCreateDisabled,
1151
- }, 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)));
1152
1182
  }
1153
1183
  renderOptionAction(option, optionId, isHighlighted) {
1154
1184
  var _a;
@@ -1230,10 +1260,10 @@ export class PdsMultiselect {
1230
1260
  }
1231
1261
  render() {
1232
1262
  const hasSelections = this.selectedItems.length > 0;
1233
- return (h(Host, { key: 'fcc35a82c16d5cf35a49ce997f19618104f9cc45', "aria-disabled": this.disabled ? 'true' : null }, h("div", { key: '72d1fdf759d9173f54bac80ec50aff651fd2b357', class: "pds-multiselect", onFocusout: this.handleContainerFocusOut }, this.label && (h("label", { key: 'e28f02c2beb23dc2c0deefadbd0645b20d938d91', id: `${this.componentId}-label`, htmlFor: this.componentId, class: {
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: {
1234
1264
  'pds-multiselect__label': true,
1235
1265
  'visually-hidden': this.hideLabel,
1236
- } }, this.label)), h("div", { key: '06539bf2c4b8da2889505a9f042d5cd6721b1853', 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: {
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: {
1237
1267
  'pds-multiselect__trigger': true,
1238
1268
  'pds-multiselect__trigger--open': this.isOpen,
1239
1269
  'pds-multiselect__trigger--disabled': this.disabled,
@@ -1249,7 +1279,7 @@ export class PdsMultiselect {
1249
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: {
1250
1280
  'pds-multiselect__trigger-text': true,
1251
1281
  'pds-multiselect__trigger-text--placeholder': !hasSelections || (this.selectedDisplay === 'pill' && this.pillPosition === 'below'),
1252
- } }, 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: '3364fc00bc744fcd599436a9cb6dc563564d89d9', class: "visually-hidden", "aria-live": "polite", "aria-atomic": "true" }, this.removalAnnouncement), this.helperMessage && !(this.errorMessage && this.errorMessage.length > 0) && (h("p", { key: 'bf712c65b9acb66e2998a43686fed408fc1ff48a', class: "pds-multiselect__helper", id: messageId(this.componentId, 'helper') }, this.helperMessage)), this.errorMessage && (h("p", { key: 'b485db6c2c3ae312cce2b90db60e850ad6dfdcf5', class: "pds-multiselect__error", id: messageId(this.componentId, 'error') }, h("pds-icon", { key: '20daf861cf9584f33f5a9574e9581acc487e7dfe', icon: danger, size: "small" }), this.errorMessage)), h("div", { key: '018d333254771695a8c191f1cea40af6e78427a2', style: { display: 'none' } }, h("slot", { key: '2ef4a01fbe5d294a9ead5cc1183c28341834539b' })))));
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' })))));
1253
1283
  }
1254
1284
  static get is() { return "pds-multiselect"; }
1255
1285
  static get encapsulation() { return "shadow"; }
@@ -2440,7 +2470,7 @@ export class PdsMultiselect {
2440
2470
  "return": "Promise<void>"
2441
2471
  },
2442
2472
  "docs": {
2443
- "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.",
2444
2474
  "tags": []
2445
2475
  }
2446
2476
  },
@@ -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 !== undefined && this.alignItems.trim() !== '' ? `pds-align-items-${this.alignItems}` : ''}
54
+ ${this.alignItems != null && this.alignItems.trim() !== '' ? `pds-align-items-${this.alignItems}` : ''}
55
55
  ${this.border ? 'pds-row--border' : ''}
56
- ${this.justifyContent !== undefined && this.justifyContent.trim() !== '' ? `pds-justify-content-${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 !== undefined && this.colGap.trim() !== '' ? this.colGapMap[this.colGap] : '',
61
- '--row-gap-y': this.colGap !== undefined && this.colGap.trim() !== '' ? this.colGapMap[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 !== undefined && this.colGapBlock.trim() !== '' ? this.colGapMap[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 !== undefined && this.colGapInline.trim() !== '' ? this.colGapMap[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: '78a505fef7132f9545916155d2485a6d2df8f4a5', class: `pds-row ${rowClasses}`, style: rowInlineStyles });
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: 'ee8576e523348ff9eed1b6087626849bb0966608', class: hostClass, "aria-disabled": ariaDisabled }, h("label", { key: '09433b5356d718be65f4f2eb61f35fff1d000e10', htmlFor: this.componentId }, h("input", Object.assign({ key: 'f996a0fad56119674cfb7d95e1444bf411b64396', "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: '4b23305d3cc0f5b37b23c6b79a14cfba57c16816', class: this.hideLabel ? 'visually-hidden' : '' }, h("slot", { key: '258b5ccf0d4b01518df3a37772d694cb37569ffa', name: "label", onSlotchange: this.updateHasLabelSlot }), !this.hasLabelSlot && this.label)), this.helperMessage &&
105
- h("div", { key: 'c8196fa2ce832de3a8c6d987a78fd65d791c4c59', class: `pds-switch__message`, id: messageId(this.componentId, 'helper') }, this.helperMessage), this.errorMessage &&
106
- h("div", { key: '948894dd2e642689af6cad545a0b31f7c4711d87', class: `pds-switch__message pds-switch__message--error`, id: messageId(this.componentId, 'error'), "aria-live": "assertive" }, h("pds-icon", { key: 'd4b72b49bfd38a396b8f7c0686e1b2ef92d65491', icon: danger, size: "small" }), this.errorMessage)));
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
- if (this.tableRef && this.tableRef.responsive && this.tableRef.fixedColumn) {
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: 'bedaeeb5723299656f872a760ed1dd80c7fe8793', class: this.classNames(), role: "gridcell", part: "cell", style: this.tableRef &&
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: '45182ee3e004097660432f552780b3d27671bd46' })));
150
+ : {} }, h("slot", { key: '5e2b3308291e480323d7a1ac0575035758fb3695' })));
131
151
  }
132
152
  static get is() { return "pds-table-cell"; }
133
153
  static get encapsulation() { return "shadow"; }
@@ -23,9 +23,10 @@ export class PdsText {
23
23
  }
24
24
  validateSize(newValue) {
25
25
  // Skip when the prop is omitted or explicitly cleared (an empty string is a
26
- // common "unset" sentinel). Any other unsupported value — including a
26
+ // common "unset" sentinel), or its attribute was removed (Stencil sets the
27
+ // prop to `null`). Any other unsupported value — including a
27
28
  // whitespace-only string — is a developer mistake worth warning about.
28
- if (newValue === undefined || newValue === '') {
29
+ if (newValue == null || newValue === '') {
29
30
  return;
30
31
  }
31
32
  if (!TEXT_SIZES.includes(newValue)) {
@@ -38,6 +39,13 @@ export class PdsText {
38
39
  // any attempt to apply an unknown size class. @Watch covers later changes.
39
40
  this.validateSize(this.size);
40
41
  }
42
+ // componentDidLoad runs once, so a moved element re-binds here what disconnectedCallback tore
43
+ // down. Before the first render there's no contentEl yet, and componentDidLoad binds it.
44
+ connectedCallback() {
45
+ if (this.truncate && this.contentEl) {
46
+ this.initTruncationTooltip();
47
+ }
48
+ }
41
49
  componentDidLoad() {
42
50
  if (this.truncate) {
43
51
  this.initTruncationTooltip();
@@ -67,23 +75,23 @@ export class PdsText {
67
75
  const Tag = this.tag;
68
76
  const typeClasses = `
69
77
  pds-text
70
- ${this.align !== undefined && this.align.trim() !== ''
78
+ ${this.align != null && this.align.trim() !== ''
71
79
  ? `pds-text--align-${this.align}`
72
80
  : ''}
73
- ${this.gutter !== undefined && this.gutter.trim() !== ''
81
+ ${this.gutter != null && this.gutter.trim() !== ''
74
82
  ? `pds-text--gutter-${this.gutter}`
75
83
  : ''}
76
- ${this.size !== undefined && this.size.trim() !== ''
84
+ ${this.size != null && this.size.trim() !== ''
77
85
  ? `pds-text--size-${this.size}`
78
86
  : ''}
79
- ${this.weight !== undefined && this.weight.trim() !== ''
87
+ ${this.weight != null && this.weight.trim() !== ''
80
88
  ? `pds-text--weight-${this.weight}`
81
89
  : ''}
82
- ${this.decoration !== undefined && this.decoration.trim() !== ''
90
+ ${this.decoration != null && this.decoration.trim() !== ''
83
91
  ? `pds-text--decoration-${this.decoration}`
84
92
  : ''}
85
93
  `;
86
- return (h(Tag, { key: '6ae89af63963745cd4e8fa734a62f37bc27c59ac', ref: (el) => (this.contentEl = el), style: this.color && setColor(this.color), class: typeClasses, part: "content" }, h("slot", { key: '008f5852aeb4b43cff1a2fea9be9d8fbba9f7934' })));
94
+ return (h(Tag, { key: '6460288f1d395080a39aec214e55cab87fdaec9f', ref: (el) => (this.contentEl = el), style: this.color && setColor(this.color), class: typeClasses, part: "content" }, h("slot", { key: 'a8be0d96f72d8ee44288d7c8615155dc68d92663' })));
87
95
  }
88
96
  static get is() { return "pds-text"; }
89
97
  static get encapsulation() { return "shadow"; }
@@ -69,7 +69,7 @@ function isOverflowing(el) {
69
69
  * @returns A cleanup function that removes all listeners, observers, and DOM elements.
70
70
  */
71
71
  export function setupTruncationTooltip(options) {
72
- const { hostEl, contentEl, getTooltipText, placement = 'top', manageTabIndex = true } = options;
72
+ const { hostEl, contentEl, getTooltipText, placement = 'top', reference = hostEl, manageTabIndex = true, focusEl = hostEl } = options;
73
73
  injectStyles();
74
74
  let portalEl = null;
75
75
  let isHovering = false;
@@ -164,7 +164,7 @@ export function setupTruncationTooltip(options) {
164
164
  if (!portalEl)
165
165
  return;
166
166
  try {
167
- const { x, y } = await computePosition(hostEl, portalEl, {
167
+ const { x, y } = await computePosition(reference, portalEl, {
168
168
  placement,
169
169
  strategy: 'fixed',
170
170
  middleware: [offset(4), flip(), shift({ padding: 5 })],
@@ -177,7 +177,7 @@ export function setupTruncationTooltip(options) {
177
177
  catch (_a) {
178
178
  // Fallback: position above the element with bounds checking
179
179
  if (portalEl) {
180
- const rect = hostEl.getBoundingClientRect();
180
+ const rect = reference.getBoundingClientRect();
181
181
  const portalRect = portalEl.getBoundingClientRect();
182
182
  const padding = 5;
183
183
  // Ensure tooltip stays within viewport bounds
@@ -263,8 +263,8 @@ export function setupTruncationTooltip(options) {
263
263
  }
264
264
  hostEl.addEventListener('mouseenter', handleMouseEnter);
265
265
  hostEl.addEventListener('mouseleave', handleMouseLeave);
266
- hostEl.addEventListener('focusin', handleFocusIn);
267
- hostEl.addEventListener('focusout', handleFocusOut);
266
+ focusEl.addEventListener('focusin', handleFocusIn);
267
+ focusEl.addEventListener('focusout', handleFocusOut);
268
268
  // Return cleanup function
269
269
  return () => {
270
270
  disposed = true;
@@ -284,8 +284,8 @@ export function setupTruncationTooltip(options) {
284
284
  }
285
285
  hostEl.removeEventListener('mouseenter', handleMouseEnter);
286
286
  hostEl.removeEventListener('mouseleave', handleMouseLeave);
287
- hostEl.removeEventListener('focusin', handleFocusIn);
288
- hostEl.removeEventListener('focusout', handleFocusOut);
287
+ focusEl.removeEventListener('focusin', handleFocusIn);
288
+ focusEl.removeEventListener('focusout', handleFocusOut);
289
289
  removePortal();
290
290
  };
291
291
  }
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-10-21T00:46:53",
2
+ "timestamp": "2026-10-22T21:37:51",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.43.5",
@@ -14659,7 +14659,7 @@
14659
14659
  },
14660
14660
  "signature": "clear() => Promise<void>",
14661
14661
  "parameters": [],
14662
- "docs": "Clears the selected value and resets the component.",
14662
+ "docs": "Clears the selected value and resets the component. Works while disabled too, as setting a\nnative control's value from script does.",
14663
14663
  "docsTags": []
14664
14664
  },
14665
14665
  {
@@ -20004,6 +20004,10 @@
20004
20004
  "HTMLElement": {
20005
20005
  "location": "global",
20006
20006
  "id": "global::HTMLElement"
20007
+ },
20008
+ "HTMLPdsModalElement": {
20009
+ "location": "global",
20010
+ "id": "global::HTMLPdsModalElement"
20007
20011
  }
20008
20012
  },
20009
20013
  "return": "Promise<void>"
@@ -21587,7 +21591,7 @@
21587
21591
  },
21588
21592
  "signature": "clear() => Promise<void>",
21589
21593
  "parameters": [],
21590
- "docs": "Clears all selected values and resets the component.",
21594
+ "docs": "Clears all selected values and resets the component. Works while disabled too, as setting a\nnative control's value from script does.",
21591
21595
  "docsTags": []
21592
21596
  },
21593
21597
  {