All files index.ts

100% Statements 19/19
100% Branches 1/1
100% Functions 8/8
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 721x 1x                                                                 1x       5x         5x 5x           5x     4x 2x         2x 2x 2x     5x              
import { useCallback, useState } from 'react';
import { PowerGlitch, PowerGlitchOptions, RecursivePartial } from 'powerglitch';
 
 
/**
 * Handle to control the glitch once useGlitch is called.
 */
export type GlitchHandle = {
    /**
     * Function to use as ref for the element to glitch.
     */
    ref: (node: HTMLElement | null) => void,
 
    /**
     * Glitch control to start the glitch animation.
     */
    startGlitch: () => void,
 
    /**
     * Glitch control to stop the glitch animation.
     */
    stopGlitch: () => void,
 
    /**
     * Change the glitch options.
     */
    setOptions: (options: RecursivePartial<PowerGlitchOptions>) => void,
};
 
/**
 * Hook to glitch one element.
 * @param userOptions Options given to PowerGlitch
 * @returns A glitch handle with glitch controls, a function to update the options and 
 */
export function useGlitch(userOptions?: RecursivePartial<PowerGlitchOptions>): GlitchHandle {
    /**
     * Copy the options into a state object to avoid unecessary re-renders if the client is re-creating an options object in the main block.
     */
    const [options, setOptions] = useState(userOptions);
 
    /**
     * Placeholder functions to start/stop the glitch, set after actually glitching the element.
     */
    const [startGlitch, setStartGlitch] = useState<(() => void)>(() => () => void 0);
    const [stopGlitch, setStopGlitch] = useState<(() => void)>(() => () => void 0);
 
    /**
     * Will run each time the ref to the node to glitch changes.
     * E.g. after mount or when added/removed due to conditional rendering.
     */
    const ref = useCallback((node: HTMLElement | null) => {
        // If glitching an element inside a conditional render,
        // `node` might not exist at some point, in which case we have nothing to glitch.
        if (! node) {
            return;
        }
        
        // When/if node is visible, glitch it
        // Because of useCallback, we should not glitch an already glitched element, even though the underlying library supports it.
        const result = PowerGlitch.glitch(node, options);
        setStartGlitch(() => result.startGlitch);
        setStopGlitch(() => result.stopGlitch);
    }, [options]);
 
    return {
        ref,
        startGlitch,
        stopGlitch,
        setOptions,
    };
}