@crossed/primitive
Version:
A universal & performant styling library for React Native, Next.js & React
110 lines (109 loc) • 3.43 kB
JavaScript
import { jsx } from "react/jsx-runtime";
import {
createContext,
forwardRef,
useCallback,
useContext,
useId,
useRef
} from "react";
import { Pressable, View } from "react-native";
import { Focus, useFocus } from "./Focus";
import { composeEventHandlers, useUncontrolled } from "@crossed/core";
import { VisibilityHidden } from "../VisibilityHidden";
const createAccordion = () => {
const rootContext = createContext(
{}
);
const itemContext = createContext({});
const Accordion2 = (props) => {
const {
children,
allowMultiple = false,
defaultValues,
values: valueProps,
onChange,
...restProps
} = props;
const [values, setValues] = useUncontrolled({
defaultValue: defaultValues,
value: valueProps,
onChange
});
return /* @__PURE__ */ jsx(Focus, { ...restProps, children: /* @__PURE__ */ jsx(rootContext.Provider, { value: { values, setValues, allowMultiple }, children }) });
};
const AccordionItem2 = forwardRef(
({ value, ...props }, ref) => {
const buttonId = useRef();
const panelId = useRef();
return /* @__PURE__ */ jsx(itemContext.Provider, { value: { value, buttonId, panelId }, children: /* @__PURE__ */ jsx(View, { ...props, ref }) });
}
);
const AccordionTrigger2 = forwardRef(
(props, ref) => {
const id = useId();
const propsId = props.id || props.nativeID || `accordion-trigger-${id}`;
const { setValues, values, allowMultiple } = useContext(rootContext);
const { value, buttonId, panelId } = useContext(itemContext);
const onPress = useCallback(() => {
setValues(
allowMultiple ? values.includes(value) ? values.filter((e) => e !== value) : [...values, value] : [value]
);
}, [setValues, value, allowMultiple, values]);
const propsFocus = useFocus({ onPress });
buttonId.current = propsId;
return /* @__PURE__ */ jsx(
Pressable,
{
role: "button",
...props,
...propsFocus,
id: propsId,
"aria-controls": panelId.current,
"aria-expanded": values.includes(value),
onPress: composeEventHandlers(onPress, props.onPress),
ref
}
);
}
);
const AccordionPanel2 = forwardRef((props, ref) => {
const { values } = useContext(rootContext);
const { value, buttonId, panelId } = useContext(itemContext);
const id = useId();
const propsId = props.id || props.nativeID || `accordion-panel-${id}`;
panelId.current = propsId;
return /* @__PURE__ */ jsx(
VisibilityHidden,
{
role: "region",
ref,
id: propsId,
"aria-labelledby": buttonId.current,
hide: !values.includes(value),
...props
}
);
});
Accordion2.displayName = "Accordion";
AccordionItem2.displayName = "Accordion.Item";
AccordionTrigger2.displayName = "Accordion.Trigger";
AccordionPanel2.displayName = "Accordion.Panel";
return {
Accordion: Accordion2,
AccordionItem: AccordionItem2,
AccordionTrigger: AccordionTrigger2,
AccordionPanel: AccordionPanel2,
rootContext,
itemContext
};
};
const { Accordion, AccordionItem, AccordionTrigger, AccordionPanel } = createAccordion();
export {
Accordion,
AccordionItem,
AccordionPanel,
AccordionTrigger,
createAccordion
};
//# sourceMappingURL=index.js.map