UNPKG

kaioken-gsap

Version:

Tools for using GSAP in Kaioken, like useGSAP() which is a drop-in replacement for useLayoutEffect()/useEffect()

53 lines (52 loc) 2.27 kB
/** * @fileoverview Tools for using GSAP in Kaioken, like useGSAP() which is a drop-in replacement for useLayoutEffect()/useEffect() * @version 1.0.0 * @license ISC * Based on the work of Jack Doyle, jack@greensock.com - (https://github.com/greensock/react/blob/main/src/index.js) */ import { useLayoutEffect, useRef } from "kaioken"; import gsap from "gsap"; const isConfig = (obj) => typeof obj === "object" && !!obj && !Array.isArray(obj); const defaultConfig = {}; const emptyArray = []; let _gsap = gsap; export function useGSAP(callback, dependencies = emptyArray) { let config = defaultConfig; if (isConfig(callback)) { config = callback; callback = null; dependencies = "dependencies" in config ? config.dependencies : emptyArray; } else if (isConfig(dependencies)) { config = dependencies; dependencies = "dependencies" in config ? config.dependencies : emptyArray; } if (callback && typeof callback !== "function") { console.warn("First parameter must be a function or config object"); } const { scope, revertOnUpdate } = config; const mounted = useRef(false); const context = useRef(_gsap.context(() => { }, scope)); const contextSafe = useRef((func) => context.current.add(null, func)); const deferCleanup = dependencies && dependencies.length && !revertOnUpdate; deferCleanup && useLayoutEffect(() => { mounted.current = true; return () => context.current.revert(); }, emptyArray); // @ts-expect-error useLayoutEffect(() => { callback && context.current.add(callback, scope); if (!deferCleanup || !mounted.current) { // Kaioken renders bottom-up, thus there could be hooks with dependencies that run BEFORE the component mounts, thus cleanup wouldn't occur since a hook with an empty dependency Array would only run once the component mounts. return () => context.current.revert(); } }, dependencies); return { context: context.current, contextSafe: contextSafe.current, }; } // @ts-expect-error shut up ts useGSAP.register = (core) => (_gsap = core); useGSAP.headless = true; // doesn't require the window to be registered.