@pine-ds/core 4.6.0 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/components/pds-combobox.js +1 -1
  2. package/components/pds-drawer.js +1 -1
  3. package/components/pds-dropdown-menu.js +1 -1
  4. package/components/pds-modal2.js +1 -1
  5. package/components/pds-multiselect.js +1 -1
  6. package/components/pds-popover.js +1 -1
  7. package/dist/cjs/loader.cjs.js +1 -1
  8. package/dist/cjs/pds-combobox.cjs.entry.js +33 -3
  9. package/dist/cjs/pds-drawer.cjs.entry.js +23 -10
  10. package/dist/cjs/pds-dropdown-menu.cjs.entry.js +9 -5
  11. package/dist/cjs/pds-modal.cjs.entry.js +116 -31
  12. package/dist/cjs/pds-multiselect.cjs.entry.js +6 -5
  13. package/dist/cjs/pds-popover.cjs.entry.js +170 -26
  14. package/dist/cjs/pine-core.cjs.js +1 -1
  15. package/dist/collection/components/pds-combobox/pds-combobox.js +33 -3
  16. package/dist/collection/components/pds-drawer/pds-drawer.css +4 -1
  17. package/dist/collection/components/pds-drawer/pds-drawer.js +54 -17
  18. package/dist/collection/components/pds-drawer/stories/pds-drawer.stories.js +6 -1
  19. package/dist/collection/components/pds-dropdown-menu/pds-dropdown-menu.js +15 -5
  20. package/dist/collection/components/pds-modal/pds-modal.js +117 -32
  21. package/dist/collection/components/pds-multiselect/pds-multiselect.js +8 -7
  22. package/dist/collection/components/pds-popover/pds-popover.js +171 -27
  23. package/dist/docs.json +42 -7
  24. package/dist/esm/loader.js +1 -1
  25. package/dist/esm/pds-combobox.entry.js +33 -3
  26. package/dist/esm/pds-drawer.entry.js +23 -10
  27. package/dist/esm/pds-dropdown-menu.entry.js +9 -5
  28. package/dist/esm/pds-modal.entry.js +116 -31
  29. package/dist/esm/pds-multiselect.entry.js +6 -5
  30. package/dist/esm/pds-popover.entry.js +171 -27
  31. package/dist/esm/pine-core.js +1 -1
  32. package/dist/esm-es5/loader.js +1 -1
  33. package/dist/esm-es5/pds-combobox.entry.js +1 -1
  34. package/dist/esm-es5/pds-drawer.entry.js +1 -1
  35. package/dist/esm-es5/pds-dropdown-menu.entry.js +1 -1
  36. package/dist/esm-es5/pds-modal.entry.js +1 -1
  37. package/dist/esm-es5/pds-multiselect.entry.js +1 -1
  38. package/dist/esm-es5/pds-popover.entry.js +1 -1
  39. package/dist/esm-es5/pine-core.js +1 -1
  40. package/dist/pine-core/p-153ba77b.entry.js +1 -0
  41. package/dist/pine-core/p-21fe6ee1.system.entry.js +1 -0
  42. package/dist/pine-core/p-24fbbb74.system.entry.js +1 -0
  43. package/dist/pine-core/{p-df539c42.system.entry.js → p-5a10784e.system.entry.js} +1 -1
  44. package/dist/pine-core/p-74a05bcc.entry.js +1 -0
  45. package/dist/pine-core/p-92ae6082.entry.js +1 -0
  46. package/dist/pine-core/p-945fb0b1.entry.js +1 -0
  47. package/dist/pine-core/p-CuSNnuFu.system.js +1 -1
  48. package/dist/pine-core/p-a0344e30.entry.js +2 -0
  49. package/dist/pine-core/p-a787b34a.system.entry.js +1 -0
  50. package/dist/pine-core/{p-646afbca.system.entry.js → p-b60ac7eb.system.entry.js} +1 -1
  51. package/dist/pine-core/p-bf5887e8.system.entry.js +1 -0
  52. package/dist/pine-core/p-e21ff692.entry.js +1 -0
  53. package/dist/pine-core/pine-core.esm.js +1 -1
  54. package/dist/types/components/pds-combobox/pds-combobox.d.ts +1 -0
  55. package/dist/types/components/pds-drawer/pds-drawer.d.ts +21 -9
  56. package/dist/types/components/pds-dropdown-menu/pds-dropdown-menu.d.ts +1 -0
  57. package/dist/types/components/pds-modal/pds-modal.d.ts +10 -3
  58. package/dist/types/components/pds-multiselect/pds-multiselect.d.ts +2 -1
  59. package/dist/types/components/pds-popover/pds-popover.d.ts +31 -1
  60. package/dist/types/components.d.ts +45 -30
  61. package/dist/vscode.html-data.json +11 -4
  62. package/hydrate/index.js +369 -90
  63. package/hydrate/index.mjs +369 -90
  64. package/package.json +2 -2
  65. package/dist/pine-core/p-01c9b8f3.entry.js +0 -1
  66. package/dist/pine-core/p-3c27088f.system.entry.js +0 -1
  67. package/dist/pine-core/p-73eb47fa.entry.js +0 -1
  68. package/dist/pine-core/p-7f367db4.system.entry.js +0 -1
  69. package/dist/pine-core/p-9a0083dd.system.entry.js +0 -1
  70. package/dist/pine-core/p-a3735199.entry.js +0 -1
  71. package/dist/pine-core/p-da103a54.system.entry.js +0 -1
  72. package/dist/pine-core/p-ec5428fb.entry.js +0 -1
  73. package/dist/pine-core/p-ed4b979e.entry.js +0 -1
  74. package/dist/pine-core/p-f1f17940.entry.js +0 -2
@@ -80,6 +80,34 @@ function containsComposed(ancestor, node) {
80
80
  }
81
81
  return false;
82
82
  }
83
+ /**
84
+ * Every open modal, with the order it opened in, which ranks top-layer modals and the modals
85
+ * inside them. Kept here rather than queried from the document, which can't see a modal inside
86
+ * another component's shadow root.
87
+ */
88
+ const openModals = new Map();
89
+ let openSequence = 0;
90
+ /** Whether an open auto popover's panel sits in `root`, including inside shadow roots under it. */
91
+ function hasOpenPopover(root) {
92
+ if (root.querySelector('[data-pds-popover-open]'))
93
+ return true;
94
+ return Array.from(root.querySelectorAll('*')).some(el => !!el.shadowRoot && hasOpenPopover(el.shadowRoot));
95
+ }
96
+ /**
97
+ * Whether `a` comes before `b` in the page. `compareDocumentPosition` is arbitrary across a shadow
98
+ * boundary, so each side climbs to its host until both are in the same tree.
99
+ */
100
+ function precedesComposed(a, b) {
101
+ // A document has no host, which ends each climb.
102
+ for (let x = a; x; x = x.getRootNode().host) {
103
+ for (let y = b; y; y = y.getRootNode().host) {
104
+ if (x.getRootNode() === y.getRootNode()) {
105
+ return !!(x.compareDocumentPosition(y) & Node.DOCUMENT_POSITION_FOLLOWING);
106
+ }
107
+ }
108
+ }
109
+ return false;
110
+ }
83
111
  /** The focused element, followed down through shadow roots to the control that has focus. */
84
112
  function deepActiveElement() {
85
113
  var _a;
@@ -95,7 +123,8 @@ export class PdsModal {
95
123
  constructor() {
96
124
  this.focusableElements = [];
97
125
  /**
98
- * Whether the modal can be dismissed by clicking the backdrop
126
+ * Whether the modal can be dismissed by clicking the backdrop, pressing Escape, or the browser's
127
+ * own close request (such as a back gesture)
99
128
  * @default true
100
129
  */
101
130
  this.backdropDismiss = true;
@@ -143,19 +172,33 @@ export class PdsModal {
143
172
  * Stores the list of focusable elements in the modal
144
173
  */
145
174
  this.focusableElementsArray = [];
175
+ // The browser's own close request (an Escape nothing prevented, a back gesture) would close the
176
+ // dialog without updating `open`, so close it through hideModal() instead, or not at all.
177
+ this.handleCancel = (e) => {
178
+ e.preventDefault();
179
+ if (!this.open)
180
+ return;
181
+ // The request reaches the top-layer dialog even when a disableTopLayer modal inside it is on
182
+ // top; that one closes first, as it would on Escape.
183
+ const top = this.innermostOpenModal();
184
+ const target = (top && containsComposed(this.el, top) ? top : this.el);
185
+ if (target.backdropDismiss)
186
+ target.hideModal();
187
+ };
146
188
  this.handleBackdropClick = (e) => {
147
189
  if (!this.backdropDismiss || !this.open)
148
190
  return;
149
- if (e.target.classList.contains('pds-modal__backdrop')) {
191
+ // This modal's own backdrop; a nested modal's backdrop handles its own clicks.
192
+ if (e.target === this.modalRef) {
150
193
  e.stopPropagation();
151
194
  // Only close if this is the innermost modal
152
- if (this.isInnermostModal()) {
195
+ if (this.innermostOpenModal() === this.el) {
153
196
  this.hideModal();
154
197
  }
155
198
  }
156
199
  };
157
200
  this.handleKeyDown = (e) => {
158
- var _a, _b, _c;
201
+ var _a, _b, _c, _d;
159
202
  // If the modal is not open, don't handle any keyboard events
160
203
  if (!this.open)
161
204
  return;
@@ -178,24 +221,39 @@ export class PdsModal {
178
221
  if (!('__pdsActiveElementAtEscape' in eventSnapshot)) {
179
222
  const activeAtDispatch = document.activeElement;
180
223
  eventSnapshot.__pdsActiveElementAtEscape = activeAtDispatch;
224
+ // Followed into shadow roots: for a modal inside one, document.activeElement is only the host.
225
+ eventSnapshot.__pdsDeepActiveElementAtEscape = deepActiveElement();
181
226
  const topLayerDialog = (_a = activeAtDispatch === null || activeAtDispatch === void 0 ? void 0 : activeAtDispatch.closest('dialog')) !== null && _a !== void 0 ? _a : null;
182
227
  eventSnapshot.__pdsTopLayerDialogAtEscape = topLayerDialog;
183
228
  eventSnapshot.__pdsTopLayerDialogWasModalAtEscape = !!(topLayerDialog && topLayerDialog.matches(':modal'));
229
+ // A control that closed on this Escape (a combobox on its own element, a dropdown menu or
230
+ // multiselect in document's capture phase) has prevented it before this bubble listener.
231
+ // Read before any modal prevents it below.
232
+ eventSnapshot.__pdsEscapeHandledInside = e.defaultPrevented;
233
+ // Which modal is innermost is read once too: the inner one closing first would make its
234
+ // outer modal the innermost by the time that modal's listener runs.
235
+ eventSnapshot.__pdsInnermostModalAtEscape = this.innermostOpenModal();
184
236
  }
237
+ if (eventSnapshot.__pdsEscapeHandledInside)
238
+ return;
185
239
  // Leave Escape to a genuinely stacked-above overlay (disableTopLayer's
186
240
  // reason for existing) — not just to anything outside this modal.
187
241
  const active = eventSnapshot.__pdsActiveElementAtEscape;
188
242
  if (this.disableTopLayer &&
189
243
  active &&
190
244
  active !== document.body &&
191
- !this.el.contains(active) &&
192
- this.isStackedAboveOverlay(active, (_b = eventSnapshot.__pdsTopLayerDialogAtEscape) !== null && _b !== void 0 ? _b : null, (_c = eventSnapshot.__pdsTopLayerDialogWasModalAtEscape) !== null && _c !== void 0 ? _c : false)) {
245
+ !containsComposed(this.el, (_b = eventSnapshot.__pdsDeepActiveElementAtEscape) !== null && _b !== void 0 ? _b : active) &&
246
+ this.isStackedAboveOverlay(active, (_c = eventSnapshot.__pdsTopLayerDialogAtEscape) !== null && _c !== void 0 ? _c : null, (_d = eventSnapshot.__pdsTopLayerDialogWasModalAtEscape) !== null && _d !== void 0 ? _d : false)) {
193
247
  return;
194
248
  }
249
+ // An open popover inside takes Escape from its own document listener, which runs after this
250
+ // one, so leave the key for it. Its preventDefault() keeps the native dialog open.
251
+ if (this.modalRef && hasOpenPopover(this.modalRef))
252
+ return;
195
253
  // Always prevent native dialog close behavior
196
254
  e.preventDefault();
197
255
  // Only close if backdropDismiss is enabled and this is the innermost modal
198
- if (this.backdropDismiss && this.isInnermostModal()) {
256
+ if (this.backdropDismiss && eventSnapshot.__pdsInnermostModalAtEscape === this.el) {
199
257
  this.hideModal();
200
258
  }
201
259
  return;
@@ -255,8 +313,6 @@ export class PdsModal {
255
313
  }
256
314
  componentDidLoad() {
257
315
  this.modalRef = this.el.querySelector('.pds-modal__backdrop');
258
- // Add keyboard event listener
259
- document.addEventListener('keydown', this.handleKeyDown);
260
316
  // @Watch('open') only fires on a later change, not the prop's initial
261
317
  // value — a modal mounted with `open` already true (static markup, or a
262
318
  // framework passing it on first render) would otherwise never call
@@ -272,9 +328,18 @@ export class PdsModal {
272
328
  componentDidRender() {
273
329
  unwrapReconnectedContent(this.el.querySelector('.pds-modal'), 'dialog.pds-modal__backdrop', '.pds-modal');
274
330
  }
331
+ // Here rather than in componentDidLoad, which runs once: a modal taken out of the page and put
332
+ // back (a morph or a framework moving it) gets its keyboard handling, and its place among the
333
+ // open modals, back too. Adding the same listener twice is a no-op.
334
+ connectedCallback() {
335
+ document.addEventListener('keydown', this.handleKeyDown);
336
+ if (this.open && !openModals.has(this.el))
337
+ openModals.set(this.el, ++openSequence);
338
+ }
275
339
  disconnectedCallback() {
276
340
  // Clean up event listener
277
341
  document.removeEventListener('keydown', this.handleKeyDown);
342
+ openModals.delete(this.el);
278
343
  }
279
344
  handleOpenChange(newValue) {
280
345
  if (newValue) {
@@ -339,6 +404,9 @@ export class PdsModal {
339
404
  this.modalRef.showModal();
340
405
  }
341
406
  this.open = true;
407
+ // Showing an open modal again doesn't move it above one opened after it.
408
+ if (!openModals.has(this.el))
409
+ openModals.set(this.el, ++openSequence);
342
410
  // Update focusable elements and set initial focus
343
411
  // Using a longer timeout to ensure all components are fully rendered
344
412
  setTimeout(() => {
@@ -401,6 +469,7 @@ export class PdsModal {
401
469
  const focusAlreadyMovedElsewhere = activeElement !== null && activeElement !== document.body && !this.modalRef.contains(activeElement);
402
470
  this.modalRef.close();
403
471
  this.open = false;
472
+ openModals.delete(this.el);
404
473
  // Restore focus to the element that was focused before the modal was opened
405
474
  if (!focusAlreadyMovedElsewhere &&
406
475
  this.previousActiveElement &&
@@ -419,7 +488,9 @@ export class PdsModal {
419
488
  */
420
489
  getBackdropZIndex(modal) {
421
490
  const backdrop = modal.querySelector('.pds-modal__backdrop');
422
- return backdrop ? parseInt(getComputedStyle(backdrop).zIndex, 10) : -1;
491
+ // `auto` (no z-index token loaded) parses to NaN, which no comparison can rank.
492
+ const zIndex = backdrop ? parseInt(getComputedStyle(backdrop).zIndex, 10) : -1;
493
+ return Number.isNaN(zIndex) ? 0 : zIndex;
423
494
  }
424
495
  /**
425
496
  * Whether `active` sits inside a surface actually stacked above this modal.
@@ -446,7 +517,8 @@ export class PdsModal {
446
517
  * lose that evidence depending on listener order.
447
518
  */
448
519
  isStackedAboveOverlay(active, topLayerDialog, topLayerDialogWasModal) {
449
- if (topLayerDialog && topLayerDialog !== this.modalRef && topLayerDialogWasModal) {
520
+ // A top-layer dialog this modal sits inside is underneath it, not an overlay above.
521
+ if (topLayerDialog && topLayerDialog !== this.modalRef && topLayerDialogWasModal && !containsComposed(topLayerDialog, this.el)) {
450
522
  return true;
451
523
  }
452
524
  const ownZIndex = this.getBackdropZIndex(this.el);
@@ -462,24 +534,37 @@ export class PdsModal {
462
534
  return false;
463
535
  }
464
536
  /**
465
- * Checks if this modal is the innermost (highest z-index) modal
537
+ * The open modal that takes Escape or a backdrop click, among those with no other open modal
538
+ * inside them (a nested modal's backdrop can share its outer modal's z-index). A top-layer dialog
539
+ * (or a modal inside one) paints above anything outside it, and within the top layer the last
540
+ * opened is on top. Modals in the same layer (the page, or one top-layer dialog) then rank by
541
+ * the highest backdrop, then the one later in the page.
466
542
  */
467
- isInnermostModal() {
468
- // Find all open modals
469
- const openModals = Array.from(document.querySelectorAll('pds-modal')).filter(modal => modal.open);
470
- if (openModals.length === 0)
471
- return false;
472
- // Get this modal's backdrop element
473
- const thisBackdrop = this.el.querySelector('.pds-modal__backdrop');
474
- if (!thisBackdrop)
475
- return false;
476
- // Get computed z-index of all open modal backdrops
477
- const modalZIndexes = openModals.map(modal => this.getBackdropZIndex(modal));
478
- // Get the highest z-index
479
- const maxZIndex = Math.max(...modalZIndexes);
480
- // Check if this modal's backdrop has the highest z-index
481
- const thisZIndex = this.getBackdropZIndex(this.el);
482
- return thisZIndex === maxZIndex;
543
+ innermostOpenModal() {
544
+ const open = Array.from(openModals.keys()).filter(modal => modal.isConnected);
545
+ const innermost = open.filter(modal => !open.some(other => other !== modal && containsComposed(modal, other)));
546
+ const byDocumentOrder = [...innermost].sort((a, b) => (precedesComposed(a, b) ? -1 : 1));
547
+ // A modal inside a top-layer dialog paints in that dialog's place in the top layer, even when it
548
+ // isn't in the top layer itself (disableTopLayer), so that dialog's open order ranks it first.
549
+ const rank = (modal) => {
550
+ var _a;
551
+ const backdrop = modal.querySelector('.pds-modal__backdrop');
552
+ const topLayerDialog = backdrop ? closest('dialog:modal', backdrop) : null;
553
+ const topLayerModal = topLayerDialog === null || topLayerDialog === void 0 ? void 0 : topLayerDialog.closest('pds-modal');
554
+ const layer = topLayerDialog ? ((_a = (topLayerModal && openModals.get(topLayerModal))) !== null && _a !== void 0 ? _a : 0) : 0;
555
+ return [topLayerDialog ? 1 : 0, layer, this.getBackdropZIndex(modal), byDocumentOrder.indexOf(modal)];
556
+ };
557
+ let top = null;
558
+ let topRank = [-1, -1, -1, -1];
559
+ for (const modal of innermost) {
560
+ const modalRank = rank(modal);
561
+ const above = modalRank.findIndex((value, i) => value !== topRank[i]);
562
+ if (above >= 0 && modalRank[above] > topRank[above]) {
563
+ top = modal;
564
+ topRank = modalRank;
565
+ }
566
+ }
567
+ return top;
483
568
  }
484
569
  /** Whether a modal dialog other than this one sits between the focused element and this modal. */
485
570
  modalDialogAbove(active) {
@@ -519,14 +604,14 @@ export class PdsModal {
519
604
  }
520
605
  render() {
521
606
  const [sizeClass = 'md', customSize] = this.resolveSize();
522
- return (h("dialog", { key: '12ea38928ea287f16ffa33e246caa2bfde6fc130', class: {
607
+ return (h("dialog", { key: '0633d4e8a7cb81f2f9280e754564960a00a4d60b', class: {
523
608
  'pds-modal__backdrop': true,
524
609
  'open': this.open
525
- }, "aria-modal": this.disableTopLayer ? 'false' : 'true', "aria-labelledby": `${this.componentId}-heading`, onClick: this.handleBackdropClick }, h("div", { key: 'b9d83cabda56c315d9115f7030e3bdbcf923ec08', class: {
610
+ }, "aria-modal": this.disableTopLayer ? 'false' : 'true', "aria-labelledby": `${this.componentId}-heading`, onClick: this.handleBackdropClick, onCancel: this.handleCancel }, h("div", { key: '466f8a3476cf066817554f47ec7d3a0e3ab10b89', class: {
526
611
  'pds-modal': true,
527
612
  [`pds-modal--${sizeClass}`]: true,
528
613
  'pds-modal--scrollable': this.scrollable
529
- }, style: customSize !== undefined ? { '--pds-modal-max-width': customSize } : undefined, part: "modal" }, h("slot", { key: '3c5edad1482cb124e503197adf411890573b076d' }))));
614
+ }, style: customSize !== undefined ? { '--pds-modal-max-width': customSize } : undefined, part: "modal" }, h("slot", { key: '01ca45c96540416216a1082bad52b137720f0f4d' }))));
530
615
  }
531
616
  static get is() { return "pds-modal"; }
532
617
  static get originalStyleUrls() {
@@ -556,7 +641,7 @@ export class PdsModal {
556
641
  "name": "default",
557
642
  "text": "true"
558
643
  }],
559
- "text": "Whether the modal can be dismissed by clicking the backdrop"
644
+ "text": "Whether the modal can be dismissed by clicking the backdrop, pressing Escape, or the browser's\nown close request (such as a back gesture)"
560
645
  },
561
646
  "getter": false,
562
647
  "setter": false,
@@ -535,11 +535,12 @@ export class PdsMultiselect {
535
535
  }
536
536
  /**
537
537
  * Handle global keyboard events for accessibility.
538
- * Closes dropdown on Escape key press regardless of focus location.
538
+ * Closes dropdown on Escape key press regardless of focus location. Taken in document's capture
539
+ * phase, before a modal around the multiselect hears it on document and closes too.
539
540
  */
540
541
  handleWindowKeyDown(event) {
541
542
  var _a;
542
- if (!this.isOpen)
543
+ if (!this.isOpen || event.defaultPrevented)
543
544
  return;
544
545
  if (event.key === 'Escape') {
545
546
  event.preventDefault();
@@ -1229,10 +1230,10 @@ export class PdsMultiselect {
1229
1230
  }
1230
1231
  render() {
1231
1232
  const hasSelections = this.selectedItems.length > 0;
1232
- return (h(Host, { key: '0ef6791666063e0d951d28f980b3bca89cf24287', "aria-disabled": this.disabled ? 'true' : null }, h("div", { key: 'f0ccbabfbd2dcf38f6df52f73f2152eb4bd2828e', class: "pds-multiselect", onFocusout: this.handleContainerFocusOut }, this.label && (h("label", { key: '88e01c744644ce1f75c8d5b71dfaeeb79d1ef7df', id: `${this.componentId}-label`, htmlFor: this.componentId, class: {
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: {
1233
1234
  'pds-multiselect__label': true,
1234
1235
  'visually-hidden': this.hideLabel,
1235
- } }, this.label)), h("div", { key: '0bf4a3b1378ff18e6d6b449507ebbae1bfb279e4', 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
+ } }, 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: {
1236
1237
  'pds-multiselect__trigger': true,
1237
1238
  'pds-multiselect__trigger--open': this.isOpen,
1238
1239
  'pds-multiselect__trigger--disabled': this.disabled,
@@ -1248,7 +1249,7 @@ export class PdsMultiselect {
1248
1249
  }, 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
1250
  'pds-multiselect__trigger-text': true,
1250
1251
  '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: '5202a263b219d06891bda739f98db0162bf33c48', class: "visually-hidden", "aria-live": "polite", "aria-atomic": "true" }, this.removalAnnouncement), this.helperMessage && !(this.errorMessage && this.errorMessage.length > 0) && (h("p", { key: '47f7b55863c5b72d41c4ef1893b9364988fc0b56', class: "pds-multiselect__helper", id: messageId(this.componentId, 'helper') }, this.helperMessage)), this.errorMessage && (h("p", { key: '3930dc30b2df7179d178873c470aa1da0f6f258c', class: "pds-multiselect__error", id: messageId(this.componentId, 'error') }, h("pds-icon", { key: 'e31d55db3fd0173c56faa23e34e0be92371983d4', icon: danger, size: "small" }), this.errorMessage)), h("div", { key: 'b3326cc1a5e5886be05327a066e0a7ddd36ccefc', style: { display: 'none' } }, h("slot", { key: '91559cb9510abce6084348a17516460fd8545ef7' })))));
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' })))));
1252
1253
  }
1253
1254
  static get is() { return "pds-multiselect"; }
1254
1255
  static get encapsulation() { return "shadow"; }
@@ -2488,8 +2489,8 @@ export class PdsMultiselect {
2488
2489
  return [{
2489
2490
  "name": "keydown",
2490
2491
  "method": "handleWindowKeyDown",
2491
- "target": "window",
2492
- "capture": false,
2492
+ "target": "document",
2493
+ "capture": true,
2493
2494
  "passive": false
2494
2495
  }];
2495
2496
  }