@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
JavaScript
;
'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";