feat(listbox): add click on enter for options with href

This commit is contained in:
Remco Gubbels 2020-10-16 09:34:23 +02:00 committed by Joren Broekema
parent 6498ab716f
commit c844c017a9
6 changed files with 105 additions and 0 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/listbox': minor
---
Add click on enter for options with href, to ensure that anchors are navigated towards, for example when applying LinkMixin to LionOption as part of a listbox.

View file

@ -51,6 +51,9 @@ const LinkMixinImplementation = superclass =>
if (changedProperties.has('target')) {
this._nativeAnchor.target = this.target;
}
if (changedProperties.has('rel')) {
this._nativeAnchor.rel = this.rel;
}
}
__navigate() {

View file

@ -5,6 +5,7 @@ import { html } from 'lit-html';
import './md-combobox/md-combobox.js';
import './gh-combobox/gh-combobox.js';
import './wa-combobox/wa-combobox.js';
import './lm-option/lm-option.js';
export default {
title: 'Forms/Combobox/Extensions',
@ -79,3 +80,45 @@ export const Whatsapp = () => html`
</wa-combobox>
`;
```
```js preview-story
export const LinkMixinBox = () => html`
<lion-combobox name="combo" label="Default">
<lm-option
href="https://www.google.com/search?query=apple"
target="_blank"
rel="noopener noreferrer"
.choiceValue=${'Apple'}
>Apple</lm-option
>
<lm-option
href="https://www.google.com/search?query=Artichoke"
target="_blank"
rel="noopener noreferrer"
.choiceValue=${'Artichoke'}
>Artichoke</lm-option
>
<lm-option
href="https://www.google.com/search?query=Asparagus"
target="_blank"
rel="noopener noreferrer"
.choiceValue=${'Asparagus'}
>Asparagus</lm-option
>
<lm-option
href="https://www.google.com/search?query=Banana"
target="_blank"
rel="noopener noreferrer"
.choiceValue=${'Banana'}
>Banana</lm-option
>
<lm-option
href="https://www.google.com/search?query=Beets"
target="_blank"
rel="noopener noreferrer"
.choiceValue=${'Beets'}
>Beets</lm-option
>
</lion-combobox>
`;
```

View file

@ -0,0 +1,6 @@
import { LionOption } from '@lion/listbox';
import { LinkMixin } from '../LinkMixin.js';
export class LmOption extends LinkMixin(LionOption) {}
customElements.define('lm-option', LmOption);

View file

@ -493,6 +493,11 @@ const ListboxMixinImplementation = superclass =>
if (this.formElements[this.activeIndex].disabled) {
return;
}
if (this.formElements[this.activeIndex].href) {
this.formElements[this.activeIndex].click();
}
this.setCheckedIndex(this.activeIndex);
break;
}

View file

@ -1184,5 +1184,48 @@ export function runListboxMixinSuite(customConfig = {}) {
expect(listbox.children[0].tagName).to.equal(cfg.optionTagString.toUpperCase());
});
});
describe('Href Options', () => {
it('allows anchors to be clicked when a [href] attribute is present', async () => {
const el = await fixture(html`
<${tag}>
<${optionTag}>Google</${optionTag}>
<${optionTag} .href=${'https://duckduckgo.com'}>DuckDuck Go</${optionTag}>
</${tag}>
`);
const { listbox } = getProtectedMembers(el);
el.activeIndex = 1;
// Allow options that behave like anchors (think of Google Search) to trigger the anchor behavior
const activeOption = el.formElements[1];
const clickSpy = sinon.spy(activeOption, 'click');
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
expect(clickSpy).to.have.been.calledOnce;
});
it('does not allow anchors to be clicked when a [href] attribute is not present', async () => {
const el = await fixture(html`
<${tag}>
<${optionTag}>Google</${optionTag}>
<${optionTag} .href=${'https://duckduckgo.com'}>DuckDuck Go</${optionTag}>
</${tag}>
`);
const { listbox } = getProtectedMembers(el);
el.activeIndex = 0;
const activeOption = el.formElements[0];
const clickSpy = sinon.spy(activeOption, 'click');
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
expect(clickSpy).to.not.have.been.called;
});
});
});
}