import type { MutableRefObject, ReactNode } from 'react';
import React from 'react';
import type { ExtractProps } from '../../util/utility-types';
import type { Size } from '../../util/variant-types';
import Heading from '../Heading';
import Text from '../Text';
type ModalContentProps = {
/**
* Optional aria-label for the modal.
*
* If undefined, the headingText of the Modal.Header will be used.
* If there is no Modal.Header, an aria-label is required.
*/
'aria-label'?: string;
/**
* Additional classnames passed in for styling.
*/
className?: string;
/**
* Contents of the modal.
*/
children: ReactNode;
/**
* Hides the close button in the top right of the modal.
*
* **Default is `false`**.
*/
hideCloseButton?: boolean;
/**
* A ref to an element that should receive focus when the modal first opens.
*
* If undefined, the first focusable element (usually the close button) will be used.
*
* ```
* const inputFieldRef = useRef();
*
*
* ...
*
*
* ```
*/
initialFocus?: MutableRefObject;
/**
* Method called when the close button is clicked. Use this to hide the modal.
* This should be used to also reset the `open` state.
*
* This is required even if you don't have a close button so the ESC key can close the modal.
*
* Closing is cancellable by passing in a function that returns `void` or by not altering the state.
*
* ```
* const [isOpen, setIsOpen] = useState(true);
* // ....
*
* setIsOpen(false)}>
* ...
*
* ```
*/
onClose: () => void;
/**
* Determine how the height of the modal container is calculated when `size` is `"lg"`:
* - `"fixed"` applies the fixed dimensions, which will not adjust
* - `"auto"` applies a floating height dimension, that will fit to the content (can be smaller or larger than `"default"`)
* - `"max"` applies the maximum height within the viewport, leaving space along the top and bottom edges
* - `"dynamic"` manages the height for you, with intelligent presets and scroll truncation as needed
*
* **Default is `"fixed"`**.
*/
height?: 'fixed' | 'auto' | 'max' | 'dynamic';
open?: boolean;
/**
* Emphasis used on the backgound overlay (behind the modal)
*
* **Default is `"low"`**.
*/
overlayEmphasis?: 'low' | 'high';
/**
* Fixed sizes for the modal's height and width. Used in conjunction with `height` when using size `lg`.
*
* **Default is `"lg"`**.
*/
size?: Extract | 'full';
};
type ModalProps = ModalContentProps & {
/**
* Whether or not the modal is visible. Recommend using `useState` to set this
* variable instead of a boolean literal, to avoid component control issues.
* @see https://headlessui.com/react/dialog
*
* ```
* const [isOpen, setIsOpen] = useState(true);
* // ....
*
*
* ...
*
* ```
*/
open: boolean;
/**
* Additional classnames passed in for the modal container.
*/
modalContainerClassName?: string;
};
type ModalTitleProps = ExtractProps & {
/**
* Contents for the modal title.
*/
children: ReactNode;
/**
* CSS class names that can be appended to the component.
*/
className?: string;
};
type ModalSubTitleProps = ExtractProps & {
/**
* Contents for the modal title.
*/
children: ReactNode;
/**
* CSS class names that can be appended to the component.
*/
className?: string;
};
type ModalBodyProps = {
/**
* Child node(s) that can be nested inside component. `Modal.Header`,
* `Modal.Body`, and `Model.Footer` are the only permissible children of the Modal.
*/
children: ReactNode;
/**
* CSS class names that can be appended to the component.
*/
className?: string;
/**
* Determine how the height of the modal container is calculated when `size` is `"lg"`:
* - `"fixed"` applies the fixed dimensions, which will not adjust
* - `"auto"` applies a floating height dimension, that will fit to the content (can be smaller or larger than `"default"`)
* - `"max"` applies the maximum height within the viewport, leaving space along the top and bottom edges
* - `"dynamic"` manages the height for you, with intelligent presets and scroll truncation as needed
*
* **Default is `"fixed"`**.
*/
height?: ModalContentProps['height'];
};
type ModalHeaderProps = {
/**
* Child node(s) to place inside the Modal header.
* Should include the
*/
children: ReactNode;
/**
* CSS class names that can be appended to the component.
*/
className?: string;
};
type ModalFooterProps = {
/**
* Child node(s) to place inside the Modal footer.
*/
children: ReactNode;
/**
* CSS class names that can be appended to the component.
*/
className?: string;
};
/**
* `import {Modal} from "@chanzuckerberg/eds";`
*
* EDS Wrapper for the HeadlessUI Dialog component
* @see https://headlessui.dev/react/dialog
*
* NOTE: You must have at least one focusable element in the modal contents, for keyboard
* accessibility reasons. (The close button counts as a focusable element.) Use `initialFocus`
* to choose a different element.
*
*/
export declare const Modal: {
(props: ModalProps): React.JSX.Element;
displayName: string;
Header: ({ children, className, ...other }: ModalHeaderProps) => React.JSX.Element;
Content: (props: ModalContentProps) => React.JSX.Element;
Title: {
({ children, className, preset, ...other }: ModalTitleProps): React.JSX.Element;
displayName: string;
};
SubTitle: {
({ children, className, preset, ...other }: ModalSubTitleProps): React.JSX.Element;
displayName: string;
};
Body: {
(props: ModalBodyProps): React.JSX.Element;
displayName: string;
};
Footer: {
({ children, className, ...other }: ModalFooterProps): React.JSX.Element;
displayName: string;
};
};
export {};