Form Dialog
A modal dialog that renders a form.
FormDialog
can be used to quickly request information from people without leaving the current page.
Source
@saas-ui/modals
- 2.10.0 (latest)
Import
import { FormDialog } from '@saas-ui/react'
Best practises
Do
- Use FormDialog for simple forms to increase productivity.
- Set focus on the first field.
Don't
- Use more than 4/5 fields in a dialog.
Usage
import { Button, useDisclosure } from '@chakra-ui/react'import { FormDialog, FormLayout } from '@saas-ui/react'import { FiUsers, FiTag, FiArchive } from 'react-icons/fi'export default function Page() {const disclosure = useDisclosure()const onSubmit = async (data) => {disclosure.onClose()}return (<><Button onClick={() => disclosure.onOpen()}>Create new post</Button><FormDialogtitle="New post"defaultValues={{ title: '', description: '' }}{...disclosure}onSubmit={onSubmit}>{({ Field }) => (<FormLayout><Fieldname="title"label="Title"type="text"rules={{ required: 'Title is required' }}autoFocus/><Field name="description" type="textarea" label="Description" /></FormLayout>)}</FormDialog></>)}
Focus first field
Use initialFocusRef
for fields that don't support autoFocus
.
import { Button, useDisclosure } from '@chakra-ui/react'import { FormDialog, FormLayout } from '@saas-ui/react'import { FiUsers, FiTag, FiArchive } from 'react-icons/fi'export default function Page() {const disclosure = useDisclosure()const initialRef = useRef()const onSubmit = async (data) => {disclosure.onClose()}return (<><Button onClick={() => disclosure.onOpen()}>Create new post</Button><FormDialogtitle="New post"defaultValues={{ title: '' }}{...disclosure}onSubmit={onSubmit}initialFocusRef={initialRef}><FormLayout><Fieldname="category"label="Category"type="select"options={[{value: 'general',label: 'General',},]}ref={initialRef}/><Fieldname="title"label="Title"rules={{ required: 'Title is required' }}/><Field name="description" type="textarea" label="Description" /></FormLayout></FormDialog></>)}
Auto form
When you don't pass any children and supply a schema, the fields will be auto rendered.
import { Button, useDisclosure } from '@chakra-ui/react'import { FormLayout, FormDialog } from '@saas-ui/react'import { FiUsers, FiTag, FiArchive } from 'react-icons/fi'const schema = {title: {type: 'text',label: 'Title',rules: {required: 'Title is required',},},description: {type: 'textarea',label: 'Description',},}export default function Page() {const disclosure = useDisclosure()const onSubmit = async (data) => {disclosure.onClose()}return (<><Button onClick={() => disclosure.onOpen()}>Create new post</Button><FormDialogtitle="New post"schema={schema}{...disclosure}defaultValues={{title: '',description: '',}}onSubmit={onSubmit}/></>)}
Custom footer
import { Button, useDisclosure, MenuItem } from '@chakra-ui/react'import { FormDialog, FormLayout } from '@saas-ui/react'import { FiUsers, FiTag, FiArchive } from 'react-icons/fi'export default function Page() {const disclosure = useDisclosure()const initialRef = React.useRef()const footer = (<ModalFooter><SubmitButton>Save post</SubmitButton></ModalFooter>)const onSubmit = async (data) => {disclosure.onClose()}return (<><ButtononClick={() => {disclosure.onOpen()}}>Create new post</Button><FormDialogtitle="New post"{...disclosure}onSubmit={onSubmit}initialFocusRef={initialRef}footer={footer}>{({ Field }) => (<FormLayout><Fieldname="title"label="Title"rules={{ required: 'Title is required' }}ref={initialRef}/><Field name="description" type="textarea" label="Description" /></FormLayout>)}</FormDialog></>)}
ZodFormDialog
To use Zod schemas, you can import FormDialog
from @saas-ui/modals/zod
.
import { Button, useDisclosure } from '@chakra-ui/react'import { FormLayout, createFormDialog } from '@saas-ui/react'import { FiUsers, FiTag, FiArchive } from 'react-icons/fi'import { FormDialog } from '@saas-ui/modals/zod'import * as z from 'zod'const schema = z.object({title: z.string().nonempty().describe('Title'),description: z.string().optional().describe('Description'),})export default function Page() {const disclosure = useDisclosure()const onSubmit = async (data) => {disclosure.onClose()}return (<><Button onClick={() => disclosure.onOpen()}>Create new post</Button><FormDialogtitle="New post"schema={schema}{...disclosure}defaultValues={{title: '',description: '',}}fields={{description: {type: 'textarea',},}}onSubmit={onSubmit}/></>)}
YupFormDialog
To use Yup schemas, you can import FormDialog
from @saas-ui/modals/yup
.
import { Button, useDisclosure } from '@chakra-ui/react'import { FormLayout, createFormDialog } from '@saas-ui/react'import { FiUsers, FiTag, FiArchive } from 'react-icons/fi'import { FormDialog } from '@saas-ui/modals/yup'import * as yup from 'yup'const schema = yup.object().shape({title: yup.string().required().label('Title'),description: yup.string().label('Description').meta({ type: 'textarea' }),})export default function Page() {const disclosure = useDisclosure()const onSubmit = async (data) => {disclosure.onClose()}return (<><Button onClick={() => disclosure.onOpen()}>Create new post</Button><FormDialogtitle="New post"schema={schema}{...disclosure}defaultValues={{title: '',description: '',}}fields={{description: {type: 'textarea',},}}onSubmit={onSubmit}/></>)}
Accessibility
Keyboard Interaction
Key | Action |
---|---|
Enter | When the dialog is open, submits the form. |
Escape | When the dialog is open, closes the dialog. |
Tab | Focus next field |
Was this helpful?