import { CommonProps } from "@trackunit/react-components";
import { ReactElement, ReactNode } from "react";
import type { DrawerPosition } from "../../types";
import type { DrawerFloatingUiProps, DrawerVariant } from "./useDrawer";
/**
* Presentational props for `Drawer`. State (`isOpen`), resolved `variant`,
* focus-trap opt-in (`trapFocus`), `position`, and Floating UI wiring
* (`floatingUi`) all flow in from `useDrawer()`.
*
* Decoupled from the full `UseDrawerReturnValue` — `Drawer` only declares the
* props it actually reads. Consumers spread the hook return
* (``) and TypeScript allows extra properties on spread
* expressions, so the imperative actions (`open` / `close` / `toggle` /
* `requestClose`) travel through the JSX without being typed here. This keeps
* the Storybook autodocs table (and the component's declared surface) focused
* on what `Drawer` genuinely consumes. Mirrors `Sheet`'s pattern in
* `@trackunit/react-components`.
*/
export interface DrawerProps extends CommonProps {
/**
* Current open state — spread from `useDrawer()`. Drives the enter / exit
* animation and whether the overlay renders (when `variant="modal"`).
*/
readonly isOpen: boolean;
/**
* Semantic variant controlling backdrop, focus trap, and dismiss behavior.
* Spread from `useDrawer()`. See {@link DrawerVariant}.
*/
readonly variant: DrawerVariant;
/**
* Whether to trap focus inside the panel when `variant="modal"`. Ignored for
* `variant="default"` (which never traps focus). Spread from `useDrawer()`.
*/
readonly trapFocus: boolean;
/**
* Which edge of the viewport the panel is anchored to and slides in from.
* Spread from `useDrawer()`.
*/
readonly position: DrawerPosition;
/**
* Floating UI wiring for the panel's focus manager and dismiss bindings.
* `Drawer` merges `refs.setFloating` onto the panel and uses `context` for
* its `FloatingFocusManager`. Spread from `useDrawer()`.
*/
readonly floatingUi: DrawerFloatingUiProps;
/**
* Content rendered inside the drawer panel. Compose layout parts explicitly — typically
* `` (or a custom header such as `CardHeader`) followed by the body.
*/
children?: ReactNode;
/**
* Whether to render the drawer in a portal or not.
* Default is false.
* If true, the drawer will be rendered in a portal at the end of the document.
* This is useful when the drawer needs to be rendered on top of other elements.
* For example, when the drawer is used with a map component.
*/
renderInPortal?: boolean;
/**
* The class name for the drawer container.
*/
containerClassName?: string;
/**
* Accessible name for the drawer's panel, forwarded as `aria-label`. Strongly recommended:
* without either this or `ariaLabelledBy`, assistive technology has no name for the panel and
* will announce it as an unnamed dialog / region. Mutually exclusive in intent with
* `ariaLabelledBy` — set one or the other, not both.
*/
ariaLabel?: string;
/**
* Id of an existing element (typically a heading rendered inside the drawer body) whose text
* names the drawer's panel, forwarded as `aria-labelledby`. Prefer this over `ariaLabel` when
* the drawer body renders a visible heading so the two stay in sync.
*/
ariaLabelledBy?: string;
/**
* Internal signal fired exactly once per genuine open→close→fully-exited cycle,
* once the panel has actually finished animating (or would have, in headless /
* test environments where CSS transitions are suppressed) off-screen. Spread from
* `useDrawer()`, which uses it to flip its `isExiting` state back to `false`.
*
* Does not fire for the enter-settle transitionend, on initial mount, while
* remaining closed, or more than once for the same close cycle even if both the
* real `transitionend` and the headless RAF fallback resolve it.
*/
readonly onExitComplete?: () => void;
}
/**
* Drawers slide in from the left or right edge of the viewport as either a modal
* dialog or a docked inspector panel.
*
* ### When to use
* - For secondary content that doesn't need to be always visible
* - For inspector panels or item detail views that slide in from the side
* - When you need to preserve context of the underlying page
*
* ### When not to use
* - For critical actions requiring user confirmation (use Modal instead)
* - For simple tooltips or small contextual information (use Popover)
* - To show a table selection and bulk actions (use ActionSheet instead)
*
* ### API
* `Drawer` is a presentation component. Call `useDrawer()` to own the drawer's
* open state, dismiss handling, and (optional) `onBeforeClose` guard, then spread
* its return value onto ``.
*
* @example Basic modal drawer with the standard toolbar
* ```tsx
* import { Drawer, DrawerHeader, useDrawer } from "@trackunit/react-drawer";
* import { Button } from "@trackunit/react-components";
*
* const FilterDrawer = () => {
* const drawer = useDrawer({ position: "right", variant: "modal" });
*
* return (
* <>
*
*
*
*