Form Dialog

A modal dialog that renders a form.

FormDialog can be used to quickly request information from people without leaving the current page.

Import#

import { FormDialog } from '@saas-ui/modals'

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#

function Page() {
const disclosure = useDisclosure()
const onSubmit = async (data) => {
disclosure.onClose()
}
return (
<>
<Button onClick={() => disclosure.onOpen()}>Create new post</Button>
<FormDialog
title="New post"
defaultValues={{ title: '' }}
{...disclosure}
onSubmit={onSubmit}
>
<FormLayout>
<Field
name="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.

function Page() {
const disclosure = useDisclosure()
const initialRef = useRef()
const onSubmit = async (data) => {
disclosure.onClose()
}
return (
<>
<Button onClick={() => disclosure.onOpen()}>Create new post</Button>
<FormDialog
title="New post"
defaultValues={{ title: '' }}
{...disclosure}
onSubmit={onSubmit}
initialFocusRef={initialRef}
>
<FormLayout>
<Field
name="category"
label="Category"
type="select"
options={[
{
value: 'general',
label: 'General',
},
]}
ref={initialRef}
/>
<Field
name="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.

function Page() {
const disclosure = useDisclosure()
const schema = Yup.object().shape({
title: Yup.string().required().label('Title'),
description: Yup.string().label('Description').meta({ type: 'textarea' }),
})
const onSubmit = async (data) => {
disclosure.onClose()
}
return (
<>
<Button onClick={() => disclosure.onOpen()}>Create new post</Button>
<FormDialog
title="New post"
{...disclosure}
defaultValues={{
title: '',
description: '',
}}
onSubmit={onSubmit}
{...yupForm(schema)}
/>
</>
)
}
function Page() {
const disclosure = useDisclosure()
const initialRef = React.useRef()
const footer = (
<ModalFooter>
<SubmitButton label="Save post" />
</ModalFooter>
)
const onSubmit = async (data) => {
disclosure.onClose()
}
return (
<>
<Button
onClick={() => {
disclosure.onOpen()
}}
>
Create new post
</Button>
<FormDialog
title="New post"
{...disclosure}
onSubmit={onSubmit}
initialFocusRef={initialRef}
footer={footer}
>
<FormLayout>
<Field
name="title"
label="Title"
rules={{ required: 'Title is required' }}
ref={initialRef}
/>
<Field name="description" type="textarea" label="Description" />
</FormLayout>
</FormDialog>
</>
)
}

Accessibility#

Keyboard Interaction#

KeyAction
EnterWhen the dialog is open, submits the form.
EscapeWhen the dialog is open, closes the dialog.
TabFocus next field

Props#

FormDialog Props#

onSubmitrequired

Description

The submit handler.

Type
SubmitHandler<TFieldValues>

cancelLabel

Description

The cancel button label

Type
ReactNode
Default
"Cancel"

children

Description

If no children are passed, this will auto render fields based on the supplied schema.

Type
ReactNode

criteriaMode

Type
CriteriaMode

defaultValues

Type
{ [x: string]: any; }

delayError

Type
number

fieldResolver

Description

A schema field resolver used to auto generate form fields.

Type
FieldResolver

footer

Description

The modal footer, will be wrapped with ModalFooter. Defaults to a cancel and submit button.

Type
ReactNode

hideCloseButton

Description

Hide the close button

Type
boolean

hideOverlay

Description

Hide the overlay

Type
boolean

mode

Type
keyof ValidationMode

onChange

Description

Triggers when any of the field change.

Type
WatchObserver<TFieldValues>

onError

Description

Triggers when there are validation errors.

Type
SubmitErrorHandler<TFieldValues>

ref

Type
ForwardedRef<UseFormReturn<TFieldValues, any>>

resolver

Type
Resolver<TFieldValues, any>

reValidateMode

Type
"onBlur" | "onChange" | "onSubmit"

schema

Description

The form schema, currently supports Yup schema only.

Type
any

shouldFocusError

Type
boolean

shouldUnregister

Type
boolean

shouldUseNativeValidation

Type
boolean

submitLabel

Description

The submit button label

Type
ReactNode
Default
"Submit"

title

Description

The modal title

Type
ReactNode

Was this helpful?