UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

146 lines (142 loc) • 5.15 kB
"use client"; import { createContext as createContext$1 } from "../../utils/context.js"; import { runKeyAction } from "../../utils/dom.js"; import { mergeRefs } from "../../utils/ref.js"; import { utils_exports } from "../../utils/index.js"; import { useControllableState } from "../../hooks/use-controllable-state/index.js"; import { createDescendants } from "../../hooks/use-descendants/index.js"; import { useCallback, useEffect, useId, useState } from "react"; //#region src/components/accordion/use-accordion.ts const { DescendantsContext: AccordionDescendantsContext, useDescendant: useAccordionDescendant, useDescendants: useAccordionDescendants } = createDescendants(); const [AccordionContext, useAccordionContext] = createContext$1({ name: "AccordionContext" }); const [AccordionItemContext, useAccordionItemContext] = createContext$1({ name: "AccordionItemContext" }); const useAccordion = ({ defaultIndex: defaultIndexProp, index: indexProp, multiple, toggle, onChange,...rest } = {}) => { if ((indexProp || defaultIndexProp) != null && !(0, utils_exports.isArray)(indexProp || defaultIndexProp) && multiple) console.warn(`Accordion: If 'multiple' is passed, then 'index' or 'defaultIndex' must be an array.`); if (multiple && toggle) console.warn(`Accordion: If 'multiple' is passed, 'toggle' will be ignored. Either remove 'toggle' or 'multiple' depending on whether you want multiple accordions visible or not`); const descendants = useAccordionDescendants(); const [focusedIndex, setFocusedIndex] = useState(-1); const [index, setIndex] = useControllableState({ defaultValue: () => multiple ? defaultIndexProp ?? [] : defaultIndexProp ?? -1, value: indexProp, onChange }); const getRootProps = useCallback(({ ref,...props } = {}) => ({ ...props, ...rest, ref: mergeRefs(ref, rest.ref) }), [rest]); useEffect(() => { return () => setFocusedIndex(-1); }, []); return { descendants, focusedIndex, index, multiple, setFocusedIndex, setIndex, toggle, getRootProps }; }; const useAccordionItem = ({ disabled, index,...rest }) => { const itemId = useId(); const panelId = useId(); const { index: selectedIndex, multiple, setFocusedIndex, setIndex, toggle } = useAccordionContext(); const { descendants, register } = useAccordionDescendant({ disabled }); const open = index !== -1 ? (0, utils_exports.isArray)(selectedIndex) ? selectedIndex.includes(index) : selectedIndex === index : false; if (open && disabled) console.warn(`Accordion: Cannot open a disabled accordion item`); const onChange = useCallback((open$1) => { if (index === -1) return; if (multiple && (0, utils_exports.isArray)(selectedIndex)) setIndex(open$1 ? selectedIndex.concat(index) : selectedIndex.filter((i) => i !== index)); else if (open$1) setIndex(index); else if (toggle) setIndex(-1); }, [ multiple, toggle, index, selectedIndex, setIndex ]); const onFocus = useCallback(() => { setFocusedIndex(index); }, [setFocusedIndex, index]); const onClick = useCallback(() => { onChange(!open); setFocusedIndex(index); }, [ index, setFocusedIndex, open, onChange ]); const onKeyDown = useCallback((ev) => { runKeyAction(ev, { ArrowDown: () => { descendants.enabledNextValue(index)?.node.focus(); }, ArrowUp: () => { descendants.enabledPrevValue(index)?.node.focus(); }, End: () => { descendants.enabledLastValue()?.node.focus(); }, Home: () => { descendants.enabledFirstValue()?.node.focus(); } }); }, [descendants, index]); const getItemProps = useCallback(({ ref,...props } = {}) => ({ "data-expanded": (0, utils_exports.dataAttr)(open), ...props, ...rest, ref: mergeRefs(ref, rest.ref) }), [open, rest]); const getButtonProps = useCallback(({ ref,...props } = {}) => ({ id: itemId, type: "button", "aria-controls": panelId, "aria-disabled": (0, utils_exports.ariaAttr)(!multiple && !toggle && open || disabled), "aria-expanded": open, ...props, ref: mergeRefs(register, ref), disabled, onClick: (0, utils_exports.handlerAll)(props.onClick, onClick), onFocus: (0, utils_exports.handlerAll)(props.onFocus, onFocus), onKeyDown: (0, utils_exports.handlerAll)(props.onKeyDown, onKeyDown) }), [ itemId, open, panelId, multiple, toggle, disabled, register, onClick, onFocus, onKeyDown ]); const getPanelProps = useCallback(({ "aria-labelledby": ariaLabelledby,...props } = {}) => ({ id: panelId, "aria-labelledby": (0, utils_exports.cx)(ariaLabelledby, itemId), role: "region", ...props }), [itemId, panelId]); return { disabled, open, getButtonProps, getIconProps: useCallback((props) => ({ "aria-disabled": (0, utils_exports.ariaAttr)(disabled), "aria-expanded": open, "aria-hidden": true, role: "presentation", ...props }), [open, disabled]), getItemProps, getPanelProps }; }; //#endregion export { AccordionContext, AccordionDescendantsContext, AccordionItemContext, useAccordion, useAccordionContext, useAccordionDescendant, useAccordionDescendants, useAccordionItem, useAccordionItemContext }; //# sourceMappingURL=use-accordion.js.map