/**
 * @file BottomSheet.tsx
 * @input Uses React, StyleX, theme tokens, core hooks (useScrollLock), utils, useSheetGestures
 * @output Exports BottomSheet component and BottomSheetProps
 * @position Lab implementation; consumed by index.ts, tested by BottomSheet.test.tsx, demonstrated in Storybook
 *
 * A mobile touch surface that rises from the bottom edge: grab handle, snap
 * points, and swipe-to-dismiss. It owns a native `<dialog>` directly and
 * composes core primitives (`useScrollLock`, `<dialog>.showModal()` for the
 * top layer + focus trap, a `::backdrop` scrim) rather than delegating to a
 * heavier overlay component — so it controls its own sizing and can render a
 * full-height transparent shell with the visible sheet bottom-anchored inside.
 * That shell is what lets the sheet translate freely (including a little past
 * fully-open) without clipping against a fixed dialog edge.
 *
 * `hasScrim` picks the presentation: `true` (default) uses `showModal()` (top
 * layer, focus trap, scrim, scroll lock, background inert); `false` uses
 * `show()` for a non-modal sheet with no scrim, leaving the page behind
 * interactive and scrollable (the transparent shell is pointer-events:none so
 * taps pass through).
 *
 * The drag/snap/dismiss machinery lives in `useSheetGestures`; the offset
 * geometry lives in the pure, tested `snapOffsets` module. Both are internal
 * to BottomSheet and not exported from the lab entry point.
 *
 * SYNC: When modified, update these files to stay in sync:
 * - /packages/lab/src/BottomSheet/BottomSheet.doc.mjs (props table, features, usage)
 * - /packages/lab/src/BottomSheet/BottomSheet.test.tsx (tests for new/changed behavior)
 * - /packages/lab/src/BottomSheet/index.ts (exports if types change)
 * - /apps/storybook/stories/BottomSheet.stories.tsx (examples and visual coverage)
 */
import { type ReactNode } from 'react';
import type { BaseProps } from '@astryxdesign/core';
/**
 * Height budget for each named size, as a fraction of the viewport:
 * - `hug` — fits its content, never taller than 92%.
 * - `capped` — a scrolling mid-height panel (62%).
 * - `tall` — a pinned near-full panel (92%); use when content streams in so
 *   the sheet doesn't resize under the user.
 */
declare const HEIGHT_BUDGETS: {
    readonly hug: "92dvh";
    readonly capped: "62dvh";
    readonly tall: "92dvh";
};
export type BottomSheetHeight = keyof typeof HEIGHT_BUDGETS;
export interface BottomSheetProps extends BaseProps<HTMLDialogElement> {
    /** Ref forwarded to the underlying <dialog> element. */
    ref?: React.Ref<HTMLDialogElement>;
    /** Whether the sheet is open. Fully controlled — pair with `onOpenChange`. */
    isOpen: boolean;
    /**
     * Called when the sheet opens or closes. The boolean is the requested next
     * state (`false` on Escape, scrim click, or a swipe past the dismiss
     * threshold). The caller owns the open state.
     */
    onOpenChange: (isOpen: boolean) => void;
    /**
     * Accessible label for the sheet (required — the sheet has no built-in
     * heading to derive a name from).
     */
    label: string;
    /** Sheet content, rendered below the grab handle in a scrollable area. */
    children: ReactNode;
    /**
     * How tall the sheet is. A named budget, or any explicit height:
     * - `'hug'` — fits its content, never taller than 92% of the viewport.
     * - `'capped'` — a scrolling mid-height panel (~62%).
     * - `'tall'` — a pinned near-full panel (~92%); use when content streams in
     *   so the sheet doesn't resize under the user.
     * - a `number` (px) or CSS length string (e.g. `'70dvh'`, `480`) for a
     *   custom budget.
     *
     * The user can still drag between snap points regardless of the starting
     * height. On viewports shorter than the budget the sheet fills the
     * available height.
     * @default 'capped'
     */
    height?: BottomSheetHeight | number | string;
    /**
     * Whether to render a modal scrim behind the sheet.
     * - `true` (default) — `showModal()`: renders in the top layer with a focus
     *   trap, a `::backdrop` scrim, body scroll lock, and tap-scrim-to-dismiss.
     *   The background is inert. Use for focused tasks (filters, forms).
     * - `false` — `show()`: a non-modal sheet with **no scrim**. The page behind
     *   stays interactive and scrollable (like Material's *standard* bottom
     *   sheet, or an iOS undimmed detent). Escape still closes while focus is
     *   inside the sheet, and drag/flick-to-dismiss still work. Use for a peek
     *   surface that coexists with the page (e.g. a panel over a live map).
     * @default true
     */
    hasScrim?: boolean;
    /** Test ID for the root element. */
    'data-testid'?: string;
}
/**
 * A mobile touch sheet that rises from the bottom edge, with a grab handle,
 * drag-to-resize snap points, and swipe-to-dismiss. It owns a native
 * `<dialog>` and, by default (`hasScrim`), enters the top layer with a focus
 * trap + `::backdrop` scrim and locks body scroll; a slow drag settles to the
 * nearest snap point, a flick down dismisses, and Escape closes — so the swipe
 * always has a keyboard equivalent.
 *
 * With `hasScrim={false}` it opens non-modally (`show()`, no scrim), leaving
 * the page behind interactive and scrollable.
 *
 * @example
 * ```
 * const [isOpen, setIsOpen] = useState(false);
 * <BottomSheet
 *   isOpen={isOpen}
 *   onOpenChange={setIsOpen}
 *   label="Filters">
 *   <FilterControls />
 * </BottomSheet>
 * ```
 */
export declare function BottomSheet({ ref, isOpen, onOpenChange, label, children, height, hasScrim, xstyle, ...props }: BottomSheetProps): import("react").JSX.Element;
export declare namespace BottomSheet {
    var displayName: string;
}
export {};
//# sourceMappingURL=BottomSheet.d.ts.map