{"version":3,"file":"useSpoiler.mjs","sources":[""],"sourcesContent":["import { setCSSVar } from \"@web3r/flowerkit/css\";\r\nimport { getDebouncedFn, wait } from \"@web3r/flowerkit/fn\";\r\nimport type { Dispatch, RefObject, SetStateAction } from \"react\";\r\nimport {\r\n  useEffect, useCallback, useState, useRef,\r\n} from \"react\";\r\nimport { getWindow } from \"ssr-window\";\r\nimport { useListeners } from \"./useListeners\";\r\n\r\ntype TUseSpoilerProps = {\r\n  ref: RefObject<HTMLElement | null>;\r\n  isActive?: boolean;\r\n};\r\n\r\ntype TUseSpoilerReturn = {\r\n  isOpen: boolean;\r\n  setIsOpen: Dispatch<SetStateAction<boolean>>;\r\n  setHeight: () => void;\r\n};\r\n\r\n/**\n * Возвращает переменную высоты элемента для создания спойлеров и переменные управления состоянием\n * @param ref - референс элемента, для которого необходимо рассчитать высоту\n * @param isActive - состояние активности спойлера\n * @returns {TUseSpoilerReturn} Возвращает текущее состояние спойлера (`isOpen`), setter `setIsOpen` и функцию `setHeight` для пересчёта CSS-переменной высоты.\n * @example\n * import { useSpoiler, useCN } from \"@delement/ui/utils/react\";\r\n * import { useRef } from \"react\";\r\n * import { Btn } from \"@delement/ui/components\";\r\n *\r\n * const App = ({ baseClass = \"myApp\" }) => {\r\n *\r\n *   const { getCN } = useCN(baseClass)\r\n *\r\n *   const refOfElement = useRef(null); // к данному элементу добавится переменная --scrollHeight\r\n *\r\n *   const { isOpen, setIsOpen } = useSpoiler({ ref: refOfElement, isActive: false });\r\n *\r\n *   const onClick = (e) => {\r\n *     e.preventDefault();\r\n *     setIsOpen(isOpen => !isOpen);\r\n *   }\r\n *\r\n *   return (\r\n *     <div className={getCN(\"\", { isOpen })}>\r\n *       <Btn label={isOpen ? \"Открыть\" : \"Закрыть\"} onClick={onClick} />\r\n *       <div ref={refOfElement}>\r\n *         <p>Контент элемента, который необходимо скрыть</p>\r\n *       </div>\r\n *     </div>\r\n *   )\r\n * }\r\n */\r\nexport const useSpoiler = ({ ref, isActive = false }: TUseSpoilerProps): TUseSpoilerReturn => {\r\n\r\n  const [ isOpen, setIsOpen ] = useState<boolean>(isActive);\r\n\r\n  const windowRef = useRef<Window>(getWindow());\r\n\r\n  const setHeight = useCallback(() => {\r\n    const { current } = ref;\r\n    if (current) {\r\n      setCSSVar(current, \"--scrollHeight\", `${Math.ceil(current.scrollHeight)}px`);\r\n    } else {\r\n      console.error(`[${useSpoiler.name}] Ref is null or undefined`);\r\n    }\r\n  }, [ ref ]);\r\n\r\n  const onResize = getDebouncedFn(() => setHeight());\r\n\r\n  useListeners({\r\n    listeners: {\r\n      resize: onResize,\r\n    },\r\n    ref: windowRef,\r\n  });\r\n\r\n  useEffect(() => {\r\n    setIsOpen(isOpen);\r\n  }, [ isOpen ]);\r\n\r\n  useEffect(() => {\r\n    wait(100).finally(() => {\r\n      setHeight();\r\n    });\r\n  }, []);\r\n\r\n  return {\r\n    isOpen,\r\n    setIsOpen,\r\n    setHeight,\r\n  };\r\n};\r\n"],"names":["useSpoiler","ref","isActive","isOpen","setIsOpen","useState","windowRef","useRef","getWindow","setHeight","useCallback","current","setCSSVar","Math","ceil","scrollHeight","console","error","name","onResize","getDebouncedFn","useListeners","listeners","resize","useEffect","wait","finally"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDO,MAAMA,WAAa,EAAGC,QAAKC,kBAAW,UAE3C,MAAQC,OAAQC,WAAcC,SAAkBH,UAEhD,MAAMI,UAAYC,OAAeC,aAEjC,MAAMC,UAAYC,YAAY,KAC5B,MAAMC,QAAEA,SAAYV,IACpB,GAAIU,QACFC,UAAUD,QAAS,iBAAkB,GAAGE,KAAKC,KAAKH,QAAQI,wBAE1DC,QAAQC,MAAM,IAAIjB,WAAWkB,mCAE9B,CAAEjB,MAEL,MAAMkB,SAAWC,eAAe,IAAMX,aAEtCY,aAAa,CACXC,UAAW,CACTC,OAAQJ,UAEVlB,IAAKK,YAGPkB,UAAU,KACRpB,UAAUD,SACT,CAAEA,SAELqB,UAAU,KACRC,KAAK,KAAKC,QAAQ,KAChBjB,eAED,IAEH,MAAO,CACLN,cACAC,oBACAK"}