Open tchak opened 1 year ago
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
}
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.
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 :
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.
Related https://github.com/adobe/react-spectrum/discussions/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.
🙋 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 setform
attribute in anuseEffect
. In some cases I am also usingdata-testid
to gain access to underlying DOM/input and setform
attribute in anuseEffect
. Neither is a good solution.Another solution is to not use internal
<input>
(not setname
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.