Skip to content
React NativeBeta

Dialog

Alert, confirm and prompt dialogs, awaited from code with dialog.confirm().

Beta. React Native support is in beta. APIs may change or break between prereleases (npm tag native).

On this page
Web preview — real device may differ
tsx
import { useState } from "react";
import { Text } from "react-native";
import { Button } from "@/component-lib/button";
import { Dialog, DialogHost, dialog } from "@/component-lib/dialog";
import { useKitTheme } from "@/component-lib/shared/native";
import { Row, Section } from "./layout"; // Section and Row: page layout for the demo
 
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
 
export function DialogDemo() {
  const { tokens } = useKitTheme();
  const [answer, setAnswer] = useState("—");
  const [open, setOpen] = useState(false);
 
  return (
    <>
      {/* Normally mounted once at the app root; here so the demo stands alone. */}
      <DialogHost />
 
      <Section title="dialog · promise API">
        <Row>
          <Button
            variant="danger"
            onPress={async () => {
              const ok = await dialog.confirm({
                title: "Delete 3 invoices?",
                description: "They move to the bin for 30 days.",
                intent: "danger",
                confirmLabel: "Delete",
                onConfirm: async () => {
                  await wait(900);
                },
              });
              setAnswer(`confirm → ${ok}`);
            }}
          >
            Confirm (danger)
          </Button>
          <Button
            variant="outline"
            onPress={async () => {
              const name = await dialog.prompt({
                title: "Rename report",
                inputLabel: "Report name",
                defaultValue: "Q3 collections",
                required: true,
                validate: (v) => (v.length > 40 ? "Keep it under 40 characters." : null),
              });
              setAnswer(`prompt → ${JSON.stringify(name)}`);
            }}
          >
            Prompt
          </Button>
        </Row>
        <Row>
          <Button
            variant="secondary"
            onPress={async () => {
              await dialog.alert({ title: "Export ready", description: "invoices-q3.xlsx was saved.", intent: "success" });
              setAnswer("alert → closed");
            }}
          >
            Alert (success)
          </Button>
          <Button
            variant="secondary"
            onPress={async () => {
              const ok = await dialog.confirm({
                title: "Retry the upload?",
                intent: "warning",
                onConfirm: async () => {
                  await wait(700);
                  throw new Error("The server is still unreachable.");
                },
              });
              setAnswer(`confirm → ${ok}`);
            }}
          >
            Confirm that fails
          </Button>
        </Row>
        <Text style={{ color: tokens.muted }}>Last answer: {answer}</Text>
      </Section>
 
      <Section title="Dialog · controlled">
        <Button variant="outline" onPress={() => setOpen(true)}>
          Open info dialog
        </Button>
        <Dialog
          open={open}
          kind="alert"
          intent="info"
          title="Statements are generated nightly"
          description="Changes you make today appear in tomorrow's statement."
          onClose={() => setOpen(false)}
        />
      </Section>
    </>
  );
}

Install

npx @grampro/kit@native add DialogHost

Usage

tsx
import { DialogHost, dialog } from "@/component-lib/dialog";
 
// Once, inside KitProvider:
<DialogHost />
 
const ok = await dialog.confirm({ title: "Delete invoice?", intent: "danger" });

Props

DialogProps

PropTypeDescription
open (required)booleanWhether the dialog is on screen. Always controlled: set it to false in onClose.
kindDialogKindalert has one button, confirm two, prompt adds a text field. Default confirm.
onConfirm(value: string) => void | Promise<void>Runs on Confirm, with the prompt's value. While its promise is pending the buttons show progress; if it throws, the error is shown and the dialog stays open.
onClose(action: DialogAction, value: string) => voidThe user answered. Set open to false here.
onExited() => voidThe exit animation finished.
idstring
styleStyleProp<ViewStyle>
stylesPartial<{ root: StyleProp<ViewStyle>; body: StyleProp<ViewStyle>; icon: StyleProp<ViewS…
localeTextPartial<DialogLocaleText>

Also accepts the props of Omit<PromptOptions, "onConfirm">.

DialogHostProps

PropTypeDescription
storeDialogStoreA store from createDialogStore(). Defaults to the one behind dialog.
styleDialogProps["style"]Applied to every dialog this host shows.
stylesDialogProps["styles"]
localeTextPartial<DialogLocaleText>

Native and web

  • Android back cancels. The prompt picks its keyboard from inputType and moves above it.
  • Web version: Dialog on the web.