Skip to content
Yuzur1ha Open

Component referenceVersion Draft

Modal

Modal interrupts the current task for a focused decision or edit. Give every dialog a clear title and a reachable close action.

Design notes

Focus stays inside the dialog while open and returns to the trigger when closed. Keep a recoverable draft until the user confirms the change.

Design sourceOpen in Figma

Modal design

Inspect the original component, variants and visual details.

Playground

Playgrounddemo.tsx
Alex Morgan

content/components/modal/demo.tsx

import { useState } from "react"
import { Button, Modal, ModalClose, TextField } from "@yuzur1ha/ui"
import { DemoResult } from "../../examples/result"

export function ModalDemo() {
  const [formOpen, setFormOpen] = useState(false)
  const [name, setName] = useState("Alex Morgan")
  const [draft, setDraft] = useState(name)
  const [error, setError] = useState("")
  return (
    <>
      <div className="demo-row">
        <Modal
          trigger={<Button appearance="secondary">Open notice</Button>}
          title="Changes saved"
          description="Your account settings have been updated."
          closeLabel="Close"
        >
          <div className="yu-modal-actions">
            <ModalClose asChild>
              <Button>Done</Button>
            </ModalClose>
          </div>
        </Modal>
        <Modal
          trigger={<Button appearance="secondary">Open confirmation</Button>}
          title="Sign out of this demo?"
          description="This only closes the example. No real session will be changed."
          closeLabel="Close"
        >
          <div className="yu-modal-actions">
            <ModalClose asChild>
              <Button appearance="secondary">Cancel</Button>
            </ModalClose>
            <ModalClose asChild>
              <Button>Sign out</Button>
            </ModalClose>
          </div>
        </Modal>
        <Modal
          open={formOpen}
          onOpenChange={(next) => {
            setFormOpen(next)
            if (next) {
              setDraft(name)
              setError("")
            }
          }}
          trigger={<Button>Open form</Button>}
          title="Edit display name"
          description="Use a name people recognize."
          closeLabel="Close"
        >
          <form
            style={{ display: "grid", gap: "var(--yu-space-4)" }}
            onSubmit={(event) => {
              event.preventDefault()
              if (draft.trim().length < 2 || draft.trim().length > 64) {
                setError("Use between 2 and 64 characters.")
                return
              }
              setName(draft.trim())
              setFormOpen(false)
            }}
          >
            <TextField
              label="Display name"
              value={draft}
              onChange={(event) => setDraft(event.target.value)}
              {...(error ? { error } : {})}
            />
            <div className="yu-modal-actions">
              <ModalClose asChild>
                <Button appearance="secondary">Cancel</Button>
              </ModalClose>
              <Button type="submit">Save changes</Button>
            </div>
          </form>
        </Modal>
      </div>
      <DemoResult>{name}</DemoResult>
    </>
  )
}

API

Modal

A modal dialog with required title and description. Focus is managed by Radix; outside pointer interaction does not dismiss it. Escape and close actions do.

ModalProps
PropertyTypeRequiredDefaultDescription
triggerReactElementYes—One ref-capable action element used as the dialog trigger.
titlestringYes—Required visible and accessible dialog title.
descriptionstringYes—Required visible and accessible dialog description.
closeLabelstringYes—Accessible name of the built-in close action.
openbooleanNo—Controlled open state. Pair with onOpenChange.
defaultOpenbooleanNofalseInitial open state when open is omitted.
onOpenChange((open: boolean) => void)No—Called when opening or closing is requested.
childrenReactNodeYes—Content rendered inside the component.
classNamestringNo""Additional classes applied to the component’s documented root or control.

No custom imperative methods. Event callbacks are listed as properties.

ModalClose

Closes the nearest matching overlay. Use asChild with one ref-capable action element, or render the default native button.

ComponentPropsWithRef<typeof ModalClose>
PropertyTypeRequiredDefaultDescription
asChildbooleanNofalseRender through one child element instead of the default element. The child must forward its ref and accept the supplied props.
childrenReactNodeNo—Content rendered inside the component.
disabledbooleanNo—Disables the native control.
onClickMouseEventHandler<HTMLButtonElement>No—Native activation handler.
classNamestringNo—Additional classes applied to the component’s documented root or control.
idstringNo—DOM identifier for the rendered element.
refRef<HTMLButtonElement>No—Ref to the component’s documented DOM element.

No custom imperative methods. Event callbacks are listed as properties.