kopia lustrzana https://github.com/shoelace-style/shoelace
fix(arbitrary content): tabbing closes the dropdown when it's open
rodzic
e1fe8b0489
commit
223e33d345
src/components/dropdown
|
@ -180,6 +180,12 @@ export default class SlDropdown extends ShoelaceElement {
|
|||
return computeActiveElement(element?.shadowRoot?.activeElement);
|
||||
};
|
||||
|
||||
const computeClosestContaining = (element: Element | null, tagName: string) => {
|
||||
const closest = element?.closest(tagName);
|
||||
if (closest !== null) return closest;
|
||||
return computeClosestContaining((element?.getRootNode() as ShadowRoot).host, tagName);
|
||||
};
|
||||
|
||||
// Tabbing outside of the containing element closes the panel
|
||||
//
|
||||
// If the dropdown is used within a shadow DOM, we need to obtain the activeElement within that shadowRoot,
|
||||
|
@ -192,7 +198,8 @@ export default class SlDropdown extends ShoelaceElement {
|
|||
|
||||
if (
|
||||
!this.containingElement ||
|
||||
activeElement?.closest(this.containingElement.tagName.toLowerCase()) !== this.containingElement
|
||||
computeClosestContaining(activeElement, this.containingElement.tagName.toLowerCase()) !==
|
||||
this.containingElement
|
||||
) {
|
||||
this.hide();
|
||||
}
|
||||
|
|
|
@ -402,4 +402,53 @@ describe('<sl-dropdown>', () => {
|
|||
expect(dropdown.open).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when arbitrary content is provided and the dropdown is opened', () => {
|
||||
beforeEach(() => {
|
||||
@customElement('custom-wrapper-arbitrary')
|
||||
class WrapperArbitrary extends LitElement {
|
||||
render() {
|
||||
return html`<nested-dropdown-arbitrary></nested-dropdown-arbitrary>`;
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line chai-friendly/no-unused-expressions
|
||||
WrapperArbitrary;
|
||||
|
||||
@customElement('nested-dropdown-arbitrary')
|
||||
class NestedDropdownArbitrary extends LitElement {
|
||||
render() {
|
||||
return html`
|
||||
<sl-dropdown>
|
||||
<sl-button slot="trigger" caret>Toggle</sl-button>
|
||||
<ul>
|
||||
<li><a href="/settings">Settings</a></li>
|
||||
<li><a href="/profile">Profile</a></li>
|
||||
</ul>
|
||||
</sl-dropdown>
|
||||
`;
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line chai-friendly/no-unused-expressions
|
||||
NestedDropdownArbitrary;
|
||||
});
|
||||
|
||||
it('should remain open on tab key', async () => {
|
||||
const el = await fixture<SlDropdown>(html`<custom-wrapper-arbitrary></custom-wrapper-arbitrary>`);
|
||||
|
||||
const dropdown = el
|
||||
.shadowRoot!.querySelector('nested-dropdown-arbitrary')!
|
||||
.shadowRoot!.querySelector('sl-dropdown')!;
|
||||
|
||||
const trigger = dropdown.querySelector('sl-button')!;
|
||||
|
||||
trigger.focus();
|
||||
await dropdown.updateComplete;
|
||||
await sendKeys({ press: 'Enter' });
|
||||
await dropdown.updateComplete;
|
||||
await sendKeys({ press: 'Tab' });
|
||||
await dropdown.updateComplete;
|
||||
|
||||
expect(dropdown.open).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Ładowanie…
Reference in New Issue