Repository navigation
fix(fab-button): restore submit, reset, and disabled form functionality - #31249
Conversation
Shadow DOM prevents ion-fab-button's native button from participating in form submission. Port the hidden-button pattern from ion-button: inject a hidden <button> into the associated form (found via the new `form` prop or by walking up to the closest <form> ancestor), then click it on Host click to trigger native form submission and Enter-key support. Fixes ionic-team#18550
|
@LucasArray is attempting to deploy a commit to the Ionic Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Hey @LucasArray! Thanks for the PR. Sorry it's been sitting so long! I pushed some changes to your PR, one just updates from main, the other fixes a few issues. The hidden button wasn't syncing We'll try to get this reviewed and merged shortly. Thank you for your patience! |
brandyscarney
left a comment
There was a problem hiding this comment.
Thank you for the PR! Left some optional feedback. 🙂
…ty (ionic-team#31249) ## Summary Fixes ionic-team#18550 — `ion-fab-button` with `type="submit"` does not submit its parent form. **Root cause:** `ion-fab-button` uses Shadow DOM, so its internal `<button>` element is not part of the form-associated elements in the light DOM. Clicking it (or pressing Enter in a text field) never triggers the form's `submit` event. **Fix:** Port the hidden-button pattern already used by `ion-button`: - On render (when `type !== 'button'`), inject a hidden `<button>` into the associated form in the light DOM. - On click, call `ev.preventDefault()` to stop the shadow button from acting, then `.click()` the hidden button — which is a proper form participant and triggers submission. - Add a `form` prop (`string | HTMLFormElement`) so the button can target a form outside its DOM subtree (same API as `ion-button`). - Keep the `disabled` watcher in sync with the hidden button so a disabled fab-button cannot submit. ## Changes - `core/src/components/fab-button/fab-button.tsx` — core fix - `core/src/components/fab-button/test/form/fab-button.e2e.ts` — Playwright e2e tests (closest form, form by id, form by reference, Enter key, disabled, reset) - `core/src/components/fab-button/test/form/fab-button.spec.ts` — unit test asserting the hidden button is not duplicated on re-renders - `core/src/components/fab-button/test/form/index.html` — visual test page ## Test plan - [ ] `npm run test.spec` passes (unit test for hidden-button dedup) - [ ] `npm run test.e2e` passes for `fab-button/test/form/fab-button.e2e.ts` - [ ] Manual: `ion-fab-button type="submit"` inside a `<form>` submits on click - [ ] Manual: pressing Enter in a form input triggers submit - [ ] Manual: `ion-fab-button type="reset"` resets form fields - [ ] Manual: disabled fab-button does not submit - [ ] Manual: `form="id"` targets an external form --------- Co-authored-by: ShaneK <shane@shanessite.net>
Summary
Fixes #18550 —
ion-fab-buttonwithtype="submit"does not submit its parent form.Root cause:
ion-fab-buttonuses Shadow DOM, so its internal<button>element is not part of the form-associated elements in the light DOM. Clicking it (or pressing Enter in a text field) never triggers the form'ssubmitevent.Fix: Port the hidden-button pattern already used by
ion-button:type !== 'button'), inject a hidden<button>into the associated form in the light DOM.ev.preventDefault()to stop the shadow button from acting, then.click()the hidden button — which is a proper form participant and triggers submission.formprop (string | HTMLFormElement) so the button can target a form outside its DOM subtree (same API asion-button).disabledwatcher in sync with the hidden button so a disabled fab-button cannot submit.Changes
core/src/components/fab-button/fab-button.tsx— core fixcore/src/components/fab-button/test/form/fab-button.e2e.ts— Playwright e2e tests (closest form, form by id, form by reference, Enter key, disabled, reset)core/src/components/fab-button/test/form/fab-button.spec.ts— unit test asserting the hidden button is not duplicated on re-renderscore/src/components/fab-button/test/form/index.html— visual test pageTest plan
npm run test.specpasses (unit test for hidden-button dedup)npm run test.e2epasses forfab-button/test/form/fab-button.e2e.tsion-fab-button type="submit"inside a<form>submits on clickion-fab-button type="reset"resets form fieldsform="id"targets an external form