|
13 | 13 | import { |
14 | 14 | CSSResultArray, |
15 | 15 | html, |
| 16 | + nothing, |
16 | 17 | PropertyValues, |
17 | 18 | SpectrumElement, |
18 | 19 | TemplateResult, |
19 | 20 | } from '@spectrum-web-components/base'; |
20 | 21 | import { |
21 | 22 | property, |
22 | 23 | query, |
| 24 | + queryAssignedElements, |
23 | 25 | } from '@spectrum-web-components/base/src/decorators.js'; |
24 | 26 | import '@spectrum-web-components/underlay/sp-underlay.js'; |
25 | 27 | import { firstFocusableIn } from '@spectrum-web-components/shared/src/first-focusable-in.js'; |
@@ -98,6 +100,46 @@ export class Tray extends SpectrumElement { |
98 | 100 | `; |
99 | 101 | } |
100 | 102 |
|
| 103 | + /** |
| 104 | + * Add a state property to track if dismiss buttons are needed |
| 105 | + * Set to false if your tray content already includes keyboard-accessible dismiss buttons. |
| 106 | + */ |
| 107 | + @property({ type: Boolean, attribute: false }) |
| 108 | + private needsDismissHelper = true; |
| 109 | + |
| 110 | + // Track slotted content |
| 111 | + @queryAssignedElements({ flatten: true }) |
| 112 | + private slottedContent!: HTMLElement[]; |
| 113 | + |
| 114 | + // Check if slotted content has keyboard-accessible dismiss buttons |
| 115 | + private checkForDismissButtons(): void { |
| 116 | + // Look for common dismiss button patterns |
| 117 | + const hasDismissButton = this.slottedContent.some((element) => { |
| 118 | + // Check for buttons at the top level |
| 119 | + if ( |
| 120 | + element.tagName === 'SP-BUTTON' || |
| 121 | + element.tagName === 'SP-CLOSE-BUTTON' || |
| 122 | + element.tagName === 'BUTTON' |
| 123 | + ) |
| 124 | + return true; |
| 125 | + |
| 126 | + // Check for buttons within the slotted content |
| 127 | + const buttons = element.querySelectorAll( |
| 128 | + 'sp-button, sp-close-button, button' |
| 129 | + ); |
| 130 | + if (buttons.length > 0) return true; |
| 131 | + |
| 132 | + return false; |
| 133 | + }); |
| 134 | + |
| 135 | + this.needsDismissHelper = !hasDismissButton; |
| 136 | + } |
| 137 | + |
| 138 | + // Update when slot content changes |
| 139 | + private handleSlotChange(): void { |
| 140 | + this.checkForDismissButtons(); |
| 141 | + } |
| 142 | + |
101 | 143 | private dispatchClosed(): void { |
102 | 144 | this.dispatchEvent( |
103 | 145 | new Event('close', { |
@@ -148,9 +190,9 @@ export class Tray extends SpectrumElement { |
148 | 190 | tabindex="-1" |
149 | 191 | @transitionend=${this.handleTrayTransitionend} |
150 | 192 | > |
151 | | - ${this.dismissHelper} |
152 | | - <slot></slot> |
153 | | - ${this.dismissHelper} |
| 193 | + ${this.needsDismissHelper ? this.dismissHelper : nothing} |
| 194 | + <slot @slotchange=${this.handleSlotChange}></slot> |
| 195 | + ${this.needsDismissHelper ? this.dismissHelper : nothing} |
154 | 196 | </div> |
155 | 197 | `; |
156 | 198 | } |
|
0 commit comments