"use client"; // packages/react/accordion/src/Accordion.tsx import React from "react"; import { createContextScope } from "@radix-ui/react-context"; import { createCollection } from "@radix-ui/react-collection"; import { useComposedRefs } from "@radix-ui/react-compose-refs"; import { composeEventHandlers } from "@radix-ui/primitive"; import { useControllableState } from "@radix-ui/react-use-controllable-state"; import { Primitive } from "@radix-ui/react-primitive"; import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"; import { createCollapsibleScope } from "@radix-ui/react-collapsible"; import { useId } from "@radix-ui/react-id"; import { useDirection } from "@radix-ui/react-direction"; import { jsx } from "react/jsx-runtime"; var ACCORDION_NAME = "Accordion"; var ACCORDION_KEYS = ["Home", "End", "ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight"]; var [Collection, useCollection, createCollectionScope] = createCollection(ACCORDION_NAME); var [createAccordionContext, createAccordionScope] = createContextScope(ACCORDION_NAME, [ createCollectionScope, createCollapsibleScope ]); var useCollapsibleScope = createCollapsibleScope(); var Accordion = React.forwardRef( (props, forwardedRef) => { const { type, ...accordionProps } = props; const singleProps = accordionProps; const multipleProps = accordionProps; return /* @__PURE__ */ jsx(Collection.Provider, { scope: props.__scopeAccordion, children: type === "multiple" ? /* @__PURE__ */ jsx(AccordionImplMultiple, { ...multipleProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(AccordionImplSingle, { ...singleProps, ref: forwardedRef }) }); } ); Accordion.displayName = ACCORDION_NAME; var [AccordionValueProvider, useAccordionValueContext] = createAccordionContext(ACCORDION_NAME); var [AccordionCollapsibleProvider, useAccordionCollapsibleContext] = createAccordionContext( ACCORDION_NAME, { collapsible: false } ); var AccordionImplSingle = React.forwardRef( (props, forwardedRef) => { const { value: valueProp, defaultValue, onValueChange = () => { }, collapsible = false, ...accordionSingleProps } = props; const [value, setValue] = useControllableState({ prop: valueProp, defaultProp: defaultValue, onChange: onValueChange }); return /* @__PURE__ */ jsx( AccordionValueProvider, { scope: props.__scopeAccordion, value: value ? [value] : [], onItemOpen: setValue, onItemClose: React.useCallback(() => collapsible && setValue(""), [collapsible, setValue]), children: /* @__PURE__ */ jsx(AccordionCollapsibleProvider, { scope: props.__scopeAccordion, collapsible, children: /* @__PURE__ */ jsx(AccordionImpl, { ...accordionSingleProps, ref: forwardedRef }) }) } ); } ); var AccordionImplMultiple = React.forwardRef((props, forwardedRef) => { const { value: valueProp, defaultValue, onValueChange = () => { }, ...accordionMultipleProps } = props; const [value = [], setValue] = useControllableState({ prop: valueProp, defaultProp: defaultValue, onChange: onValueChange }); const handleItemOpen = React.useCallback( (itemValue) => setValue((prevValue = []) => [...prevValue, itemValue]), [setValue] ); const handleItemClose = React.useCallback( (itemValue) => setValue((prevValue = []) => prevValue.filter((value2) => value2 !== itemValue)), [setValue] ); return /* @__PURE__ */ jsx( AccordionValueProvider, { scope: props.__scopeAccordion, value, onItemOpen: handleItemOpen, onItemClose: handleItemClose, children: /* @__PURE__ */ jsx(AccordionCollapsibleProvider, { scope: props.__scopeAccordion, collapsible: true, children: /* @__PURE__ */ jsx(AccordionImpl, { ...accordionMultipleProps, ref: forwardedRef }) }) } ); }); var [AccordionImplProvider, useAccordionContext] = createAccordionContext(ACCORDION_NAME); var AccordionImpl = React.forwardRef( (props, forwardedRef) => { const { __scopeAccordion, disabled, dir, orientation = "vertical", ...accordionProps } = props; const accordionRef = React.useRef(null); const composedRefs = useComposedRefs(accordionRef, forwardedRef); const getItems = useCollection(__scopeAccordion); const direction = useDirection(dir); const isDirectionLTR = direction === "ltr"; const handleKeyDown = composeEventHandlers(props.onKeyDown, (event) => { if (!ACCORDION_KEYS.includes(event.key)) return; const target = event.target; const triggerCollection = getItems().filter((item) => !item.ref.current?.disabled); const triggerIndex = triggerCollection.findIndex((item) => item.ref.current === target); const triggerCount = triggerCollection.length; if (triggerIndex === -1) return; event.preventDefault(); let nextIndex = triggerIndex; const homeIndex = 0; const endIndex = triggerCount - 1; const moveNext = () => { nextIndex = triggerIndex + 1; if (nextIndex > endIndex) { nextIndex = homeIndex; } }; const movePrev = () => { nextIndex = triggerIndex - 1; if (nextIndex < homeIndex) { nextIndex = endIndex; } }; switch (event.key) { case "Home": nextIndex = homeIndex; break; case "End": nextIndex = endIndex; break; case "ArrowRight": if (orientation === "horizontal") { if (isDirectionLTR) { moveNext(); } else { movePrev(); } } break; case "ArrowDown": if (orientation === "vertical") { moveNext(); } break; case "ArrowLeft": if (orientation === "horizontal") { if (isDirectionLTR) { movePrev(); } else { moveNext(); } } break; case "ArrowUp": if (orientation === "vertical") { movePrev(); } break; } const clampedIndex = nextIndex % triggerCount; triggerCollection[clampedIndex].ref.current?.focus(); }); return /* @__PURE__ */ jsx( AccordionImplProvider, { scope: __scopeAccordion, disabled, direction: dir, orientation, children: /* @__PURE__ */ jsx(Collection.Slot, { scope: __scopeAccordion, children: /* @__PURE__ */ jsx( Primitive.div, { ...accordionProps, "data-orientation": orientation, ref: composedRefs, onKeyDown: disabled ? void 0 : handleKeyDown } ) }) } ); } ); var ITEM_NAME = "AccordionItem"; var [AccordionItemProvider, useAccordionItemContext] = createAccordionContext(ITEM_NAME); var AccordionItem = React.forwardRef( (props, forwardedRef) => { const { __scopeAccordion, value, ...accordionItemProps } = props; const accordionContext = useAccordionContext(ITEM_NAME, __scopeAccordion); const valueContext = useAccordionValueContext(ITEM_NAME, __scopeAccordion); const collapsibleScope = useCollapsibleScope(__scopeAccordion); const triggerId = useId(); const open = value && valueContext.value.includes(value) || false; const disabled = accordionContext.disabled || props.disabled; return /* @__PURE__ */ jsx( AccordionItemProvider, { scope: __scopeAccordion, open, disabled, triggerId, children: /* @__PURE__ */ jsx( CollapsiblePrimitive.Root, { "data-orientation": accordionContext.orientation, "data-state": getState(open), ...collapsibleScope, ...accordionItemProps, ref: forwardedRef, disabled, open, onOpenChange: (open2) => { if (open2) { valueContext.onItemOpen(value); } else { valueContext.onItemClose(value); } } } ) } ); } ); AccordionItem.displayName = ITEM_NAME; var HEADER_NAME = "AccordionHeader"; var AccordionHeader = React.forwardRef( (props, forwardedRef) => { const { __scopeAccordion, ...headerProps } = props; const accordionContext = useAccordionContext(ACCORDION_NAME, __scopeAccordion); const itemContext = useAccordionItemContext(HEADER_NAME, __scopeAccordion); return /* @__PURE__ */ jsx( Primitive.h3, { "data-orientation": accordionContext.orientation, "data-state": getState(itemContext.open), "data-disabled": itemContext.disabled ? "" : void 0, ...headerProps, ref: forwardedRef } ); } ); AccordionHeader.displayName = HEADER_NAME; var TRIGGER_NAME = "AccordionTrigger"; var AccordionTrigger = React.forwardRef( (props, forwardedRef) => { const { __scopeAccordion, ...triggerProps } = props; const accordionContext = useAccordionContext(ACCORDION_NAME, __scopeAccordion); const itemContext = useAccordionItemContext(TRIGGER_NAME, __scopeAccordion); const collapsibleContext = useAccordionCollapsibleContext(TRIGGER_NAME, __scopeAccordion); const collapsibleScope = useCollapsibleScope(__scopeAccordion); return /* @__PURE__ */ jsx(Collection.ItemSlot, { scope: __scopeAccordion, children: /* @__PURE__ */ jsx( CollapsiblePrimitive.Trigger, { "aria-disabled": itemContext.open && !collapsibleContext.collapsible || void 0, "data-orientation": accordionContext.orientation, id: itemContext.triggerId, ...collapsibleScope, ...triggerProps, ref: forwardedRef } ) }); } ); AccordionTrigger.displayName = TRIGGER_NAME; var CONTENT_NAME = "AccordionContent"; var AccordionContent = React.forwardRef( (props, forwardedRef) => { const { __scopeAccordion, ...contentProps } = props; const accordionContext = useAccordionContext(ACCORDION_NAME, __scopeAccordion); const itemContext = useAccordionItemContext(CONTENT_NAME, __scopeAccordion); const collapsibleScope = useCollapsibleScope(__scopeAccordion); return /* @__PURE__ */ jsx( CollapsiblePrimitive.Content, { role: "region", "aria-labelledby": itemContext.triggerId, "data-orientation": accordionContext.orientation, ...collapsibleScope, ...contentProps, ref: forwardedRef, style: { ["--radix-accordion-content-height"]: "var(--radix-collapsible-content-height)", ["--radix-accordion-content-width"]: "var(--radix-collapsible-content-width)", ...props.style } } ); } ); AccordionContent.displayName = CONTENT_NAME; function getState(open) { return open ? "open" : "closed"; } var Root2 = Accordion; var Item = AccordionItem; var Header = AccordionHeader; var Trigger2 = AccordionTrigger; var Content2 = AccordionContent; export { Accordion, AccordionContent, AccordionHeader, AccordionItem, AccordionTrigger, Content2 as Content, Header, Item, Root2 as Root, Trigger2 as Trigger, createAccordionScope }; //# sourceMappingURL=index.mjs.map