UNPKG

@fremtind/jkl-react-hooks

Version:
141 lines (140 loc) 5.76 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var useAnimatedHeightBetween_exports = {}; __export(useAnimatedHeightBetween_exports, { useAnimatedHeightBetween: () => useAnimatedHeightBetween }); module.exports = __toCommonJS(useAnimatedHeightBetween_exports); var import_jkl_core = require("@fremtind/jkl-core"); var import_react = require("react"); var import_useBrowserPreferences = require("../useBrowserPreferences/useBrowserPreferences"); var import_usePreviousValue = require("../usePreviousValue/usePreviousValue"); const defaultEasing = "standard"; const defaultTiming = "productive"; function collapseElement(elementRef, transition, raf1, raf2) { const element = elementRef.current; if (!element) return; element.removeAttribute("style"); const expandedHeight = element.scrollHeight; raf1.current = requestAnimationFrame(() => { element.style.removeProperty("transition"); element.dataset["expanded"] = "false"; const collapsedHeight = element.getBoundingClientRect().height; element.dataset["expanded"] = "true"; element.style.setProperty("height", "".concat(expandedHeight, "px")); element.style.setProperty("overflow-y", "hidden"); raf2.current = requestAnimationFrame(() => { element.style.setProperty("transition", transition); element.style.setProperty("height", "".concat(collapsedHeight, "px")); element.dataset["expanded"] = "false"; }); }); } function expandElement(elementRef, transition, raf1, raf2) { const element = elementRef.current; if (!element) return; element.removeAttribute("style"); const expandedHeight = element.scrollHeight; raf1.current = requestAnimationFrame(() => { element.style.removeProperty("transition"); element.dataset["expanded"] = "false"; const collapsedHeight = element.getBoundingClientRect().height; element.style.setProperty("height", "".concat(collapsedHeight, "px")); element.style.setProperty("overflow-y", "hidden"); raf2.current = requestAnimationFrame(() => { element.style.setProperty("transition", transition); element.style.setProperty("height", "".concat(expandedHeight, "px")); element.dataset["expanded"] = "true"; }); }); } function useAnimatedHeightBetween(isExpanded, options) { const wasExpanded = (0, import_usePreviousValue.usePreviousValue)(isExpanded); const easing = (options == null ? void 0 : options.easing) || defaultEasing; const timing = (options == null ? void 0 : options.timing) || defaultTiming; const transition = "".concat(import_jkl_core.timings[timing], " height ").concat(import_jkl_core.easings[easing]); const { prefersReducedMotion } = (0, import_useBrowserPreferences.useBrowserPreferences)(); const raf1 = (0, import_react.useRef)(); const raf2 = (0, import_react.useRef)(); const elementRef = (0, import_react.useRef)(null); const handleTransitionEnd = (0, import_react.useCallback)( (event) => { var _a; const element = elementRef.current; if (element && event.target === element) { element.removeAttribute("style"); (_a = options == null ? void 0 : options.onTransitionEnd) == null ? void 0 : _a.call(options, isExpanded, elementRef); } }, [options, isExpanded] ); const runAnimation = (0, import_react.useCallback)(() => { var _a, _b; const element = elementRef.current; if (!element) return; if (wasExpanded === void 0) { element.dataset["expanded"] = isExpanded ? "true" : "false"; } if (!isExpanded && !wasExpanded || isExpanded && wasExpanded) { return; } (_a = options == null ? void 0 : options.onTransitionStart) == null ? void 0 : _a.call(options, isExpanded, elementRef); if (prefersReducedMotion) { element.removeAttribute("style"); element.dataset["expanded"] = isExpanded ? "true" : "false"; (_b = options == null ? void 0 : options.onTransitionEnd) == null ? void 0 : _b.call(options, isExpanded, elementRef); return; } if (isExpanded) { expandElement(elementRef, transition, raf1, raf2); } else { collapseElement(elementRef, transition, raf1, raf2); } }, [wasExpanded, isExpanded, options, prefersReducedMotion, transition]); (0, import_react.useEffect)(() => { runAnimation(); }, [isExpanded, runAnimation]); (0, import_react.useEffect)(() => { const element = elementRef.current; if (element) { element.addEventListener("transitionend", handleTransitionEnd); } return () => { if (element) { element.removeEventListener( "transitionend", handleTransitionEnd ); } }; }, [isExpanded]); (0, import_react.useEffect)(() => { const r1 = raf1.current; const r2 = raf2.current; return () => { r1 && cancelAnimationFrame(r1); r2 && cancelAnimationFrame(r2); }; }, [raf1, raf2]); return [elementRef, runAnimation]; } //# sourceMappingURL=useAnimatedHeightBetween.js.map