From c844c017a973cb8552c6fd63f6f436077f3e9f1c Mon Sep 17 00:00:00 2001 From: Remco Gubbels Date: Fri, 16 Oct 2020 09:34:23 +0200 Subject: [PATCH] feat(listbox): add click on enter for options with href --- .changeset/eight-lions-provide.md | 5 +++ packages/combobox/docs/LinkMixin.js | 3 ++ packages/combobox/docs/Subclassers.md | 43 +++++++++++++++++++ packages/combobox/docs/lm-option/lm-option.js | 6 +++ packages/listbox/src/ListboxMixin.js | 5 +++ .../listbox/test-suites/ListboxMixin.suite.js | 43 +++++++++++++++++++ 6 files changed, 105 insertions(+) create mode 100644 .changeset/eight-lions-provide.md create mode 100644 packages/combobox/docs/lm-option/lm-option.js diff --git a/.changeset/eight-lions-provide.md b/.changeset/eight-lions-provide.md new file mode 100644 index 000000000..3a4f054f0 --- /dev/null +++ b/.changeset/eight-lions-provide.md @@ -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. diff --git a/packages/combobox/docs/LinkMixin.js b/packages/combobox/docs/LinkMixin.js index 305abc5b5..01cc58614 100644 --- a/packages/combobox/docs/LinkMixin.js +++ b/packages/combobox/docs/LinkMixin.js @@ -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() { diff --git a/packages/combobox/docs/Subclassers.md b/packages/combobox/docs/Subclassers.md index cbd1aadb4..7ae142276 100644 --- a/packages/combobox/docs/Subclassers.md +++ b/packages/combobox/docs/Subclassers.md @@ -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` `; ``` + +```js preview-story +export const LinkMixinBox = () => html` + + Apple + Artichoke + Asparagus + Banana + Beets + +`; +``` diff --git a/packages/combobox/docs/lm-option/lm-option.js b/packages/combobox/docs/lm-option/lm-option.js new file mode 100644 index 000000000..242aa2701 --- /dev/null +++ b/packages/combobox/docs/lm-option/lm-option.js @@ -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); diff --git a/packages/listbox/src/ListboxMixin.js b/packages/listbox/src/ListboxMixin.js index 968e12a10..157044ae2 100644 --- a/packages/listbox/src/ListboxMixin.js +++ b/packages/listbox/src/ListboxMixin.js @@ -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; } diff --git a/packages/listbox/test-suites/ListboxMixin.suite.js b/packages/listbox/test-suites/ListboxMixin.suite.js index cf39c5a03..1f7a2608d 100644 --- a/packages/listbox/test-suites/ListboxMixin.suite.js +++ b/packages/listbox/test-suites/ListboxMixin.suite.js @@ -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} .href=${'https://duckduckgo.com'}>DuckDuck Go + + `); + + 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} .href=${'https://duckduckgo.com'}>DuckDuck Go + + `); + + 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; + }); + }); }); }