diff --git a/packages/core/src/components/button/button.spec.ts b/packages/core/src/components/button/button.spec.ts index c1f3d7019..a21fe43dc 100644 --- a/packages/core/src/components/button/button.spec.ts +++ b/packages/core/src/components/button/button.spec.ts @@ -131,4 +131,53 @@ describe('AtomButton', () => { expect(spy).toHaveBeenCalled() }) + + it('should submit button call parent form requestSubmit', async () => { + const page = await newSpecPage({ + components: [AtomButton], + html: '
Click
', + }) + + await page.waitForChanges() + const formEl = page.body.querySelector('form') as HTMLFormElement + formEl.requestSubmit = jest.fn + const buttonEl = page.root?.shadowRoot?.querySelector('ion-button') + jest.spyOn(formEl, 'requestSubmit') + + buttonEl?.click() + + expect(formEl.requestSubmit).toHaveBeenCalled() + }) + + it('should submit button call parent form reset', async () => { + const page = await newSpecPage({ + components: [AtomButton], + html: '
Click
', + }) + + await page.waitForChanges() + const formEl = page.body.querySelector('form') as HTMLFormElement + formEl.reset = jest.fn() + const buttonEl = page.root?.shadowRoot?.querySelector('ion-button') + jest.spyOn(formEl, 'reset') + buttonEl?.click() + + expect(formEl.reset).toHaveBeenCalled() + }) + + it('should not call form reset if button is disabled', async () => { + const page = await newSpecPage({ + components: [AtomButton], + html: '
Click
', + }) + + await page.waitForChanges() + const formEl = page.body.querySelector('form') as HTMLFormElement + formEl.reset = jest.fn() + const buttonEl = page.root?.shadowRoot?.querySelector('ion-button') + jest.spyOn(formEl, 'reset') + buttonEl?.click() + + expect(formEl.reset).not.toHaveBeenCalled() + }) }) diff --git a/packages/core/src/components/button/button.tsx b/packages/core/src/components/button/button.tsx index 39a510dd9..425d31ac1 100644 --- a/packages/core/src/components/button/button.tsx +++ b/packages/core/src/components/button/button.tsx @@ -1,5 +1,13 @@ import { Mode } from '@ionic/core' -import { Component, Host, Prop, h } from '@stencil/core' +import { + Component, + Element, + Event, + EventEmitter, + Host, + Prop, + h, +} from '@stencil/core' @Component({ tag: 'atom-button', @@ -21,6 +29,29 @@ export class AtomButton { @Prop() target?: string @Prop() type: 'submit' | 'reset' | 'button' = 'button' + @Event() click: EventEmitter + + @Element() element: HTMLElement + + formFunctions = { + reset: 'reset', + submit: 'requestSubmit', + } + + private handleClick = (event) => { + event.preventDefault() + + if (this.loading || this.disabled) return + if (this.type === 'button') { + return this.click.emit(event) + } else { + const form = this.element.closest('form') + if (form) { + return form[this.formFunctions[this.type]]() + } + } + } + render() { return ( {this.loading && (