UNPKG

@base-ui/react

Version:

Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.

90 lines (88 loc) 3.07 kB
'use client'; import * as React from 'react'; import { useOnFirstRender } from '@base-ui/utils/useOnFirstRender'; import { DialogInteractions, useDialogRoot } from "./useDialogRoot.js"; import { DialogRootContext, IsDrawerContext, useDialogRootContext } from "./DialogRootContext.js"; import { DialogStore } from "../store/DialogStore.js"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; export function useRenderDialogRoot(props, mode = 'dialog') { const { children, open: openProp, defaultOpen = false, onOpenChange, onOpenChangeComplete, disablePointerDismissal: disablePointerDismissalProp = false, modal: modalProp = true, actionsRef, handle, triggerId: triggerIdProp, defaultTriggerId: defaultTriggerIdProp = null } = props; const isDrawer = mode === 'drawer'; const isAlertDialog = mode === 'alert-dialog'; const modal = isAlertDialog ? true : modalProp; const disablePointerDismissal = isAlertDialog || disablePointerDismissalProp; const role = isAlertDialog ? 'alertdialog' : 'dialog'; const parentDialogRootContext = useDialogRootContext(true); const nested = Boolean(parentDialogRootContext); const rootState = { modal, disablePointerDismissal, nested, role }; const store = DialogStore.useStore(handle?.store, { open: defaultOpen, openProp, activeTriggerId: defaultTriggerIdProp, triggerIdProp, ...rootState }); // Support initially open state when uncontrolled useOnFirstRender(() => { const nextState = openProp === undefined && store.state.open === false && defaultOpen === true ? { open: true, activeTriggerId: defaultTriggerIdProp } : null; if (isAlertDialog) { // Handles can reuse plain Dialog stores; alert dialog invariants must exist immediately. store.update(nextState ? { ...rootState, ...nextState } : rootState); } else if (nextState) { store.update(nextState); } }); store.useControlledProp('openProp', openProp); store.useControlledProp('triggerIdProp', triggerIdProp); store.useSyncedValues(rootState); store.useContextCallback('onOpenChange', onOpenChange); store.useContextCallback('onOpenChangeComplete', onOpenChangeComplete); const open = store.useState('open'); const mounted = store.useState('mounted'); const payload = store.useState('payload'); const dialogRoot = useDialogRoot({ store, actionsRef, parentContext: parentDialogRootContext?.store.context, isDrawer }); const shouldRenderInteractions = open || mounted; const contextValue = React.useMemo(() => ({ store }), [store]); return /*#__PURE__*/_jsx(IsDrawerContext.Provider, { value: false, children: /*#__PURE__*/_jsxs(DialogRootContext.Provider, { value: contextValue, children: [shouldRenderInteractions && /*#__PURE__*/_jsx(DialogInteractions, { store: store, dialogRoot: dialogRoot }), typeof children === 'function' ? children({ payload }) : children] }) }); }