@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.
53 lines (52 loc) • 1.77 kB
JavaScript
'use client';
import * as React from 'react';
import { useControlled } from '@base-ui/utils/useControlled';
import { useStableCallback } from '@base-ui/utils/useStableCallback';
import { useBaseUiId } from "../../internals/useBaseUiId.mjs";
import { createChangeEventDetails } from "../../internals/createBaseUIEventDetails.mjs";
import { REASONS } from "../../internals/reasons.mjs";
import { useTransitionStatus } from "../../internals/useTransitionStatus.mjs";
export function useCollapsibleRoot(parameters) {
const {
open: openParam,
defaultOpen,
onOpenChange,
disabled
} = parameters;
const [open, setOpen] = useControlled({
controlled: openParam,
default: defaultOpen,
name: 'Collapsible',
state: 'open'
});
const {
mounted,
setMounted,
transitionStatus
} = useTransitionStatus(open, true, true);
const defaultPanelId = useBaseUiId();
// `undefined` uses the initial generated fallback; `null` means the panel unmounted.
const [registeredPanelId, setPanelIdState] = React.useState();
const panelId = registeredPanelId === null ? undefined : registeredPanelId ?? defaultPanelId;
const handleTrigger = useStableCallback(event => {
const nextOpen = !open;
const eventDetails = createChangeEventDetails(REASONS.triggerPress, event.nativeEvent);
onOpenChange(nextOpen, eventDetails);
if (eventDetails.isCanceled) {
return;
}
setOpen(nextOpen);
});
return React.useMemo(() => ({
defaultPanelId,
disabled,
handleTrigger,
mounted,
open,
panelId,
setMounted,
setOpen,
setPanelIdState,
transitionStatus
}), [defaultPanelId, disabled, handleTrigger, mounted, open, panelId, setMounted, setOpen, setPanelIdState, transitionStatus]);
}