@lion/button
Advanced tools
Comparing version 0.7.14 to 0.7.15
# Change Log | ||
## 0.7.15 | ||
### Patch Changes | ||
- 6679fe77: Types button and combobox | ||
## 0.7.14 | ||
@@ -4,0 +10,0 @@ |
@@ -0,2 +1,5 @@ | ||
/** | ||
* @param {Function} tag | ||
*/ | ||
export default tag => | ||
tag`<svg focusable="false" style="width: 24px; height: 24px;" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><g><path d="M44.8,44.2c-0.3-0.1-6.9-2.3-10-8c-0.9-1.7-1.7-3.6-2.4-5.4c-1.4-3.4-2.7-6.6-4.6-6.8l0.1-1.9c3.1,0.2,4.5,3.8,6.2,7.9 c0.7,1.7,1.4,3.5,2.3,5.2c2.7,5.1,8.9,7.1,8.9,7.1L44.8,44.2z"/></g><g><path d="M19.8,61.7v-1.9c4.7,0,10.7-6.6,13.4-10.7c2.6-4,11.2-2.1,12.2-1.9l-0.4,1.8c-2.3-0.5-8.6-1.4-10.2,1.1 C32.7,53.4,25.9,61.7,19.8,61.7z"/></g><g><path d="M25.1,86.5l-0.3-1.9c6-0.9,6.9-9.7,7.6-16.8c0.2-1.9,0.4-3.6,0.6-5.1c1.4-7.4,11.6-10.3,12.1-10.4l0.5,1.8 c-0.1,0-9.6,2.7-10.7,8.9c-0.3,1.4-0.4,3.1-0.6,5C33.5,75.3,32.5,85.4,25.1,86.5z"/></g><g><path d="M45.8,25.4c-0.1-1.4-0.1-4.7,0.9-5.7c0.3-0.3,0.6-0.4,1-0.4v1.9c0.2,0,0.3-0.1,0.4-0.2c-0.3,0.4-0.5,2.4-0.4,4.4 L45.8,25.4z"/></g><g><path d="M43.6,28c-0.3-0.3-6.8-6.2-6.8-11.4c0-5,1.4-8.7,1.5-8.8L40,8.5c0,0-1.3,3.6-1.3,8.1c0,4.4,6.2,10,6.2,10L43.6,28z"/></g><g><path d="M54.6,54.5c0-2.7,0.8-13-0.3-13c-1.1,0-1.8-2.2-1.8-3.4c0-1.1,4.1-3.4,4.1-8.1c0-4.8-6.6-5.6-6.6-5.6s-6.6,0.8-6.6,5.6 c0,4.8,4.1,7,4.1,8.1c0,1.1-0.7,3.4-1.8,3.4c-1.1,0-0.3,10.4-0.3,13c0,2.7-5.3,7.7-5.3,17.2s5.9,19.5,9.9,19.5 c4.1,0,9.9-9.9,9.9-19.5S54.6,57.2,54.6,54.5z"/></g><g><path d="M50,92.2c-5,0-10.9-11.1-10.9-20.4c0-6.5,2.4-11,4-14c0.7-1.4,1.4-2.6,1.4-3.3c0-0.6-0.1-1.8-0.1-3.1 c-0.3-7.6-0.2-9.8,0.5-10.5c0.2-0.2,0.5-0.4,0.8-0.4c0.3-0.1,0.8-1.4,0.9-2.3c-0.1-0.2-0.5-0.6-0.8-1c-1.2-1.4-3.3-3.7-3.3-7.3 c0-5.5,7.1-6.5,7.4-6.5c0.1,0,0.2,0,0.2,0c0.3,0,7.4,1,7.4,6.5c0,3.6-2.1,5.9-3.3,7.3c-0.3,0.3-0.7,0.8-0.8,1 c0,0.9,0.6,2.2,0.9,2.3c0.3,0,0.6,0.1,0.8,0.4c0.7,0.8,0.8,2.9,0.5,10.5c-0.1,1.3-0.1,2.4-0.1,3.1c0,0.7,0.6,1.9,1.4,3.3 c1.6,3,4,7.5,4,14C60.9,81.1,55,92.2,50,92.2z M46.2,42.4c-0.3,1.4-0.1,6.5,0,9c0.1,1.3,0.1,2.5,0.1,3.2c0,1.2-0.7,2.4-1.6,4.1 c-1.6,3-3.7,7.1-3.7,13.1c0,9.4,5.7,18.5,9,18.5s9-9.2,9-18.5c0-6-2.2-10.1-3.7-13.1c-0.9-1.7-1.6-3-1.6-4.1 c0-0.7,0.1-1.8,0.1-3.2c0.1-2.5,0.3-7.6,0-9c-1.6-0.5-2.2-3.1-2.2-4.2c0-0.7,0.5-1.3,1.3-2.1c1.2-1.3,2.8-3.1,2.8-6 c0-3.6-4.8-4.5-5.6-4.6c-0.8,0.1-5.6,1.1-5.6,4.6c0,2.8,1.6,4.7,2.8,6c0.7,0.8,1.3,1.4,1.3,2.1C48.4,39.3,47.8,41.9,46.2,42.4z"/></g><g><path d="M55.2,44.2l-0.6-1.8c0.1,0,6.2-2.1,9-7.1c0.9-1.7,1.6-3.4,2.3-5.2c1.7-4.2,3.2-7.7,6.2-7.9l0.1,1.9 c-1.9,0.1-3.2,3.3-4.6,6.8c-0.7,1.8-1.5,3.6-2.4,5.4C62.1,41.9,55.4,44.1,55.2,44.2z"/></g><g><path d="M80.2,61.7c-6.1,0-12.9-8.4-15-11.6c-1.6-2.5-8-1.6-10.2-1.1l-0.4-1.8c1-0.2,9.6-2.1,12.2,1.9c2.7,4.1,8.7,10.7,13.4,10.7 V61.7z"/></g><g><path d="M74.9,86.5c-7.4-1.1-8.5-11.2-9.2-18.5c-0.2-1.8-0.4-3.6-0.6-5c-1.1-6.3-10.6-8.9-10.7-8.9l0.5-1.8 c0.4,0.1,10.7,3,12.1,10.4c0.3,1.5,0.4,3.2,0.6,5.1c0.7,7.1,1.6,16,7.6,16.9L74.9,86.5z"/></g><g><path d="M54.2,25.4l-1.9-0.1c0.1-1.9-0.1-4-0.4-4.4c0,0,0.2,0.2,0.4,0.2v-1.9c0.4,0,0.7,0.2,1,0.4C54.3,20.7,54.3,24.1,54.2,25.4z "/></g><g><path d="M56.4,28l-1.3-1.4c0.1-0.1,6.2-5.7,6.2-10c0-4.6-1.3-8.1-1.3-8.1l1.8-0.7c0.1,0.2,1.5,3.9,1.5,8.8 C63.2,21.8,56.6,27.8,56.4,28z"/></g></g></svg>`; |
{ | ||
"name": "@lion/button", | ||
"version": "0.7.14", | ||
"version": "0.7.15", | ||
"description": "A button that is easily styleable and accessible in all contexts", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -9,9 +9,17 @@ import { | ||
} from '@lion/core'; | ||
import '@lion/core/src/differentKeyEventNamesShimIE.js'; | ||
const isKeyboardClickEvent = (/** @type {KeyboardEvent} */ e) => | ||
e.keyCode === 32 /* space */ || e.keyCode === 13; /* enter */ | ||
const isSpaceKeyboardClickEvent = (/** @type {KeyboardEvent} */ e) => | ||
// @ts-expect-error | ||
e.keyCode === 32 || e.key === 32; /* space */ | ||
// TODO: several improvements: | ||
// [1] remove click-area | ||
// [2] remove the native _button slot. We can detect and submit parent form without the slot. | ||
// [3] reduce css so that extending styles makes sense. Merge .btn with host | ||
// [4] reduce the template and remove the if else construction inside the template (an extra | ||
// div by default to support IE is fine) => <div id="${this._buttonId}"><slot></slot></div> | ||
// should be all needed | ||
// [5] do we need the before and after templates? Could be added by subclasser | ||
// [6] extract all functionality (except for form submission) into LionButtonMixin | ||
const isKeyboardClickEvent = (/** @type {KeyboardEvent} */ e) => e.key === ' ' || e.key === 'Enter'; | ||
const isSpaceKeyboardClickEvent = (/** @type {KeyboardEvent} */ e) => e.key === ' '; | ||
export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement)) { | ||
@@ -149,2 +157,3 @@ static get properties() { | ||
// @ts-ignore | ||
get slots() { | ||
@@ -170,4 +179,4 @@ return { | ||
this._buttonId = `button-${Math.random().toString(36).substr(2, 10)}`; | ||
if (browserDetection.isIE11) { | ||
this._buttonId = `button-${Math.random().toString(36).substr(2, 10)}`; | ||
this.updateComplete.then(() => this.setAttribute('aria-labelledby', this._buttonId)); | ||
@@ -174,0 +183,0 @@ } |
@@ -0,1 +1,2 @@ | ||
// @ts-nocheck | ||
/* globals capture getStoryPage */ | ||
@@ -2,0 +3,0 @@ |
import { browserDetection } from '@lion/core'; | ||
import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing'; | ||
import sinon from 'sinon'; | ||
import '@lion/core/src/differentKeyEventNamesShimIE.js'; | ||
import '../lion-button.js'; | ||
@@ -10,12 +11,2 @@ | ||
/** | ||
* @param {HTMLElement} el | ||
*/ | ||
function getClickArea(el) { | ||
if (el.shadowRoot) { | ||
return el.shadowRoot.querySelector('.click-area'); | ||
} | ||
return undefined; | ||
} | ||
describe('lion-button', () => { | ||
@@ -107,3 +98,3 @@ it('behaves like native `button` in terms of a11y', async () => { | ||
el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 32 })); | ||
el.dispatchEvent(new KeyboardEvent('keydown', { key: ' ' })); | ||
expect(el.active).to.be.true; | ||
@@ -113,3 +104,3 @@ await el.updateComplete; | ||
el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 })); | ||
el.dispatchEvent(new KeyboardEvent('keyup', { key: ' ' })); | ||
expect(el.active).to.be.false; | ||
@@ -123,3 +114,3 @@ await el.updateComplete; | ||
el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 32 })); | ||
el.dispatchEvent(new KeyboardEvent('keydown', { key: ' ' })); | ||
expect(el.active).to.be.true; | ||
@@ -129,3 +120,3 @@ await el.updateComplete; | ||
el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 })); | ||
el.dispatchEvent(new KeyboardEvent('keyup', { key: ' ' })); | ||
expect(el.active).to.be.false; | ||
@@ -139,3 +130,3 @@ await el.updateComplete; | ||
el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 })); | ||
el.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' })); | ||
expect(el.active).to.be.true; | ||
@@ -145,3 +136,3 @@ await el.updateComplete; | ||
el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 })); | ||
el.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' })); | ||
expect(el.active).to.be.false; | ||
@@ -155,3 +146,3 @@ await el.updateComplete; | ||
el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 })); | ||
el.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' })); | ||
expect(el.active).to.be.true; | ||
@@ -161,3 +152,3 @@ await el.updateComplete; | ||
document.body.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 })); | ||
document.body.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' })); | ||
expect(el.active).to.be.false; | ||
@@ -225,4 +216,4 @@ await el.updateComplete; | ||
const wrapperId = el.getAttribute('aria-labelledby'); | ||
expect(el.shadowRoot.querySelector(`#${wrapperId}`)).to.exist; | ||
expect(el.shadowRoot.querySelector(`#${wrapperId}`)).dom.to.equal( | ||
expect(/** @type {ShadowRoot} */ (el.shadowRoot).querySelector(`#${wrapperId}`)).to.exist; | ||
expect(/** @type {ShadowRoot} */ (el.shadowRoot).querySelector(`#${wrapperId}`)).dom.to.equal( | ||
`<div id="${wrapperId}"><slot></slot></div>`, | ||
@@ -261,7 +252,7 @@ ); | ||
`); | ||
const button = form.querySelector('lion-button'); | ||
getClickArea(button).click(); | ||
expect(formSubmitSpy.callCount).to.equal(1); | ||
const button = /** @type {LionButton} */ ( | ||
/** @type {LionButton} */ (form.querySelector('lion-button')) | ||
); | ||
button.click(); | ||
expect(formSubmitSpy).to.have.been.calledOnce; | ||
}); | ||
@@ -276,9 +267,9 @@ | ||
`); | ||
form | ||
.querySelector('lion-button') | ||
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 })); | ||
await aTimeout(); | ||
await aTimeout(); | ||
expect(formSubmitSpy.callCount).to.equal(1); | ||
const button = /** @type {LionButton} */ ( | ||
/** @type {LionButton} */ (form.querySelector('lion-button')) | ||
); | ||
button.dispatchEvent(new KeyboardEvent('keyup', { key: ' ' })); | ||
await aTimeout(0); | ||
await aTimeout(0); | ||
expect(formSubmitSpy).to.have.been.calledOnce; | ||
}); | ||
@@ -294,9 +285,8 @@ | ||
form | ||
.querySelector('lion-button') | ||
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 })); | ||
await aTimeout(); | ||
await aTimeout(); | ||
const button = /** @type {LionButton} */ (form.querySelector('lion-button')); | ||
button.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' })); | ||
await aTimeout(0); | ||
await aTimeout(0); | ||
expect(formSubmitSpy.callCount).to.equal(1); | ||
expect(formSubmitSpy).to.have.been.calledOnce; | ||
}); | ||
@@ -312,5 +302,11 @@ | ||
`); | ||
const btn = form.querySelector('lion-button'); | ||
const firstName = form.querySelector('input[name=firstName]'); | ||
const lastName = form.querySelector('input[name=lastName]'); | ||
const btn = /** @type {LionButton} */ ( | ||
/** @type {LionButton} */ (form.querySelector('lion-button')) | ||
); | ||
const firstName = /** @type {HTMLInputElement} */ (form.querySelector( | ||
'input[name=firstName]', | ||
)); | ||
const lastName = /** @type {HTMLInputElement} */ (form.querySelector( | ||
'input[name=lastName]', | ||
)); | ||
firstName.value = 'Foo'; | ||
@@ -339,9 +335,8 @@ lastName.value = 'Bar'; | ||
form | ||
.querySelector('input[name="foo2"]') | ||
.dispatchEvent(new KeyboardEvent('keyup', { key: 13 })); | ||
await aTimeout(); | ||
await aTimeout(); | ||
const input2 = /** @type {HTMLInputElement} */ (form.querySelector('input[name="foo2"]')); | ||
input2.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' })); | ||
await aTimeout(0); | ||
await aTimeout(0); | ||
expect(formSubmitSpy.callCount).to.equal(1); | ||
expect(formSubmitSpy).to.have.been.calledOnce; | ||
}); | ||
@@ -354,3 +349,3 @@ }); | ||
const form = await fixture(html` | ||
<form @submit=${ev => ev.preventDefault()}> | ||
<form @submit=${/** @type {EventListener} */ ev => ev.preventDefault()}> | ||
<lion-button @click="${formButtonClickedSpy}" type="submit">foo</lion-button> | ||
@@ -360,6 +355,6 @@ </form> | ||
const button = form.querySelector('lion-button'); | ||
getClickArea(button).click(); | ||
const button = /** @type {LionButton} */ (form.querySelector('lion-button')); | ||
button.click(); | ||
expect(formButtonClickedSpy.callCount).to.equal(1); | ||
expect(formButtonClickedSpy).to.have.been.calledOnce; | ||
}); | ||
@@ -370,3 +365,3 @@ | ||
const form = await fixture(html` | ||
<form @submit=${ev => ev.preventDefault()}> | ||
<form @submit=${/** @type {EventListener} */ ev => ev.preventDefault()}> | ||
<lion-button @click="${formButtonClickedSpy}" type="submit">foo</lion-button> | ||
@@ -376,9 +371,9 @@ </form> | ||
form | ||
.querySelector('lion-button') | ||
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 })); | ||
await aTimeout(); | ||
await aTimeout(); | ||
/** @type {LionButton} */ (form.querySelector('lion-button')).dispatchEvent( | ||
new KeyboardEvent('keyup', { key: ' ' }), | ||
); | ||
await aTimeout(0); | ||
await aTimeout(0); | ||
expect(formButtonClickedSpy.callCount).to.equal(1); | ||
expect(formButtonClickedSpy).to.have.been.calledOnce; | ||
}); | ||
@@ -389,3 +384,3 @@ | ||
const form = await fixture(html` | ||
<form @submit=${ev => ev.preventDefault()}> | ||
<form @submit=${/** @type {EventListener} */ ev => ev.preventDefault()}> | ||
<lion-button @click="${formButtonClickedSpy}" type="submit">foo</lion-button> | ||
@@ -395,9 +390,8 @@ </form> | ||
form | ||
.querySelector('lion-button') | ||
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 })); | ||
await aTimeout(); | ||
await aTimeout(); | ||
const button = /** @type {LionButton} */ (form.querySelector('lion-button')); | ||
button.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' })); | ||
await aTimeout(0); | ||
await aTimeout(0); | ||
expect(formButtonClickedSpy.callCount).to.equal(1); | ||
expect(formButtonClickedSpy).to.have.been.calledOnce; | ||
}); | ||
@@ -409,3 +403,3 @@ | ||
const form = await fixture(html` | ||
<form @submit=${ev => ev.preventDefault()}> | ||
<form @submit=${/** @type {EventListener} */ ev => ev.preventDefault()}> | ||
<input name="foo" /> | ||
@@ -417,9 +411,8 @@ <input name="foo2" /> | ||
form | ||
.querySelector('input[name="foo2"]') | ||
.dispatchEvent(new KeyboardEvent('keyup', { key: 13 })); | ||
await aTimeout(); | ||
await aTimeout(); | ||
const input2 = /** @type {HTMLInputElement} */ (form.querySelector('input[name="foo2"]')); | ||
input2.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' })); | ||
await aTimeout(0); | ||
await aTimeout(0); | ||
expect(formButtonClickedSpy.callCount).to.equal(1); | ||
expect(formButtonClickedSpy).to.have.been.calledOnce; | ||
}); | ||
@@ -436,24 +429,24 @@ }); | ||
getClickArea(el).click(); | ||
el.click(); | ||
// trying to wait for other possible redispatched events | ||
await aTimeout(); | ||
await aTimeout(); | ||
await aTimeout(0); | ||
await aTimeout(0); | ||
expect(clickSpy.callCount).to.equal(1); | ||
expect(clickSpy).to.have.been.calledOnce; | ||
}); | ||
describe('native button behavior', async () => { | ||
/** | ||
* @param {HTMLButtonElement | LionButton} el | ||
*/ | ||
async function prepareClickEvent(el) { | ||
setTimeout(() => { | ||
if (getClickArea(el)) { | ||
getClickArea(el).click(); | ||
} else { | ||
el.click(); | ||
} | ||
el.click(); | ||
}); | ||
return oneEvent(el, 'click'); | ||
} | ||
/** @type {Event} */ | ||
let nativeButtonEvent; | ||
/** @type {Event} */ | ||
let lionButtonEvent; | ||
@@ -460,0 +453,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
66520
15
787