Siteplane UI

Overlays and confirmation

Choose an overlay by the action, focus behavior, and amount of content.

Markdown

Choose the surface

NeedComponent
A focused task or formDialog
Confirm a consequential actionAlertDialog
Anchored interactive contentPopover
Supplemental hover/focus informationTooltip
Preview a linked objectPreviewCard
Edge panel for navigation or contentSheet
Edge panel with swipe to dismissDrawer
A composed right-side detail viewDetailDrawer

Keep the accessible structure

"use client";

import { Button } from "@/siteplane/components/button";
import {
  Dialog,
  DialogClose,
  DialogPopup,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogPanel,
  DialogTitle,
  DialogTrigger,
} from "@/siteplane/components/dialog";
import { Field, FieldError, FieldLabel } from "@/siteplane/components/field";
import { Form } from "@/siteplane/components/form";
import { Input } from "@/siteplane/components/input";
import { useState } from "react";

export default function Example() {
  const [open, setOpen] = useState(false);
  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger render={<Button variant="outline" />}>
        Rename project
      </DialogTrigger>
      <DialogPopup>
        <Form
          onSubmit={(event) => {
            event.preventDefault();
            setOpen(false);
          }}
        >
          <DialogHeader>
            <DialogTitle>Rename project</DialogTitle>
            <DialogDescription>
              Everyone in the workspace will see the new name.
            </DialogDescription>
          </DialogHeader>
          <DialogPanel>
            <Field name="name">
              <FieldLabel>Project name</FieldLabel>
              <Input defaultValue="Website Redesign" required />
              <FieldError match="valueMissing">
                Enter a project name.
              </FieldError>
            </Field>
          </DialogPanel>
          <DialogFooter>
            <DialogClose render={<Button variant="ghost" />}>
              Cancel
            </DialogClose>
            <Button type="submit">Save</Button>
          </DialogFooter>
        </Form>
      </DialogPopup>
    </Dialog>
  );
}

Compose the documented trigger, content, title, description, and close parts. The styled popup/content owns its portal infrastructure according to the component page; do not duplicate a portal/backdrop around a part that already includes it.

Give every dialog an accessible name. A tooltip is optional supporting information and must not be the only label for an icon button. Keep long content scrollable inside the provided panel/body parts. In a Dialog, DialogPanel scrolls while the header and footer stay in view; see Scrollable content.

Confirm an operation

The application owns the pending request, success, and failure. Keep the confirmation open on failure and preserve context; close it only after the intended result. Label the final action specifically, such as “Archive resource”. Do not treat closing a dialog as proof that an operation succeeded.

Confirm a request shows this with an AlertDialog that deletes an account. Its destructive button shows the loading state, a failed request keeps the dialog open with an error message, and only a request that succeeds closes it.

Focus and nested overlays

Test opening with the keyboard, Tab and Shift+Tab, Escape, and focus restoration. For exceptions, use the focus and dismissal props documented on each overlay page. Nested confirmations should return focus to a useful trigger or application control when they close.

Portals leave ordinary DOM ancestry. Put an explicit theme on SiteplaneUIProvider to carry it into kit portal scopes, and verify any application-specific CSS custom properties reach the overlay.

Complete application

Resource management combines a DetailDrawer with an AlertDialog that confirms a local archive action. The full example includes both state transitions; replace the local mutation with your service while keeping its confirmation semantics.