UNPKG

@vtbag/utensil-drawer

Version:

Pull out just what you need to craft seamless transitions. The Utensil Drawer holds reusable functions to help you build websites with view transitions. It is a bit sparse right now, but like the one in your kitchen, it is bound to fill up over time.

66 lines (65 loc) 2.97 kB
import { getCurrentViewTransition } from './may-start-view-transition.js'; import { createPromiseSubstitute } from './switchable-promise.js'; export function createViewTransitionProxy(types) { let delegate = undefined; let skipped = false; const waitForThose = []; return new Proxy({ updateCallbackDone: createPromiseSubstitute(), ready: createPromiseSubstitute(), finished: createPromiseSubstitute(), skipTransition: () => (delegate ? delegate.skipTransition() : (skipped = true)), waitUntil: (promise) => waitForThose.push(promise), types: new Proxy(new Set(types), { get(target, prop) { if (prop === 'add') { return (value) => (delegate ? delegate.types.add(value) : target.add(value)); } else if (prop === 'delete') { return (value) => delegate ? delegate.types.delete(value) : target.delete(value); } else if (prop === 'clear') { return () => (delegate ? delegate.types.clear() : target.clear()); } else if (prop === 'has') { return (value) => (delegate ? delegate.types.has(value) : target.has(value)); } else if (prop === 'size') { return () => (delegate ? delegate.types.size : target.size); } else if (prop === 'forEach') { return (callback, thisArg) => delegate ? delegate.types.forEach(callback, thisArg) : target.forEach(callback, thisArg); } else if (prop === Symbol.iterator) { return () => delegate ? delegate.types[Symbol.iterator]() : target[Symbol.iterator](); } return target[prop]; }, }), switch() { const currentViewTransition = getCurrentViewTransition(); if (!currentViewTransition) throw new Error('No view transition active'); if (delegate) throw new Error('Already switched to another view transition'); if (skipped) { currentViewTransition?.skipTransition(); } if ('waitUntil' in currentViewTransition) for (const promise of waitForThose) { currentViewTransition.waitUntil(promise); } this.types = currentViewTransition.types ?? this.types; this.updateCallbackDone.switch(currentViewTransition.updateCallbackDone); this.ready.switch(currentViewTransition.ready); this.finished.switch(currentViewTransition.finished); delegate = currentViewTransition; }, }, { get(target, prop) { return delegate ? delegate[prop] : target[prop]; }, }); }