ArrayField
Form field component to handle array type values.
The ArrayField
helps you to create complex forms with ease.
It uses React Hook Forms useFieldArray
internally.
Source
@saas-ui/forms
- 2.11.2 (latest)
Import#
ArrayField
: The wrapper component that composes the default ArrayField functionality.ArrayFieldContainer
: The container component provides context and state management.ArrayFieldRows
: Render prop component, to get access to the internal fields state. Must be a child ofArrayFieldContainer
.ArrayFieldRowContainer
: The row container component providers row context.ArrayFieldRowFields
: Add the name prefix to the fields and acts as a horizontal form layout by default.ArrayFieldAddButton
: The default add button.ArrayFieldRemoveButton
: The default remove button.useArrayFieldContext
: A hook that returns theArrayField
internal state.useArrayFieldRowContext
: A hook that returns theArrayFieldRowContainer
state.useArrayFieldAddButton
: A hook that can be used to create a custom add button.useArrayFieldRemoveButton
: A hook that can be used to create a custom remove button.
import {ArrayField,ArrayFieldContainer,ArrayFieldRows,ArrayFieldRowContainer,ArrayFieldRowFields,ArrayFieldAddButton,ArrayFieldRemoveButton,useArrayFieldContext,useArrayFieldRowContext,useArrayFieldAddButton,useArrayFieldRemoveButton,} from '@saas-ui/react'
Usage#
Auto generated form#
Simple array of string values.
function CreateTodoItem() {const schema = {title: {label: 'Title',rules: {required: true,},},todos: {type: 'array',min: 1,items: {type: 'object',properties: {todo: {label: 'Todo',},},},},}return (<FormdefaultValues={{title: '',todos: [],}}schema={schema}onSubmit={() => null}/>)}
Basic object array#
Field names inside an ArrayField
need to be prefixed with array-field-name.$
. The $
will be replaced with the index of the array item.
import { SubmitButton } from '@saas-ui/react'import { Form } from '@saas-ui/forms/yup'import * as yup from 'yup'const issueSchema = yup.object().shape({title: yup.string().required().label('Title'),})const schema = issueSchema.concat(yup.object().shape({issues: yup.array().min(1).max(4).of(issueSchema),}))export default function CreateIssue() {return (<Formschema={schema}defaultValues={{title: '',issues: [{ title: '' }],}}onSubmit={() => Promise.resolve()}>{({ Field, ArrayField }) => (<FormLayout><Field name="title" label="Title" /><ArrayField name="issues" label="Sub-issues"><Field name="issues.$.title" placeholder="Sub-issue title" /></ArrayField><SubmitButton>Create todo</SubmitButton></FormLayout>)}</Form>)}
Complex array field#
The array field can be fully composed to fit your specific use case.
import { SubmitButton } from '@saas-ui/react'import { Form } from '@saas-ui/forms/yup'import * as yup from 'yup'const usersSchema = yup.object().shape({id: yup.string().required().label('Id'),name: yup.string().required().label('Name'),lastName: yup.string().required().label('Last name'),})const schema = yup.object().shape({users: yup.array().min(1).max(4).of(usersSchema),})export default function CustomArrayField() {return (<Formschema={schema}defaultValues={{users: [{id: '123',name: 'Eelco',lastName: 'Wiersma',},],}}onSubmit={() => Promise.resolve()}>{({ Field }) => (<FormLayout><ArrayFieldContainername="users"label="Users"defaultValue={{}}keyName="key"min={2}max={4}><ArrayFieldRows>{(fields) => (<>{fields.map((field, i) => {return (<ArrayFieldRowContainer key={field.key} index={i}><ArrayFieldRowFields columns={3} spacing={1}><Field name="users.$.id" placeholder="Id" /><Field name="users.$.name" placeholder="Name" /><Box><Fieldname={`users.${i}.lastName`}placeholder="Last name"/></Box></ArrayFieldRowFields><ArrayFieldRemoveButton /></ArrayFieldRowContainer>)})}</>)}</ArrayFieldRows><ArrayFieldAddButton /></ArrayFieldContainer><SubmitButton label="Submit" /></FormLayout>)}</Form>)}
Custom buttons#
Use the useArrayFieldContext
and useArrayFieldRowContext
hooks to interact with the ArrayFieldContainer and create advanced custom components.
The useArrayFieldAddButton
and useArrayFieldRemoveButton
hooks can be used to create custom buttons.
import { Button } from '@saas-ui/react'import {useArrayFieldContext,useArrayFieldAddButton,useArrayFieldRemoveButton,} from '@saas-ui/react'const SimpleAddButton = () => {return <Button {...useArrayFieldAddButton()}>Add record</Button>}const CustomAddButton = () => {const { append, defaultValue, max, fields } = useArrayFieldContext()const isDisabled = !!(max && fields.length >= max)return (<ButtononClick={() =>append(defaultValue, {shouldFocus: true,focusName: `arrayField.${fields.length}.id`,})}isDisabled={isDisabled}>Add record</Button>)}const RemoveButton = () => {return (<Button variant="ghost" {...useArrayFieldRemoveButton()}>Remove</Button>)}
Accessing the ArrayField context#
You can access the ArrayField context by using a ref, or using useArrayFieldContext
import { Button } from '@chakra-ui/react'import { SubmitButton } from '@saas-ui/react'import { Form } from '@saas-ui/forms/yup'import * as yup from 'yup'const issueSchema = yup.object().shape({title: yup.string().required().label('Title'),})const schema = issueSchema.concat(yup.object().shape({issues: yup.array().min(1).max(4).of(issueSchema),}))export default function CreateIssue() {const ref = React.useRef(null)return (<FormdefaultValues={{title: '',issues: [{ title: '' }],}}onSubmit={() => Promise.resolve()}>{({ Field, ArrayField }) => (<FormLayout><Field name="title" label="Title" /><ArrayField name="issues" label="Sub-issues" ref={ref}><Field name="issues.$.title" placeholder="Sub-issue title" /></ArrayField><ButtononClick={() =>ref.current.append({ title: 'Appended using the ref api' })}>Add todo</Button><SubmitButton>Create todo</SubmitButton></FormLayout>)}</Form>)}
Was this helpful?