big-design
big-design copied to clipboard
Uncontrolled components
Is your feature request related to a problem? Please describe.
Currently I'm trying to execute an action
using Form
component from React Router's v6, that basically under the hood implements the native HTML Form element. It is a simple implementation to use it.
Code reference:
export const action: ActionFunction = async ({ request }) => {
const userId = await requireUserId(request);
const formData = await request.formData();
const title = formData.get("title");
const body = formData.get("body");
if (typeof title !== "string" || title.length === 0) {
return json<ActionData>(
{ errors: { title: "Title is required" } },
{ status: 400 }
);
}
if (typeof body !== "string" || body.length === 0) {
return json<ActionData>(
{ errors: { body: "Body is required" } },
{ status: 400 }
);
}
const note = await createNote({ title, body, userId });
return redirect(`/notes/${note.id}`);
};
<Form method="post">
<div>
<label>
<span>Title: </span>
<input
ref={titleRef}
name="title"
aria-invalid={actionData?.errors?.title ? true : undefined}
aria-errormessage={
actionData?.errors?.title ? "title-error" : undefined
}
/>
</label>
{actionData?.errors?.title && (
<div className="pt-1 text-red-700" id="title-error">
{actionData.errors.title}
</div>
)}
</div>
<button type='submit'>submit</button>
...
Using the native input's to perform that action works, but when I tried to use it with the BigDesign components, I can't use them because they only support the controlled behavior.
Describe the solution, feature, or improvement you'd like I try to use the styled components to apply to my uncontrolled input but the styles are not exported. So I recreate the input component without the controlled state and is working.
Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.
Additional context React router Form React router Action
Hey @GOI17, could you explain a little further on why BigDesign form controls are controlled-only?
From our perspective, we let you choose whether you want your inputs to be controlled vs. uncontrolled. I whipped up a little example on how I was able to hook up react-router-dom
+ @bigcommerce/big-design
with uncontrolled form controls: https://codesandbox.io/s/gifted-tree-pmmbir?file=/src/UncontrolledForm.tsx
That is my bad. I mentioned that we have had no issues using it as a controlled input and weren't sure if there was an issue the uncontrolled element, maybe it wasn't working? But I'm guessing it could be more related to the implementation inside React Router.
Retested and they are working fine. I think my problem was that I'm was not use the as
prop, I was only using the react router's Form
Radio buttons didn't work using them as uncontrolled components, https://codesandbox.io/s/uncontrolled-bigdesign-form-react-router-dom-forked-mhhvfx?file=/src/UncontrolledForm.tsx
You'll need to add the name
property for Radio to at least register. You should also be able to use defaultChecked
for radios, but I believe this issue https://github.com/bigcommerce/big-design/issues/1024 is going to block the visual experience for it. There's more to it though, however would have to look into it further.
I already tried adding the name prop, I don't know why the sandbox was not updated, but even if I set the prop name I have the same result, on click the form change their value, but the radios are unchecked always "visually"
I update my original CodeSandbox to show that those inputs are being registered and used correctly: https://codesandbox.io/s/gifted-tree-pmmbir?file=/src/UncontrolledForm.tsx
But yeah, it's going to be visually broken, hence #1024. PR's are always welcomed 😉