1 line
12 KiB
Plaintext
1 line
12 KiB
Plaintext
|
|
{"version":3,"file":"index.mjs","sources":["../../../src/view/index.ts"],"sourcesContent":["import { noop } from \"motion-utils\"\nimport type { GroupAnimation } from \"../animation/GroupAnimation\"\nimport { AnimationOptions, DOMKeyframesDefinition } from \"../animation/types\"\nimport { addToQueue } from \"./queue\"\nimport {\n ViewTransitionOptions,\n ViewTransitionTarget,\n ViewTransitionTargetDefinition,\n} from \"./types\"\nimport \"./types.global\"\n\n// Re-export the public view-transition types so they flow out through\n// motion-dom -> framer-motion -> motion alongside `animateView`.\nexport type * from \"./types\"\n\nexport class ViewTransitionBuilder {\n private currentSubject: ViewTransitionTargetDefinition = \"root\"\n\n targets = new Map<ViewTransitionTargetDefinition, ViewTransitionTarget>()\n\n /**\n * Definitions that must be resolved to elements (and assigned a\n * `view-transition-name`) rather than treated as pre-named layers.\n */\n resolveDefs = new Set<ViewTransitionTargetDefinition>()\n\n /**\n * Per-subject crop override: `true` forces the crop (clip + object-fit:\n * cover + animated corner radii) on, `false` forces it off. A subject with\n * no entry uses the default - crop only a genuine morph (a layer present in\n * both snapshots), so a fade-only enter/exit isn't clipped to nothing.\n */\n cropOverride = new Map<ViewTransitionTargetDefinition, boolean>()\n\n /**\n * Subjects paired with a different new-snapshot target (the second `.add()`\n * argument), so two distinct elements share one name and morph into each\n * other - a shared-element transition.\n */\n pairs = new Map<\n ViewTransitionTargetDefinition,\n ViewTransitionTargetDefinition\n >()\n\n /**\n * A `view-transition-class` to apply to each subject's resolved elements,\n * so authors can target the generated layers from CSS by class rather than\n * the opaque generated name.\n */\n classNames = new Map<ViewTransitionTargetDefinition, string>()\n\n /**\n * Subjects opted out of automatic group nesting via `.group(false)`. Their\n * layer stays a flat top-level group (`view-transition-group: none`) instead\n * of nesting under its DOM-ancestor layer - so it animates independently and\n * escapes an ancestor's clip/transform (e.g. an element that lifts out of a\n * card and flies across, which nesting would clip to the card).\n */\n flatGroups = new Set<ViewTransitionTargetDefinition>()\n\n update: () => void | Promise<void>\n\n options: ViewTransitionOptions\n\n notifyReady: (value: GroupAnimation) => void = noop\n\n notifyReject: (error: unknown) => void = noop\n\n private readyPromise = new Promise<GroupAnimation>((resolve, reject) => {\n this.notifyReady = resolve\n this.notifyReject = reject\n })\n\n constructor(\n update: () => void | Promise<void>,\n options: ViewTransitionOptions = {}\n ) {\n this.update = update\n this.options = {\n interrupt: \"wait\",\n ...options,\n }\n // Avoid an unhandled rejection when a failed transition has no\n // `.then(_, reject)` handler attached (e.g. fire-and-forget).\n this.readyPromise.catch(noop)\n addToQueue(this)\n }\n\n /**\n * Target elements resolved from a selector or Element, each assigned a\n * `view-transition-name` automatically.\n *\n * Passing a second target pairs them: the first is resolved in the old\n * snapshot and the second in the new, sharing one name so two *different*\n * elements morph into each other (e.g. `.add(card, \".modal\")`). Symmetric -\n * pass them the other way round to morph back.\n */\n add(\n subject: ViewTransitionTargetDefinition,\n newSubject?: ViewTransitionTargetDefinition\n ) {\n this.currentSubject = subject\n this.resolveDefs.add(subject)\n if (newSubject !== undefined) this.pairs.set(subject, newS
|