Dialog

@sushindustries/ui

A native dialog driven by props: top layer, focus trap and Escape from the element, click-outside from here.

5 min read
View as MarkdownEdit on GitHub

Examples are the tab where the component is shown doing a job, not demonstrating a prop. The API tab already lists the props.

Viewport width
Phone22remthe floor, the narrowest this promises to work at
tanstacktanstack add https://adamjurek.com/r/tanstack/dialog.jsonshadcnpnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/dialog.json

Press Compare. The frames are real viewports, so a layout that breaks at 320 breaks here too rather than in somebody's hands.

In a page

import { useState } from "react";
import { Button, Dialog } from "@sushindustries/ui";

export function DeletePostButton({ onDelete }: { onDelete: () => void }) {
	const [confirming, setConfirming] = useState(false);

	return (
		<>
			<Button variant="ghost" onClick={() => setConfirming(true)}>
				Delete
			</Button>
			<Dialog
				open={confirming}
				onClose={() => setConfirming(false)}
				title="Delete this post?"
				footer={
					<>
						<Button variant="ghost" onClick={() => setConfirming(false)}>
							Cancel
						</Button>
						<Button
							onClick={() => {
								setConfirming(false);
								onDelete();
							}}
						>
							Delete
						</Button>
					</>
				}
			>
				This cannot be undone.
			</Dialog>
		</>
	);
}
tsx

What this example is not

Not a form dialog. children here is a sentence, not inputs - a dialog that collects data needs its own focus-management thinking about which field gets focus on open, which this example never has to consider.

UsesIconIconThe glyph set, generated from a Markdown table where every drawing carries its reason. One component, typed names, no icon font.@sushindustries/ui · content