fix: allow ctrl/command + key when the sl-select is on focus

This commit is contained in:
gtyamamoto
2021-08-19 17:21:18 -03:00
parent b0cf35d264
commit 066f7cfa08
2 changed files with 53 additions and 3 deletions

View File

@@ -1,4 +1,4 @@
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import { expect, fixture, html, waitUntil, aTimeout } from '@open-wc/testing';
import sinon from 'sinon';
import '../../../dist/shoelace.js';
@@ -21,4 +21,39 @@ describe('<sl-select>', () => {
expect(changeHandler).to.have.been.calledOnce;
});
it('should open the menu when any letter key is pressed with sl-select is on focus', async () => {
const el = (await fixture(html`
<sl-select>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
</sl-select>
`)) as SlSelect;
const selectBox = el.shadowRoot.querySelector('.select__box') as HTMLSelectElement;
selectBox.focus();
const rKeyEvent = new KeyboardEvent('keydown', { key: 'r' });
selectBox.dispatchEvent(rKeyEvent);
await aTimeout(100);
expect(selectBox.getAttribute('aria-expanded')).to.equal('true');
});
it('should not open the menu when ctrl + R is pressed with sl-select is on focus', async () => {
const el = (await fixture(html`
<sl-select>
<sl-menu-item value="option-1">Option 1</sl-menu-item>
<sl-menu-item value="option-2">Option 2</sl-menu-item>
<sl-menu-item value="option-3">Option 3</sl-menu-item>
</sl-select>
`)) as SlSelect;
const selectBox = el.shadowRoot.querySelector('.select__box') as HTMLSelectElement;
selectBox.focus();
const ctrlKeyEvent = new KeyboardEvent('keydown', { key: 'Control' });
selectBox.dispatchEvent(ctrlKeyEvent);
await aTimeout(100);
const rKeyEvent = new KeyboardEvent('keydown', { key: 'r' });
selectBox.dispatchEvent(rKeyEvent);
await aTimeout(100);
expect(selectBox.getAttribute('aria-expanded')).to.equal('false');
});
});

View File

@@ -65,6 +65,7 @@ export default class SlSelect extends LitElement {
private helpTextId = `select-help-text-${id}`;
private labelId = `select-label-${id}`;
private resizeObserver: ResizeObserver;
private isCtrlKeyPressed = false;
@state() private hasFocus = false;
@state() private hasHelpTextSlot = false;
@@ -249,8 +250,14 @@ export default class SlSelect extends LitElement {
}
}
// All other "printable" keys open the menu and initiate type to select
if (!this.isOpen && event.key.length === 1) {
// toggling CTRL/Command key state for ctrl + any key commands
if (event.key === 'Control' || event.metaKey) {
this.isCtrlKeyPressed = true;
return;
}
// All other "printable" keys open the menu (if not ctrl key is pressed) and initiate type to select
if (!this.isOpen && !this.isCtrlKeyPressed && event.key.length === 1) {
event.stopPropagation();
event.preventDefault();
this.dropdown.show();
@@ -258,6 +265,13 @@ export default class SlSelect extends LitElement {
}
}
handleKeyUp(event: KeyboardEvent) {
// toggling CTRL/Command key state for ctrl + any key commands
if (event.key === 'Control' || event.metaKey) {
this.isCtrlKeyPressed = false;
}
}
handleLabelClick() {
const box = this.shadowRoot?.querySelector('.select__box') as HTMLElement;
box.focus();
@@ -477,6 +491,7 @@ export default class SlSelect extends LitElement {
@blur=${this.handleBlur}
@focus=${this.handleFocus}
@keydown=${this.handleKeyDown}
@keyup=${this.handleKeyUp}
>
<div class="select__label">
${this.displayTags.length