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.

87 lines (86 loc) 3.27 kB
'use client'; import * as React from 'react'; import { useIsoLayoutEffect } from '@base-ui/utils/useIsoLayoutEffect'; import { useDismiss, useInteractions } from "../../floating-ui-react/index.js"; import { PreviewCardRootContext } from "./PreviewCardContext.js"; import { createChangeEventDetails } from "../../utils/createBaseUIEventDetails.js"; import { REASONS } from "../../utils/reasons.js"; import { PreviewCardStore } from "../store/PreviewCardStore.js"; import { useImplicitActiveTrigger, useOpenStateTransitions } from "../../utils/popups/index.js"; import { jsx as _jsx } from "react/jsx-runtime"; /** * Groups all parts of the preview card. * Doesn’t render its own HTML element. * * Documentation: [Base UI Preview Card](https://base-ui.com/react/components/preview-card) */ export function PreviewCardRoot(props) { const { open: openProp, defaultOpen = false, onOpenChange, onOpenChangeComplete, actionsRef, handle, triggerId: triggerIdProp, defaultTriggerId: defaultTriggerIdProp = null, children } = props; const store = PreviewCardStore.useStore(handle?.store, { open: openProp ?? defaultOpen, activeTriggerId: triggerIdProp !== undefined ? triggerIdProp : defaultTriggerIdProp }); store.useControlledProp('open', openProp, defaultOpen); store.useControlledProp('activeTriggerId', triggerIdProp, defaultTriggerIdProp); store.useContextCallback('onOpenChange', onOpenChange); store.useContextCallback('onOpenChangeComplete', onOpenChangeComplete); const open = store.useState('open'); const activeTriggerId = store.useState('activeTriggerId'); const payload = store.useState('payload'); useImplicitActiveTrigger(store); const { forceUnmount } = useOpenStateTransitions(open, store); useIsoLayoutEffect(() => { if (open) { if (activeTriggerId == null) { store.set('payload', undefined); } } }, [store, activeTriggerId, open]); const handleImperativeClose = React.useCallback(() => { store.setOpen(false, createPreviewCardEventDetails(store, REASONS.imperativeAction)); }, [store]); React.useImperativeHandle(actionsRef, () => ({ unmount: forceUnmount, close: handleImperativeClose }), [forceUnmount, handleImperativeClose]); const floatingRootContext = store.useState('floatingRootContext'); const dismiss = useDismiss(floatingRootContext); const { getReferenceProps, getTriggerProps, getFloatingProps } = useInteractions([dismiss]); const activeTriggerProps = React.useMemo(() => getReferenceProps(), [getReferenceProps]); const inactiveTriggerProps = React.useMemo(() => getTriggerProps(), [getTriggerProps]); const popupProps = React.useMemo(() => getFloatingProps(), [getFloatingProps]); store.useSyncedValues({ activeTriggerProps, inactiveTriggerProps, popupProps }); return /*#__PURE__*/_jsx(PreviewCardRootContext.Provider, { value: store, children: typeof children === 'function' ? children({ payload }) : children }); } function createPreviewCardEventDetails(store, reason) { const details = createChangeEventDetails(reason); details.preventUnmountOnClose = () => { store.set('preventUnmountingOnClose', true); }; return details; }