Reticle@etched/reticle 0.0.0

Dialog

The dialog panel, with its backdrop, in a portal.

Kumo source
import { TrashIcon } from "@phosphor-icons/react";
import { Button } from "@etched/reticle/button";
import { Dialog, DialogActions, DialogClose, DialogDescription, DialogRoot, DialogTitle, DialogTrigger } from "@etched/reticle/dialog";

export function Preview() {
  return (
    <DialogRoot role="alertdialog">
      <DialogTrigger render={<Button variant="secondary-destructive" icon={<TrashIcon />}>Delete chip</Button>} />
      <Dialog size="sm">
        <DialogTitle>Delete chip SH-24A-0193?</DialogTitle>
        <DialogDescription>Its runs and logs are deleted too. You cannot undo this.</DialogDescription>
        <DialogActions>
          <DialogClose render={<Button>Cancel</Button>} />
          <DialogClose render={<Button variant="destructive">Delete</Button>} />
        </DialogActions>
      </Dialog>
    </DialogRoot>
  );
}

Installation

import { Dialog, DialogActions, DialogClose, DialogDescription, DialogHeader, DialogRoot, DialogTitle, DialogTrigger } from "@etched/reticle/dialog";

Examples

Dialogs

import { Button } from "@etched/reticle/button";
import { Combobox } from "@etched/reticle/combobox";
import { Input } from "@etched/reticle/input";
import { Select } from "@etched/reticle/select";
import { Dialog, DialogActions, DialogClose, DialogDescription, DialogHeader, DialogRoot, DialogTitle, DialogTrigger } from "@etched/reticle/dialog";

export function Dialogs() {
  return (
    <div className="row">
      <DialogRoot>
        <DialogTrigger render={<Button variant="primary">Assign owner</Button>} />
        <Dialog size="lg">
          <DialogHeader close>Assign owner</DialogHeader>
          <DialogDescription>The owner gets alerts for chip SH-24A-0193.</DialogDescription>
          <Select label="Owner" items={{ ana: "Ana Ruiz", sam: "Sam Lee", kai: "Kai Ito" }} placeholder="Choose an owner" />
          <Combobox
            label="Reviewer"
            items={[
              { value: "ana", label: "Ana Ruiz" },
              { value: "sam", label: "Sam Lee" },
            ]}
            placeholder="Choose a reviewer"
          />
          <Input label="Note" placeholder="Optional note for the owner" />
          <DialogActions>
            <DialogClose render={<Button>Cancel</Button>} />
            <DialogClose render={<Button variant="primary">Assign</Button>} />
          </DialogActions>
        </Dialog>
      </DialogRoot>

      <DialogRoot role="alertdialog">
        <DialogTrigger render={<Button variant="secondary-destructive">Delete run</Button>} />
        <Dialog size="sm">
          <DialogTitle>Delete run 1,284?</DialogTitle>
          <DialogDescription>Its results and logs are deleted too. You cannot undo this.</DialogDescription>
          <DialogActions>
            <DialogClose render={<Button>Cancel</Button>} />
            <DialogClose render={<Button variant="destructive">Delete</Button>} />
          </DialogActions>
        </Dialog>
      </DialogRoot>
    </div>
  );
}

Saving

While the dialog saves, it cannot close: onOpenChange ignores the request, and the close button and Cancel show disabled.

import { useState } from "react";
import { Button } from "@etched/reticle/button";
import { Input } from "@etched/reticle/input";
import { Dialog, DialogActions, DialogClose, DialogHeader, DialogRoot, DialogTrigger } from "@etched/reticle/dialog";

export function Saving() {
  const [open, setOpen] = useState(false);
  const [busy, setBusy] = useState(false);

  const save = () => {
    setBusy(true);
    setTimeout(() => {
      setBusy(false);
      setOpen(false);
    }, 1200);
  };

  return (
    <DialogRoot open={open} onOpenChange={(next) => busy || setOpen(next)}>
      <DialogTrigger render={<Button>Rename trace</Button>} />
      <Dialog>
        <DialogHeader close closeDisabled={busy}>
          Rename trace
        </DialogHeader>
        <Input label="Name" defaultValue="Thermal soak, lot 7801" />
        <DialogActions>
          <DialogClose disabled={busy} render={<Button>Cancel</Button>} />
          <Button variant="primary" loading={busy} onClick={save}>
            Save
          </Button>
        </DialogActions>
      </Dialog>
    </DialogRoot>
  );
}

API reference

DialogHeader

PropTypeDefaultDescription
children *ReactNode–The title.
closeboolean–Shows a close button at the end of the title's line.
closeLabelstring"Close"Names the close button.
closeDisabledboolean–Shows the close button disabled, for example while the dialog saves and cannot close.

Dialog

PropTypeDefaultDescription
size"sm" | "base" | "lg" | "xl""base"
initialFocusPopupProps["initialFocus"]–What gets focus when the dialog opens, for example a ref to one field. By default, the first focusable element.
finalFocusPopupProps["finalFocus"]–What gets focus when the dialog closes. By default, the trigger.
aria-labelstring–Names a dialog that has no visible DialogTitle, such as a search dialog.
children *ReactNode–
classNamestring–

DialogRoot

PropTypeDefaultDescription
role"dialog" | "alertdialog"–