diff --git a/packages/button/src/LionButton.js b/packages/button/src/LionButton.js index 07460592f..d462c7f9b 100644 --- a/packages/button/src/LionButton.js +++ b/packages/button/src/LionButton.js @@ -71,6 +71,12 @@ export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement)) :host .btn ::slotted(button) { position: absolute; + clip: rect(0 0 0 0); + clip-path: inset(50%); + overflow: hidden; + white-space: nowrap; + height: 1px; + width: 1px; } .click-area { @@ -110,22 +116,6 @@ export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement)) fill: #adadad; } `, - ...(this.__isIE11() /* visibility hidden in IE11 breaks native button functionality */ - ? [ - /* TODO: Make SR-only css mixin? */ - css` - :host .btn ::slotted(button) { - clip: rect(0, 0, 0, 0); - } - `, - ] - : [ - css` - :host .btn ::slotted(button) { - visibility: hidden; - } - `, - ]), ]; } @@ -181,33 +171,16 @@ export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement)) } } - _redispatchClickEvent(oldEvent) { - // replacing `MouseEvent` with `oldEvent.constructor` breaks IE - const newEvent = new MouseEvent(oldEvent.type, oldEvent); - newEvent.__isRedispatchedOnNativeButton = true; - this.__enforceHostEventTarget(newEvent); - this._nativeButtonNode.dispatchEvent(newEvent); - } - /** - * Prevent normal click and redispatch submit on the native button unless already redispatched. + * Dispatch submit event and invoke submit on the native form when clicked */ __clickDelegationHandler() { if (this.type === 'submit' && this._nativeButtonNode.form) { + this._nativeButtonNode.form.dispatchEvent(new Event('submit')); this._nativeButtonNode.form.submit(); } } - __enforceHostEventTarget(event) { - try { - // this is for IE11 (and works in others), because `Object.defineProperty` does not give any effect there - event.__defineGetter__('target', () => this); // eslint-disable-line no-restricted-properties - } catch (error) { - // in case `__defineGetter__` is removed from the platform - Object.defineProperty(event, 'target', { writable: false, value: this }); - } - } - __setupDelegationInConstructor() { // do not move to connectedCallback, otherwise IE11 breaks // more info: https://github.com/ing-bank/lion/issues/179#issuecomment-511763835 @@ -252,7 +225,7 @@ export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement)) __keyupHandler(e) { if (this.__isKeyboardClickEvent(e)) { // redispatch click - this.shadowRoot.querySelector('.click-area').click(); + this.click(); } } diff --git a/packages/button/stories/index.stories.js b/packages/button/stories/index.stories.js index a6f54e7ce..bc9f02d12 100644 --- a/packages/button/stories/index.stories.js +++ b/packages/button/stories/index.stories.js @@ -35,16 +35,14 @@ storiesOf('Buttons|Button', module) .add( 'Within a form', () => html` - console.log('form submitted')} - >
- - - console.log(document.querySelector('#form').serializeGroup())} - >Submit -
+
console.log('native form submitted')}> + + + console.log(document.querySelector('#form').serializeGroup())} + >Submit +
`, ); diff --git a/packages/button/test/lion-button.test.js b/packages/button/test/lion-button.test.js index fb37f49fb..71b021624 100644 --- a/packages/button/test/lion-button.test.js +++ b/packages/button/test/lion-button.test.js @@ -57,7 +57,8 @@ describe('lion-button', () => { it('hides the native button in the UI', async () => { const el = await fixture(`foo`); expect(el._nativeButtonNode.getAttribute('tabindex')).to.equal('-1'); - expect(window.getComputedStyle(el._nativeButtonNode).visibility).to.equal('hidden'); + // TODO: If we abstract to an srOnlyMixin, we should test that the styling equals that of the srOnlyMixin output + expect(window.getComputedStyle(el._nativeButtonNode).clip).to.equal('rect(0px, 0px, 0px, 0px)'); }); it('can be disabled imperatively', async () => { @@ -231,6 +232,8 @@ describe('lion-button', () => { foo `); + // Prevent page refresh + form.submit = () => {}; const button = form.querySelector('lion-button'); getTopElement(button).click(); @@ -245,6 +248,8 @@ describe('lion-button', () => { foo `); + // Prevent page refresh + form.submit = () => {}; pressSpace(form.querySelector('lion-button')); await aTimeout(); @@ -260,6 +265,8 @@ describe('lion-button', () => { foo `); + // Prevent page refresh + form.submit = () => {}; pressEnter(form.querySelector('lion-button')); await aTimeout(); @@ -267,6 +274,26 @@ describe('lion-button', () => { expect(formSubmitSpy.called).to.be.true; }); + + // input "enter" keypress mock doesn't seem to work right now, but should be tested in the future (maybe with Selenium) + it.skip('works with implicit form submission on-enter inside an input', async () => { + const formSubmitSpy = sinon.spy(e => e.preventDefault()); + const form = await fixture(html` +
+ + + foo +
+ `); + // Prevent page refresh + form.submit = () => {}; + + pressEnter(form.querySelector('input[name="foo2"]')); + await aTimeout(); + await aTimeout(); + + expect(formSubmitSpy.called).to.be.true; + }); }); describe('click event', () => {