use-start-view-transition
Version:
A set of hooks to use `document.startViewTransition` upon state/value changes
47 lines (46 loc) • 1.61 kB
JavaScript
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);
};