diff --git a/docs/assets/scripts/theme-picker.js b/docs/assets/scripts/theme-picker.js index 04df4843b..31310e77b 100644 --- a/docs/assets/scripts/theme-picker.js +++ b/docs/assets/scripts/theme-picker.js @@ -1,34 +1,5 @@ -let initialPageLoadComplete = document.readyState === 'complete'; - -if (!initialPageLoadComplete) { - window.addEventListener('load', () => { - initialPageLoadComplete = true; - }); -} - -// Helper for view transitions -export function domChange(fn, { behavior = 'smooth', ignoreInitialLoad = true } = {}) { - const canUseViewTransitions = - document.startViewTransition && !window.matchMedia('(prefers-reduced-motion: reduce)').matches; - - // Skip transitions on initial page load - if (!initialPageLoadComplete && ignoreInitialLoad) { - fn(false); - return null; - } - - if (canUseViewTransitions && behavior === 'smooth') { - const transition = document.startViewTransition(() => { - fn(true); - // Wait a brief delay before finishing the transition to prevent jumpiness - return new Promise(resolve => setTimeout(resolve, 200)); - }); - return transition; - } else { - fn(false); - return null; - } -} +import { domChange } from './util/dom-change.js'; +export { domChange }; export function nextFrame() { return new Promise(resolve => requestAnimationFrame(resolve)); diff --git a/docs/assets/scripts/util/dom-change.js b/docs/assets/scripts/util/dom-change.js new file mode 100644 index 000000000..48b939e1e --- /dev/null +++ b/docs/assets/scripts/util/dom-change.js @@ -0,0 +1,37 @@ +let initialPageLoadComplete = document.readyState === 'complete'; + +if (!initialPageLoadComplete) { + window.addEventListener('load', () => { + initialPageLoadComplete = true; + }); +} + +/** + * Helper for performing a DOM change using a view transition, wherever supported and reduced motion is not desired. + * @param {function} fn - Function to perform the DOM change. If async, must resolve when the change is complete. + * @param {object} [options] - Options for the transition + * @param {'smooth' | 'instant'} [options.behavior] - Transition behavior. Defaults to 'smooth'. 'instant' will skip the transition. + * @param {boolean} [options.ignoreInitialLoad] - If true, will skip the transition on initial page load. Defaults to true. + */ +export function domChange(fn, { behavior = 'smooth', ignoreInitialLoad = true } = {}) { + const canUseViewTransitions = + document.startViewTransition && !window.matchMedia('(prefers-reduced-motion: reduce)').matches; + + // Skip transitions on initial page load + if (!initialPageLoadComplete && ignoreInitialLoad) { + fn(false); + return null; + } + + if (canUseViewTransitions && behavior === 'smooth') { + const transition = document.startViewTransition(() => { + fn(true); + // Wait a brief delay before finishing the transition to prevent jumpiness + return new Promise(resolve => setTimeout(resolve, 200)); + }); + return transition; + } else { + fn(false); + return null; + } +}