import type { DialogHTMLAttributes, ReactNode, Ref } from "react";
type Width = 400 | 560 | 720;
/** Where the panel sits. `inline-*` pin it full-height to that edge — that is
* a drawer / side sheet, and D66 is the decision that it is a placement rather
* than a sibling component. Logical, not `left`/`right`, so RTL flips without a
* second code path. */
export type DialogPlacement = "center" | "inline-start" | "inline-end";
export interface DialogProps extends Omit, "title" | "onClose" | "open"> {
/** Body content, between the title and footer slots. */
children?: ReactNode;
/** Controlled open state; syncs to showModal()/close(). */
open: boolean;
/** Called on every dismissal attempt with its source; the consumer flips `open`. */
onClose: (reason: "esc" | "backdrop" | "close-button") => void;
/** Heading; renders an wired to aria-labelledby. Without it, pass aria-label. */
title?: ReactNode;
/** Action row (Buttons — one accent per group, danger for destructive). */
footer?: ReactNode;
/** Panel width in px (400 | 560 | 720). For an `inline-*` placement this is
* the drawer's width; the height is always the full viewport. @default 560 */
width?: Width;
/** Where the panel sits. `inline-start` / `inline-end` pin it full-height to
* that edge, making it a drawer (D66). @default "center" */
placement?: DialogPlacement;
/** false = no close button, Esc and backdrop swallowed — footer is the only exit. @default true */
dismissible?: boolean;
/** Forwarded ref to the underlying