analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
163 lines (162 loc) • 4.7 kB
JavaScript
// src/components/Accordation/AccordionGroup.tsx
import {
Children,
cloneElement,
forwardRef,
isValidElement,
useEffect,
useRef,
useState
} from "react";
import { create } from "zustand";
import { jsx } from "react/jsx-runtime";
function createAccordionGroupStore(type, initialValue, collapsible) {
return create((set, get) => ({
type,
value: initialValue,
collapsible,
setValue: (value) => set({ value }),
isItemExpanded: (itemValue) => {
const state = get();
if (state.type === "single") {
return state.value === itemValue;
} else {
return Array.isArray(state.value) && state.value.includes(itemValue);
}
}
}));
}
var injectStore = (children, store, indexRef, onItemToggle) => {
return Children.map(children, (child) => {
if (!isValidElement(child)) {
return child;
}
const typedChild = child;
const displayName = typedChild.type?.displayName;
if (displayName === "AccordionGroup") {
return child;
}
let newProps = {};
if (displayName === "CardAccordation") {
const itemValue = typedChild.props.value || `accordion-item-${indexRef.current++}`;
const storeState = store.getState();
const expanded = storeState.isItemExpanded(itemValue);
newProps.value = itemValue;
newProps.expanded = expanded;
newProps.onToggleExpanded = (isExpanded) => {
onItemToggle(itemValue, isExpanded);
typedChild.props.onToggleExpanded?.(isExpanded);
};
}
if (typedChild.props.children) {
const processedChildren = injectStore(
typedChild.props.children,
store,
indexRef,
onItemToggle
);
if (displayName === "CardAccordation") {
newProps.children = processedChildren;
} else if (processedChildren !== typedChild.props.children) {
return cloneElement(typedChild, { children: processedChildren });
}
}
if (Object.keys(newProps).length > 0) {
return cloneElement(typedChild, newProps);
}
return child;
});
};
var AccordionGroup = forwardRef(
({
type = "single",
defaultValue,
value: controlledValue,
onValueChange,
collapsible = true,
children,
className,
...props
}, ref) => {
const [internalValue, setInternalValue] = useState(
defaultValue || (type === "single" ? "" : [])
);
const isControlled = controlledValue !== void 0;
const currentValue = isControlled ? controlledValue : internalValue;
const storeRef = useRef(null);
if (storeRef.current) {
storeRef.current.setState((prev) => {
const nextState = {};
if (prev.type !== type) {
nextState.type = type;
}
if (prev.collapsible !== collapsible) {
nextState.collapsible = collapsible;
}
return nextState;
});
} else {
storeRef.current = createAccordionGroupStore(
type,
currentValue,
collapsible
);
}
const store = storeRef.current;
useEffect(() => {
store.setState({ value: currentValue });
}, [currentValue, store]);
useEffect(() => {
if (!isControlled) {
setInternalValue((prev) => {
if (type === "single") {
if (Array.isArray(prev)) {
return prev[0] ?? "";
}
return typeof prev === "string" ? prev : "";
}
if (Array.isArray(prev)) {
return prev;
}
return prev ? [prev] : [];
});
}
}, [isControlled, type]);
const handleItemToggle = (itemValue, isExpanded) => {
const storeState = store.getState();
let newValue;
if (type === "single") {
if (isExpanded) {
newValue = itemValue;
} else {
newValue = collapsible ? "" : storeState.value;
}
} else {
const currentArray = Array.isArray(storeState.value) ? storeState.value : [];
if (isExpanded) {
newValue = [...currentArray, itemValue];
} else {
newValue = currentArray.filter((v) => v !== itemValue);
}
}
if (!isControlled) {
setInternalValue(newValue);
}
store.setState({ value: newValue });
onValueChange?.(newValue);
};
const indexRef = { current: 0 };
const enhancedChildren = injectStore(
children,
store,
indexRef,
handleItemToggle
);
return /* @__PURE__ */ jsx("div", { ref, className, ...props, children: enhancedChildren });
}
);
AccordionGroup.displayName = "AccordionGroup";
export {
AccordionGroup
};
//# sourceMappingURL=chunk-ILCBSWZF.mjs.map