diff --git a/docs/data/components/dialog/UnstyledDialogIntroduction/tailwind/index.tsx b/docs/data/components/dialog/UnstyledDialogIntroduction/tailwind/index.tsx index d94898973c..5b07e97241 100644 --- a/docs/data/components/dialog/UnstyledDialogIntroduction/tailwind/index.tsx +++ b/docs/data/components/dialog/UnstyledDialogIntroduction/tailwind/index.tsx @@ -26,7 +26,7 @@ export default function UnstyledDialogIntroduction() { ); } -function TriggerButton(props: Dialog.TriggerProps) { +function TriggerButton(props: Dialog.Trigger.Props) { const className = ` bg-slate-900 dark:bg-slate-50 text-slate-50 dark:text-slate-900 py-2 px-4 rounded min-w-[80px] border-none font-sans @@ -35,7 +35,7 @@ function TriggerButton(props: Dialog.TriggerProps) { return ; } -function Popup(props: Dialog.PopupProps) { +function Popup(props: Dialog.Popup.Props) { const className = ` bg-slate-50 dark:bg-slate-900 border-[1px] border-solid border-slate-100 dark:border-slate-700 min-w-[400px] rounded shadow-xl fixed top-2/4 left-2/4 z-[2100] @@ -53,7 +53,7 @@ function Controls(props: React.ComponentPropsWithoutRef<'div'>) { ); } -function CloseButton(props: Dialog.CloseProps) { +function CloseButton(props: Dialog.Close.Props) { const className = ` bg-transparent border-[1px] border-solid border-slate-500 dark:border-slate-300 text-slate-900 dark:text-slate-50 py-2 px-4 rounded font-sans min-w-[80px] @@ -62,15 +62,15 @@ function CloseButton(props: Dialog.CloseProps) { return ; } -function Title(props: Dialog.TitleProps) { +function Title(props: Dialog.Title.Props) { return ; } -function Description(props: Dialog.DescriptionProps) { +function Description(props: Dialog.Description.Props) { return ; } -function Backdrop(props: Dialog.BackdropProps) { +function Backdrop(props: Dialog.Backdrop.Props) { return ( ; + export type Props = Omit; } AlertDialogRoot.propTypes /* remove-proptypes */ = { diff --git a/packages/mui-base/src/AlertDialog/Root/AlertDialogRootContext.ts b/packages/mui-base/src/AlertDialog/Root/AlertDialogRootContext.ts index c3e72b2b51..2afa9dac68 100644 --- a/packages/mui-base/src/AlertDialog/Root/AlertDialogRootContext.ts +++ b/packages/mui-base/src/AlertDialog/Root/AlertDialogRootContext.ts @@ -1,8 +1,8 @@ 'use client'; import * as React from 'react'; -import { UseDialogRootReturnValue } from '@base_ui/react/Dialog'; +import { type useDialogRoot } from '../../Dialog/Root/useDialogRoot'; -export interface AlertDialogRootContext extends UseDialogRootReturnValue { +export interface AlertDialogRootContext extends useDialogRoot.ReturnValue { /** * If `true`, the dialog supports CSS-based animations and transitions. * It is kept in the DOM until the animation completes. diff --git a/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.tsx b/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.tsx index da58021bae..60d233e799 100644 --- a/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.tsx +++ b/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.tsx @@ -2,10 +2,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { FloatingPortal } from '@floating-ui/react'; -import type { DialogBackdropOwnerState, DialogBackdropProps } from './DialogBackdrop.types'; import { useDialogBackdrop } from './useDialogBackdrop'; import { useDialogRootContext } from '../Root/DialogRootContext'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; +import { type TransitionStatus } from '../../utils/useTransitionStatus'; +import { type BaseUIComponentProps } from '../../utils/types'; /** * @@ -18,7 +19,7 @@ import { useComponentRenderer } from '../../utils/useComponentRenderer'; * - [DialogBackdrop API](https://base-ui.netlify.app/components/react-dialog/#api-reference-DialogBackdrop) */ const DialogBackdrop = React.forwardRef(function DialogBackdrop( - props: DialogBackdropProps, + props: DialogBackdrop.Props, forwardedRef: React.ForwardedRef, ) { const { render, className, keepMounted = false, ...other } = props; @@ -35,7 +36,7 @@ const DialogBackdrop = React.forwardRef(function DialogBackdrop( onUnmount: handleUnmount, }); - const ownerState: DialogBackdropOwnerState = React.useMemo( + const ownerState: DialogBackdrop.OwnerState = React.useMemo( () => ({ open, modal, transitionStatus }), [open, modal, transitionStatus], ); @@ -72,6 +73,23 @@ const DialogBackdrop = React.forwardRef(function DialogBackdrop( return {renderElement()}; }); +namespace DialogBackdrop { + export interface Props extends BaseUIComponentProps<'div', OwnerState> { + /** + * If `true`, the backdrop element is kept in the DOM when closed. + * + * @default false + */ + keepMounted?: boolean; + } + + export interface OwnerState { + open: boolean; + modal: boolean; + transitionStatus: TransitionStatus; + } +} + DialogBackdrop.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.types.ts b/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.types.ts deleted file mode 100644 index 3a95ac0b08..0000000000 --- a/packages/mui-base/src/Dialog/Backdrop/DialogBackdrop.types.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { TransitionStatus } from '../../utils/useTransitionStatus'; -import { BaseUIComponentProps } from '../../utils/types'; - -export interface DialogBackdropProps extends BaseUIComponentProps<'div', DialogBackdropOwnerState> { - /** - * If `true`, the backdrop element is kept in the DOM when closed. - * - * @default false - */ - keepMounted?: boolean; -} - -export interface DialogBackdropOwnerState { - open: boolean; - modal: boolean; - transitionStatus: TransitionStatus; -} - -export interface UseDialogBackdropParams { - /** - * If `true`, the dialog supports CSS-based animations and transitions. - * It is kept in the DOM until the animation completes. - */ - animated: boolean; - /** - * Determines if the dialog is open. - */ - open: boolean; - /** - * The ref to the background element. - */ - ref: React.Ref; - /** - * Callback to invoke when the backdrop is mounted. - */ - onMount: () => void; - /** - * Callback to invoke when the backdrop is unmounted. - */ - onUnmount: () => void; -} - -export interface UseDialogBackdropReturnValue { - /** - * Resolver for the root element props. - */ - getRootProps: (externalProps?: Record) => Record; - /** - * Determines if the dialog should be mounted even if closed (as the exit animation is still in progress). - */ - mounted: boolean; - /** - * The current transition status of the dialog. - */ - transitionStatus: TransitionStatus; -} diff --git a/packages/mui-base/src/Dialog/Backdrop/useDialogBackdrop.ts b/packages/mui-base/src/Dialog/Backdrop/useDialogBackdrop.ts index 2736a38acc..cc189ae34f 100644 --- a/packages/mui-base/src/Dialog/Backdrop/useDialogBackdrop.ts +++ b/packages/mui-base/src/Dialog/Backdrop/useDialogBackdrop.ts @@ -1,13 +1,15 @@ 'use client'; import * as React from 'react'; -import type { UseDialogBackdropParams, UseDialogBackdropReturnValue } from './DialogBackdrop.types'; import { mergeReactProps } from '../../utils/mergeReactProps'; import { useAnimatedElement } from '../../utils/useAnimatedElement'; import { useForkRef } from '../../utils/useForkRef'; import { useEventCallback } from '../../utils/useEventCallback'; import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; +import { type TransitionStatus } from '../../utils/useTransitionStatus'; -export function useDialogBackdrop(params: UseDialogBackdropParams): UseDialogBackdropReturnValue { +export function useDialogBackdrop( + params: useDialogBackdrop.Parameters, +): useDialogBackdrop.ReturnValue { const { animated, open, ref, onMount: onMountParam, onUnmount: onUnmountParam } = params; const backdropRef = React.useRef(null); @@ -43,3 +45,44 @@ export function useDialogBackdrop(params: UseDialogBackdropParams): UseDialogBac transitionStatus, }; } + +export namespace useDialogBackdrop { + export interface Parameters { + /** + * If `true`, the dialog supports CSS-based animations and transitions. + * It is kept in the DOM until the animation completes. + */ + animated: boolean; + /** + * Determines if the dialog is open. + */ + open: boolean; + /** + * The ref to the background element. + */ + ref: React.Ref; + /** + * Callback to invoke when the backdrop is mounted. + */ + onMount: () => void; + /** + * Callback to invoke when the backdrop is unmounted. + */ + onUnmount: () => void; + } + + export interface ReturnValue { + /** + * Resolver for the root element props. + */ + getRootProps: (externalProps?: Record) => Record; + /** + * Determines if the dialog should be mounted even if closed (as the exit animation is still in progress). + */ + mounted: boolean; + /** + * The current transition status of the dialog. + */ + transitionStatus: TransitionStatus; + } +} diff --git a/packages/mui-base/src/Dialog/Close/DialogClose.tsx b/packages/mui-base/src/Dialog/Close/DialogClose.tsx index eadb19c665..17da0a68dc 100644 --- a/packages/mui-base/src/Dialog/Close/DialogClose.tsx +++ b/packages/mui-base/src/Dialog/Close/DialogClose.tsx @@ -1,10 +1,10 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import { DialogCloseProps } from './DialogClose.types'; import { useDialogClose } from './useDialogClose'; import { useDialogRootContext } from '../Root/DialogRootContext'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; +import type { BaseUIComponentProps } from '../../utils/types'; /** * @@ -17,14 +17,14 @@ import { useComponentRenderer } from '../../utils/useComponentRenderer'; * - [DialogClose API](https://base-ui.netlify.app/components/react-dialog/#api-reference-DialogClose) */ const DialogClose = React.forwardRef(function DialogClose( - props: DialogCloseProps, + props: DialogClose.Props, forwardedRef: React.ForwardedRef, ) { const { render, className, ...other } = props; const { open, onOpenChange, modal } = useDialogRootContext(); const { getRootProps } = useDialogClose({ open, onOpenChange }); - const ownerState = { + const ownerState: DialogClose.OwnerState = { open, modal, }; @@ -41,6 +41,15 @@ const DialogClose = React.forwardRef(function DialogClose( return renderElement(); }); +namespace DialogClose { + export interface Props extends BaseUIComponentProps<'button', OwnerState> {} + + export interface OwnerState { + open: boolean; + modal: boolean; + } +} + DialogClose.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Dialog/Close/DialogClose.types.ts b/packages/mui-base/src/Dialog/Close/DialogClose.types.ts deleted file mode 100644 index 5eff54dbbb..0000000000 --- a/packages/mui-base/src/Dialog/Close/DialogClose.types.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { BaseUIComponentProps } from '../../utils/types'; - -export interface DialogCloseProps extends BaseUIComponentProps<'button', DialogCloseOwnerState> {} - -export interface DialogCloseOwnerState { - open: boolean; - modal: boolean; -} - -export interface UseDialogCloseParameters { - /** - * Determines whether the dialog is open. - */ - open: boolean; - /** - * Callback invoked when the dialog is being opened or closed. - */ - onOpenChange: (open: boolean) => void; -} - -export interface UseDialogCloseReturnValue { - /** - * Resolver for the root element props. - */ - getRootProps: (externalProps: React.HTMLAttributes) => React.HTMLAttributes; -} diff --git a/packages/mui-base/src/Dialog/Close/useDialogClose.ts b/packages/mui-base/src/Dialog/Close/useDialogClose.ts index 6126fe5d57..45af0d84f6 100644 --- a/packages/mui-base/src/Dialog/Close/useDialogClose.ts +++ b/packages/mui-base/src/Dialog/Close/useDialogClose.ts @@ -1,9 +1,8 @@ 'use client'; import * as React from 'react'; import { mergeReactProps } from '../../utils/mergeReactProps'; -import type { UseDialogCloseParameters, UseDialogCloseReturnValue } from './DialogClose.types'; -export function useDialogClose(params: UseDialogCloseParameters): UseDialogCloseReturnValue { +export function useDialogClose(params: useDialogClose.Parameters): useDialogClose.ReturnValue { const { open, onOpenChange } = params; const handleClick = React.useCallback(() => { if (open) { @@ -18,3 +17,23 @@ export function useDialogClose(params: UseDialogCloseParameters): UseDialogClose getRootProps, }; } + +export namespace useDialogClose { + export interface Parameters { + /** + * Determines whether the dialog is open. + */ + open: boolean; + /** + * Callback invoked when the dialog is being opened or closed. + */ + onOpenChange: (open: boolean) => void; + } + + export interface ReturnValue { + /** + * Resolver for the root element props. + */ + getRootProps: (externalProps: React.HTMLAttributes) => React.HTMLAttributes; + } +} diff --git a/packages/mui-base/src/Dialog/Description/DialogDescription.tsx b/packages/mui-base/src/Dialog/Description/DialogDescription.tsx index f95329ab42..505d6837e5 100644 --- a/packages/mui-base/src/Dialog/Description/DialogDescription.tsx +++ b/packages/mui-base/src/Dialog/Description/DialogDescription.tsx @@ -1,11 +1,11 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import type { DialogDescriptionProps } from './DialogDescription.types'; import { useDialogRootContext } from '../Root/DialogRootContext'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; import { useId } from '../../utils/useId'; +import type { BaseUIComponentProps } from '../../utils/types'; /** * @@ -18,7 +18,7 @@ import { useId } from '../../utils/useId'; * - [DialogDescription API](https://base-ui.netlify.app/components/react-dialog/#api-reference-DialogDescription) */ const DialogDescription = React.forwardRef(function DialogDescription( - props: DialogDescriptionProps, + props: DialogDescription.Props, forwardedRef: React.ForwardedRef, ) { const { render, className, id: idProp, ...other } = props; @@ -49,6 +49,15 @@ const DialogDescription = React.forwardRef(function DialogDescription( return renderElement(); }); +namespace DialogDescription { + export interface Props extends BaseUIComponentProps<'p', OwnerState> {} + + export interface OwnerState { + open: boolean; + modal: boolean; + } +} + DialogDescription.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Dialog/Description/DialogDescription.types.ts b/packages/mui-base/src/Dialog/Description/DialogDescription.types.ts deleted file mode 100644 index 9336b958e7..0000000000 --- a/packages/mui-base/src/Dialog/Description/DialogDescription.types.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { BaseUIComponentProps } from '../../utils/types'; - -export interface DialogDescriptionProps - extends BaseUIComponentProps<'p', DialogDescriptionOwnerState> {} - -export interface DialogDescriptionOwnerState { - open: boolean; - modal: boolean; -} diff --git a/packages/mui-base/src/Dialog/Popup/DialogPopup.tsx b/packages/mui-base/src/Dialog/Popup/DialogPopup.tsx index d79027adb5..88c9593fe8 100644 --- a/packages/mui-base/src/Dialog/Popup/DialogPopup.tsx +++ b/packages/mui-base/src/Dialog/Popup/DialogPopup.tsx @@ -2,11 +2,12 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { FloatingFocusManager, FloatingPortal } from '@floating-ui/react'; -import { DialogPopupOwnerState, DialogPopupProps } from './DialogPopup.types'; import { useDialogPopup } from './useDialogPopup'; import { useDialogRootContext } from '../Root/DialogRootContext'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; import { refType, HTMLElementType } from '../../utils/proptypes'; +import { type BaseUIComponentProps } from '../../utils/types'; +import { type TransitionStatus } from '../../utils/useTransitionStatus'; /** * @@ -19,7 +20,7 @@ import { refType, HTMLElementType } from '../../utils/proptypes'; * - [DialogPopup API](https://base-ui.netlify.app/components/react-dialog/#api-reference-DialogPopup) */ const DialogPopup = React.forwardRef(function DialogPopup( - props: DialogPopupProps, + props: DialogPopup.Props, forwardedRef: React.ForwardedRef, ) { const { className, container, id, keepMounted = false, render, ...other } = props; @@ -33,7 +34,7 @@ const DialogPopup = React.forwardRef(function DialogPopup( ...rootContext, }); - const ownerState: DialogPopupOwnerState = { + const ownerState: DialogPopup.OwnerState = { open, modal, nestedOpenDialogCount, @@ -82,6 +83,28 @@ const DialogPopup = React.forwardRef(function DialogPopup( ); }); +namespace DialogPopup { + export interface Props extends BaseUIComponentProps<'div', OwnerState> { + /** + * The container element to which the popup is appended to. + */ + container?: HTMLElement | null | React.MutableRefObject; + /** + * If `true`, the dialog element is kept in the DOM when closed. + * + * @default false + */ + keepMounted?: boolean; + } + + export interface OwnerState { + open: boolean; + modal: boolean; + nestedOpenDialogCount: number; + transitionStatus: TransitionStatus; + } +} + DialogPopup.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Dialog/Popup/DialogPopup.types.ts b/packages/mui-base/src/Dialog/Popup/DialogPopup.types.ts deleted file mode 100644 index fed361bff7..0000000000 --- a/packages/mui-base/src/Dialog/Popup/DialogPopup.types.ts +++ /dev/null @@ -1,94 +0,0 @@ -import * as React from 'react'; -import { type FloatingContext } from '@floating-ui/react'; -import { type BaseUIComponentProps } from '../../utils/types'; -import { TransitionStatus } from '../../utils/useTransitionStatus'; - -export interface DialogPopupProps extends BaseUIComponentProps<'div', DialogPopupOwnerState> { - /** - * The container element to which the popup is appended to. - */ - container?: HTMLElement | null | React.MutableRefObject; - /** - * If `true`, the dialog element is kept in the DOM when closed. - * - * @default false - */ - keepMounted?: boolean; -} - -export interface DialogPopupOwnerState { - open: boolean; - modal: boolean; - nestedOpenDialogCount: number; - transitionStatus: TransitionStatus; -} - -export interface UseDialogPopupParameters { - /** - * If `true`, the dialog supports CSS-based animations and transitions. - * It is kept in the DOM until the animation completes. - */ - animated: boolean; - /** - * The id of the dialog element. - */ - id?: string; - /** - * The ref to the dialog element. - */ - ref: React.Ref; - /** - * Determines if the dialog is modal. - */ - modal: boolean; - /** - * Determines if the dialog is open. - */ - open: boolean; - /** - * Callback fired when the dialog is requested to be opened or closed. - */ - onOpenChange: (open: boolean) => void; - /** - * The id of the title element associated with the dialog. - */ - titleElementId: string | undefined; - /** - * The id of the description element associated with the dialog. - */ - descriptionElementId: string | undefined; - /** - * Callback to set the id of the popup element. - */ - setPopupElementId: (id: string | undefined) => void; - /** - * Determines whether the dialog should close when clicking outside of it. - * @default true - */ - dismissible?: boolean; - /** - * Determines if the dialog is the top-most one. - */ - isTopmost: boolean; -} - -export interface UseDialogPopupReturnValue { - /** - * Floating UI context for the dialog's FloatingFocusManager. - */ - floatingContext: FloatingContext; - /** - * Resolver for the root element props. - */ - getRootProps: ( - externalProps: React.ComponentPropsWithRef<'div'>, - ) => React.ComponentPropsWithRef<'div'>; - /** - * Determines if the dialog should be mounted even if closed (as the exit animation is still in progress). - */ - mounted: boolean; - /** - * The current transition status of the dialog. - */ - transitionStatus: TransitionStatus; -} diff --git a/packages/mui-base/src/Dialog/Popup/useDialogPopup.tsx b/packages/mui-base/src/Dialog/Popup/useDialogPopup.tsx index 71274a6d5b..953c6e685a 100644 --- a/packages/mui-base/src/Dialog/Popup/useDialogPopup.tsx +++ b/packages/mui-base/src/Dialog/Popup/useDialogPopup.tsx @@ -1,15 +1,15 @@ 'use client'; import * as React from 'react'; -import { useFloating, useInteractions, useDismiss } from '@floating-ui/react'; -import { UseDialogPopupParameters, UseDialogPopupReturnValue } from './DialogPopup.types'; +import { useFloating, useInteractions, useDismiss, type FloatingContext } from '@floating-ui/react'; import { useId } from '../../utils/useId'; import { useForkRef } from '../../utils/useForkRef'; import { mergeReactProps } from '../../utils/mergeReactProps'; import { useAnimatedElement } from '../../utils/useAnimatedElement'; import { useScrollLock } from '../../utils/useScrollLock'; import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; +import { type TransitionStatus } from '../../utils/useTransitionStatus'; -export function useDialogPopup(parameters: UseDialogPopupParameters): UseDialogPopupReturnValue { +export function useDialogPopup(parameters: useDialogPopup.Parameters): useDialogPopup.ReturnValue { const { animated, descriptionElementId, @@ -76,3 +76,75 @@ export function useDialogPopup(parameters: UseDialogPopupParameters): UseDialogP transitionStatus, }; } + +export namespace useDialogPopup { + export interface Parameters { + /** + * If `true`, the dialog supports CSS-based animations and transitions. + * It is kept in the DOM until the animation completes. + */ + animated: boolean; + /** + * The id of the dialog element. + */ + id?: string; + /** + * The ref to the dialog element. + */ + ref: React.Ref; + /** + * Determines if the dialog is modal. + */ + modal: boolean; + /** + * Determines if the dialog is open. + */ + open: boolean; + /** + * Callback fired when the dialog is requested to be opened or closed. + */ + onOpenChange: (open: boolean) => void; + /** + * The id of the title element associated with the dialog. + */ + titleElementId: string | undefined; + /** + * The id of the description element associated with the dialog. + */ + descriptionElementId: string | undefined; + /** + * Callback to set the id of the popup element. + */ + setPopupElementId: (id: string | undefined) => void; + /** + * Determines whether the dialog should close when clicking outside of it. + * @default true + */ + dismissible?: boolean; + /** + * Determines if the dialog is the top-most one. + */ + isTopmost: boolean; + } + + export interface ReturnValue { + /** + * Floating UI context for the dialog's FloatingFocusManager. + */ + floatingContext: FloatingContext; + /** + * Resolver for the root element props. + */ + getRootProps: ( + externalProps: React.ComponentPropsWithRef<'div'>, + ) => React.ComponentPropsWithRef<'div'>; + /** + * Determines if the dialog should be mounted even if closed (as the exit animation is still in progress). + */ + mounted: boolean; + /** + * The current transition status of the dialog. + */ + transitionStatus: TransitionStatus; + } +} diff --git a/packages/mui-base/src/Dialog/Root/DialogRoot.tsx b/packages/mui-base/src/Dialog/Root/DialogRoot.tsx index 0531b0fc43..cd93fbb374 100644 --- a/packages/mui-base/src/Dialog/Root/DialogRoot.tsx +++ b/packages/mui-base/src/Dialog/Root/DialogRoot.tsx @@ -1,9 +1,8 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import { DialogRootProps } from './DialogRoot.types'; import { DialogRootContext } from './DialogRootContext'; -import { useDialogRoot } from './useDialogRoot'; +import { CommonParameters, useDialogRoot } from './useDialogRoot'; /** * @@ -15,7 +14,7 @@ import { useDialogRoot } from './useDialogRoot'; * * - [DialogRoot API](https://base-ui.netlify.app/components/react-dialog/#api-reference-DialogRoot) */ -const DialogRoot = function DialogRoot(props: DialogRootProps) { +const DialogRoot = function DialogRoot(props: DialogRoot.Props) { const { children, defaultOpen, @@ -48,6 +47,12 @@ const DialogRoot = function DialogRoot(props: DialogRootProps) { return {children}; }; +namespace DialogRoot { + export interface Props extends CommonParameters { + children?: React.ReactNode; + } +} + DialogRoot.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Dialog/Root/DialogRoot.types.ts b/packages/mui-base/src/Dialog/Root/DialogRoot.types.ts deleted file mode 100644 index 667127bb2c..0000000000 --- a/packages/mui-base/src/Dialog/Root/DialogRoot.types.ts +++ /dev/null @@ -1,119 +0,0 @@ -interface DialogRootParameters { - /** - * If `true`, the dialog supports CSS-based animations and transitions. - * It is kept in the DOM until the animation completes. - * - * @default true - */ - animated?: boolean; - /** - * Determines whether the dialog is open. - */ - open?: boolean; - /** - * Determines whether the dialog is initally open. - * This is an uncontrolled equivalent of the `open` prop. - */ - defaultOpen?: boolean; - /** - * Determines whether the dialog is modal. - * @default true - */ - modal?: boolean; - /** - * Callback invoked when the dialog is being opened or closed. - */ - onOpenChange?: (open: boolean) => void; - /** - * Determines whether the dialog should close when clicking outside of it. - * @default true - */ - dismissible?: boolean; -} - -export interface DialogRootProps extends DialogRootParameters { - children?: React.ReactNode; -} - -export interface UseDialogRootParameters extends DialogRootParameters { - /** - * Callback to invoke when a nested dialog is opened. - */ - onNestedDialogOpen?: (ownChildrenCount: number) => void; - /** - * Callback to invoke when a nested dialog is closed. - */ - onNestedDialogClose?: () => void; -} - -export interface UseDialogRootReturnValue { - /** - * The id of the description element associated with the dialog. - */ - descriptionElementId: string | undefined; - /** - * Determines if the dialog is modal. - */ - modal: boolean; - /** - * Number of nested dialogs that are currently open. - */ - nestedOpenDialogCount: number; - /** - * Callback to invoke when a nested dialog is closed. - */ - onNestedDialogClose?: () => void; - /** - * Callback to invoke when a nested dialog is opened. - */ - onNestedDialogOpen?: (ownChildrenCount: number) => void; - /** - * Callback to fire when the dialog is requested to be opened or closed. - */ - onOpenChange: (open: boolean) => void; - /** - * Determines if the dialog is open. - */ - open: boolean; - /** - * The id of the popup element. - */ - popupElementId: string | undefined; - /** - * Callback to notify the dialog that the backdrop is present. - */ - setBackdropPresent: (present: boolean) => void; - /** - * Callback to set the id of the description element associated with the dialog. - */ - setDescriptionElementId: (elementId: string | undefined) => void; - /** - * Callback to set the id of the popup element. - */ - setPopupElementId: (elementId: string | undefined) => void; - /** - * Callback to set the id of the title element. - */ - setTitleElementId: (elementId: string | undefined) => void; - /** - * The id of the title element associated with the dialog. - */ - titleElementId: string | undefined; -} - -export interface DialogRootContextValue extends UseDialogRootReturnValue { - /** - * If `true`, the dialog supports CSS-based animations and transitions. - * It is kept in the DOM until the animation completes. - */ - animated: boolean; - /** - * Determines if the dialog is nested within a parent dialog. - */ - hasParentDialog: boolean; - /** - * Determines whether the dialog should close when clicking outside of it. - * @default true - */ - dismissible?: boolean; -} diff --git a/packages/mui-base/src/Dialog/Root/DialogRootContext.ts b/packages/mui-base/src/Dialog/Root/DialogRootContext.ts index 09efe1bf8f..ade4da0cd0 100644 --- a/packages/mui-base/src/Dialog/Root/DialogRootContext.ts +++ b/packages/mui-base/src/Dialog/Root/DialogRootContext.ts @@ -1,8 +1,25 @@ 'use client'; import * as React from 'react'; -import type { DialogRootContextValue } from './DialogRoot.types'; +import type { useDialogRoot } from './useDialogRoot'; -export const DialogRootContext = React.createContext(undefined); +export interface DialogRootContext extends useDialogRoot.ReturnValue { + /** + * If `true`, the dialog supports CSS-based animations and transitions. + * It is kept in the DOM until the animation completes. + */ + animated: boolean; + /** + * Determines if the dialog is nested within a parent dialog. + */ + hasParentDialog: boolean; + /** + * Determines whether the dialog should close when clicking outside of it. + * @default true + */ + dismissible?: boolean; +} + +export const DialogRootContext = React.createContext(undefined); export function useDialogRootContext() { const context = React.useContext(DialogRootContext); diff --git a/packages/mui-base/src/Dialog/Root/useDialogRoot.ts b/packages/mui-base/src/Dialog/Root/useDialogRoot.ts index 9fac5000d3..4a96b0af86 100644 --- a/packages/mui-base/src/Dialog/Root/useDialogRoot.ts +++ b/packages/mui-base/src/Dialog/Root/useDialogRoot.ts @@ -1,9 +1,8 @@ 'use client'; import * as React from 'react'; -import type { UseDialogRootParameters, UseDialogRootReturnValue } from './DialogRoot.types'; import { useControlled } from '../../utils/useControlled'; -export function useDialogRoot(parameters: UseDialogRootParameters): UseDialogRootReturnValue { +export function useDialogRoot(parameters: useDialogRoot.Parameters): useDialogRoot.ReturnValue { const { open: openParam, defaultOpen = false, @@ -108,3 +107,104 @@ export function useDialogRoot(parameters: UseDialogRootParameters): UseDialogRoo setBackdropPresent, ]); } + +export interface CommonParameters { + /** + * If `true`, the dialog supports CSS-based animations and transitions. + * It is kept in the DOM until the animation completes. + * + * @default true + */ + animated?: boolean; + /** + * Determines whether the dialog is open. + */ + open?: boolean; + /** + * Determines whether the dialog is initally open. + * This is an uncontrolled equivalent of the `open` prop. + */ + defaultOpen?: boolean; + /** + * Determines whether the dialog is modal. + * @default true + */ + modal?: boolean; + /** + * Callback invoked when the dialog is being opened or closed. + */ + onOpenChange?: (open: boolean) => void; + /** + * Determines whether the dialog should close when clicking outside of it. + * @default true + */ + dismissible?: boolean; +} + +export namespace useDialogRoot { + export interface Parameters extends CommonParameters { + /** + * Callback to invoke when a nested dialog is opened. + */ + onNestedDialogOpen?: (ownChildrenCount: number) => void; + /** + * Callback to invoke when a nested dialog is closed. + */ + onNestedDialogClose?: () => void; + } + + export interface ReturnValue { + /** + * The id of the description element associated with the dialog. + */ + descriptionElementId: string | undefined; + /** + * Determines if the dialog is modal. + */ + modal: boolean; + /** + * Number of nested dialogs that are currently open. + */ + nestedOpenDialogCount: number; + /** + * Callback to invoke when a nested dialog is closed. + */ + onNestedDialogClose?: () => void; + /** + * Callback to invoke when a nested dialog is opened. + */ + onNestedDialogOpen?: (ownChildrenCount: number) => void; + /** + * Callback to fire when the dialog is requested to be opened or closed. + */ + onOpenChange: (open: boolean) => void; + /** + * Determines if the dialog is open. + */ + open: boolean; + /** + * The id of the popup element. + */ + popupElementId: string | undefined; + /** + * Callback to notify the dialog that the backdrop is present. + */ + setBackdropPresent: (present: boolean) => void; + /** + * Callback to set the id of the description element associated with the dialog. + */ + setDescriptionElementId: (elementId: string | undefined) => void; + /** + * Callback to set the id of the popup element. + */ + setPopupElementId: (elementId: string | undefined) => void; + /** + * Callback to set the id of the title element. + */ + setTitleElementId: (elementId: string | undefined) => void; + /** + * The id of the title element associated with the dialog. + */ + titleElementId: string | undefined; + } +} diff --git a/packages/mui-base/src/Dialog/Title/DialogTitle.tsx b/packages/mui-base/src/Dialog/Title/DialogTitle.tsx index f5e82366a7..06fba73803 100644 --- a/packages/mui-base/src/Dialog/Title/DialogTitle.tsx +++ b/packages/mui-base/src/Dialog/Title/DialogTitle.tsx @@ -1,11 +1,11 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import type { DialogTitleProps } from './DialogTitle.types'; import { useDialogRootContext } from '../Root/DialogRootContext'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; import { useId } from '../../utils/useId'; +import { type BaseUIComponentProps } from '../../utils/types'; /** * @@ -18,7 +18,7 @@ import { useId } from '../../utils/useId'; * - [DialogTitle API](https://base-ui.netlify.app/components/react-dialog/#api-reference-DialogTitle) */ const DialogTitle = React.forwardRef(function DialogTitle( - props: DialogTitleProps, + props: DialogTitle.Props, forwardedRef: React.ForwardedRef, ) { const { render, className, id: idProp, ...other } = props; @@ -49,6 +49,15 @@ const DialogTitle = React.forwardRef(function DialogTitle( return renderElement(); }); +namespace DialogTitle { + export interface Props extends BaseUIComponentProps<'h2', OwnerState> {} + + export interface OwnerState { + open: boolean; + modal: boolean; + } +} + DialogTitle.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Dialog/Title/DialogTitle.types.ts b/packages/mui-base/src/Dialog/Title/DialogTitle.types.ts deleted file mode 100644 index 443a1afdbb..0000000000 --- a/packages/mui-base/src/Dialog/Title/DialogTitle.types.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { BaseUIComponentProps } from '../../utils/types'; - -export interface DialogTitleProps extends BaseUIComponentProps<'h2', DialogTitleOwnerState> {} - -export interface DialogTitleOwnerState { - open: boolean; - modal: boolean; -} diff --git a/packages/mui-base/src/Dialog/Trigger/DialogTrigger.tsx b/packages/mui-base/src/Dialog/Trigger/DialogTrigger.tsx index 31804a93b4..e0621df3c3 100644 --- a/packages/mui-base/src/Dialog/Trigger/DialogTrigger.tsx +++ b/packages/mui-base/src/Dialog/Trigger/DialogTrigger.tsx @@ -2,9 +2,9 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useDialogTrigger } from './useDialogTrigger'; -import type { DialogTriggerOwnerState, DialogTriggerProps } from './DialogTrigger.types'; import { useDialogRootContext } from '../Root/DialogRootContext'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; +import type { BaseUIComponentProps } from '../../utils/types'; /** * @@ -17,7 +17,7 @@ import { useComponentRenderer } from '../../utils/useComponentRenderer'; * - [DialogTrigger API](https://base-ui.netlify.app/components/react-dialog/#api-reference-DialogTrigger) */ const DialogTrigger = React.forwardRef(function DialogTrigger( - props: DialogTriggerProps, + props: DialogTrigger.Props, forwardedRef: React.ForwardedRef, ) { const { render, className, ...other } = props; @@ -29,7 +29,10 @@ const DialogTrigger = React.forwardRef(function DialogTrigger( popupElementId, }); - const ownerState: DialogTriggerOwnerState = React.useMemo(() => ({ open, modal }), [open, modal]); + const ownerState: DialogTrigger.OwnerState = React.useMemo( + () => ({ open, modal }), + [open, modal], + ); const { renderElement } = useComponentRenderer({ render: render ?? 'button', @@ -46,6 +49,15 @@ const DialogTrigger = React.forwardRef(function DialogTrigger( return renderElement(); }); +namespace DialogTrigger { + export interface Props extends BaseUIComponentProps<'button', OwnerState> {} + + export interface OwnerState { + open: boolean; + modal: boolean; + } +} + DialogTrigger.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Dialog/Trigger/DialogTrigger.types.ts b/packages/mui-base/src/Dialog/Trigger/DialogTrigger.types.ts deleted file mode 100644 index feaca73f0f..0000000000 --- a/packages/mui-base/src/Dialog/Trigger/DialogTrigger.types.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { BaseUIComponentProps } from '../../utils/types'; - -export interface DialogTriggerProps - extends BaseUIComponentProps<'button', DialogTriggerOwnerState> {} - -export interface DialogTriggerOwnerState { - open: boolean; - modal: boolean; -} - -export interface UseDialogTriggerParameters { - /** - * Determines if the dialog is open. - */ - open: boolean; - /** - * Callback to fire when the dialog is requested to be opened or closed. - */ - onOpenChange: (open: boolean) => void; - /** - * The id of the popup element. - */ - popupElementId: string | undefined; -} - -export interface UseDialogTriggerReturnValue { - /** - * Resolver for the root element props. - */ - getRootProps: (externalProps?: React.HTMLAttributes) => React.HTMLAttributes; -} diff --git a/packages/mui-base/src/Dialog/Trigger/useDialogTrigger.ts b/packages/mui-base/src/Dialog/Trigger/useDialogTrigger.ts index e33c881408..7c54f88010 100644 --- a/packages/mui-base/src/Dialog/Trigger/useDialogTrigger.ts +++ b/packages/mui-base/src/Dialog/Trigger/useDialogTrigger.ts @@ -1,12 +1,10 @@ 'use client'; import * as React from 'react'; import { mergeReactProps } from '../../utils/mergeReactProps'; -import type { - UseDialogTriggerParameters, - UseDialogTriggerReturnValue, -} from './DialogTrigger.types'; -export function useDialogTrigger(params: UseDialogTriggerParameters): UseDialogTriggerReturnValue { +export function useDialogTrigger( + params: useDialogTrigger.Parameters, +): useDialogTrigger.ReturnValue { const { open, onOpenChange, popupElementId } = params; const getRootProps = React.useCallback( @@ -30,3 +28,27 @@ export function useDialogTrigger(params: UseDialogTriggerParameters): UseDialogT [getRootProps], ); } + +namespace useDialogTrigger { + export interface Parameters { + /** + * Determines if the dialog is open. + */ + open: boolean; + /** + * Callback to fire when the dialog is requested to be opened or closed. + */ + onOpenChange: (open: boolean) => void; + /** + * The id of the popup element. + */ + popupElementId: string | undefined; + } + + export interface ReturnValue { + /** + * Resolver for the root element props. + */ + getRootProps: (externalProps?: React.HTMLAttributes) => React.HTMLAttributes; + } +} diff --git a/packages/mui-base/src/Dialog/index.barrel.ts b/packages/mui-base/src/Dialog/index.barrel.ts index 4118fe2146..b12eac69e0 100644 --- a/packages/mui-base/src/Dialog/index.barrel.ts +++ b/packages/mui-base/src/Dialog/index.barrel.ts @@ -1,48 +1,7 @@ export { DialogBackdrop } from './Backdrop/DialogBackdrop'; -export type { - DialogBackdropProps, - DialogBackdropOwnerState, -} from './Backdrop/DialogBackdrop.types'; - export { DialogClose } from './Close/DialogClose'; -export { useDialogClose } from './Close/useDialogClose'; -export type { - DialogCloseProps, - DialogCloseOwnerState, - UseDialogCloseParameters, - UseDialogCloseReturnValue, -} from './Close/DialogClose.types'; - export { DialogDescription } from './Description/DialogDescription'; -export type { - DialogDescriptionProps, - DialogDescriptionOwnerState, -} from './Description/DialogDescription.types'; - export { DialogPopup } from './Popup/DialogPopup'; -export { useDialogPopup } from './Popup/useDialogPopup'; -export type { - DialogPopupProps, - DialogPopupOwnerState, - UseDialogPopupParameters, - UseDialogPopupReturnValue, -} from './Popup/DialogPopup.types'; - export { DialogRoot } from './Root/DialogRoot'; -export { useDialogRoot } from './Root/useDialogRoot'; -export type { - DialogRootProps, - UseDialogRootParameters, - UseDialogRootReturnValue, -} from './Root/DialogRoot.types'; - export { DialogTitle } from './Title/DialogTitle'; -export type { DialogTitleProps, DialogTitleOwnerState } from './Title/DialogTitle.types'; - export { DialogTrigger } from './Trigger/DialogTrigger'; -export { useDialogTrigger } from './Trigger/useDialogTrigger'; -export type { - DialogTriggerProps, - UseDialogTriggerParameters, - UseDialogTriggerReturnValue, -} from './Trigger/DialogTrigger.types'; diff --git a/packages/mui-base/src/Dialog/index.ts b/packages/mui-base/src/Dialog/index.ts index 8fea472a28..f242e5602e 100644 --- a/packages/mui-base/src/Dialog/index.ts +++ b/packages/mui-base/src/Dialog/index.ts @@ -1,52 +1,7 @@ export { DialogBackdrop as Backdrop } from './Backdrop/DialogBackdrop'; -export type { - DialogBackdropProps as BackdropProps, - DialogBackdropOwnerState as BackdropOwnerState, -} from './Backdrop/DialogBackdrop.types'; - export { DialogClose as Close } from './Close/DialogClose'; -export { useDialogClose } from './Close/useDialogClose'; -export type { - DialogCloseProps as CloseProps, - DialogCloseOwnerState as CloseOwnerState, - UseDialogCloseParameters, - UseDialogCloseReturnValue, -} from './Close/DialogClose.types'; - export { DialogDescription as Description } from './Description/DialogDescription'; -export type { - DialogDescriptionProps as DescriptionProps, - DialogDescriptionOwnerState as DescriptionOwnerState, -} from './Description/DialogDescription.types'; - export { DialogPopup as Popup } from './Popup/DialogPopup'; -export { useDialogPopup } from './Popup/useDialogPopup'; -export type { - DialogPopupProps as PopupProps, - DialogPopupOwnerState as PopupOwnerState, - UseDialogPopupParameters, - UseDialogPopupReturnValue, -} from './Popup/DialogPopup.types'; - export { DialogRoot as Root } from './Root/DialogRoot'; -export { useDialogRoot } from './Root/useDialogRoot'; -export type { - DialogRootProps as RootProps, - UseDialogRootParameters, - UseDialogRootReturnValue, -} from './Root/DialogRoot.types'; - export { DialogTitle as Title } from './Title/DialogTitle'; -export type { - DialogTitleProps as TitleProps, - DialogTitleOwnerState as TitleOwnerState, -} from './Title/DialogTitle.types'; - export { DialogTrigger as Trigger } from './Trigger/DialogTrigger'; -export { useDialogTrigger } from './Trigger/useDialogTrigger'; -export type { - DialogTriggerProps as TriggerProps, - DialogTriggerOwnerState as TriggerOwnerState, - UseDialogTriggerParameters, - UseDialogTriggerReturnValue, -} from './Trigger/DialogTrigger.types';