auto-form
auto-form copied to clipboard
String Arrays Support
Hi there, First of all thanks for the great tool which you developed. For my case, I need AutoForm to support String Arrays. which unfortunately, I couldn't figure out how to do it.
The field is as below:
highlights: z
.array(
z
.string()
.describe(
"e.g. Increased profits by 20% from 2011-2012 through viral advertising"
)
)
.describe("Specify multiple accomplishments")
.optional(),
Currently, AutoForm only supports array of objects (https://github.com/vantezzen/auto-form#arrays) as inferring field labels etc. needs to be done another way otherwise. PRs welcome if you want to extend the functionality there!
Thanks Bennett for your response. I've resolved my issue by creating a new INPUT_COMPONENTS and tweaking the AutoForm as needed. However, given the specific nature of my modifications and the number of custom changes involved, submitting a pull request might not be feasible.
Thanks Bennett for your response. I've resolved my issue by creating a new INPUT_COMPONENTS and tweaking the AutoForm as needed. However, given the specific nature of my modifications and the number of custom changes involved, submitting a pull request might not be feasible.
Hi, can you share the modifications? I have also stumbled upon this problem
Hi, can you share the modifications? I have also stumbled upon this problem
For my case I created a Component for Tags listing for my project as blow:
import { useEffect, useRef, useState } from "react";
import { Button } from "./ui/button";
import { XIcon } from "lucide-react";
type Params = {
onValueChange?: (value: string[]) => void;
value: string[];
readonly?: boolean;
};
export function TagsListInput({ value, onValueChange, readonly }: Params) {
const [tags, setTags] = useState<string[]>();
const inputRef = useRef(null);
useEffect(() => {
if (value) {
setTags(value);
}
}, [value]);
useEffect(() => {
if (onValueChange && tags) {
onValueChange(tags);
}
}, [tags]);
return (
<>
{tags &&
tags.map((item, index) => (
<Button
key={"tag-" + index + "item"}
className="me-1 font-normal text-xs px-2.5 py-0.5 h-auto mb-1"
variant="secondary"
onClick={(e) => {
let temp = tags.filter((str, idx) => idx != index);
setTags(temp);
e.preventDefault();
}}
>
{item}
<XIcon className="ms-2 w-3" />
</Button>
))}
<input
type="text"
placeholder="Enter Keyword"
className="text-sm px-2.5 py-0.5 border-muted border w-32"
ref={inputRef}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === "Tab") {
let temp = tags;
if (!temp) temp = [];
if (inputRef.current) {
temp.push((inputRef.current as HTMLInputElement).value);
(inputRef.current as HTMLInputElement).value = "";
}
setTags([...temp]);
e.preventDefault();
}
}}
/>
</>
);
}
And I added an Autoform Field to the Autoform.ts file to support this new field as below:
function AutoFormTagsInput({
label,
isRequired,
field,
fieldConfigItem,
fieldProps,
}: AutoFormInputComponentProps) {
return (
<FormItem>
<FormLabel>
{label}
{isRequired && <span className="text-destructive"> *</span>}
</FormLabel>
<FormControl>
<TagsListInput
value={field.value}
onValueChange={field.onChange}
{...fieldProps}
/>
</FormControl>
{fieldConfigItem.description && (
<FormDescription>{fieldConfigItem.description}</FormDescription>
)}
<FormMessage />
</FormItem>
);
}
I added the support for the new component to the INPUT_COMPONENTS type as below:
const INPUT_COMPONENTS = {
...
tags: AutoFormTagsInput,
textlist: AutoFormTextListInput,
};
And in AutoForm usage I set the FieldConfig as below:
fieldConfig={{
keywords: { fieldType: "tags" },
}}
BTW, as I noted Bennett has refactored the project a lot. So, you must figure out how to do this approach on the updated project structure.
I hope it helps.
this is my implementation for handling primitive arrays. Huge thanks to the projects I forked and to all the other people whose answers I found useful. The list is virtualized, to manage large enums. This is draft code, but it should be sufficient for someone to refine and use. pull my code do yarn install then yarn run dev and you can see it working
https://shadcnui-expansions.typeart.cc/docs/multiple-selector https://github.com/oaarnikoivu/shadcn-virtualized-combobox/tree/main
you can see it in my forked repo
example https://github.com/vozmarkov/auto-form/blob/main/src/examples/ArrayPrimitive.tsx
multi select virtualized and uses popover for content https://github.com/vozmarkov/auto-form/blob/main/src/components/ui/multiple-selector.tsx
autofrom component https://github.com/vozmarkov/auto-form/blob/main/src/components/ui/auto-form/fields/enum-multi-input.tsx
auto from object.tsx array logic https://github.com/vozmarkov/auto-form/blob/7d5df68dcb312b2451e9cc3e6e577ed9aa4739a3/src/components/ui/auto-form/fields/object.tsx#L133