HextaUI

Dialog: Form

Keep the form in <DialogBody /> and point the submit button in the footer at it with form. Enter submits, and the dialog closes through onOpenChange once the value is saved.

Workspace: Acme

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogBody,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"

export function DialogForm() {
  const [open, setOpen] = React.useState(false)
  const [name, setName] = React.useState("Acme")
  const [draft, setDraft] = React.useState(name)
  const formId = React.useId()

  return (
    <div className="flex flex-col items-center gap-3">
      <Dialog
        open={open}
        onOpenChange={(nextOpen) => {
          if (nextOpen) {
            setDraft(name)
          }
          setOpen(nextOpen)
        }}
      >
        <DialogTrigger render={<Button variant="outline" />}>
          Rename workspace
        </DialogTrigger>
        <DialogContent size="sm">
          <DialogHeader>
            <DialogTitle>Rename workspace</DialogTitle>
            <DialogDescription>
              Everyone in the workspace will see the new name.
            </DialogDescription>
          </DialogHeader>
          <DialogBody>
            <form
              id={formId}
              onSubmit={(event) => {
                event.preventDefault()
                setName(draft.trim() || name)
                setOpen(false)
              }}
            >
              <FieldGroup>
                <Field>
                  <FieldLabel>Workspace name</FieldLabel>
                  <Input
                    name="name"
                    value={draft}
                    onChange={(event) => setDraft(event.target.value)}
                    required
                  />
                </Field>
              </FieldGroup>
            </form>
          </DialogBody>
          <DialogFooter>
            <DialogClose render={<Button variant="outline" />}>
              Cancel
            </DialogClose>
            <Button type="submit" form={formId}>
              Save
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
      <p className="text-sm text-muted-foreground">Workspace: {name}</p>
    </div>
  )
}

This adds the example as components/examples/dialog/form.tsx, together with the Dialog component and the HextaUI theme tokens it needs.

pnpm dlx shadcn@latest add https://hextaui.com/r/dialog-form.json

To add only the component, follow the Dialog installation.

Props in this example

The Dialog props this example sets, from the API reference.

PropTypeDefault
open
boolean–
onOpenChange
(open: boolean, details) => void–
PropTypeDefault
render
ReactElement | (props, state) => ReactElement<button>
PropTypeDefault
size
"sm" | "default" | "lg""default"
PropTypeDefault
render
ReactElement | (props, state) => ReactElement<button>

Every prop is in the Dialog API reference.

See them all, with keyboard support and accessibility notes, on the Dialog page.