@fremtind/jkl-react-hooks
Version:
Jøkul react button components
141 lines (140 loc) • 5.76 kB
JavaScript
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
;