UNPKG

@base-ui-components/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.

131 lines (128 loc) 4.8 kB
"use strict"; 'use client'; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.AccordionRoot = void 0; var React = _interopRequireWildcard(require("react")); var _useControlled = require("@base-ui-components/utils/useControlled"); var _useEventCallback = require("@base-ui-components/utils/useEventCallback"); var _useIsoLayoutEffect = require("@base-ui-components/utils/useIsoLayoutEffect"); var _warn = require("@base-ui-components/utils/warn"); var _CompositeList = require("../../composite/list/CompositeList"); var _DirectionContext = require("../../direction-provider/DirectionContext"); var _AccordionRootContext = require("./AccordionRootContext"); var _useRenderElement = require("../../utils/useRenderElement"); var _createBaseUIEventDetails = require("../../utils/createBaseUIEventDetails"); var _jsxRuntime = require("react/jsx-runtime"); const rootStateAttributesMapping = { value: () => null }; /** * Groups all parts of the accordion. * Renders a `<div>` element. * * Documentation: [Base UI Accordion](https://base-ui.com/react/components/accordion) */ const AccordionRoot = exports.AccordionRoot = /*#__PURE__*/React.forwardRef(function AccordionRoot(componentProps, forwardedRef) { const { render, className, disabled = false, hiddenUntilFound: hiddenUntilFoundProp, keepMounted: keepMountedProp, loop = true, onValueChange: onValueChangeProp, multiple = true, orientation = 'vertical', value: valueProp, defaultValue: defaultValueProp, ...elementProps } = componentProps; const direction = (0, _DirectionContext.useDirection)(); if (process.env.NODE_ENV !== 'production') { // eslint-disable-next-line react-hooks/rules-of-hooks (0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => { if (hiddenUntilFoundProp && keepMountedProp === false) { (0, _warn.warn)('The `keepMounted={false}` prop on a Accordion.Root will be ignored when using `hiddenUntilFound` since it requires Panels to remain mounted when closed.'); } }, [hiddenUntilFoundProp, keepMountedProp]); } // memoized to allow omitting both defaultValue and value // which would otherwise trigger a warning in useControlled const defaultValue = React.useMemo(() => { if (valueProp === undefined) { return defaultValueProp ?? []; } return undefined; }, [valueProp, defaultValueProp]); const onValueChange = (0, _useEventCallback.useEventCallback)(onValueChangeProp); const accordionItemRefs = React.useRef([]); const [value, setValue] = (0, _useControlled.useControlled)({ controlled: valueProp, default: defaultValue, name: 'Accordion', state: 'value' }); const handleValueChange = React.useCallback((newValue, nextOpen) => { const details = (0, _createBaseUIEventDetails.createChangeEventDetails)('none'); if (!multiple) { const nextValue = value[0] === newValue ? [] : [newValue]; onValueChange(nextValue, details); if (details.isCanceled) { return; } setValue(nextValue); } else if (nextOpen) { const nextOpenValues = value.slice(); nextOpenValues.push(newValue); onValueChange(nextOpenValues, details); if (details.isCanceled) { return; } setValue(nextOpenValues); } else { const nextOpenValues = value.filter(v => v !== newValue); onValueChange(nextOpenValues, details); if (details.isCanceled) { return; } setValue(nextOpenValues); } }, [onValueChange, multiple, setValue, value]); const state = React.useMemo(() => ({ value, disabled, orientation }), [value, disabled, orientation]); const contextValue = React.useMemo(() => ({ accordionItemRefs, direction, disabled, handleValueChange, hiddenUntilFound: hiddenUntilFoundProp ?? false, keepMounted: keepMountedProp ?? false, loop, orientation, state, value }), [direction, disabled, handleValueChange, hiddenUntilFoundProp, keepMountedProp, loop, orientation, state, value]); const element = (0, _useRenderElement.useRenderElement)('div', componentProps, { state, ref: forwardedRef, props: [{ dir: direction, role: 'region' }, elementProps], stateAttributesMapping: rootStateAttributesMapping }); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_AccordionRootContext.AccordionRootContext.Provider, { value: contextValue, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CompositeList.CompositeList, { elementsRef: accordionItemRefs, children: element }) }); }); if (process.env.NODE_ENV !== "production") AccordionRoot.displayName = "AccordionRoot";