UNPKG

use-start-view-transition

Version:

A set of hooks to use `document.startViewTransition` upon state/value changes

47 lines (46 loc) 1.61 kB
import { useCallback, useRef, useState } from 'react'; export const startViewTransition = async (fn)=>{ if (typeof window === 'undefined' || !('startViewTransition' in document)) { fn(); } else { let readyPromise; try { readyPromise = document.startViewTransition(fn).ready; } catch {} return readyPromise; } }; export const useStartViewTransitionWrap = ([value, _setState], options = {})=>{ const optionsRef = useRef(options); optionsRef.current = options; const setState = useCallback(async (v)=>{ const { skipTransition } = optionsRef.current; const skipFn = typeof skipTransition === 'function' ? skipTransition : (v)=>skipTransition; if (!skipFn(value)) { return startViewTransition(()=>_setState(v)); } _setState(v); }, [ _setState, value ]); return [ value, setState ]; }; export const useStartViewTransitionValue = (_value, options = {})=>{ const valueRef = useRef(_value); const [value, setValue] = useStartViewTransitionWrap(useState(_value), options); const { skipTransition } = options; const skipFn = typeof skipTransition === 'function' ? skipTransition : (v)=>skipTransition; const shouldSkip = skipFn(_value); if (_value !== valueRef.current) { valueRef.current = _value; setValue(_value); } return shouldSkip ? _value : value; }; export const useStartViewTransitionState = (state, options = {})=>{ return useStartViewTransitionWrap(useState(state), options); };