Closed mulyoved closed 1 year ago
Yeah I'd agree it's probably a little too magical, but I like the idea of expanding the use case coverage to support at least simple containers.
One approach I've thought of is potentially some special container fields that can be used in the schema or something?
const MyContainer = createContainer('id', ContainerComponent);
const MyFormSchema = z.object({
containedFields: MyContainer({
textField: z.string(),
numberField: z.number()
})
})
Or:
const MyFormSchema = z.object({
...MyContainer({
textField: z.string(),
numberField: z.number()
})
})
Would render the components for textField
and numberField
as a children of ContainerComponent
.
And then use some hardcore typescript magic to make the form type be treated as:
{
textField: string,
numberField: number,
}
Could export a few default one's for simple use cases like Rows and stuff.
What about that? Would it enable the same stuff you're doing with your current approach?
To be honest, I don't like the idea of pushing this information to the zod object, already too much TypeScript magic around it and this is the place to do validation if I have complex validation like refine at the object/form level this will get in the way
I think not having container around multiple form section it's actually the only reason I can't use this library right know. The fact that you just can't place two inputs with unrelated type side-by-side is a no-go for me.
It's a shame because I realize that I'm hardly trying to do what this library do by myself. And it take time, has a lot of boilerplate and it's not working great.
we have this use case too. here's an idea a co-worker @gpeal came up with: the loose idea would be to pass the rendered form field components in a named map to the CustomFormComponent given to react-ts-form. Then we could build the following, which gives us ultra layout flexibility without sacrificing any of the benefits of generating the components:
function MyForm() {
return (
<ZodForm schema={z.object({title : z.string(), description: z.string()})}>
{({childMap}) => (
<Box>
{childMap['title']}
<Typography>Some text</Typography>
{childMap['description']}
</Box>
)}
</ZodForm>
)
}
seems like this method could solve https://github.com/iway1/react-ts-form/issues/34 as well if we also pass the formstate per field as props here?
From the limitations section:
@ts-react/form allows you to pass props to your components and render elements in between your components, which is good for almost all form designs out there. Some designs may not be easily achievable. For example, if you need a container around multiple sections of your form, this library doesn't allow splitting child components into containers at the moment. (Though if it's a common-enough use case and you'd like to see it added, open an issue!)
Not sure what will be the right approach but I like to be declarative as possible
For now, I experimented with this approach, not sure I like the DX, too much magic?
Passing some components to beforeElement, like section header GridColumnHeader
before layout the childrens, do some Children.toArray(children) tricks to split them based on the beforeElement and plot each part as separate section
Not sure I like this approach but it seem to do the work