UNPKG

@ariakit/react-core

Version:

Ariakit React core

264 lines (263 loc) 12.6 kB
import type { BooleanOrCallback } from "@ariakit/core/utils/types"; import type { ComponentPropsWithRef, ElementType, FC, ReactElement, KeyboardEvent as ReactKeyboardEvent, RefObject, SyntheticEvent } from "react"; import type { DisclosureContentOptions } from "../disclosure/disclosure-content.tsx"; import type { FocusableOptions } from "../focusable/focusable.tsx"; import type { PortalOptions } from "../portal/portal.tsx"; import type { Props } from "../utils/types.ts"; import type { DialogStore } from "./dialog-store.ts"; declare const TagName = "div"; type TagName = typeof TagName; /** * Returns props to create a `Dialog` component. * @see https://ariakit.org/components/dialog * @example * ```jsx * const store = useDialogStore(); * const props = useDialog({ store }); * <Role {...props}>Dialog</Role> * ``` */ export declare const useDialog: import("../utils/types.ts").Hook<"div", DialogOptions<"div">>; export declare function createDialogComponent<T extends DialogOptions>(Component: FC<T>, useProviderContext?: () => DialogStore | undefined): (props: T) => import("react/jsx-runtime").JSX.Element | null; /** * Renders a dialog similar to the native `dialog` element that's rendered in a * [`portal`](https://ariakit.org/reference/dialog#portal) by default. * * The dialog can be either * [`modal`](https://ariakit.org/reference/dialog#modal) or non-modal. The * visibility state can be controlled with the * [`open`](https://ariakit.org/reference/dialog#open) and * [`onClose`](https://ariakit.org/reference/dialog#onclose) props. * @see https://ariakit.org/components/dialog * @example * ```jsx {4-6} * const [open, setOpen] = useState(false); * * <button onClick={() => setOpen(true)}>Open dialog</button> * <Dialog open={open} onClose={() => setOpen(false)}> * Dialog * </Dialog> * ``` */ export declare const Dialog: (props: DialogProps<"div">) => import("react/jsx-runtime").JSX.Element | null; export interface DialogOptions<T extends ElementType = TagName> extends FocusableOptions<T>, PortalOptions<T>, DisclosureContentOptions<T> { /** * Object returned by the * [`useDialogStore`](https://ariakit.org/reference/use-dialog-store) hook. If * not provided, the closest * [`DialogProvider`](https://ariakit.org/reference/dialog-provider) * component's context will be used. Otherwise, an internal store will be * created. */ store?: DialogStore; /** * Controls the open state of the dialog. This is similar to the * [`open`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/open) * attribute on native dialog elements. * * Live examples: * - [Dialog with scrollable * backdrop](https://ariakit.org/examples/dialog-backdrop-scrollable) * - [Dialog with details & * summary](https://ariakit.org/examples/dialog-details) * - [Warning on Dialog * hide](https://ariakit.org/examples/dialog-hide-warning) * - [Dialog with Menu](https://ariakit.org/examples/dialog-menu) */ open?: boolean; /** * This is an event handler prop triggered when the dialog's `close` event is * dispatched. The `close` event is similar to the native dialog * [`close`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/close_event) * event. The only difference is that this event can be canceled with * `event.preventDefault()`, which will prevent the dialog from hiding. * * It's important to note that this event only fires when the dialog store's * [`open`](https://ariakit.org/reference/use-dialog-store#open) state is set * to `false`. If the controlled * [`open`](https://ariakit.org/reference/dialog#open) prop value changes, or * if the dialog's visibility is altered in any other way (such as unmounting * the dialog without adjusting the open state), this event won't be * triggered. * * Live examples: * - [Dialog with scrollable * backdrop](https://ariakit.org/examples/dialog-backdrop-scrollable) * - [Dialog with details & * summary](https://ariakit.org/examples/dialog-details) * - [Warning on Dialog * hide](https://ariakit.org/examples/dialog-hide-warning) * - [Dialog with Menu](https://ariakit.org/examples/dialog-menu) */ onClose?: (event: Event) => void; /** * Determines whether the dialog is modal. Modal dialogs have distinct states * and behaviors: * - The [`portal`](https://ariakit.org/reference/dialog#portal) and * [`preventBodyScroll`](https://ariakit.org/reference/dialog#preventbodyscroll) * props are set to `true`. They can still be manually set to `false`. * - When using the [`Heading`](https://ariakit.org/reference/heading) or * [`DialogHeading`](https://ariakit.org/reference/dialog-heading) * components within the dialog, their level will be reset so they start * with `h1`. * - A visually hidden dismiss button will be rendered if the * [`DialogDismiss`](https://ariakit.org/reference/dialog-dismiss) component * hasn't been used. This allows screen reader users to close the dialog. * - When the dialog is open, element tree outside it will be inert. * * Live examples: * - [Combobox with Tabs](https://ariakit.org/examples/combobox-tabs) * - [Dialog with details & * summary](https://ariakit.org/examples/dialog-details) * - [Form with Select](https://ariakit.org/examples/form-select) * - [Context menu](https://ariakit.org/examples/menu-context-menu) * - [Responsive Popover](https://ariakit.org/examples/popover-responsive) * @default true */ modal?: boolean; /** * Determines whether there will be a backdrop behind the dialog. On modal * dialogs, this is `true` by default. Besides a `boolean`, this prop can also * be a React component or JSX element that will be rendered as the backdrop. * * **Note**: If a custom component is used, it must [accept ref and spread all * props to its underlying DOM * element](https://ariakit.org/guide/composition#custom-components-must-be-open-for-extension), * the same way a native element would. * * Live examples: * - [Animated Dialog](https://ariakit.org/examples/dialog-animated) * - [Dialog with scrollable * backdrop](https://ariakit.org/examples/dialog-backdrop-scrollable) * - [Dialog with Framer * Motion](https://ariakit.org/examples/dialog-framer-motion) * - [Dialog with Menu](https://ariakit.org/examples/dialog-menu) * - [Nested Dialog](https://ariakit.org/examples/dialog-nested) * - [Dialog with Next.js App * Router](https://ariakit.org/examples/dialog-next-router) * @example * ```jsx * <Dialog backdrop={<div className="backdrop" />} /> * ``` */ backdrop?: boolean | ReactElement<ComponentPropsWithRef<"div">> | ElementType<ComponentPropsWithRef<"div">>; /** * Determines if the dialog will hide when the user presses the Escape key. * * This prop can be either a boolean or a function that accepts an event as an * argument and returns a boolean. The event object represents the keydown * event that initiated the hide action, which could be either a native * keyboard event or a React synthetic event. * * **Note**: When placing Ariakit dialogs inside third-party dialogs, using * `event.stopPropagation()` within this function will stop the event from * reaching the third-party dialog, closing only the Ariakit dialog. * @default true */ hideOnEscape?: BooleanOrCallback<KeyboardEvent | ReactKeyboardEvent>; /** * Determines if the dialog should hide when the user clicks or focuses on an * element outside the dialog. * * This prop can be either a boolean or a function that takes an event as an * argument and returns a boolean. The event object represents the event that * triggered the action, which could be a native event or a React synthetic * event of various types. * * Live examples: * - [Selection Popover](https://ariakit.org/examples/popover-selection) * @default true */ hideOnInteractOutside?: BooleanOrCallback<Event | SyntheticEvent>; /** * When a dialog is open, the elements outside of it are disabled to prevent * interaction if the dialog is * [`modal`](https://ariakit.org/reference/dialog#modal). For non-modal * dialogs, interacting with elements outside the dialog prompts it to close. * * This function allows you to return an iterable collection of elements that * will be considered as part of the dialog, thus excluding them from this * behavior. * * **Note**: The elements returned by this function must exist in the DOM when * the dialog opens. * * Live examples: * - [Dialog with * React-Toastify](https://ariakit.org/examples/dialog-react-toastify) */ getPersistentElements?: () => Iterable<Element>; /** * Determines whether the body scrolling will be prevented when the dialog is * shown. This is automatically set to `true` when the dialog is * [`modal`](https://ariakit.org/reference/dialog#modal). You can disable this * prop if you want to implement your own logic. */ preventBodyScroll?: boolean; /** * Determines whether an element inside the dialog will receive focus when the * dialog is shown. By default, this is usually the first tabbable element in * the dialog or the dialog itself. The * [`initialFocus`](https://ariakit.org/reference/dialog#initialfocus) prop * can be used to set a different element to receive focus. * * Live examples: * - [Warning on Dialog * hide](https://ariakit.org/examples/dialog-hide-warning) * - [Sliding Menu](https://ariakit.org/examples/menu-slide) * - [Selection Popover](https://ariakit.org/examples/popover-selection) * @default true */ autoFocusOnShow?: BooleanOrCallback<HTMLElement | null>; /** * Determines whether an element outside of the dialog will be focused when * the dialog is hidden if another element hasn't been focused in the action * of hiding the dialog (for example, by clicking or tabbing into another * tabbable element outside of the dialog). * * By default, this is usually the disclosure element. The * [`finalFocus`](https://ariakit.org/reference/dialog#finalfocus) prop can be * used to define a different element to be focused. * * Live examples: * - [Dialog with Next.js App * Router](https://ariakit.org/examples/dialog-next-router) * - [Sliding menu](https://ariakit.org/examples/menu-slide) * @default true */ autoFocusOnHide?: BooleanOrCallback<HTMLElement | null>; /** * Specifies the element that will receive focus when the dialog is first * opened. It can be an `HTMLElement` or a `React.RefObject` with an * `HTMLElement`. * * If * [`autoFocusOnShow`](https://ariakit.org/reference/dialog#autofocusonshow) * is set to `false`, this prop will have no effect. If left unset, the dialog * will attempt to determine the initial focus element in the following order: * 1. A [Focusable](https://ariakit.org/components/focusable) element with an * [`autoFocus`](https://ariakit.org/reference/focusable#autofocus) prop. * 2. The first tabbable element inside the dialog. * 3. The first focusable element inside the dialog. * 4. The dialog element itself. */ initialFocus?: HTMLElement | RefObject<HTMLElement> | null; /** * Determines the element that will receive focus once the dialog is closed, * provided that no other element has been focused while the dialog was being * hidden (e.g., by clicking or tabbing into another tabbable element outside * of the dialog). * - If * [`autoFocusOnHide`](https://ariakit.org/reference/dialog#autofocusonhide) * is set to `false`, this prop will have no effect. * - If left unset, the element that was focused before the dialog was opened * will be focused again. */ finalFocus?: HTMLElement | RefObject<HTMLElement> | null; /** * @private */ unstable_treeSnapshotKey?: string | number | boolean | null; } export type DialogProps<T extends ElementType = TagName> = Props<T, DialogOptions<T>>; export {};