@gravity-ui/uikit
Version:
Gravity UI base styling and components
81 lines (80 loc) • 4.03 kB
JavaScript
'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import { useUniqId } from "../../../hooks/index.js";
import { Disclosure } from "../../Disclosure/index.js";
import { DefaultDisclosureSummary } from "../../Disclosure/DisclosureSummary/DisclosureSummary.js";
import { useAccordion } from "../AccordionContext.js";
import { AccordionSummaryContent, isAccordionSummaryComponent, } from "../AccordionSummary/AccordionSummary.js";
import { accordionDetailsBlock, accordionItemBlock, accordionSummaryTriggerBlock, } from "../constants.js";
import "./AccordionItem.css";
export const AccordionItem = React.forwardRef(function AccordionItem(props, _ref) {
const { children, expanded, defaultExpanded, disabled, keepMounted, value, summary, onUpdate, qa, className, } = props;
const attributes = useAccordion();
const { id, isExpanded, handleUpdate } = useAccordionItemState({
expanded,
defaultExpanded,
value,
onUpdate,
});
const disclosureExpanded = expanded !== undefined || defaultExpanded !== true ? isExpanded : undefined;
const [preparedSummary, details] = React.useMemo(() => {
return prepareChildren(children, qa);
}, [children, qa]);
return (_jsxs(Disclosure, { arrowPosition: attributes?.arrowPosition, keepMounted: keepMounted, onUpdate: handleUpdate, expanded: disclosureExpanded, defaultExpanded: defaultExpanded, summary: summary, disabled: disabled, qa: qa, className: accordionItemBlock({
size: attributes?.size,
view: attributes?.view,
disabled,
}, className), children: [preparedSummary, _jsx(Disclosure.Details, { className: accordionDetailsBlock, children: details })] }, value ?? id));
});
function useAccordionItemState({ expanded, defaultExpanded, value, onUpdate, }) {
const id = useUniqId();
const { items, updateItems } = useAccordion();
const isControlledItem = expanded !== undefined;
const hasDefaultExpanded = defaultExpanded === true;
const isExpanded = React.useMemo(() => {
if (isControlledItem) {
return expanded;
}
if (hasDefaultExpanded) {
return false;
}
if (Array.isArray(items)) {
return items.includes(value ?? id);
}
return items === (value ?? id);
}, [isControlledItem, expanded, hasDefaultExpanded, items, value, id]);
const handleUpdate = React.useCallback((next) => {
onUpdate?.(next);
if (!isControlledItem && !hasDefaultExpanded) {
updateItems(value ?? id);
}
}, [onUpdate, isControlledItem, hasDefaultExpanded, updateItems, value, id]);
return { id, isExpanded, handleUpdate };
}
function prepareChildren(children, qa) {
const items = React.Children.toArray(children);
let accordionSummaryElement;
let details;
const content = [];
for (const item of items) {
const isAccordionSummary = isAccordionSummaryComponent(item);
if (isAccordionSummary) {
if (accordionSummaryElement) {
throw new Error('Only one <Accordion.Summary> component is allowed');
}
accordionSummaryElement = item;
continue;
}
content.push(item);
}
if (content.length > 0) {
details = _jsx(React.Fragment, { children: content });
}
const summaryQa = qa ? `${qa}-summary` : undefined;
const summaryChildren = accordionSummaryElement?.props?.children ??
((props) => (_jsx(DefaultDisclosureSummary, { ...props, qa: summaryQa, className: accordionSummaryTriggerBlock })));
const summary = (_jsx(Disclosure.Summary, { qa: accordionSummaryElement?.props?.qa ?? summaryQa, children: (disclosureProps, defaultSummary) => (_jsx(AccordionSummaryContent, { disclosureProps: disclosureProps, defaultSummary: defaultSummary, children: summaryChildren })) }));
return [summary, details];
}
//# sourceMappingURL=AccordionItem.js.map