@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
154 lines (150 loc) • 5.61 kB
JavaScript
"use client";
import { useSplitChildren } from "../../utils/children.js";
import { createContext as createContext$1 } from "../../utils/context.js";
import { utils_exports } from "../../utils/index.js";
import { styled } from "../../core/system/factory.js";
import { createSlotComponent } from "../../core/components/create-component.js";
import { accordionStyle } from "./accordion.style.js";
import { Collapse } from "../collapse/collapse.js";
import { ChevronDownIcon } from "../icon/icons/chevron-down-icon.js";
import { AccordionContext, AccordionDescendantsContext, AccordionItemContext, useAccordion, useAccordionItem, useAccordionItemContext } from "./use-accordion.js";
import { Children, cloneElement, isValidElement, useMemo } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
//#region src/components/accordion/accordion.tsx
const [AccordionItemComponentContext, useAccordionItemComponentContext] = createContext$1({ name: "AccordionItemComponentContext" });
const { ComponentContext, PropsContext: AccordionPropsContext, useComponentContext, usePropsContext: useAccordionPropsContext, withContext, withProvider } = createSlotComponent("accordion", accordionStyle);
/**
* `Accordion` is a component for a list that displays information in an expandable or collapsible manner.
*
* @see https://yamada-ui.com/docs/components/accordion
*/
const AccordionRoot = withProvider(({ children, icon, iconHidden, items,...props }) => {
const { descendants, focusedIndex, index, multiple, setFocusedIndex, setIndex, toggle, getRootProps } = useAccordion(props);
const computedChildren = useMemo(() => {
if (children) return children;
return items?.map((props$1, index$1) => /* @__PURE__ */ jsx(AccordionItem, {
index: index$1,
...props$1
}, index$1));
}, [children, items]);
return /* @__PURE__ */ jsx(AccordionDescendantsContext, {
value: descendants,
children: /* @__PURE__ */ jsx(AccordionContext, {
value: useMemo(() => ({
focusedIndex,
icon,
iconHidden,
index,
multiple,
setFocusedIndex,
setIndex,
toggle
}), [
focusedIndex,
icon,
iconHidden,
index,
multiple,
setFocusedIndex,
setIndex,
toggle
]),
children: /* @__PURE__ */ jsx(ComponentContext, {
value: useMemo(() => ({
icon,
iconHidden
}), [icon, iconHidden]),
children: /* @__PURE__ */ jsx(styled.div, {
...getRootProps(),
children: computedChildren
})
})
})
});
}, "root")();
const AccordionItem = withContext(({ button, children, icon,...rest }) => {
const { disabled, open, getButtonProps, getIconProps, getItemProps, getPanelProps } = useAccordionItem(rest);
children = useMemo(() => (0, utils_exports.runIfFn)(children, {
disabled,
expanded: open
}), [
children,
disabled,
open
]);
const [omittedChildren, customAccordionButton, customAccordionPanel] = useSplitChildren(children, AccordionButton, AccordionPanel);
return /* @__PURE__ */ jsx(AccordionItemContext, {
value: useMemo(() => ({
disabled,
icon,
open,
getButtonProps,
getIconProps,
getPanelProps
}), [
disabled,
getButtonProps,
getPanelProps,
getIconProps,
icon,
open
]),
children: /* @__PURE__ */ jsx(AccordionItemComponentContext, {
value: useMemo(() => ({ icon }), [icon]),
children: /* @__PURE__ */ jsxs(styled.div, {
...getItemProps(),
children: [customAccordionButton ?? /* @__PURE__ */ jsx(AccordionButton, { children: (0, utils_exports.runIfFn)(button, {
disabled,
expanded: open
}) }), customAccordionPanel ?? /* @__PURE__ */ jsx(AccordionPanel, { children: omittedChildren })]
})
})
});
}, "item")();
const AccordionButton = withContext(({ children, icon: customIcon, containerProps,...rest }) => {
const { icon: rootIcon } = useComponentContext();
const { icon: itemIcon } = useAccordionItemComponentContext();
const { disabled, open, getButtonProps } = useAccordionItemContext();
const props = {
disabled,
expanded: open
};
return /* @__PURE__ */ jsx(styled.h3, {
...containerProps,
children: /* @__PURE__ */ jsxs(styled.button, {
...getButtonProps(rest),
children: [children, /* @__PURE__ */ jsx(AccordionIcon, { children: (0, utils_exports.runIfFn)(itemIcon, props) ?? (0, utils_exports.runIfFn)(rootIcon, props) ?? (0, utils_exports.runIfFn)(customIcon, props) })]
})
});
}, "button")();
const AccordionIcon = withContext(({ children = /* @__PURE__ */ jsx(ChevronDownIcon, {}),...rest }) => {
const { iconHidden } = useComponentContext();
const { getIconProps } = useAccordionItemContext();
if (iconHidden) return null;
if (isValidElement(children)) return cloneElement(children, getIconProps({
...rest,
...children.props
}));
return Children.count(children) > 1 ? Children.only(null) : null;
}, "icon")();
const AccordionPanel = withContext(({ animationOpacity, children, delay, duration, endingHeight, startingHeight, transition, transitionEnd, unmountOnExit,...rest }) => {
const { open, getPanelProps } = useAccordionItemContext();
return /* @__PURE__ */ jsx(Collapse, {
animationOpacity,
delay,
duration,
endingHeight,
open,
startingHeight,
transition,
transitionEnd,
unmountOnExit,
children: /* @__PURE__ */ jsx(styled.div, {
...getPanelProps(rest),
children: (0, utils_exports.isString)(children) ? /* @__PURE__ */ jsx(styled.p, { children }) : children
})
});
}, "panel")();
//#endregion
export { AccordionButton, AccordionItem, AccordionPanel, AccordionPropsContext, AccordionRoot, useAccordionPropsContext };
//# sourceMappingURL=accordion.js.map