Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "form" attribute to all components that render an <input>, <textarea> or <select> #4117

Open
tchak opened this issue Feb 24, 2023 · 4 comments
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed rsp:Form

Comments

@tchak
Copy link

tchak commented Feb 24, 2023

馃檵 Feature Request

Add "form" attribute to all components that render an <input>, <textarea> or <select>.

馃 Expected Behavior

Be able to set form attribute on the internal <input>, <textarea> or <select>.

馃槸 Current Behavior

form attribute is not exposed.

馃拋 Possible Solution

I have tried to use ref and set form attribute in an useEffect. In some cases I am also using data-testid to gain access to underlying DOM/input and set form attribute in an useEffect. Neither is a good solution.

Another solution is to not use internal <input> (not set name on the component) and always use an external hidden <input>.

馃敠 Context

It is more practical some time to render form and fields in separate parts of the DOM. For example, in cases when I want each field to have its own form. I can still group fields with one fieldset and put forms outside while referencing them from the inputs.

@LFDanLu LFDanLu added the enhancement New feature or request label Feb 24, 2023
@wojtekmaj
Copy link
Contributor

wojtekmaj commented Mar 1, 2024

I nearly ripped my eyes out writing this but here's a workaround if you're in an urgent need of a fix like myself:

        ref={
          // Workaround for react-aria-components not supporting form attribute
          // See https://github.com/adobe/react-spectrum/issues/4117
          form
            ? (ref) => {
                if (!ref) {
                  return;
                }

                // A hidden section rendered by react-aria-components
                const nextSibling = ref.nextSibling;

                if (!nextSibling || !(nextSibling instanceof HTMLElement)) {
                  return;
                }

                // A hidden input rendered by react-aria-components
                const formElement = nextSibling.querySelector(`[name="${name}"]`);

                if (!formElement) {
                  return;
                }

                formElement.setAttribute('form', form);
              }
            : undefined
        }

@snowystinger
Copy link
Member

For components where you provide an Input you can access it through the ref to that element
https://stackblitz.com/edit/vitejs-vite-28q1zf?file=package.json,src%2FApp.tsx&terminal=dev

For the others, I think we could consider exposing an inputRef on the component or adding it to the ref via a useImperativeHandle.

If we do expose an inputRef then we'll have to determine how to deal with components that are implemented with multiple inputs, such as DatePicker or ColorArea.

@mxp-qk
Copy link

mxp-qk commented Mar 20, 2024

Hey,

I used to rewire the name and form props with the react-aria hooks, but since this PR I switch to RAC and it works great (馃憦) except for this two uses cases :

  • As mentioned in this issue, sometimes placing an input somewhere in the DOM is necessary
  • But a more simple use cas is to track if the form inputs have been changed without controlled component

For the second use case, here is an example with a TextField, a NumberField and a Select.

I tried with the form attribute on the <Input /> element but it land on the "aria input version" not the hidden one. The form attribute only purpose, if I'm correct, is to associate the input to the given form and should solve both use case. I cannot find a way to be sure it won't impact assistive technology.

@vincerubinetti
Copy link

vincerubinetti commented Apr 28, 2024

Related #6262

I've taken to just reimplementing these hidden inputs myself. Here's an example, but keep in mind that this is only to be used in FormData. It doesn't replace the hidden inputs RAC adds for accessibility, e.g. for slider thumbs.

<input
  className="sr-only"
  type="checkbox"
  aria-hidden={true}
  tabIndex={-1}
  value={isSelected ? checkedValue : uncheckedValue}
  checked={!(required && !isSelected)}
  required={required}
  name={name}
  form={form}
  onChange={() => null}
/>

Cannot believe that the supposedly golden standard component library overlooks this.

@devongovett devongovett added help wanted Extra attention is needed good first issue Good for newcomers labels Apr 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed rsp:Form
Projects
None yet
Development

No branches or pull requests

7 participants