BOC v1.0: RS256 auth, Ledger integration, Prometheus metrics, CI/CD, backup
This commit is contained in:
+58
@@ -0,0 +1,58 @@
|
||||
import { GroupAnimationWithThen } from 'motion-dom';
|
||||
import { removeItem } from 'motion-utils';
|
||||
import { animateSequence } from './sequence.mjs';
|
||||
import { animateSubject } from './subject.mjs';
|
||||
|
||||
function isSequence(value) {
|
||||
return Array.isArray(value) && value.some(Array.isArray);
|
||||
}
|
||||
/**
|
||||
* Creates an animation function that is optionally scoped
|
||||
* to a specific element.
|
||||
*/
|
||||
function createScopedAnimate(options = {}) {
|
||||
const { scope, reduceMotion, skipAnimations } = options;
|
||||
/**
|
||||
* Implementation
|
||||
*/
|
||||
function scopedAnimate(subjectOrSequence, optionsOrKeyframes, options) {
|
||||
let animations = [];
|
||||
let animationOnComplete;
|
||||
const inherited = {};
|
||||
if (reduceMotion !== undefined)
|
||||
inherited.reduceMotion = reduceMotion;
|
||||
if (skipAnimations !== undefined)
|
||||
inherited.skipAnimations = skipAnimations;
|
||||
if (isSequence(subjectOrSequence)) {
|
||||
const { onComplete, ...sequenceOptions } = optionsOrKeyframes || {};
|
||||
if (typeof onComplete === "function") {
|
||||
animationOnComplete = onComplete;
|
||||
}
|
||||
animations = animateSequence(subjectOrSequence, { ...inherited, ...sequenceOptions }, scope);
|
||||
}
|
||||
else {
|
||||
// Extract top-level onComplete so it doesn't get applied per-value
|
||||
const { onComplete, ...rest } = options || {};
|
||||
if (typeof onComplete === "function") {
|
||||
animationOnComplete = onComplete;
|
||||
}
|
||||
animations = animateSubject(subjectOrSequence, optionsOrKeyframes, { ...inherited, ...rest }, scope);
|
||||
}
|
||||
const animation = new GroupAnimationWithThen(animations);
|
||||
if (animationOnComplete) {
|
||||
animation.finished.then(animationOnComplete);
|
||||
}
|
||||
if (scope) {
|
||||
scope.animations.push(animation);
|
||||
animation.finished.then(() => {
|
||||
removeItem(scope.animations, animation);
|
||||
});
|
||||
}
|
||||
return animation;
|
||||
}
|
||||
return scopedAnimate;
|
||||
}
|
||||
const animate = createScopedAnimate();
|
||||
|
||||
export { animate, createScopedAnimate };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+23
@@ -0,0 +1,23 @@
|
||||
import { resolveElements } from 'motion-dom';
|
||||
import { isDOMKeyframes } from '../utils/is-dom-keyframes.mjs';
|
||||
|
||||
function resolveSubjects(subject, keyframes, scope, selectorCache) {
|
||||
if (subject == null) {
|
||||
return [];
|
||||
}
|
||||
if (typeof subject === "string" && isDOMKeyframes(keyframes)) {
|
||||
return resolveElements(subject, scope, selectorCache);
|
||||
}
|
||||
else if (subject instanceof NodeList) {
|
||||
return Array.from(subject);
|
||||
}
|
||||
else if (Array.isArray(subject)) {
|
||||
return subject.filter((s) => s != null);
|
||||
}
|
||||
else {
|
||||
return [subject];
|
||||
}
|
||||
}
|
||||
|
||||
export { resolveSubjects };
|
||||
//# sourceMappingURL=resolve-subjects.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"resolve-subjects.mjs","sources":["../../../../src/animation/animate/resolve-subjects.ts"],"sourcesContent":["import {\n AnimationScope,\n DOMKeyframesDefinition,\n SelectorCache,\n resolveElements,\n} from \"motion-dom\"\nimport { ObjectTarget } from \"../sequence/types\"\nimport { isDOMKeyframes } from \"../utils/is-dom-keyframes\"\n\nexport function resolveSubjects<O extends {}>(\n subject:\n | string\n | Element\n | Element[]\n | NodeListOf<Element>\n | O\n | O[]\n | null\n | undefined,\n keyframes: DOMKeyframesDefinition | ObjectTarget<O>,\n scope?: AnimationScope,\n selectorCache?: SelectorCache\n) {\n if (subject == null) {\n return []\n }\n\n if (typeof subject === \"string\" && isDOMKeyframes(keyframes)) {\n return resolveElements(subject, scope, selectorCache)\n } else if (subject instanceof NodeList) {\n return Array.from(subject)\n } else if (Array.isArray(subject)) {\n return subject.filter((s) => s != null)\n } else {\n return [subject]\n }\n}\n"],"names":[],"mappings":";;;AASM,SAAU,eAAe,CAC3B,OAQe,EACf,SAAmD,EACnD,KAAsB,EACtB,aAA6B,EAAA;AAE7B,IAAA,IAAI,OAAO,IAAI,IAAI,EAAE;AACjB,QAAA,OAAO,EAAE;IACb;IAEA,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,cAAc,CAAC,SAAS,CAAC,EAAE;QAC1D,OAAO,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC;IACzD;AAAO,SAAA,IAAI,OAAO,YAAY,QAAQ,EAAE;AACpC,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;IAC9B;AAAO,SAAA,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;AAC/B,QAAA,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IAC3C;SAAO;QACH,OAAO,CAAC,OAAO,CAAC;IACpB;AACJ;;;;"}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import { motionValue, spring } from 'motion-dom';
|
||||
import { createAnimationsFromSequence } from '../sequence/create.mjs';
|
||||
import { animateSubject } from './subject.mjs';
|
||||
|
||||
function animateSequence(sequence, options, scope) {
|
||||
const animations = [];
|
||||
/**
|
||||
* Pre-process: replace function segments with MotionValue segments,
|
||||
* subscribe callbacks immediately
|
||||
*/
|
||||
const processedSequence = sequence.map((segment) => {
|
||||
if (Array.isArray(segment) && typeof segment[0] === "function") {
|
||||
const callback = segment[0];
|
||||
const mv = motionValue(0);
|
||||
mv.on("change", callback);
|
||||
if (segment.length === 1) {
|
||||
return [mv, [0, 1]];
|
||||
}
|
||||
else if (segment.length === 2) {
|
||||
return [mv, [0, 1], segment[1]];
|
||||
}
|
||||
else {
|
||||
return [mv, segment[1], segment[2]];
|
||||
}
|
||||
}
|
||||
return segment;
|
||||
});
|
||||
const animationDefinitions = createAnimationsFromSequence(processedSequence, options, scope, { spring });
|
||||
animationDefinitions.forEach(({ keyframes, transition }, subject) => {
|
||||
animations.push(...animateSubject(subject, keyframes, transition));
|
||||
});
|
||||
return animations;
|
||||
}
|
||||
|
||||
export { animateSequence };
|
||||
//# sourceMappingURL=sequence.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"sequence.mjs","sources":["../../../../src/animation/animate/sequence.ts"],"sourcesContent":["import {\n AnimationPlaybackControlsWithThen,\n AnimationScope,\n motionValue,\n spring,\n} from \"motion-dom\"\nimport { createAnimationsFromSequence } from \"../sequence/create\"\nimport { AnimationSequence, SequenceOptions } from \"../sequence/types\"\nimport { animateSubject } from \"./subject\"\n\nexport function animateSequence(\n sequence: AnimationSequence,\n options?: SequenceOptions,\n scope?: AnimationScope\n) {\n const animations: AnimationPlaybackControlsWithThen[] = []\n\n /**\n * Pre-process: replace function segments with MotionValue segments,\n * subscribe callbacks immediately\n */\n const processedSequence = sequence.map((segment) => {\n if (Array.isArray(segment) && typeof segment[0] === \"function\") {\n const callback = segment[0] as (value: any) => void\n const mv = motionValue(0)\n mv.on(\"change\", callback)\n\n if (segment.length === 1) {\n return [mv, [0, 1]] as any\n } else if (segment.length === 2) {\n return [mv, [0, 1], segment[1]] as any\n } else {\n return [mv, segment[1], segment[2]] as any\n }\n }\n return segment\n }) as AnimationSequence\n\n const animationDefinitions = createAnimationsFromSequence(\n processedSequence,\n options,\n scope,\n { spring }\n )\n\n animationDefinitions.forEach(({ keyframes, transition }, subject) => {\n animations.push(...animateSubject(subject, keyframes, transition))\n })\n\n return animations\n}\n"],"names":[],"mappings":";;;;SAUgB,eAAe,CAC3B,QAA2B,EAC3B,OAAyB,EACzB,KAAsB,EAAA;IAEtB,MAAM,UAAU,GAAwC,EAAE;AAE1D;;;AAGG;IACH,MAAM,iBAAiB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,KAAI;AAC/C,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE;AAC5D,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAyB;AACnD,YAAA,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC;AACzB,YAAA,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;AAEzB,YAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;gBACtB,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAQ;YAC9B;AAAO,iBAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;AAC7B,gBAAA,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAQ;YAC1C;iBAAO;AACH,gBAAA,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAQ;YAC9C;QACJ;AACA,QAAA,OAAO,OAAO;AAClB,IAAA,CAAC,CAAsB;AAEvB,IAAA,MAAM,oBAAoB,GAAG,4BAA4B,CACrD,iBAAiB,EACjB,OAAO,EACP,KAAK,EACL,EAAE,MAAM,EAAE,CACb;AAED,IAAA,oBAAoB,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,OAAO,KAAI;AAChE,QAAA,UAAU,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AACtE,IAAA,CAAC,CAAC;AAEF,IAAA,OAAO,UAAU;AACrB;;;;"}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
import { animateSingleValue, visualElementStore, animateTarget, isMotionValue } from 'motion-dom';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { createDOMVisualElement, createObjectVisualElement } from '../utils/create-visual-element.mjs';
|
||||
import { isDOMKeyframes } from '../utils/is-dom-keyframes.mjs';
|
||||
import { resolveSubjects } from './resolve-subjects.mjs';
|
||||
|
||||
function isSingleValue(subject, keyframes) {
|
||||
return (isMotionValue(subject) ||
|
||||
typeof subject === "number" ||
|
||||
(typeof subject === "string" && !isDOMKeyframes(keyframes)));
|
||||
}
|
||||
/**
|
||||
* Implementation
|
||||
*/
|
||||
function animateSubject(subject, keyframes, options, scope) {
|
||||
const animations = [];
|
||||
if (isSingleValue(subject, keyframes)) {
|
||||
animations.push(animateSingleValue(subject, isDOMKeyframes(keyframes)
|
||||
? keyframes.default || keyframes
|
||||
: keyframes, options ? options.default || options : options));
|
||||
}
|
||||
else {
|
||||
// Gracefully handle null/undefined subjects (e.g., from querySelector returning null)
|
||||
if (subject == null) {
|
||||
return animations;
|
||||
}
|
||||
const subjects = resolveSubjects(subject, keyframes, scope);
|
||||
const numSubjects = subjects.length;
|
||||
invariant(Boolean(numSubjects), "No valid elements provided.", "no-valid-elements");
|
||||
for (let i = 0; i < numSubjects; i++) {
|
||||
const thisSubject = subjects[i];
|
||||
const createVisualElement = thisSubject instanceof Element
|
||||
? createDOMVisualElement
|
||||
: createObjectVisualElement;
|
||||
if (!visualElementStore.has(thisSubject)) {
|
||||
createVisualElement(thisSubject);
|
||||
}
|
||||
const visualElement = visualElementStore.get(thisSubject);
|
||||
const transition = { ...options };
|
||||
/**
|
||||
* Resolve stagger function if provided.
|
||||
*/
|
||||
if ("delay" in transition &&
|
||||
typeof transition.delay === "function") {
|
||||
transition.delay = transition.delay(i, numSubjects);
|
||||
}
|
||||
animations.push(...animateTarget(visualElement, { ...keyframes, transition }, {}));
|
||||
}
|
||||
}
|
||||
return animations;
|
||||
}
|
||||
|
||||
export { animateSubject };
|
||||
//# sourceMappingURL=subject.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+110
@@ -0,0 +1,110 @@
|
||||
import { resolveElements, getValueTransition, getAnimationMap, animationMapKey, getComputedStyle, fillWildcards, applyPxDefaults, NativeAnimation } from 'motion-dom';
|
||||
import { invariant, secondsToMilliseconds } from 'motion-utils';
|
||||
|
||||
function animateElements(elementOrSelector, keyframes, options, scope) {
|
||||
// Gracefully handle null/undefined elements (e.g., from querySelector returning null)
|
||||
if (elementOrSelector == null) {
|
||||
return [];
|
||||
}
|
||||
const elements = resolveElements(elementOrSelector, scope);
|
||||
const numElements = elements.length;
|
||||
invariant(Boolean(numElements), "No valid elements provided.", "no-valid-elements");
|
||||
/**
|
||||
* WAAPI doesn't support interrupting animations.
|
||||
*
|
||||
* Therefore, starting animations requires a three-step process:
|
||||
* 1. Stop existing animations (write styles to DOM)
|
||||
* 2. Resolve keyframes (read styles from DOM)
|
||||
* 3. Create new animations (write styles to DOM)
|
||||
*
|
||||
* The hybrid `animate()` function uses AsyncAnimation to resolve
|
||||
* keyframes before creating new animations, which removes style
|
||||
* thrashing. Here, we have much stricter filesize constraints.
|
||||
* Therefore we do this in a synchronous way that ensures that
|
||||
* at least within `animate()` calls there is no style thrashing.
|
||||
*
|
||||
* In the motion-native-animate-mini-interrupt benchmark this
|
||||
* was 80% faster than a single loop.
|
||||
*/
|
||||
const animationDefinitions = [];
|
||||
/**
|
||||
* Step 1: Build options and stop existing animations (write)
|
||||
*/
|
||||
for (let i = 0; i < numElements; i++) {
|
||||
const element = elements[i];
|
||||
const elementTransition = { ...options };
|
||||
/**
|
||||
* Resolve stagger function if provided.
|
||||
*/
|
||||
if (typeof elementTransition.delay === "function") {
|
||||
elementTransition.delay = elementTransition.delay(i, numElements);
|
||||
}
|
||||
for (const valueName in keyframes) {
|
||||
let valueKeyframes = keyframes[valueName];
|
||||
if (!Array.isArray(valueKeyframes)) {
|
||||
valueKeyframes = [valueKeyframes];
|
||||
}
|
||||
const valueOptions = {
|
||||
...getValueTransition(elementTransition, valueName),
|
||||
};
|
||||
valueOptions.duration && (valueOptions.duration = secondsToMilliseconds(valueOptions.duration));
|
||||
valueOptions.delay && (valueOptions.delay = secondsToMilliseconds(valueOptions.delay));
|
||||
/**
|
||||
* If there's an existing animation playing on this element then stop it
|
||||
* before creating a new one.
|
||||
*/
|
||||
const map = getAnimationMap(element);
|
||||
const key = animationMapKey(valueName, valueOptions.pseudoElement || "");
|
||||
const currentAnimation = map.get(key);
|
||||
currentAnimation && currentAnimation.stop();
|
||||
animationDefinitions.push({
|
||||
map,
|
||||
key,
|
||||
unresolvedKeyframes: valueKeyframes,
|
||||
options: {
|
||||
...valueOptions,
|
||||
element,
|
||||
name: valueName,
|
||||
allowFlatten: !elementTransition.type && !elementTransition.ease,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Step 2: Resolve keyframes (read)
|
||||
*/
|
||||
for (let i = 0; i < animationDefinitions.length; i++) {
|
||||
const { unresolvedKeyframes, options: animationOptions } = animationDefinitions[i];
|
||||
const { element, name, pseudoElement } = animationOptions;
|
||||
if (!pseudoElement && unresolvedKeyframes[0] === null) {
|
||||
unresolvedKeyframes[0] = getComputedStyle(element, name);
|
||||
}
|
||||
fillWildcards(unresolvedKeyframes);
|
||||
applyPxDefaults(unresolvedKeyframes, name);
|
||||
/**
|
||||
* If we only have one keyframe, explicitly read the initial keyframe
|
||||
* from the computed style. This is to ensure consistency with WAAPI behaviour
|
||||
* for restarting animations, for instance .play() after finish, when it
|
||||
* has one vs two keyframes.
|
||||
*/
|
||||
if (!pseudoElement && unresolvedKeyframes.length < 2) {
|
||||
unresolvedKeyframes.unshift(getComputedStyle(element, name));
|
||||
}
|
||||
animationOptions.keyframes = unresolvedKeyframes;
|
||||
}
|
||||
/**
|
||||
* Step 3: Create new animations (write)
|
||||
*/
|
||||
const animations = [];
|
||||
for (let i = 0; i < animationDefinitions.length; i++) {
|
||||
const { map, key, options: animationOptions } = animationDefinitions[i];
|
||||
const animation = new NativeAnimation(animationOptions);
|
||||
map.set(key, animation);
|
||||
animation.finished.finally(() => map.delete(key));
|
||||
animations.push(animation);
|
||||
}
|
||||
return animations;
|
||||
}
|
||||
|
||||
export { animateElements };
|
||||
//# sourceMappingURL=animate-elements.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
import { GroupAnimationWithThen } from 'motion-dom';
|
||||
import { createAnimationsFromSequence } from '../../sequence/create.mjs';
|
||||
import { animateElements } from './animate-elements.mjs';
|
||||
|
||||
function animateSequence(definition, options) {
|
||||
const animations = [];
|
||||
createAnimationsFromSequence(definition, options).forEach(({ keyframes, transition }, element) => {
|
||||
animations.push(...animateElements(element, keyframes, transition));
|
||||
});
|
||||
return new GroupAnimationWithThen(animations);
|
||||
}
|
||||
|
||||
export { animateSequence };
|
||||
//# sourceMappingURL=animate-sequence.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"animate-sequence.mjs","sources":["../../../../../src/animation/animators/waapi/animate-sequence.ts"],"sourcesContent":["import { AnimationPlaybackControls, GroupAnimationWithThen } from \"motion-dom\"\nimport { createAnimationsFromSequence } from \"../../sequence/create\"\nimport { AnimationSequence, SequenceOptions } from \"../../sequence/types\"\nimport { animateElements } from \"./animate-elements\"\n\nexport function animateSequence(\n definition: AnimationSequence,\n options?: SequenceOptions\n) {\n const animations: AnimationPlaybackControls[] = []\n\n createAnimationsFromSequence(definition, options).forEach(\n ({ keyframes, transition }, element: Element) => {\n animations.push(...animateElements(element, keyframes, transition))\n }\n )\n\n return new GroupAnimationWithThen(animations)\n}\n"],"names":[],"mappings":";;;;AAKM,SAAU,eAAe,CAC3B,UAA6B,EAC7B,OAAyB,EAAA;IAEzB,MAAM,UAAU,GAAgC,EAAE;AAElD,IAAA,4BAA4B,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,OAAO,CACrD,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,OAAgB,KAAI;AAC5C,QAAA,UAAU,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AACvE,IAAA,CAAC,CACJ;AAED,IAAA,OAAO,IAAI,sBAAsB,CAAC,UAAU,CAAC;AACjD;;;;"}
|
||||
Generated
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
import { GroupAnimationWithThen } from 'motion-dom';
|
||||
import { animateElements } from './animate-elements.mjs';
|
||||
|
||||
const createScopedWaapiAnimate = (scope) => {
|
||||
function scopedAnimate(elementOrSelector, keyframes, options) {
|
||||
return new GroupAnimationWithThen(animateElements(elementOrSelector, keyframes, options, scope));
|
||||
}
|
||||
return scopedAnimate;
|
||||
};
|
||||
const animateMini = /*@__PURE__*/ createScopedWaapiAnimate();
|
||||
|
||||
export { animateMini, createScopedWaapiAnimate };
|
||||
//# sourceMappingURL=animate-style.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"animate-style.mjs","sources":["../../../../../src/animation/animators/waapi/animate-style.ts"],"sourcesContent":["import {\n AnimationPlaybackControlsWithThen,\n AnimationScope,\n DOMKeyframesDefinition,\n AnimationOptions as DynamicAnimationOptions,\n ElementOrSelector,\n GroupAnimationWithThen,\n} from \"motion-dom\"\nimport { animateElements } from \"./animate-elements\"\n\nexport const createScopedWaapiAnimate = (scope?: AnimationScope) => {\n function scopedAnimate(\n elementOrSelector: ElementOrSelector,\n keyframes: DOMKeyframesDefinition,\n options?: DynamicAnimationOptions\n ): AnimationPlaybackControlsWithThen {\n return new GroupAnimationWithThen(\n animateElements(\n elementOrSelector,\n keyframes as DOMKeyframesDefinition,\n options,\n scope\n )\n )\n }\n\n return scopedAnimate\n}\n\nexport const animateMini = /*@__PURE__*/ createScopedWaapiAnimate()\n"],"names":[],"mappings":";;;AAUO,MAAM,wBAAwB,GAAG,CAAC,KAAsB,KAAI;AAC/D,IAAA,SAAS,aAAa,CAClB,iBAAoC,EACpC,SAAiC,EACjC,OAAiC,EAAA;AAEjC,QAAA,OAAO,IAAI,sBAAsB,CAC7B,eAAe,CACX,iBAAiB,EACjB,SAAmC,EACnC,OAAO,EACP,KAAK,CACR,CACJ;IACL;AAEA,IAAA,OAAO,aAAa;AACxB;MAEa,WAAW,iBAAiB,wBAAwB;;;;"}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
import { animateVisualElement, setTarget } from 'motion-dom';
|
||||
import { invariant } from 'motion-utils';
|
||||
|
||||
function stopAnimation(visualElement) {
|
||||
visualElement.values.forEach((value) => value.stop());
|
||||
}
|
||||
function setVariants(visualElement, variantLabels) {
|
||||
const reversedLabels = [...variantLabels].reverse();
|
||||
reversedLabels.forEach((key) => {
|
||||
const variant = visualElement.getVariant(key);
|
||||
variant && setTarget(visualElement, variant);
|
||||
if (visualElement.variantChildren) {
|
||||
visualElement.variantChildren.forEach((child) => {
|
||||
setVariants(child, variantLabels);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function setValues(visualElement, definition) {
|
||||
if (Array.isArray(definition)) {
|
||||
return setVariants(visualElement, definition);
|
||||
}
|
||||
else if (typeof definition === "string") {
|
||||
return setVariants(visualElement, [definition]);
|
||||
}
|
||||
else {
|
||||
setTarget(visualElement, definition);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
function animationControls() {
|
||||
/**
|
||||
* Track whether the host component has mounted.
|
||||
*/
|
||||
let hasMounted = false;
|
||||
/**
|
||||
* A collection of linked component animation controls.
|
||||
*/
|
||||
const subscribers = new Set();
|
||||
const controls = {
|
||||
subscribe(visualElement) {
|
||||
subscribers.add(visualElement);
|
||||
return () => void subscribers.delete(visualElement);
|
||||
},
|
||||
start(definition, transitionOverride) {
|
||||
invariant(hasMounted, "controls.start() should only be called after a component has mounted. Consider calling within a useEffect hook.");
|
||||
const animations = [];
|
||||
subscribers.forEach((visualElement) => {
|
||||
animations.push(animateVisualElement(visualElement, definition, {
|
||||
transitionOverride,
|
||||
}));
|
||||
});
|
||||
return Promise.all(animations);
|
||||
},
|
||||
set(definition) {
|
||||
invariant(hasMounted, "controls.set() should only be called after a component has mounted. Consider calling within a useEffect hook.");
|
||||
return subscribers.forEach((visualElement) => {
|
||||
setValues(visualElement, definition);
|
||||
});
|
||||
},
|
||||
stop() {
|
||||
subscribers.forEach((visualElement) => {
|
||||
stopAnimation(visualElement);
|
||||
});
|
||||
},
|
||||
mount() {
|
||||
hasMounted = true;
|
||||
return () => {
|
||||
hasMounted = false;
|
||||
controls.stop();
|
||||
};
|
||||
},
|
||||
};
|
||||
return controls;
|
||||
}
|
||||
|
||||
export { animationControls, setValues };
|
||||
//# sourceMappingURL=animation-controls.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+19
@@ -0,0 +1,19 @@
|
||||
"use client";
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useUnmountEffect } from '../../utils/use-unmount-effect.mjs';
|
||||
import { createScopedWaapiAnimate } from '../animators/waapi/animate-style.mjs';
|
||||
|
||||
function useAnimateMini() {
|
||||
const scope = useConstant(() => ({
|
||||
current: null, // Will be hydrated by React
|
||||
animations: [],
|
||||
}));
|
||||
const animate = useConstant(() => createScopedWaapiAnimate(scope));
|
||||
useUnmountEffect(() => {
|
||||
scope.animations.forEach((animation) => animation.stop());
|
||||
});
|
||||
return [scope, animate];
|
||||
}
|
||||
|
||||
export { useAnimateMini };
|
||||
//# sourceMappingURL=use-animate-style.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-animate-style.mjs","sources":["../../../../src/animation/hooks/use-animate-style.ts"],"sourcesContent":["\"use client\"\n\nimport { useConstant } from \"../../utils/use-constant\"\nimport { useUnmountEffect } from \"../../utils/use-unmount-effect\"\nimport { createScopedWaapiAnimate } from \"../animators/waapi/animate-style\"\nimport { AnimationScope } from \"motion-dom\"\n\nexport function useAnimateMini<T extends Element = any>() {\n const scope: AnimationScope<T> = useConstant(() => ({\n current: null!, // Will be hydrated by React\n animations: [],\n }))\n\n const animate = useConstant(() => createScopedWaapiAnimate(scope))\n\n useUnmountEffect(() => {\n scope.animations.forEach((animation) => animation.stop())\n })\n\n return [scope, animate] as [AnimationScope<T>, typeof animate]\n}\n"],"names":[],"mappings":";;;;;;AAQI;;AAEI;AACH;AAED;;AAGI;AACJ;AAEA;AACJ;;"}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
"use client";
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useUnmountEffect } from '../../utils/use-unmount-effect.mjs';
|
||||
import { useReducedMotionConfig } from '../../utils/reduced-motion/use-reduced-motion-config.mjs';
|
||||
import { MotionConfigContext } from '../../context/MotionConfigContext.mjs';
|
||||
import { createScopedAnimate } from '../animate/index.mjs';
|
||||
|
||||
function useAnimate() {
|
||||
const scope = useConstant(() => ({
|
||||
current: null, // Will be hydrated by React
|
||||
animations: [],
|
||||
}));
|
||||
const reduceMotion = useReducedMotionConfig() ?? undefined;
|
||||
const { skipAnimations } = useContext(MotionConfigContext);
|
||||
const animate = useMemo(() => createScopedAnimate({ scope, reduceMotion, skipAnimations }), [scope, reduceMotion, skipAnimations]);
|
||||
useUnmountEffect(() => {
|
||||
scope.animations.forEach((animation) => animation.stop());
|
||||
scope.animations.length = 0;
|
||||
});
|
||||
return [scope, animate];
|
||||
}
|
||||
|
||||
export { useAnimate };
|
||||
//# sourceMappingURL=use-animate.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-animate.mjs","sources":["../../../../src/animation/hooks/use-animate.ts"],"sourcesContent":["\"use client\"\n\nimport { useContext, useMemo } from \"react\"\nimport { AnimationScope } from \"motion-dom\"\nimport { useConstant } from \"../../utils/use-constant\"\nimport { useUnmountEffect } from \"../../utils/use-unmount-effect\"\nimport { useReducedMotionConfig } from \"../../utils/reduced-motion/use-reduced-motion-config\"\nimport { MotionConfigContext } from \"../../context/MotionConfigContext\"\nimport { createScopedAnimate } from \"../animate\"\n\nexport function useAnimate<T extends Element = any>() {\n const scope: AnimationScope<T> = useConstant(() => ({\n current: null!, // Will be hydrated by React\n animations: [],\n }))\n\n const reduceMotion = useReducedMotionConfig() ?? undefined\n const { skipAnimations } = useContext(MotionConfigContext)\n\n const animate = useMemo(\n () => createScopedAnimate({ scope, reduceMotion, skipAnimations }),\n [scope, reduceMotion, skipAnimations]\n )\n\n useUnmountEffect(() => {\n scope.animations.forEach((animation) => animation.stop())\n scope.animations.length = 0\n })\n\n return [scope, animate] as [AnimationScope<T>, typeof animate]\n}\n"],"names":[],"mappings":";;;;;;;;;AAWI;;AAEI;AACH;AAED;;;;AASI;AACA;AACJ;AAEA;AACJ;;"}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
"use client";
|
||||
import { animateVisualElement, VisualElement, createBox } from 'motion-dom';
|
||||
import { useState, useLayoutEffect } from 'react';
|
||||
import { makeUseVisualState } from '../../motion/utils/use-visual-state.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
|
||||
const createObject = () => ({});
|
||||
class StateVisualElement extends VisualElement {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.measureInstanceViewportBox = createBox;
|
||||
}
|
||||
build() { }
|
||||
resetTransform() { }
|
||||
restoreTransform() { }
|
||||
removeValueFromRenderState() { }
|
||||
renderInstance() { }
|
||||
scrapeMotionValuesFromProps() {
|
||||
return createObject();
|
||||
}
|
||||
getBaseTargetFromProps() {
|
||||
return undefined;
|
||||
}
|
||||
readValueFromInstance(_state, key, options) {
|
||||
return options.initialState[key] || 0;
|
||||
}
|
||||
sortInstanceNodePosition() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
const useVisualState = makeUseVisualState({
|
||||
scrapeMotionValuesFromProps: createObject,
|
||||
createRenderState: createObject,
|
||||
});
|
||||
/**
|
||||
* This is not an officially supported API and may be removed
|
||||
* on any version.
|
||||
*/
|
||||
function useAnimatedState(initialState) {
|
||||
const [animationState, setAnimationState] = useState(initialState);
|
||||
const visualState = useVisualState({}, false);
|
||||
const element = useConstant(() => {
|
||||
return new StateVisualElement({
|
||||
props: {
|
||||
onUpdate: (v) => {
|
||||
setAnimationState({ ...v });
|
||||
},
|
||||
},
|
||||
visualState,
|
||||
presenceContext: null,
|
||||
}, { initialState });
|
||||
});
|
||||
useLayoutEffect(() => {
|
||||
element.mount({});
|
||||
return () => element.unmount();
|
||||
}, [element]);
|
||||
const startAnimation = useConstant(() => (animationDefinition) => {
|
||||
return animateVisualElement(element, animationDefinition);
|
||||
});
|
||||
return [animationState, startAnimation];
|
||||
}
|
||||
|
||||
export { useAnimatedState };
|
||||
//# sourceMappingURL=use-animated-state.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-animated-state.mjs","sources":["../../../../src/animation/hooks/use-animated-state.ts"],"sourcesContent":["\"use client\"\n\nimport {\n animateVisualElement,\n createBox,\n ResolvedValues,\n TargetAndTransition,\n VisualElement,\n} from \"motion-dom\"\nimport { useLayoutEffect, useState } from \"react\"\nimport { makeUseVisualState } from \"../../motion/utils/use-visual-state\"\nimport { useConstant } from \"../../utils/use-constant\"\n\ninterface AnimatedStateOptions {\n initialState: ResolvedValues\n}\n\nconst createObject = () => ({})\n\nclass StateVisualElement extends VisualElement<\n ResolvedValues,\n {},\n AnimatedStateOptions\n> {\n type: \"state\"\n build() {}\n measureInstanceViewportBox = createBox\n resetTransform() {}\n restoreTransform() {}\n removeValueFromRenderState() {}\n renderInstance() {}\n scrapeMotionValuesFromProps() {\n return createObject()\n }\n getBaseTargetFromProps() {\n return undefined\n }\n\n readValueFromInstance(\n _state: ResolvedValues,\n key: string,\n options: AnimatedStateOptions\n ) {\n return options.initialState[key] || 0\n }\n\n sortInstanceNodePosition() {\n return 0\n }\n}\n\nconst useVisualState = makeUseVisualState({\n scrapeMotionValuesFromProps: createObject,\n createRenderState: createObject,\n})\n\n/**\n * This is not an officially supported API and may be removed\n * on any version.\n */\nexport function useAnimatedState(initialState: any) {\n const [animationState, setAnimationState] = useState(initialState)\n const visualState = useVisualState({}, false)\n\n const element = useConstant(() => {\n return new StateVisualElement(\n {\n props: {\n onUpdate: (v) => {\n setAnimationState({ ...v })\n },\n },\n visualState,\n presenceContext: null,\n },\n { initialState }\n )\n })\n\n useLayoutEffect(() => {\n element.mount({})\n return () => element.unmount()\n }, [element])\n\n const startAnimation = useConstant(\n () => (animationDefinition: TargetAndTransition) => {\n return animateVisualElement(element, animationDefinition)\n }\n )\n\n return [animationState, startAnimation]\n}\n"],"names":[],"mappings":";;;;;;AAiBA;AAEA;AAAA;;;;AAMI;AAEA;AACA;AACA;AACA;;;;;AAKI;;AAGJ;;;;AASI;;AAEP;AAED;AACI;AACA;AACH;AAED;;;AAGG;AACG;;;AAIF;;AAGY;AACI;AACI;;AAEP;;AAED;AACH;AAGT;;AAGI;AACA;AACJ;;AAIQ;AACJ;AAGJ;AACJ;;"}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
"use client";
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
|
||||
import { animationControls } from './animation-controls.mjs';
|
||||
|
||||
/**
|
||||
* Creates `LegacyAnimationControls`, which can be used to manually start, stop
|
||||
* and sequence animations on one or more components.
|
||||
*
|
||||
* The returned `LegacyAnimationControls` should be passed to the `animate` property
|
||||
* of the components you want to animate.
|
||||
*
|
||||
* These components can then be animated with the `start` method.
|
||||
*
|
||||
* ```jsx
|
||||
* import * as React from 'react'
|
||||
* import { motion, useAnimation } from 'framer-motion'
|
||||
*
|
||||
* export function MyComponent(props) {
|
||||
* const controls = useAnimation()
|
||||
*
|
||||
* controls.start({
|
||||
* x: 100,
|
||||
* transition: { duration: 0.5 },
|
||||
* })
|
||||
*
|
||||
* return <motion.div animate={controls} />
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @returns Animation controller with `start` and `stop` methods
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function useAnimationControls() {
|
||||
const controls = useConstant(animationControls);
|
||||
useIsomorphicLayoutEffect(controls.mount, []);
|
||||
return controls;
|
||||
}
|
||||
const useAnimation = useAnimationControls;
|
||||
|
||||
export { useAnimation, useAnimationControls };
|
||||
//# sourceMappingURL=use-animation.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-animation.mjs","sources":["../../../../src/animation/hooks/use-animation.ts"],"sourcesContent":["\"use client\"\n\nimport { LegacyAnimationControls } from \"motion-dom\"\nimport { useConstant } from \"../../utils/use-constant\"\nimport { useIsomorphicLayoutEffect } from \"../../utils/use-isomorphic-effect\"\nimport { animationControls } from \"./animation-controls\"\n\n/**\n * Creates `LegacyAnimationControls`, which can be used to manually start, stop\n * and sequence animations on one or more components.\n *\n * The returned `LegacyAnimationControls` should be passed to the `animate` property\n * of the components you want to animate.\n *\n * These components can then be animated with the `start` method.\n *\n * ```jsx\n * import * as React from 'react'\n * import { motion, useAnimation } from 'framer-motion'\n *\n * export function MyComponent(props) {\n * const controls = useAnimation()\n *\n * controls.start({\n * x: 100,\n * transition: { duration: 0.5 },\n * })\n *\n * return <motion.div animate={controls} />\n * }\n * ```\n *\n * @returns Animation controller with `start` and `stop` methods\n *\n * @public\n */\nexport function useAnimationControls(): LegacyAnimationControls {\n const controls = useConstant(animationControls)\n\n useIsomorphicLayoutEffect(controls.mount, [])\n\n return controls\n}\n\nexport const useAnimation = useAnimationControls\n"],"names":[],"mappings":";;;;;AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BG;;AAEC;AAEA;AAEA;AACJ;AAEO;;"}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import { appearAnimationStore } from './store.mjs';
|
||||
import { appearStoreId } from './store-id.mjs';
|
||||
|
||||
function handoffOptimizedAppearAnimation(elementId, valueName, frame) {
|
||||
const storeId = appearStoreId(elementId, valueName);
|
||||
const optimisedAnimation = appearAnimationStore.get(storeId);
|
||||
if (!optimisedAnimation) {
|
||||
return null;
|
||||
}
|
||||
const { animation, startTime } = optimisedAnimation;
|
||||
function cancelAnimation() {
|
||||
window.MotionCancelOptimisedAnimation?.(elementId, valueName, frame);
|
||||
}
|
||||
/**
|
||||
* We can cancel the animation once it's finished now that we've synced
|
||||
* with Motion.
|
||||
*
|
||||
* Prefer onfinish over finished as onfinish is backwards compatible with
|
||||
* older browsers.
|
||||
*/
|
||||
animation.onfinish = cancelAnimation;
|
||||
if (startTime === null || window.MotionHandoffIsComplete?.(elementId)) {
|
||||
/**
|
||||
* If the startTime is null, this animation is the Paint Ready detection animation
|
||||
* and we can cancel it immediately without handoff.
|
||||
*
|
||||
* Or if we've already handed off the animation then we're now interrupting it.
|
||||
* In which case we need to cancel it.
|
||||
*/
|
||||
cancelAnimation();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return startTime;
|
||||
}
|
||||
}
|
||||
|
||||
export { handoffOptimizedAppearAnimation };
|
||||
//# sourceMappingURL=handoff.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"handoff.mjs","sources":["../../../../src/animation/optimized-appear/handoff.ts"],"sourcesContent":["import type { Batcher } from \"motion-dom\"\nimport { appearAnimationStore } from \"./store\"\nimport { appearStoreId } from \"./store-id\"\n\nexport function handoffOptimizedAppearAnimation(\n elementId: string,\n valueName: string,\n frame: Batcher\n): number | null {\n const storeId = appearStoreId(elementId, valueName)\n const optimisedAnimation = appearAnimationStore.get(storeId)\n\n if (!optimisedAnimation) {\n return null\n }\n\n const { animation, startTime } = optimisedAnimation\n\n function cancelAnimation() {\n window.MotionCancelOptimisedAnimation?.(elementId, valueName, frame)\n }\n\n /**\n * We can cancel the animation once it's finished now that we've synced\n * with Motion.\n *\n * Prefer onfinish over finished as onfinish is backwards compatible with\n * older browsers.\n */\n animation.onfinish = cancelAnimation\n\n if (startTime === null || window.MotionHandoffIsComplete?.(elementId)) {\n /**\n * If the startTime is null, this animation is the Paint Ready detection animation\n * and we can cancel it immediately without handoff.\n *\n * Or if we've already handed off the animation then we're now interrupting it.\n * In which case we need to cancel it.\n */\n cancelAnimation()\n return null\n } else {\n return startTime\n }\n}\n"],"names":[],"mappings":";;;SAIgB,+BAA+B,CAC3C,SAAiB,EACjB,SAAiB,EACjB,KAAc,EAAA;IAEd,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC;IACnD,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC;IAE5D,IAAI,CAAC,kBAAkB,EAAE;AACrB,QAAA,OAAO,IAAI;IACf;AAEA,IAAA,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,kBAAkB;AAEnD,IAAA,SAAS,eAAe,GAAA;QACpB,MAAM,CAAC,8BAA8B,GAAG,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC;IACxE;AAEA;;;;;;AAMG;AACH,IAAA,SAAS,CAAC,QAAQ,GAAG,eAAe;AAEpC,IAAA,IAAI,SAAS,KAAK,IAAI,IAAI,MAAM,CAAC,uBAAuB,GAAG,SAAS,CAAC,EAAE;AACnE;;;;;;AAMG;AACH,QAAA,eAAe,EAAE;AACjB,QAAA,OAAO,IAAI;IACf;SAAO;AACH,QAAA,OAAO,SAAS;IACpB;AACJ;;;;"}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
import { optimizedAppearDataId, startWaapiAnimation, getOptimisedAppearId } from 'motion-dom';
|
||||
import { noop } from 'motion-utils';
|
||||
import { handoffOptimizedAppearAnimation } from './handoff.mjs';
|
||||
import { appearAnimationStore, appearComplete } from './store.mjs';
|
||||
import { appearStoreId } from './store-id.mjs';
|
||||
|
||||
/**
|
||||
* A single time to use across all animations to manually set startTime
|
||||
* and ensure they're all in sync.
|
||||
*/
|
||||
let startFrameTime;
|
||||
/**
|
||||
* A dummy animation to detect when Chrome is ready to start
|
||||
* painting the page and hold off from triggering the real animation
|
||||
* until then. We only need one animation to detect paint ready.
|
||||
*
|
||||
* https://bugs.chromium.org/p/chromium/issues/detail?id=1406850
|
||||
*/
|
||||
let readyAnimation;
|
||||
/**
|
||||
* Keep track of animations that were suspended vs cancelled so we
|
||||
* can easily resume them when we're done measuring layout.
|
||||
*/
|
||||
const suspendedAnimations = new Set();
|
||||
function resumeSuspendedAnimations() {
|
||||
suspendedAnimations.forEach((data) => {
|
||||
data.animation.play();
|
||||
data.animation.startTime = data.startTime;
|
||||
});
|
||||
suspendedAnimations.clear();
|
||||
}
|
||||
function startOptimizedAppearAnimation(element, name, keyframes, options, onReady) {
|
||||
// Prevent optimised appear animations if Motion has already started animating.
|
||||
if (window.MotionIsMounted) {
|
||||
return;
|
||||
}
|
||||
const id = element.dataset[optimizedAppearDataId];
|
||||
if (!id)
|
||||
return;
|
||||
window.MotionHandoffAnimation = handoffOptimizedAppearAnimation;
|
||||
const storeId = appearStoreId(id, name);
|
||||
if (!readyAnimation) {
|
||||
readyAnimation = startWaapiAnimation(element, name, [keyframes[0], keyframes[0]],
|
||||
/**
|
||||
* 10 secs is basically just a super-safe duration to give Chrome
|
||||
* long enough to get the animation ready.
|
||||
*/
|
||||
{ duration: 10000, ease: "linear" });
|
||||
appearAnimationStore.set(storeId, {
|
||||
animation: readyAnimation,
|
||||
startTime: null,
|
||||
});
|
||||
/**
|
||||
* If there's no readyAnimation then there's been no instantiation
|
||||
* of handoff animations.
|
||||
*/
|
||||
window.MotionHandoffAnimation = handoffOptimizedAppearAnimation;
|
||||
window.MotionHasOptimisedAnimation = (elementId, valueName) => {
|
||||
if (!elementId)
|
||||
return false;
|
||||
/**
|
||||
* Keep a map of elementIds that have started animating. We check
|
||||
* via ID instead of Element because of hydration errors and
|
||||
* pre-hydration checks. We also actively record IDs as they start
|
||||
* animating rather than simply checking for data-appear-id as
|
||||
* this attrbute might be present but not lead to an animation, for
|
||||
* instance if the element's appear animation is on a different
|
||||
* breakpoint.
|
||||
*/
|
||||
if (!valueName) {
|
||||
return appearComplete.has(elementId);
|
||||
}
|
||||
const animationId = appearStoreId(elementId, valueName);
|
||||
return Boolean(appearAnimationStore.get(animationId));
|
||||
};
|
||||
window.MotionHandoffMarkAsComplete = (elementId) => {
|
||||
if (appearComplete.has(elementId)) {
|
||||
appearComplete.set(elementId, true);
|
||||
}
|
||||
};
|
||||
window.MotionHandoffIsComplete = (elementId) => {
|
||||
return appearComplete.get(elementId) === true;
|
||||
};
|
||||
/**
|
||||
* We only need to cancel transform animations as
|
||||
* they're the ones that will interfere with the
|
||||
* layout animation measurements.
|
||||
*/
|
||||
window.MotionCancelOptimisedAnimation = (elementId, valueName, frame, canResume) => {
|
||||
const animationId = appearStoreId(elementId, valueName);
|
||||
const data = appearAnimationStore.get(animationId);
|
||||
if (!data)
|
||||
return;
|
||||
if (frame && canResume === undefined) {
|
||||
/**
|
||||
* Wait until the end of the subsequent frame to cancel the animation
|
||||
* to ensure we don't remove the animation before the main thread has
|
||||
* had a chance to resolve keyframes and render.
|
||||
*/
|
||||
frame.postRender(() => {
|
||||
frame.postRender(() => {
|
||||
data.animation.cancel();
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
data.animation.cancel();
|
||||
}
|
||||
if (frame && canResume) {
|
||||
suspendedAnimations.add(data);
|
||||
frame.render(resumeSuspendedAnimations);
|
||||
}
|
||||
else {
|
||||
appearAnimationStore.delete(animationId);
|
||||
/**
|
||||
* If there are no more animations left, we can remove the cancel function.
|
||||
* This will let us know when we can stop checking for conflicting layout animations.
|
||||
*/
|
||||
if (!appearAnimationStore.size) {
|
||||
window.MotionCancelOptimisedAnimation = undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
window.MotionCheckAppearSync = (visualElement, valueName, value) => {
|
||||
const appearId = getOptimisedAppearId(visualElement);
|
||||
if (!appearId)
|
||||
return;
|
||||
const valueIsOptimised = window.MotionHasOptimisedAnimation?.(appearId, valueName);
|
||||
const externalAnimationValue = visualElement.props.values?.[valueName];
|
||||
if (!valueIsOptimised || !externalAnimationValue)
|
||||
return;
|
||||
const removeSyncCheck = value.on("change", (latestValue) => {
|
||||
if (externalAnimationValue.get() !== latestValue) {
|
||||
window.MotionCancelOptimisedAnimation?.(appearId, valueName);
|
||||
removeSyncCheck();
|
||||
}
|
||||
});
|
||||
return removeSyncCheck;
|
||||
};
|
||||
}
|
||||
const startAnimation = () => {
|
||||
readyAnimation.cancel();
|
||||
const appearAnimation = startWaapiAnimation(element, name, keyframes, options);
|
||||
/**
|
||||
* Record the time of the first started animation. We call performance.now() once
|
||||
* here and once in handoff to ensure we're getting
|
||||
* close to a frame-locked time. This keeps all animations in sync.
|
||||
*/
|
||||
if (startFrameTime === undefined) {
|
||||
startFrameTime = performance.now();
|
||||
}
|
||||
appearAnimation.startTime = startFrameTime;
|
||||
appearAnimationStore.set(storeId, {
|
||||
animation: appearAnimation,
|
||||
startTime: startFrameTime,
|
||||
});
|
||||
if (onReady)
|
||||
onReady(appearAnimation);
|
||||
};
|
||||
appearComplete.set(id, false);
|
||||
if (readyAnimation.ready) {
|
||||
readyAnimation.ready.then(startAnimation).catch(noop);
|
||||
}
|
||||
else {
|
||||
startAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
export { startOptimizedAppearAnimation };
|
||||
//# sourceMappingURL=start.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
import { transformProps } from 'motion-dom';
|
||||
|
||||
const appearStoreId = (elementId, valueName) => {
|
||||
const key = transformProps.has(valueName) ? "transform" : valueName;
|
||||
return `${elementId}: ${key}`;
|
||||
};
|
||||
|
||||
export { appearStoreId };
|
||||
//# sourceMappingURL=store-id.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"store-id.mjs","sources":["../../../../src/animation/optimized-appear/store-id.ts"],"sourcesContent":["import { transformProps } from \"motion-dom\"\n\nexport const appearStoreId = (elementId: string, valueName: string) => {\n const key = transformProps.has(valueName) ? \"transform\" : valueName\n\n return `${elementId}: ${key}`\n}\n"],"names":[],"mappings":";;MAEa,aAAa,GAAG,CAAC,SAAiB,EAAE,SAAiB,KAAI;AAClE,IAAA,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,WAAW,GAAG,SAAS;AAEnE,IAAA,OAAO,CAAA,EAAG,SAAS,CAAA,EAAA,EAAK,GAAG,EAAE;AACjC;;;;"}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
const appearAnimationStore = new Map();
|
||||
const appearComplete = new Map();
|
||||
|
||||
export { appearAnimationStore, appearComplete };
|
||||
//# sourceMappingURL=store.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"store.mjs","sources":["../../../../src/animation/optimized-appear/store.ts"],"sourcesContent":["export interface AppearStoreEntry {\n animation: Animation\n startTime: number | null\n}\n\nexport type AppearElementId = string\n\nexport type IsComplete = boolean\n\nexport const appearAnimationStore = new Map<AppearElementId, AppearStoreEntry>()\n\nexport const appearComplete = new Map<AppearElementId, IsComplete>()\n"],"names":[],"mappings":"AASO,MAAM,oBAAoB,GAAG,IAAI,GAAG;AAEpC,MAAM,cAAc,GAAG,IAAI,GAAG;;;;"}
|
||||
+308
@@ -0,0 +1,308 @@
|
||||
import { isMotionValue, defaultOffset, isGenerator, createGeneratorEasing, fillOffset } from 'motion-dom';
|
||||
import { progress, secondsToMilliseconds, warning, reverseEasing, getEasingForSegment } from 'motion-utils';
|
||||
import { resolveSubjects } from '../animate/resolve-subjects.mjs';
|
||||
import { calculateRepeatDuration } from './utils/calc-repeat-duration.mjs';
|
||||
import { calcNextTime } from './utils/calc-time.mjs';
|
||||
import { addKeyframes } from './utils/edit.mjs';
|
||||
import { normalizeTimes } from './utils/normalize-times.mjs';
|
||||
import { compareByTime } from './utils/sort.mjs';
|
||||
|
||||
const defaultSegmentEasing = "easeInOut";
|
||||
const MAX_REPEAT = 20;
|
||||
function createAnimationsFromSequence(sequence, { defaultTransition = {}, ...sequenceTransition } = {}, scope, generators) {
|
||||
const defaultDuration = defaultTransition.duration || 0.3;
|
||||
const animationDefinitions = new Map();
|
||||
const sequences = new Map();
|
||||
const elementCache = {};
|
||||
const timeLabels = new Map();
|
||||
let prevTime = 0;
|
||||
let currentTime = 0;
|
||||
let totalDuration = 0;
|
||||
/**
|
||||
* Build the timeline by mapping over the sequence array and converting
|
||||
* the definitions into keyframes and offsets with absolute time values.
|
||||
* These will later get converted into relative offsets in a second pass.
|
||||
*/
|
||||
for (let i = 0; i < sequence.length; i++) {
|
||||
const segment = sequence[i];
|
||||
/**
|
||||
* If this is a timeline label, mark it and skip the rest of this iteration.
|
||||
*/
|
||||
if (typeof segment === "string") {
|
||||
timeLabels.set(segment, currentTime);
|
||||
continue;
|
||||
}
|
||||
else if (!Array.isArray(segment)) {
|
||||
timeLabels.set(segment.name, calcNextTime(currentTime, segment.at, prevTime, timeLabels));
|
||||
continue;
|
||||
}
|
||||
let [subject, keyframes, transition = {}] = segment;
|
||||
/**
|
||||
* If a relative or absolute time value has been specified we need to resolve
|
||||
* it in relation to the currentTime.
|
||||
*/
|
||||
if (transition.at !== undefined) {
|
||||
currentTime = calcNextTime(currentTime, transition.at, prevTime, timeLabels);
|
||||
}
|
||||
/**
|
||||
* Keep track of the maximum duration in this definition. This will be
|
||||
* applied to currentTime once the definition has been parsed.
|
||||
*/
|
||||
let maxDuration = 0;
|
||||
const resolveValueSequence = (valueKeyframes, valueTransition, valueSequence, elementIndex = 0, numSubjects = 0) => {
|
||||
const valueKeyframesAsList = keyframesAsList(valueKeyframes);
|
||||
const { delay = 0, times = defaultOffset(valueKeyframesAsList), type = defaultTransition.type || "keyframes", repeat, repeatType, repeatDelay = 0, ...remainingTransition } = valueTransition;
|
||||
let { ease = defaultTransition.ease || "easeOut", duration } = valueTransition;
|
||||
/**
|
||||
* Resolve stagger() if defined.
|
||||
*/
|
||||
const calculatedDelay = typeof delay === "function"
|
||||
? delay(elementIndex, numSubjects)
|
||||
: delay;
|
||||
/**
|
||||
* If this animation should and can use a spring, generate a spring easing function.
|
||||
*/
|
||||
const numKeyframes = valueKeyframesAsList.length;
|
||||
const createGenerator = isGenerator(type)
|
||||
? type
|
||||
: generators?.[type || "keyframes"];
|
||||
if (numKeyframes <= 2 && createGenerator) {
|
||||
/**
|
||||
* As we're creating an easing function from a spring,
|
||||
* ideally we want to generate it using the real distance
|
||||
* between the two keyframes. However this isn't always
|
||||
* possible - in these situations we use 0-100.
|
||||
*/
|
||||
let absoluteDelta = 100;
|
||||
if (numKeyframes === 2 &&
|
||||
isNumberKeyframesArray(valueKeyframesAsList)) {
|
||||
const delta = valueKeyframesAsList[1] - valueKeyframesAsList[0];
|
||||
absoluteDelta = Math.abs(delta);
|
||||
}
|
||||
const springTransition = {
|
||||
...defaultTransition,
|
||||
...remainingTransition,
|
||||
};
|
||||
if (duration !== undefined) {
|
||||
springTransition.duration = secondsToMilliseconds(duration);
|
||||
}
|
||||
const springEasing = createGeneratorEasing(springTransition, absoluteDelta, createGenerator);
|
||||
ease = springEasing.ease;
|
||||
duration = springEasing.duration;
|
||||
}
|
||||
duration ?? (duration = defaultDuration);
|
||||
const startTime = currentTime + calculatedDelay;
|
||||
/**
|
||||
* If there's only one time offset of 0, fill in a second with length 1
|
||||
*/
|
||||
if (times.length === 1 && times[0] === 0) {
|
||||
times[1] = 1;
|
||||
}
|
||||
/**
|
||||
* Fill out if offset if fewer offsets than keyframes
|
||||
*/
|
||||
const remainder = times.length - valueKeyframesAsList.length;
|
||||
remainder > 0 && fillOffset(times, remainder);
|
||||
/**
|
||||
* If only one value has been set, ie [1], push a null to the start of
|
||||
* the keyframe array. This will let us mark a keyframe at this point
|
||||
* that will later be hydrated with the previous value.
|
||||
*/
|
||||
valueKeyframesAsList.length === 1 &&
|
||||
valueKeyframesAsList.unshift(null);
|
||||
/**
|
||||
* Segments can't express `repeat: Infinity` or very large
|
||||
* counts — they'd leave dead time after the segment or
|
||||
* explode the keyframe array. Ignore with a warning.
|
||||
*/
|
||||
if (repeat) {
|
||||
warning(repeat < MAX_REPEAT, `Sequence segments can't repeat ${repeat} times — ignoring repeat option. Use a value below ${MAX_REPEAT} or apply repeat at the sequence level instead.`);
|
||||
}
|
||||
if (repeat && repeat < MAX_REPEAT) {
|
||||
/**
|
||||
* Express repeatDelay in units of a single iteration's duration
|
||||
* so it can be added to the per-iteration time offsets below
|
||||
* before they're normalized to 0-1.
|
||||
*/
|
||||
const repeatDelayUnits = duration > 0 ? repeatDelay / duration : 0;
|
||||
duration = calculateRepeatDuration(duration, repeat, repeatDelay);
|
||||
const originalKeyframes = [...valueKeyframesAsList];
|
||||
const originalTimes = [...times];
|
||||
ease = Array.isArray(ease) ? [...ease] : [ease];
|
||||
const originalEase = [...ease];
|
||||
/**
|
||||
* For reverse/mirror, alternate iterations play the segment
|
||||
* backwards. mirror matches JSAnimation's mirroredGenerator:
|
||||
* reversed keyframes, easings unchanged. reverse matches
|
||||
* JSAnimation's iterationProgress = 1 - p: reversed
|
||||
* keyframes, easing array reversed AND each function easing
|
||||
* mapped through reverseEasing (string easings unchanged —
|
||||
* they're resolved later by the keyframes engine).
|
||||
*/
|
||||
const isFlipping = repeatType === "reverse" || repeatType === "mirror";
|
||||
let flippedKeyframes = originalKeyframes;
|
||||
let flippedEases = originalEase;
|
||||
if (isFlipping) {
|
||||
flippedKeyframes = [...originalKeyframes].reverse();
|
||||
if (repeatType === "reverse") {
|
||||
flippedEases = [...originalEase]
|
||||
.reverse()
|
||||
.map((e) => typeof e === "function"
|
||||
? reverseEasing(e)
|
||||
: e);
|
||||
}
|
||||
}
|
||||
for (let repeatIndex = 0; repeatIndex < repeat; repeatIndex++) {
|
||||
const isFlipped = isFlipping && repeatIndex % 2 === 0;
|
||||
const iterKeyframes = isFlipped
|
||||
? flippedKeyframes
|
||||
: originalKeyframes;
|
||||
const iterEase = isFlipped ? flippedEases : originalEase;
|
||||
const iterStartOffset = (repeatIndex + 1) * (1 + repeatDelayUnits);
|
||||
/**
|
||||
* If repeatDelay is set, hold the previous iteration's
|
||||
* final value through the delay by inserting a keyframe
|
||||
* at the moment the next iteration begins.
|
||||
*/
|
||||
if (repeatDelayUnits > 0) {
|
||||
valueKeyframesAsList.push(valueKeyframesAsList[valueKeyframesAsList.length - 1]);
|
||||
times.push(iterStartOffset);
|
||||
ease.push("linear");
|
||||
}
|
||||
valueKeyframesAsList.push(...iterKeyframes);
|
||||
for (let keyframeIndex = 0; keyframeIndex < iterKeyframes.length; keyframeIndex++) {
|
||||
times.push(originalTimes[keyframeIndex] + iterStartOffset);
|
||||
ease.push(keyframeIndex === 0
|
||||
? "linear"
|
||||
: getEasingForSegment(iterEase, keyframeIndex - 1));
|
||||
}
|
||||
}
|
||||
normalizeTimes(times, repeat, repeatDelayUnits);
|
||||
}
|
||||
const targetTime = startTime + duration;
|
||||
/**
|
||||
* Add keyframes, mapping offsets to absolute time.
|
||||
*/
|
||||
addKeyframes(valueSequence, valueKeyframesAsList, ease, times, startTime, targetTime);
|
||||
maxDuration = Math.max(calculatedDelay + duration, maxDuration);
|
||||
totalDuration = Math.max(targetTime, totalDuration);
|
||||
};
|
||||
if (isMotionValue(subject)) {
|
||||
const subjectSequence = getSubjectSequence(subject, sequences);
|
||||
resolveValueSequence(keyframes, transition, getValueSequence("default", subjectSequence));
|
||||
}
|
||||
else {
|
||||
const subjects = resolveSubjects(subject, keyframes, scope, elementCache);
|
||||
const numSubjects = subjects.length;
|
||||
/**
|
||||
* For every element in this segment, process the defined values.
|
||||
*/
|
||||
for (let subjectIndex = 0; subjectIndex < numSubjects; subjectIndex++) {
|
||||
/**
|
||||
* Cast necessary, but we know these are of this type
|
||||
*/
|
||||
keyframes = keyframes;
|
||||
transition = transition;
|
||||
const thisSubject = subjects[subjectIndex];
|
||||
const subjectSequence = getSubjectSequence(thisSubject, sequences);
|
||||
for (const key in keyframes) {
|
||||
resolveValueSequence(keyframes[key], getValueTransition(transition, key), getValueSequence(key, subjectSequence), subjectIndex, numSubjects);
|
||||
}
|
||||
}
|
||||
}
|
||||
prevTime = currentTime;
|
||||
currentTime += maxDuration;
|
||||
}
|
||||
/**
|
||||
* For every element and value combination create a new animation.
|
||||
*/
|
||||
sequences.forEach((valueSequences, element) => {
|
||||
for (const key in valueSequences) {
|
||||
const valueSequence = valueSequences[key];
|
||||
/**
|
||||
* Arrange all the keyframes in ascending time order.
|
||||
*/
|
||||
valueSequence.sort(compareByTime);
|
||||
const keyframes = [];
|
||||
const valueOffset = [];
|
||||
const valueEasing = [];
|
||||
/**
|
||||
* For each keyframe, translate absolute times into
|
||||
* relative offsets based on the total duration of the timeline.
|
||||
*/
|
||||
for (let i = 0; i < valueSequence.length; i++) {
|
||||
const { at, value, easing } = valueSequence[i];
|
||||
keyframes.push(value);
|
||||
valueOffset.push(progress(0, totalDuration, at));
|
||||
valueEasing.push(easing || "easeOut");
|
||||
}
|
||||
/**
|
||||
* If the first keyframe doesn't land on offset: 0
|
||||
* provide one by duplicating the initial keyframe. This ensures
|
||||
* it snaps to the first keyframe when the animation starts.
|
||||
*/
|
||||
if (valueOffset[0] !== 0) {
|
||||
valueOffset.unshift(0);
|
||||
keyframes.unshift(keyframes[0]);
|
||||
valueEasing.unshift(defaultSegmentEasing);
|
||||
}
|
||||
/**
|
||||
* If the last keyframe doesn't land on offset: 1
|
||||
* provide one with a null wildcard value. This will ensure it
|
||||
* stays static until the end of the animation.
|
||||
*/
|
||||
if (valueOffset[valueOffset.length - 1] !== 1) {
|
||||
valueOffset.push(1);
|
||||
keyframes.push(null);
|
||||
}
|
||||
if (!animationDefinitions.has(element)) {
|
||||
animationDefinitions.set(element, {
|
||||
keyframes: {},
|
||||
transition: {},
|
||||
});
|
||||
}
|
||||
const definition = animationDefinitions.get(element);
|
||||
definition.keyframes[key] = keyframes;
|
||||
/**
|
||||
* Exclude `type` from defaultTransition since springs have been
|
||||
* converted to duration-based easing functions in resolveValueSequence.
|
||||
* Including `type: "spring"` would cause JSAnimation to error when
|
||||
* the merged keyframes array has more than 2 keyframes.
|
||||
*/
|
||||
const { type: _type, ...remainingDefaultTransition } = defaultTransition;
|
||||
definition.transition[key] = {
|
||||
...remainingDefaultTransition,
|
||||
duration: totalDuration,
|
||||
ease: valueEasing,
|
||||
times: valueOffset,
|
||||
...sequenceTransition,
|
||||
};
|
||||
}
|
||||
});
|
||||
return animationDefinitions;
|
||||
}
|
||||
function getSubjectSequence(subject, sequences) {
|
||||
!sequences.has(subject) && sequences.set(subject, {});
|
||||
return sequences.get(subject);
|
||||
}
|
||||
function getValueSequence(name, sequences) {
|
||||
if (!sequences[name])
|
||||
sequences[name] = [];
|
||||
return sequences[name];
|
||||
}
|
||||
function keyframesAsList(keyframes) {
|
||||
return Array.isArray(keyframes) ? keyframes : [keyframes];
|
||||
}
|
||||
function getValueTransition(transition, key) {
|
||||
return transition && transition[key]
|
||||
? {
|
||||
...transition,
|
||||
...transition[key],
|
||||
}
|
||||
: { ...transition };
|
||||
}
|
||||
const isNumber = (keyframe) => typeof keyframe === "number";
|
||||
const isNumberKeyframesArray = (keyframes) => keyframes.every(isNumber);
|
||||
|
||||
export { createAnimationsFromSequence, getValueTransition };
|
||||
//# sourceMappingURL=create.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
function calculateRepeatDuration(duration, repeat, repeatDelay) {
|
||||
return duration * (repeat + 1) + repeatDelay * repeat;
|
||||
}
|
||||
|
||||
export { calculateRepeatDuration };
|
||||
//# sourceMappingURL=calc-repeat-duration.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"calc-repeat-duration.mjs","sources":["../../../../../src/animation/sequence/utils/calc-repeat-duration.ts"],"sourcesContent":["export function calculateRepeatDuration(\n duration: number,\n repeat: number,\n repeatDelay: number\n): number {\n return duration * (repeat + 1) + repeatDelay * repeat\n}\n"],"names":[],"mappings":"SAAgB,uBAAuB,CACnC,QAAgB,EAChB,MAAc,EACd,WAAmB,EAAA;IAEnB,OAAO,QAAQ,IAAI,MAAM,GAAG,CAAC,CAAC,GAAG,WAAW,GAAG,MAAM;AACzD;;;;"}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Given a absolute or relative time definition and current/prev time state of the sequence,
|
||||
* calculate an absolute time for the next keyframes.
|
||||
*/
|
||||
function calcNextTime(current, next, prev, labels) {
|
||||
if (typeof next === "number") {
|
||||
return next;
|
||||
}
|
||||
else if (next.startsWith("-") || next.startsWith("+")) {
|
||||
return Math.max(0, current + parseFloat(next));
|
||||
}
|
||||
else if (next === "<") {
|
||||
return prev;
|
||||
}
|
||||
else if (next.startsWith("<")) {
|
||||
return Math.max(0, prev + parseFloat(next.slice(1)));
|
||||
}
|
||||
else {
|
||||
return labels.get(next) ?? current;
|
||||
}
|
||||
}
|
||||
|
||||
export { calcNextTime };
|
||||
//# sourceMappingURL=calc-time.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"calc-time.mjs","sources":["../../../../../src/animation/sequence/utils/calc-time.ts"],"sourcesContent":["import { SequenceTime } from \"../types\"\n\n/**\n * Given a absolute or relative time definition and current/prev time state of the sequence,\n * calculate an absolute time for the next keyframes.\n */\nexport function calcNextTime(\n current: number,\n next: SequenceTime,\n prev: number,\n labels: Map<string, number>\n): number {\n if (typeof next === \"number\") {\n return next\n } else if (next.startsWith(\"-\") || next.startsWith(\"+\")) {\n return Math.max(0, current + parseFloat(next))\n } else if (next === \"<\") {\n return prev\n } else if (next.startsWith(\"<\")) {\n return Math.max(0, prev + parseFloat(next.slice(1)))\n } else {\n return labels.get(next) ?? current\n }\n}\n"],"names":[],"mappings":"AAEA;;;AAGG;AACG,SAAU,YAAY,CACxB,OAAe,EACf,IAAkB,EAClB,IAAY,EACZ,MAA2B,EAAA;AAE3B,IAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;AAC1B,QAAA,OAAO,IAAI;IACf;AAAO,SAAA,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AACrD,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAClD;AAAO,SAAA,IAAI,IAAI,KAAK,GAAG,EAAE;AACrB,QAAA,OAAO,IAAI;IACf;AAAO,SAAA,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AAC7B,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD;SAAO;QACH,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO;IACtC;AACJ;;;;"}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { mixNumber } from 'motion-dom';
|
||||
import { getEasingForSegment, removeItem } from 'motion-utils';
|
||||
|
||||
function eraseKeyframes(sequence, startTime, endTime) {
|
||||
for (let i = 0; i < sequence.length; i++) {
|
||||
const keyframe = sequence[i];
|
||||
if (keyframe.at > startTime && keyframe.at < endTime) {
|
||||
removeItem(sequence, keyframe);
|
||||
// If we remove this item we have to push the pointer back one
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
function addKeyframes(sequence, keyframes, easing, offset, startTime, endTime) {
|
||||
/**
|
||||
* Erase every existing value between currentTime and targetTime,
|
||||
* this will essentially splice this timeline into any currently
|
||||
* defined ones.
|
||||
*/
|
||||
eraseKeyframes(sequence, startTime, endTime);
|
||||
for (let i = 0; i < keyframes.length; i++) {
|
||||
sequence.push({
|
||||
value: keyframes[i],
|
||||
at: mixNumber(startTime, endTime, offset[i]),
|
||||
easing: getEasingForSegment(easing, i),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export { addKeyframes, eraseKeyframes };
|
||||
//# sourceMappingURL=edit.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"edit.mjs","sources":["../../../../../src/animation/sequence/utils/edit.ts"],"sourcesContent":["import { mixNumber, UnresolvedValueKeyframe } from \"motion-dom\"\nimport { Easing, getEasingForSegment, removeItem } from \"motion-utils\"\nimport type { ValueSequence } from \"../types\"\n\nexport function eraseKeyframes(\n sequence: ValueSequence,\n startTime: number,\n endTime: number\n): void {\n for (let i = 0; i < sequence.length; i++) {\n const keyframe = sequence[i]\n\n if (keyframe.at > startTime && keyframe.at < endTime) {\n removeItem(sequence, keyframe)\n\n // If we remove this item we have to push the pointer back one\n i--\n }\n }\n}\n\nexport function addKeyframes(\n sequence: ValueSequence,\n keyframes: UnresolvedValueKeyframe[],\n easing: Easing | Easing[],\n offset: number[],\n startTime: number,\n endTime: number\n): void {\n /**\n * Erase every existing value between currentTime and targetTime,\n * this will essentially splice this timeline into any currently\n * defined ones.\n */\n eraseKeyframes(sequence, startTime, endTime)\n\n for (let i = 0; i < keyframes.length; i++) {\n sequence.push({\n value: keyframes[i],\n at: mixNumber(startTime, endTime, offset[i]),\n easing: getEasingForSegment(easing, i),\n })\n }\n}\n"],"names":[],"mappings":";;;SAIgB,cAAc,CAC1B,QAAuB,EACvB,SAAiB,EACjB,OAAe,EAAA;AAEf,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,QAAA,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC;AAE5B,QAAA,IAAI,QAAQ,CAAC,EAAE,GAAG,SAAS,IAAI,QAAQ,CAAC,EAAE,GAAG,OAAO,EAAE;AAClD,YAAA,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC;;AAG9B,YAAA,CAAC,EAAE;QACP;IACJ;AACJ;AAEM,SAAU,YAAY,CACxB,QAAuB,EACvB,SAAoC,EACpC,MAAyB,EACzB,MAAgB,EAChB,SAAiB,EACjB,OAAe,EAAA;AAEf;;;;AAIG;AACH,IAAA,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC;AAE5C,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACvC,QAAQ,CAAC,IAAI,CAAC;AACV,YAAA,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;YACnB,EAAE,EAAE,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5C,YAAA,MAAM,EAAE,mBAAmB,CAAC,MAAM,EAAE,CAAC,CAAC;AACzC,SAAA,CAAC;IACN;AACJ;;;;"}
|
||||
Generated
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Take an array of times that represent repeated keyframes. For instance
|
||||
* if we have original times of [0, 0.5, 1] then our repeated times will
|
||||
* be [0, 0.5, 1, 1, 1.5, 2]. Loop over the times and scale them back
|
||||
* down to a 0-1 scale.
|
||||
*
|
||||
* `repeatDelayUnits` is the repeatDelay expressed in units of a single
|
||||
* iteration's duration, so the total span equals `(repeat + 1) + repeat * repeatDelayUnits`.
|
||||
*/
|
||||
function normalizeTimes(times, repeat, repeatDelayUnits = 0) {
|
||||
const totalUnits = repeat + 1 + repeat * repeatDelayUnits;
|
||||
for (let i = 0; i < times.length; i++) {
|
||||
times[i] = times[i] / totalUnits;
|
||||
}
|
||||
}
|
||||
|
||||
export { normalizeTimes };
|
||||
//# sourceMappingURL=normalize-times.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"normalize-times.mjs","sources":["../../../../../src/animation/sequence/utils/normalize-times.ts"],"sourcesContent":["/**\n * Take an array of times that represent repeated keyframes. For instance\n * if we have original times of [0, 0.5, 1] then our repeated times will\n * be [0, 0.5, 1, 1, 1.5, 2]. Loop over the times and scale them back\n * down to a 0-1 scale.\n *\n * `repeatDelayUnits` is the repeatDelay expressed in units of a single\n * iteration's duration, so the total span equals `(repeat + 1) + repeat * repeatDelayUnits`.\n */\nexport function normalizeTimes(\n times: number[],\n repeat: number,\n repeatDelayUnits = 0\n): void {\n const totalUnits = repeat + 1 + repeat * repeatDelayUnits\n for (let i = 0; i < times.length; i++) {\n times[i] = times[i] / totalUnits\n }\n}\n"],"names":[],"mappings":"AAAA;;;;;;;;AAQG;AACG,SAAU,cAAc,CAC1B,KAAe,EACf,MAAc,EACd,gBAAgB,GAAG,CAAC,EAAA;IAEpB,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,gBAAgB;AACzD,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACnC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU;IACpC;AACJ;;;;"}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
function compareByTime(a, b) {
|
||||
if (a.at === b.at) {
|
||||
if (a.value === null)
|
||||
return 1;
|
||||
if (b.value === null)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return a.at - b.at;
|
||||
}
|
||||
}
|
||||
|
||||
export { compareByTime };
|
||||
//# sourceMappingURL=sort.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"sort.mjs","sources":["../../../../../src/animation/sequence/utils/sort.ts"],"sourcesContent":["import { AbsoluteKeyframe } from \"../types\"\n\nexport function compareByTime(\n a: AbsoluteKeyframe,\n b: AbsoluteKeyframe\n): number {\n if (a.at === b.at) {\n if (a.value === null) return 1\n if (b.value === null) return -1\n return 0\n } else {\n return a.at - b.at\n }\n}\n"],"names":[],"mappings":"AAEM,SAAU,aAAa,CACzB,CAAmB,EACnB,CAAmB,EAAA;IAEnB,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE;AACf,QAAA,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI;AAAE,YAAA,OAAO,CAAC;AAC9B,QAAA,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,EAAE;AAC/B,QAAA,OAAO,CAAC;IACZ;SAAO;AACH,QAAA,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE;IACtB;AACJ;;;;"}
|
||||
Generated
Vendored
+41
@@ -0,0 +1,41 @@
|
||||
import { isSVGElement, isSVGSVGElement, SVGVisualElement, HTMLVisualElement, visualElementStore, ObjectVisualElement } from 'motion-dom';
|
||||
|
||||
function createDOMVisualElement(element) {
|
||||
const options = {
|
||||
presenceContext: null,
|
||||
props: {},
|
||||
visualState: {
|
||||
renderState: {
|
||||
transform: {},
|
||||
transformOrigin: {},
|
||||
style: {},
|
||||
vars: {},
|
||||
attrs: {},
|
||||
},
|
||||
latestValues: {},
|
||||
},
|
||||
};
|
||||
const node = isSVGElement(element) && !isSVGSVGElement(element)
|
||||
? new SVGVisualElement(options)
|
||||
: new HTMLVisualElement(options);
|
||||
node.mount(element);
|
||||
visualElementStore.set(element, node);
|
||||
}
|
||||
function createObjectVisualElement(subject) {
|
||||
const options = {
|
||||
presenceContext: null,
|
||||
props: {},
|
||||
visualState: {
|
||||
renderState: {
|
||||
output: {},
|
||||
},
|
||||
latestValues: {},
|
||||
},
|
||||
};
|
||||
const node = new ObjectVisualElement(options);
|
||||
node.mount(subject);
|
||||
visualElementStore.set(subject, node);
|
||||
}
|
||||
|
||||
export { createDOMVisualElement, createObjectVisualElement };
|
||||
//# sourceMappingURL=create-visual-element.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"create-visual-element.mjs","sources":["../../../../src/animation/utils/create-visual-element.ts"],"sourcesContent":["import {\n HTMLVisualElement,\n isSVGElement,\n isSVGSVGElement,\n ObjectVisualElement,\n SVGVisualElement,\n visualElementStore,\n} from \"motion-dom\"\n\nexport function createDOMVisualElement(element: HTMLElement | SVGElement) {\n const options = {\n presenceContext: null,\n props: {},\n visualState: {\n renderState: {\n transform: {},\n transformOrigin: {},\n style: {},\n vars: {},\n attrs: {},\n },\n latestValues: {},\n },\n }\n const node =\n isSVGElement(element) && !isSVGSVGElement(element)\n ? new SVGVisualElement(options)\n : new HTMLVisualElement(options)\n\n node.mount(element as any)\n\n visualElementStore.set(element, node)\n}\n\nexport function createObjectVisualElement(subject: Object) {\n const options = {\n presenceContext: null,\n props: {},\n visualState: {\n renderState: {\n output: {},\n },\n latestValues: {},\n },\n }\n const node = new ObjectVisualElement(options)\n\n node.mount(subject)\n\n visualElementStore.set(subject, node)\n}\n"],"names":[],"mappings":";;AASM,SAAU,sBAAsB,CAAC,OAAiC,EAAA;AACpE,IAAA,MAAM,OAAO,GAAG;AACZ,QAAA,eAAe,EAAE,IAAI;AACrB,QAAA,KAAK,EAAE,EAAE;AACT,QAAA,WAAW,EAAE;AACT,YAAA,WAAW,EAAE;AACT,gBAAA,SAAS,EAAE,EAAE;AACb,gBAAA,eAAe,EAAE,EAAE;AACnB,gBAAA,KAAK,EAAE,EAAE;AACT,gBAAA,IAAI,EAAE,EAAE;AACR,gBAAA,KAAK,EAAE,EAAE;AACZ,aAAA;AACD,YAAA,YAAY,EAAE,EAAE;AACnB,SAAA;KACJ;IACD,MAAM,IAAI,GACN,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO;AAC7C,UAAE,IAAI,gBAAgB,CAAC,OAAO;AAC9B,UAAE,IAAI,iBAAiB,CAAC,OAAO,CAAC;AAExC,IAAA,IAAI,CAAC,KAAK,CAAC,OAAc,CAAC;AAE1B,IAAA,kBAAkB,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC;AACzC;AAEM,SAAU,yBAAyB,CAAC,OAAe,EAAA;AACrD,IAAA,MAAM,OAAO,GAAG;AACZ,QAAA,eAAe,EAAE,IAAI;AACrB,QAAA,KAAK,EAAE,EAAE;AACT,QAAA,WAAW,EAAE;AACT,YAAA,WAAW,EAAE;AACT,gBAAA,MAAM,EAAE,EAAE;AACb,aAAA;AACD,YAAA,YAAY,EAAE,EAAE;AACnB,SAAA;KACJ;AACD,IAAA,MAAM,IAAI,GAAG,IAAI,mBAAmB,CAAC,OAAO,CAAC;AAE7C,IAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AAEnB,IAAA,kBAAkB,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC;AACzC;;;;"}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
function isDOMKeyframes(keyframes) {
|
||||
return typeof keyframes === "object" && !Array.isArray(keyframes);
|
||||
}
|
||||
|
||||
export { isDOMKeyframes };
|
||||
//# sourceMappingURL=is-dom-keyframes.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"is-dom-keyframes.mjs","sources":["../../../../src/animation/utils/is-dom-keyframes.ts"],"sourcesContent":["import { DOMKeyframesDefinition } from \"motion-dom\"\n\nexport function isDOMKeyframes(\n keyframes: unknown\n): keyframes is DOMKeyframesDefinition {\n return typeof keyframes === \"object\" && !Array.isArray(keyframes)\n}\n"],"names":[],"mappings":"AAEM,SAAU,cAAc,CAC1B,SAAkB,EAAA;AAElB,IAAA,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;AACrE;;;;"}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export { MotionA as a, MotionAbbr as abbr, MotionAddress as address, MotionAnimate as animate, MotionArea as area, MotionArticle as article, MotionAside as aside, MotionAudio as audio, MotionB as b, MotionBase as base, MotionBdi as bdi, MotionBdo as bdo, MotionBig as big, MotionBlockquote as blockquote, MotionBody as body, MotionButton as button, MotionCanvas as canvas, MotionCaption as caption, MotionCircle as circle, MotionCite as cite, MotionClipPath as clipPath, MotionCode as code, MotionCol as col, MotionColgroup as colgroup, MotionData as data, MotionDatalist as datalist, MotionDd as dd, MotionDefs as defs, MotionDel as del, MotionDesc as desc, MotionDetails as details, MotionDfn as dfn, MotionDialog as dialog, MotionDiv as div, MotionDl as dl, MotionDt as dt, MotionEllipse as ellipse, MotionEm as em, MotionEmbed as embed, MotionFeBlend as feBlend, MotionFeColorMatrix as feColorMatrix, MotionFeComponentTransfer as feComponentTransfer, MotionFeComposite as feComposite, MotionFeConvolveMatrix as feConvolveMatrix, MotionFeDiffuseLighting as feDiffuseLighting, MotionFeDisplacementMap as feDisplacementMap, MotionFeDistantLight as feDistantLight, MotionFeDropShadow as feDropShadow, MotionFeFlood as feFlood, MotionFeFuncA as feFuncA, MotionFeFuncB as feFuncB, MotionFeFuncG as feFuncG, MotionFeFuncR as feFuncR, MotionFeGaussianBlur as feGaussianBlur, MotionFeImage as feImage, MotionFeMerge as feMerge, MotionFeMergeNode as feMergeNode, MotionFeMorphology as feMorphology, MotionFeOffset as feOffset, MotionFePointLight as fePointLight, MotionFeSpecularLighting as feSpecularLighting, MotionFeSpotLight as feSpotLight, MotionFeTile as feTile, MotionFeTurbulence as feTurbulence, MotionFieldset as fieldset, MotionFigcaption as figcaption, MotionFigure as figure, MotionFilter as filter, MotionFooter as footer, MotionForeignObject as foreignObject, MotionForm as form, MotionG as g, MotionH1 as h1, MotionH2 as h2, MotionH3 as h3, MotionH4 as h4, MotionH5 as h5, MotionH6 as h6, MotionHead as head, MotionHeader as header, MotionHgroup as hgroup, MotionHr as hr, MotionHtml as html, MotionI as i, MotionIframe as iframe, MotionImage as image, MotionImg as img, MotionInput as input, MotionIns as ins, MotionKbd as kbd, MotionKeygen as keygen, MotionLabel as label, MotionLegend as legend, MotionLi as li, MotionLine as line, MotionLinearGradient as linearGradient, MotionLink as link, MotionMain as main, MotionMap as map, MotionMark as mark, MotionMarker as marker, MotionMask as mask, MotionMenu as menu, MotionMenuitem as menuitem, MotionMetadata as metadata, MotionMeter as meter, MotionNav as nav, MotionObject as object, MotionOl as ol, MotionOptgroup as optgroup, MotionOption as option, MotionOutput as output, MotionP as p, MotionParam as param, MotionPath as path, MotionPattern as pattern, MotionPicture as picture, MotionPolygon as polygon, MotionPolyline as polyline, MotionPre as pre, MotionProgress as progress, MotionQ as q, MotionRadialGradient as radialGradient, MotionRect as rect, MotionRp as rp, MotionRt as rt, MotionRuby as ruby, MotionS as s, MotionSamp as samp, MotionScript as script, MotionSection as section, MotionSelect as select, MotionSmall as small, MotionSource as source, MotionSpan as span, MotionStop as stop, MotionStrong as strong, MotionStyle as style, MotionSub as sub, MotionSummary as summary, MotionSup as sup, MotionSvg as svg, MotionSymbol as symbol, MotionTable as table, MotionTbody as tbody, MotionTd as td, MotionText as text, MotionTextPath as textPath, MotionTextarea as textarea, MotionTfoot as tfoot, MotionTh as th, MotionThead as thead, MotionTime as time, MotionTitle as title, MotionTr as tr, MotionTrack as track, MotionTspan as tspan, MotionU as u, MotionUl as ul, MotionUse as use, MotionVideo as video, MotionView as view, MotionWbr as wbr, MotionWebview as webview } from './render/components/motion/elements.mjs';
|
||||
//# sourceMappingURL=client.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"client.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
Generated
Vendored
+112
@@ -0,0 +1,112 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { isHTMLElement } from 'motion-dom';
|
||||
import * as React from 'react';
|
||||
import { useId, useRef, useContext, useInsertionEffect } from 'react';
|
||||
import { MotionConfigContext } from '../../context/MotionConfigContext.mjs';
|
||||
import { useComposedRefs } from '../../utils/use-composed-ref.mjs';
|
||||
|
||||
/**
|
||||
* Measurement functionality has to be within a separate component
|
||||
* to leverage snapshot lifecycle.
|
||||
*/
|
||||
class PopChildMeasure extends React.Component {
|
||||
getSnapshotBeforeUpdate(prevProps) {
|
||||
const element = this.props.childRef.current;
|
||||
if (isHTMLElement(element) && prevProps.isPresent && !this.props.isPresent && this.props.pop !== false) {
|
||||
const parent = element.offsetParent;
|
||||
const parentWidth = isHTMLElement(parent)
|
||||
? parent.offsetWidth || 0
|
||||
: 0;
|
||||
const parentHeight = isHTMLElement(parent)
|
||||
? parent.offsetHeight || 0
|
||||
: 0;
|
||||
const computedStyle = getComputedStyle(element);
|
||||
const size = this.props.sizeRef.current;
|
||||
size.height = parseFloat(computedStyle.height);
|
||||
size.width = parseFloat(computedStyle.width);
|
||||
size.top = element.offsetTop;
|
||||
size.left = element.offsetLeft;
|
||||
size.right = parentWidth - size.width - size.left;
|
||||
size.bottom = parentHeight - size.height - size.top;
|
||||
size.direction = computedStyle.direction;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Required with getSnapshotBeforeUpdate to stop React complaining.
|
||||
*/
|
||||
componentDidUpdate() { }
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
function PopChild({ children, isPresent, anchorX, anchorY, root, pop }) {
|
||||
const id = useId();
|
||||
const ref = useRef(null);
|
||||
const size = useRef({
|
||||
width: 0,
|
||||
height: 0,
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
direction: "ltr",
|
||||
});
|
||||
const { nonce } = useContext(MotionConfigContext);
|
||||
/**
|
||||
* In React 19, refs are passed via props.ref instead of element.ref.
|
||||
* We check props.ref first (React 19) and fall back to element.ref (React 18).
|
||||
*/
|
||||
const childRef = children.props?.ref ??
|
||||
children?.ref;
|
||||
const composedRef = useComposedRefs(ref, childRef);
|
||||
/**
|
||||
* We create and inject a style block so we can apply this explicit
|
||||
* sizing in a non-destructive manner by just deleting the style block.
|
||||
*
|
||||
* We can't apply size via render as the measurement happens
|
||||
* in getSnapshotBeforeUpdate (post-render), likewise if we apply the
|
||||
* styles directly on the DOM node, we might be overwriting
|
||||
* styles set via the style prop.
|
||||
*/
|
||||
useInsertionEffect(() => {
|
||||
const { width, height, top, left, right, bottom, direction } = size.current;
|
||||
if (isPresent || pop === false || !ref.current || !width || !height)
|
||||
return;
|
||||
const isRTL = direction === "rtl";
|
||||
const x = anchorX === "left"
|
||||
? (isRTL ? `right: ${right}` : `left: ${left}`)
|
||||
: (isRTL ? `left: ${left}` : `right: ${right}`);
|
||||
const y = anchorY === "bottom" ? `bottom: ${bottom}` : `top: ${top}`;
|
||||
ref.current.dataset.motionPopId = id;
|
||||
const style = document.createElement("style");
|
||||
if (nonce)
|
||||
style.nonce = nonce;
|
||||
const parent = root ?? document.head;
|
||||
parent.appendChild(style);
|
||||
if (style.sheet) {
|
||||
style.sheet.insertRule(`
|
||||
[data-motion-pop-id="${id}"] {
|
||||
position: absolute !important;
|
||||
width: ${width}px !important;
|
||||
height: ${height}px !important;
|
||||
${x}px !important;
|
||||
${y}px !important;
|
||||
}
|
||||
`);
|
||||
}
|
||||
return () => {
|
||||
ref.current?.removeAttribute("data-motion-pop-id");
|
||||
if (parent.contains(style)) {
|
||||
parent.removeChild(style);
|
||||
}
|
||||
};
|
||||
}, [isPresent]);
|
||||
return (jsx(PopChildMeasure, { isPresent: isPresent, childRef: ref, sizeRef: size, pop: pop, children: pop === false
|
||||
? children
|
||||
: React.cloneElement(children, { ref: composedRef }) }));
|
||||
}
|
||||
|
||||
export { PopChild };
|
||||
//# sourceMappingURL=PopChild.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+77
@@ -0,0 +1,77 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import * as React from 'react';
|
||||
import { useId, useRef, useMemo } from 'react';
|
||||
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
|
||||
import { PopChild } from './PopChild.mjs';
|
||||
|
||||
const PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, presenceAffectsLayout, mode, anchorX, anchorY, root }) => {
|
||||
const presenceChildren = useConstant(newChildrenMap);
|
||||
const id = useId();
|
||||
// Written in a layout effect (not render) so discarded concurrent
|
||||
// renders can't leave the refs pointing at uncommitted state.
|
||||
const isPresentRef = useRef(isPresent);
|
||||
const onExitCompleteRef = useRef(onExitComplete);
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
isPresentRef.current = isPresent;
|
||||
onExitCompleteRef.current = onExitComplete;
|
||||
});
|
||||
let isReusedContext = true;
|
||||
let context = useMemo(() => {
|
||||
isReusedContext = false;
|
||||
return {
|
||||
id,
|
||||
initial,
|
||||
isPresent,
|
||||
custom,
|
||||
onExitComplete: (childId) => {
|
||||
presenceChildren.set(childId, true);
|
||||
for (const isComplete of presenceChildren.values()) {
|
||||
if (!isComplete)
|
||||
return; // can stop searching when any is incomplete
|
||||
}
|
||||
onExitComplete && onExitComplete();
|
||||
},
|
||||
register: (childId) => {
|
||||
presenceChildren.set(childId, false);
|
||||
return () => {
|
||||
presenceChildren.delete(childId);
|
||||
!isPresentRef.current &&
|
||||
!presenceChildren.size &&
|
||||
onExitCompleteRef.current?.();
|
||||
};
|
||||
},
|
||||
};
|
||||
}, [isPresent, presenceChildren, onExitComplete]);
|
||||
/**
|
||||
* If the presence of a child affects the layout of the components around it,
|
||||
* we want to make a new context value to ensure they get re-rendered
|
||||
* so they can detect that layout change.
|
||||
*/
|
||||
if (presenceAffectsLayout && isReusedContext) {
|
||||
context = { ...context };
|
||||
}
|
||||
useMemo(() => {
|
||||
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
||||
}, [isPresent]);
|
||||
/**
|
||||
* If there's no `motion` components to fire exit animations, we want to remove this
|
||||
* component immediately.
|
||||
*/
|
||||
React.useEffect(() => {
|
||||
!isPresent &&
|
||||
!presenceChildren.size &&
|
||||
onExitComplete &&
|
||||
onExitComplete();
|
||||
}, [isPresent]);
|
||||
children = (jsx(PopChild, { pop: mode === "popLayout", isPresent: isPresent, anchorX: anchorX, anchorY: anchorY, root: root, children: children }));
|
||||
return (jsx(PresenceContext.Provider, { value: context, children: children }));
|
||||
};
|
||||
function newChildrenMap() {
|
||||
return new Map();
|
||||
}
|
||||
|
||||
export { PresenceChild };
|
||||
//# sourceMappingURL=PresenceChild.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"PresenceChild.mjs","sources":["../../../../src/components/AnimatePresence/PresenceChild.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { useId, useMemo, useRef } from \"react\"\nimport {\n PresenceContext,\n type PresenceContextProps,\n} from \"../../context/PresenceContext\"\nimport { VariantLabels } from \"../../motion/types\"\nimport { useConstant } from \"../../utils/use-constant\"\nimport { useIsomorphicLayoutEffect } from \"../../utils/use-isomorphic-effect\"\nimport { PopChild } from \"./PopChild\"\n\ninterface PresenceChildProps {\n children: React.ReactElement\n isPresent: boolean\n onExitComplete?: () => void\n initial?: false | VariantLabels\n custom?: any\n presenceAffectsLayout: boolean\n mode: \"sync\" | \"popLayout\" | \"wait\"\n anchorX?: \"left\" | \"right\"\n anchorY?: \"top\" | \"bottom\"\n root?: HTMLElement | ShadowRoot\n}\n\nexport const PresenceChild = ({\n children,\n initial,\n isPresent,\n onExitComplete,\n custom,\n presenceAffectsLayout,\n mode,\n anchorX,\n anchorY,\n root\n}: PresenceChildProps) => {\n const presenceChildren = useConstant(newChildrenMap)\n const id = useId()\n\n // Written in a layout effect (not render) so discarded concurrent\n // renders can't leave the refs pointing at uncommitted state.\n const isPresentRef = useRef(isPresent)\n const onExitCompleteRef = useRef(onExitComplete)\n useIsomorphicLayoutEffect(() => {\n isPresentRef.current = isPresent\n onExitCompleteRef.current = onExitComplete\n })\n\n let isReusedContext = true\n let context = useMemo((): PresenceContextProps => {\n isReusedContext = false\n return {\n id,\n initial,\n isPresent,\n custom,\n onExitComplete: (childId: string) => {\n presenceChildren.set(childId, true)\n\n for (const isComplete of presenceChildren.values()) {\n if (!isComplete) return // can stop searching when any is incomplete\n }\n\n onExitComplete && onExitComplete()\n },\n register: (childId: string) => {\n presenceChildren.set(childId, false)\n return () => {\n presenceChildren.delete(childId)\n !isPresentRef.current &&\n !presenceChildren.size &&\n onExitCompleteRef.current?.()\n }\n },\n }\n }, [isPresent, presenceChildren, onExitComplete])\n\n /**\n * If the presence of a child affects the layout of the components around it,\n * we want to make a new context value to ensure they get re-rendered\n * so they can detect that layout change.\n */\n if (presenceAffectsLayout && isReusedContext) {\n context = { ...context }\n }\n\n useMemo(() => {\n presenceChildren.forEach((_, key) => presenceChildren.set(key, false))\n }, [isPresent])\n\n /**\n * If there's no `motion` components to fire exit animations, we want to remove this\n * component immediately.\n */\n React.useEffect(() => {\n !isPresent &&\n !presenceChildren.size &&\n onExitComplete &&\n onExitComplete()\n }, [isPresent])\n\n children = (\n <PopChild pop={mode === \"popLayout\"} isPresent={isPresent} anchorX={anchorX} anchorY={anchorY} root={root}>\n {children}\n </PopChild>\n )\n\n return (\n <PresenceContext.Provider value={context}>\n {children}\n </PresenceContext.Provider>\n )\n}\n\nfunction newChildrenMap(): Map<string, boolean> {\n return new Map()\n}\n"],"names":[],"mappings":";;;;;;;;;AA0BO;AAYH;AACA;;;AAIA;AACA;;AAEI;AACA;AACJ;;AAGA;;;;;;;AAOQ;AACI;;AAGI;AAAiB;;;;AAKzB;AACI;AACA;AACI;;;AAGI;AACR;;;;AAKZ;;;;AAIG;AACH;AACI;;;AAIA;AACJ;AAEA;;;AAGG;AACH;AACI;;;AAGI;AACR;AAEA;AAMA;AAKJ;AAEA;;AAEA;;"}
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
"use client";
|
||||
import { jsx, Fragment } from 'react/jsx-runtime';
|
||||
import { useMemo, useRef, useState, useContext } from 'react';
|
||||
import { LayoutGroupContext } from '../../context/LayoutGroupContext.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
|
||||
import { PresenceChild } from './PresenceChild.mjs';
|
||||
import { usePresence } from './use-presence.mjs';
|
||||
import { onlyElements, getChildKey } from './utils.mjs';
|
||||
|
||||
/**
|
||||
* `AnimatePresence` enables the animation of components that have been removed from the tree.
|
||||
*
|
||||
* When adding/removing more than a single child, every child **must** be given a unique `key` prop.
|
||||
*
|
||||
* Any `motion` components that have an `exit` property defined will animate out when removed from
|
||||
* the tree.
|
||||
*
|
||||
* ```jsx
|
||||
* import { motion, AnimatePresence } from 'framer-motion'
|
||||
*
|
||||
* export const Items = ({ items }) => (
|
||||
* <AnimatePresence>
|
||||
* {items.map(item => (
|
||||
* <motion.div
|
||||
* key={item.id}
|
||||
* initial={{ opacity: 0 }}
|
||||
* animate={{ opacity: 1 }}
|
||||
* exit={{ opacity: 0 }}
|
||||
* />
|
||||
* ))}
|
||||
* </AnimatePresence>
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* You can sequence exit animations throughout a tree using variants.
|
||||
*
|
||||
* If a child contains multiple `motion` components with `exit` props, it will only unmount the child
|
||||
* once all `motion` components have finished animating out. Likewise, any components using
|
||||
* `usePresence` all need to call `safeToRemove`.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
const AnimatePresence = ({ children, custom, initial = true, onExitComplete, presenceAffectsLayout = true, mode = "sync", propagate = false, anchorX = "left", anchorY = "top", root }) => {
|
||||
const [isParentPresent, safeToRemove] = usePresence(propagate);
|
||||
/**
|
||||
* Filter any children that aren't ReactElements. We can only track components
|
||||
* between renders with a props.key.
|
||||
*/
|
||||
const presentChildren = useMemo(() => onlyElements(children), [children]);
|
||||
/**
|
||||
* Track the keys of the currently rendered children. This is used to
|
||||
* determine which children are exiting.
|
||||
*/
|
||||
const presentKeys = propagate && !isParentPresent ? [] : presentChildren.map(getChildKey);
|
||||
/**
|
||||
* If `initial={false}` we only want to pass this to components in the first render.
|
||||
*/
|
||||
const isInitialRender = useRef(true);
|
||||
/**
|
||||
* A ref containing the currently present children. When all exit animations
|
||||
* are complete, we use this to re-render the component with the latest children
|
||||
* *committed* rather than the latest children *rendered*.
|
||||
*/
|
||||
const pendingPresentChildren = useRef(presentChildren);
|
||||
/**
|
||||
* Track which exiting children have finished animating out.
|
||||
*/
|
||||
const exitComplete = useConstant(() => new Map());
|
||||
/**
|
||||
* Track which components are currently processing exit to prevent duplicate processing.
|
||||
*/
|
||||
const exitingComponents = useRef(new Set());
|
||||
/**
|
||||
* Save children to render as React state. To ensure this component is concurrent-safe,
|
||||
* we check for exiting children via an effect.
|
||||
*/
|
||||
const [diffedChildren, setDiffedChildren] = useState(presentChildren);
|
||||
const [renderedChildren, setRenderedChildren] = useState(presentChildren);
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
isInitialRender.current = false;
|
||||
pendingPresentChildren.current = presentChildren;
|
||||
/**
|
||||
* Update complete status of exiting children.
|
||||
*/
|
||||
for (let i = 0; i < renderedChildren.length; i++) {
|
||||
const key = getChildKey(renderedChildren[i]);
|
||||
if (!presentKeys.includes(key)) {
|
||||
if (exitComplete.get(key) !== true) {
|
||||
exitComplete.set(key, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
exitComplete.delete(key);
|
||||
exitingComponents.current.delete(key);
|
||||
}
|
||||
}
|
||||
}, [renderedChildren, presentKeys.length, presentKeys.join("-")]);
|
||||
const exitingChildren = [];
|
||||
if (presentChildren !== diffedChildren) {
|
||||
let nextChildren = [...presentChildren];
|
||||
/**
|
||||
* Loop through all the currently rendered components and decide which
|
||||
* are exiting.
|
||||
*/
|
||||
for (let i = 0; i < renderedChildren.length; i++) {
|
||||
const child = renderedChildren[i];
|
||||
const key = getChildKey(child);
|
||||
if (!presentKeys.includes(key)) {
|
||||
nextChildren.splice(i, 0, child);
|
||||
exitingChildren.push(child);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* If we're in "wait" mode, and we have exiting children, we want to
|
||||
* only render these until they've all exited.
|
||||
*/
|
||||
if (mode === "wait" && exitingChildren.length) {
|
||||
nextChildren = exitingChildren;
|
||||
}
|
||||
setRenderedChildren(onlyElements(nextChildren));
|
||||
setDiffedChildren(presentChildren);
|
||||
/**
|
||||
* Early return to ensure once we've set state with the latest diffed
|
||||
* children, we can immediately re-render.
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
if (process.env.NODE_ENV !== "production" &&
|
||||
mode === "wait" &&
|
||||
renderedChildren.length > 1) {
|
||||
console.warn(`You're attempting to animate multiple children within AnimatePresence, but its mode is set to "wait". This will lead to odd visual behaviour.`);
|
||||
}
|
||||
/**
|
||||
* If we've been provided a forceRender function by the LayoutGroupContext,
|
||||
* we can use it to force a re-render amongst all surrounding components once
|
||||
* all components have finished animating out.
|
||||
*/
|
||||
const { forceRender } = useContext(LayoutGroupContext);
|
||||
return (jsx(Fragment, { children: renderedChildren.map((child) => {
|
||||
const key = getChildKey(child);
|
||||
const isPresent = propagate && !isParentPresent
|
||||
? false
|
||||
: presentChildren === renderedChildren ||
|
||||
presentKeys.includes(key);
|
||||
const onExit = () => {
|
||||
if (exitingComponents.current.has(key)) {
|
||||
return;
|
||||
}
|
||||
if (exitComplete.has(key)) {
|
||||
exitingComponents.current.add(key);
|
||||
exitComplete.set(key, true);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
let isEveryExitComplete = true;
|
||||
exitComplete.forEach((isExitComplete) => {
|
||||
if (!isExitComplete)
|
||||
isEveryExitComplete = false;
|
||||
});
|
||||
if (isEveryExitComplete) {
|
||||
forceRender?.();
|
||||
setRenderedChildren(pendingPresentChildren.current);
|
||||
propagate && safeToRemove?.();
|
||||
onExitComplete && onExitComplete();
|
||||
}
|
||||
};
|
||||
return (jsx(PresenceChild, { isPresent: isPresent, initial: !isInitialRender.current || initial
|
||||
? undefined
|
||||
: false, custom: custom, presenceAffectsLayout: presenceAffectsLayout, mode: mode, root: root, onExitComplete: isPresent ? undefined : onExit, anchorX: anchorX, anchorY: anchorY, children: child }, key));
|
||||
}) }));
|
||||
};
|
||||
|
||||
export { AnimatePresence };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
"use client";
|
||||
import { useContext } from 'react';
|
||||
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
||||
|
||||
function usePresenceData() {
|
||||
const context = useContext(PresenceContext);
|
||||
return context ? context.custom : undefined;
|
||||
}
|
||||
|
||||
export { usePresenceData };
|
||||
//# sourceMappingURL=use-presence-data.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-presence-data.mjs","sources":["../../../../src/components/AnimatePresence/use-presence-data.ts"],"sourcesContent":["\"use client\"\n\nimport { useContext } from \"react\"\nimport { PresenceContext } from \"../../context/PresenceContext\"\n\nexport function usePresenceData() {\n const context = useContext(PresenceContext)\n return context ? context.custom : undefined\n}\n"],"names":[],"mappings":";;;;;AAMI;;AAEJ;;"}
|
||||
Generated
Vendored
+72
@@ -0,0 +1,72 @@
|
||||
"use client";
|
||||
import { useContext, useId, useEffect, useCallback } from 'react';
|
||||
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
||||
|
||||
/**
|
||||
* When a component is the child of `AnimatePresence`, it can use `usePresence`
|
||||
* to access information about whether it's still present in the React tree.
|
||||
*
|
||||
* ```jsx
|
||||
* import { usePresence } from "framer-motion"
|
||||
*
|
||||
* export const Component = () => {
|
||||
* const [isPresent, safeToRemove] = usePresence()
|
||||
*
|
||||
* useEffect(() => {
|
||||
* !isPresent && setTimeout(safeToRemove, 1000)
|
||||
* }, [isPresent])
|
||||
*
|
||||
* return <div />
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* If `isPresent` is `false`, it means that a component has been removed from the tree,
|
||||
* but `AnimatePresence` won't really remove it until `safeToRemove` has been called.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function usePresence(subscribe = true) {
|
||||
const context = useContext(PresenceContext);
|
||||
if (context === null)
|
||||
return [true, null];
|
||||
const { isPresent, onExitComplete, register } = context;
|
||||
// It's safe to call the following hooks conditionally (after an early return) because the context will always
|
||||
// either be null or non-null for the lifespan of the component.
|
||||
const id = useId();
|
||||
useEffect(() => {
|
||||
if (subscribe) {
|
||||
return register(id);
|
||||
}
|
||||
}, [subscribe]);
|
||||
const safeToRemove = useCallback(() => subscribe && onExitComplete && onExitComplete(id), [id, onExitComplete, subscribe]);
|
||||
return !isPresent && onExitComplete ? [false, safeToRemove] : [true];
|
||||
}
|
||||
/**
|
||||
* Similar to `usePresence`, except `useIsPresent` simply returns whether or not the component is present.
|
||||
* There is no `safeToRemove` function.
|
||||
*
|
||||
* ```jsx
|
||||
* import { useIsPresent } from "framer-motion"
|
||||
*
|
||||
* export const Component = () => {
|
||||
* const isPresent = useIsPresent()
|
||||
*
|
||||
* useEffect(() => {
|
||||
* !isPresent && console.log("I've been removed!")
|
||||
* }, [isPresent])
|
||||
*
|
||||
* return <div />
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function useIsPresent() {
|
||||
return isPresent(useContext(PresenceContext));
|
||||
}
|
||||
function isPresent(context) {
|
||||
return context === null ? true : context.isPresent;
|
||||
}
|
||||
|
||||
export { isPresent, useIsPresent, usePresence };
|
||||
//# sourceMappingURL=use-presence.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-presence.mjs","sources":["../../../../src/components/AnimatePresence/use-presence.ts"],"sourcesContent":["\"use client\"\n\nimport { useCallback, useContext, useEffect, useId } from \"react\"\nimport {\n PresenceContext,\n PresenceContextProps,\n} from \"../../context/PresenceContext\"\n\nexport type SafeToRemove = () => void\n\ntype AlwaysPresent = [true, null]\n\ntype Present = [true]\n\ntype NotPresent = [false, SafeToRemove]\n\n/**\n * When a component is the child of `AnimatePresence`, it can use `usePresence`\n * to access information about whether it's still present in the React tree.\n *\n * ```jsx\n * import { usePresence } from \"framer-motion\"\n *\n * export const Component = () => {\n * const [isPresent, safeToRemove] = usePresence()\n *\n * useEffect(() => {\n * !isPresent && setTimeout(safeToRemove, 1000)\n * }, [isPresent])\n *\n * return <div />\n * }\n * ```\n *\n * If `isPresent` is `false`, it means that a component has been removed from the tree,\n * but `AnimatePresence` won't really remove it until `safeToRemove` has been called.\n *\n * @public\n */\nexport function usePresence(\n subscribe: boolean = true\n): AlwaysPresent | Present | NotPresent {\n const context = useContext(PresenceContext)\n\n if (context === null) return [true, null]\n\n const { isPresent, onExitComplete, register } = context\n\n // It's safe to call the following hooks conditionally (after an early return) because the context will always\n // either be null or non-null for the lifespan of the component.\n\n const id = useId()\n useEffect(() => {\n if (subscribe) {\n return register(id)\n }\n }, [subscribe])\n\n const safeToRemove = useCallback(\n () => subscribe && onExitComplete && onExitComplete(id),\n [id, onExitComplete, subscribe]\n )\n\n return !isPresent && onExitComplete ? [false, safeToRemove] : [true]\n}\n\n/**\n * Similar to `usePresence`, except `useIsPresent` simply returns whether or not the component is present.\n * There is no `safeToRemove` function.\n *\n * ```jsx\n * import { useIsPresent } from \"framer-motion\"\n *\n * export const Component = () => {\n * const isPresent = useIsPresent()\n *\n * useEffect(() => {\n * !isPresent && console.log(\"I've been removed!\")\n * }, [isPresent])\n *\n * return <div />\n * }\n * ```\n *\n * @public\n */\nexport function useIsPresent() {\n return isPresent(useContext(PresenceContext))\n}\n\nexport function isPresent(context: PresenceContextProps | null) {\n return context === null ? true : context.isPresent\n}\n"],"names":[],"mappings":";;;;AAgBA;;;;;;;;;;;;;;;;;;;;;;AAsBG;AACG;AAGF;;AAEsB;;;;AAOtB;;;AAGQ;;AAER;;AAOA;AACJ;AAEA;;;;;;;;;;;;;;;;;;;AAmBG;;AAEC;AACJ;AAEM;AACF;AACJ;;"}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { Children, isValidElement } from 'react';
|
||||
|
||||
const getChildKey = (child) => child.key || "";
|
||||
function onlyElements(children) {
|
||||
const filtered = [];
|
||||
// We use forEach here instead of map as map mutates the component key by preprending `.$`
|
||||
Children.forEach(children, (child) => {
|
||||
if (isValidElement(child))
|
||||
filtered.push(child);
|
||||
});
|
||||
return filtered;
|
||||
}
|
||||
|
||||
export { getChildKey, onlyElements };
|
||||
//# sourceMappingURL=utils.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.mjs","sources":["../../../../src/components/AnimatePresence/utils.ts"],"sourcesContent":["import { isValidElement, Children, ReactElement, ReactNode } from \"react\"\n\nexport type ComponentKey = string | number\n\nexport const getChildKey = (child: ReactElement<any>): ComponentKey =>\n child.key || \"\"\n\nexport function onlyElements(children: ReactNode): ReactElement<any>[] {\n const filtered: ReactElement<any>[] = []\n\n // We use forEach here instead of map as map mutates the component key by preprending `.$`\n Children.forEach(children, (child) => {\n if (isValidElement(child)) filtered.push(child)\n })\n\n return filtered\n}\n"],"names":[],"mappings":";;AAIO,MAAM,WAAW,GAAG,CAAC,KAAwB,KAChD,KAAK,CAAC,GAAG,IAAI;AAEX,SAAU,YAAY,CAAC,QAAmB,EAAA;IAC5C,MAAM,QAAQ,GAAwB,EAAE;;IAGxC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAI;QACjC,IAAI,cAAc,CAAC,KAAK,CAAC;AAAE,YAAA,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;AACnD,IAAA,CAAC,CAAC;AAEF,IAAA,OAAO,QAAQ;AACnB;;;;"}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { invariant } from 'motion-utils';
|
||||
import * as React from 'react';
|
||||
import { useConstant } from '../utils/use-constant.mjs';
|
||||
import { LayoutGroup } from './LayoutGroup/index.mjs';
|
||||
|
||||
let id = 0;
|
||||
const AnimateSharedLayout = ({ children }) => {
|
||||
React.useEffect(() => {
|
||||
invariant(false, "AnimateSharedLayout is deprecated: https://www.framer.com/docs/guide-upgrade/##shared-layout-animations");
|
||||
}, []);
|
||||
return (jsx(LayoutGroup, { id: useConstant(() => `asl-${id++}`), children: children }));
|
||||
};
|
||||
|
||||
export { AnimateSharedLayout };
|
||||
//# sourceMappingURL=AnimateSharedLayout.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"AnimateSharedLayout.mjs","sources":["../../../src/components/AnimateSharedLayout.tsx"],"sourcesContent":["\"use client\"\n\nimport { invariant } from \"motion-utils\"\nimport * as React from \"react\"\nimport { useConstant } from \"../utils/use-constant\"\nimport { LayoutGroup } from \"./LayoutGroup\"\n\nlet id = 0\nexport const AnimateSharedLayout: React.FunctionComponent<\n React.PropsWithChildren<unknown>\n> = ({ children }: React.PropsWithChildren<{}>) => {\n React.useEffect(() => {\n invariant(\n false,\n \"AnimateSharedLayout is deprecated: https://www.framer.com/docs/guide-upgrade/##shared-layout-animations\"\n )\n }, [])\n\n return (\n <LayoutGroup id={useConstant(() => `asl-${id++}`)}>\n {children}\n </LayoutGroup>\n )\n}\n"],"names":[],"mappings":";;;;;;;AAOA;;AAII;AACI;;;AAWR;;"}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { useContext, useRef, useMemo } from 'react';
|
||||
import { LayoutGroupContext } from '../../context/LayoutGroupContext.mjs';
|
||||
import { DeprecatedLayoutGroupContext } from '../../context/DeprecatedLayoutGroupContext.mjs';
|
||||
import { useForceUpdate } from '../../utils/use-force-update.mjs';
|
||||
import { nodeGroup } from 'motion-dom';
|
||||
|
||||
const shouldInheritGroup = (inherit) => inherit === true;
|
||||
const shouldInheritId = (inherit) => shouldInheritGroup(inherit === true) || inherit === "id";
|
||||
const LayoutGroup = ({ children, id, inherit = true }) => {
|
||||
const layoutGroupContext = useContext(LayoutGroupContext);
|
||||
const deprecatedLayoutGroupContext = useContext(DeprecatedLayoutGroupContext);
|
||||
const [forceRender, key] = useForceUpdate();
|
||||
const context = useRef(null);
|
||||
const upstreamId = layoutGroupContext.id || deprecatedLayoutGroupContext;
|
||||
if (context.current === null) {
|
||||
if (shouldInheritId(inherit) && upstreamId) {
|
||||
id = id ? upstreamId + "-" + id : upstreamId;
|
||||
}
|
||||
context.current = {
|
||||
id,
|
||||
group: shouldInheritGroup(inherit)
|
||||
? layoutGroupContext.group || nodeGroup()
|
||||
: nodeGroup(),
|
||||
};
|
||||
}
|
||||
const memoizedContext = useMemo(() => ({ ...context.current, forceRender }), [key]);
|
||||
return (jsx(LayoutGroupContext.Provider, { value: memoizedContext, children: children }));
|
||||
};
|
||||
|
||||
export { LayoutGroup };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../../../../src/components/LayoutGroup/index.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { MutableRefObject, useContext, useMemo, useRef } from \"react\"\nimport {\n LayoutGroupContext,\n LayoutGroupContextProps,\n} from \"../../context/LayoutGroupContext\"\nimport { DeprecatedLayoutGroupContext } from \"../../context/DeprecatedLayoutGroupContext\"\nimport { nodeGroup } from \"../../projection\"\nimport { useForceUpdate } from \"../../utils/use-force-update\"\n\ntype InheritOption = boolean | \"id\"\n\nexport interface Props {\n id?: string\n inherit?: InheritOption\n}\n\nconst shouldInheritGroup = (inherit: InheritOption) => inherit === true\nconst shouldInheritId = (inherit: InheritOption) =>\n shouldInheritGroup(inherit === true) || inherit === \"id\"\n\nexport const LayoutGroup: React.FunctionComponent<\n React.PropsWithChildren<Props>\n> = ({ children, id, inherit = true }) => {\n const layoutGroupContext = useContext(LayoutGroupContext)\n const deprecatedLayoutGroupContext = useContext(\n DeprecatedLayoutGroupContext\n )\n const [forceRender, key] = useForceUpdate()\n const context = useRef(\n null\n ) as MutableRefObject<LayoutGroupContextProps | null>\n\n const upstreamId = layoutGroupContext.id || deprecatedLayoutGroupContext\n if (context.current === null) {\n if (shouldInheritId(inherit) && upstreamId) {\n id = id ? upstreamId + \"-\" + id : upstreamId\n }\n\n context.current = {\n id,\n group: shouldInheritGroup(inherit)\n ? layoutGroupContext.group || nodeGroup()\n : nodeGroup(),\n }\n }\n\n const memoizedContext = useMemo(\n () => ({ ...context.current, forceRender }),\n [key]\n )\n\n return (\n <LayoutGroupContext.Provider value={memoizedContext}>\n {children}\n </LayoutGroupContext.Provider>\n )\n}\n"],"names":[],"mappings":";;;;;;;;AAmBA;AACA;AAGO;AAGH;AACA;;AAIA;AAIA;AACA;AACI;AACI;;;;AAKA;AACI;;;;;AAUZ;AAKJ;;"}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import { LazyContext } from '../../context/LazyContext.mjs';
|
||||
import { loadFeatures } from '../../motion/features/load-features.mjs';
|
||||
|
||||
/**
|
||||
* Used in conjunction with the `m` component to reduce bundle size.
|
||||
*
|
||||
* `m` is a version of the `motion` component that only loads functionality
|
||||
* critical for the initial render.
|
||||
*
|
||||
* `LazyMotion` can then be used to either synchronously or asynchronously
|
||||
* load animation and gesture support.
|
||||
*
|
||||
* ```jsx
|
||||
* // Synchronous loading
|
||||
* import { LazyMotion, m, domAnimation } from "framer-motion"
|
||||
*
|
||||
* function App() {
|
||||
* return (
|
||||
* <LazyMotion features={domAnimation}>
|
||||
* <m.div animate={{ scale: 2 }} />
|
||||
* </LazyMotion>
|
||||
* )
|
||||
* }
|
||||
*
|
||||
* // Asynchronous loading
|
||||
* import { LazyMotion, m } from "framer-motion"
|
||||
*
|
||||
* function App() {
|
||||
* return (
|
||||
* <LazyMotion features={() => import('./path/to/domAnimation')}>
|
||||
* <m.div animate={{ scale: 2 }} />
|
||||
* </LazyMotion>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function LazyMotion({ children, features, strict = false }) {
|
||||
const [, setIsLoaded] = useState(!isLazyBundle(features));
|
||||
const loadedRenderer = useRef(undefined);
|
||||
/**
|
||||
* If this is a synchronous load, load features immediately
|
||||
*/
|
||||
if (!isLazyBundle(features)) {
|
||||
const { renderer, ...loadedFeatures } = features;
|
||||
loadedRenderer.current = renderer;
|
||||
loadFeatures(loadedFeatures);
|
||||
}
|
||||
useEffect(() => {
|
||||
if (isLazyBundle(features)) {
|
||||
features().then(({ renderer, ...loadedFeatures }) => {
|
||||
loadFeatures(loadedFeatures);
|
||||
loadedRenderer.current = renderer;
|
||||
setIsLoaded(true);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
return (jsx(LazyContext.Provider, { value: { renderer: loadedRenderer.current, strict }, children: children }));
|
||||
}
|
||||
function isLazyBundle(features) {
|
||||
return typeof features === "function";
|
||||
}
|
||||
|
||||
export { LazyMotion };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../../../../src/components/LazyMotion/index.tsx"],"sourcesContent":["\"use client\"\n\nimport { useEffect, useRef, useState } from \"react\"\nimport { LazyContext } from \"../../context/LazyContext\"\nimport { loadFeatures } from \"../../motion/features/load-features\"\nimport { FeatureBundle, LazyFeatureBundle } from \"../../motion/features/types\"\nimport { CreateVisualElement } from \"../../render/types\"\nimport { LazyProps } from \"./types\"\n\n/**\n * Used in conjunction with the `m` component to reduce bundle size.\n *\n * `m` is a version of the `motion` component that only loads functionality\n * critical for the initial render.\n *\n * `LazyMotion` can then be used to either synchronously or asynchronously\n * load animation and gesture support.\n *\n * ```jsx\n * // Synchronous loading\n * import { LazyMotion, m, domAnimation } from \"framer-motion\"\n *\n * function App() {\n * return (\n * <LazyMotion features={domAnimation}>\n * <m.div animate={{ scale: 2 }} />\n * </LazyMotion>\n * )\n * }\n *\n * // Asynchronous loading\n * import { LazyMotion, m } from \"framer-motion\"\n *\n * function App() {\n * return (\n * <LazyMotion features={() => import('./path/to/domAnimation')}>\n * <m.div animate={{ scale: 2 }} />\n * </LazyMotion>\n * )\n * }\n * ```\n *\n * @public\n */\nexport function LazyMotion({ children, features, strict = false }: LazyProps) {\n const [, setIsLoaded] = useState(!isLazyBundle(features))\n const loadedRenderer = useRef<undefined | CreateVisualElement>(undefined)\n\n /**\n * If this is a synchronous load, load features immediately\n */\n if (!isLazyBundle(features)) {\n const { renderer, ...loadedFeatures } = features\n loadedRenderer.current = renderer\n loadFeatures(loadedFeatures)\n }\n\n useEffect(() => {\n if (isLazyBundle(features)) {\n features().then(({ renderer, ...loadedFeatures }) => {\n loadFeatures(loadedFeatures)\n loadedRenderer.current = renderer\n setIsLoaded(true)\n })\n }\n }, [])\n\n return (\n <LazyContext.Provider\n value={{ renderer: loadedRenderer.current, strict }}\n >\n {children}\n </LazyContext.Provider>\n )\n}\n\nfunction isLazyBundle(\n features: FeatureBundle | LazyFeatureBundle\n): features is LazyFeatureBundle {\n return typeof features === \"function\"\n}\n"],"names":[],"mappings":";;;;;;AASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCG;AACG;AACF;AACA;AAEA;;AAEG;AACH;;AAEI;;;;AAKA;AACI;;AAEI;;AAEJ;;;;AAWZ;AAEA;AAGI;AACJ;;"}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { resolveTransition } from 'motion-dom';
|
||||
import { MotionConfigContext } from '../../context/MotionConfigContext.mjs';
|
||||
import { loadExternalIsValidProp } from '../../render/dom/utils/filter-props.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
|
||||
/**
|
||||
* `MotionConfig` is used to set configuration options for all children `motion` components.
|
||||
*
|
||||
* ```jsx
|
||||
* import { motion, MotionConfig } from "framer-motion"
|
||||
*
|
||||
* export function App() {
|
||||
* return (
|
||||
* <MotionConfig transition={{ type: "spring" }}>
|
||||
* <motion.div animate={{ x: 100 }} />
|
||||
* </MotionConfig>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function MotionConfig({ children, isValidProp, ...config }) {
|
||||
isValidProp && loadExternalIsValidProp(isValidProp);
|
||||
/**
|
||||
* Inherit props from any parent MotionConfig components
|
||||
*/
|
||||
const parentConfig = useContext(MotionConfigContext);
|
||||
config = { ...parentConfig, ...config };
|
||||
config.transition = resolveTransition(config.transition, parentConfig.transition);
|
||||
/**
|
||||
* Don't allow isStatic to change between renders as it affects how many hooks
|
||||
* motion components fire.
|
||||
*/
|
||||
config.isStatic = useConstant(() => config.isStatic);
|
||||
/**
|
||||
* Creating a new config context object will re-render every `motion` component
|
||||
* every time it renders. So we only want to create a new one sparingly.
|
||||
*/
|
||||
const context = useMemo(() => config, [
|
||||
JSON.stringify(config.transition),
|
||||
config.transformPagePoint,
|
||||
config.reducedMotion,
|
||||
config.skipAnimations,
|
||||
]);
|
||||
return (jsx(MotionConfigContext.Provider, { value: context, children: children }));
|
||||
}
|
||||
|
||||
export { MotionConfig };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../../../../src/components/MotionConfig/index.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { useContext, useMemo } from \"react\"\nimport { resolveTransition } from \"motion-dom\"\nimport { MotionConfigContext } from \"../../context/MotionConfigContext\"\nimport {\n loadExternalIsValidProp,\n IsValidProp,\n} from \"../../render/dom/utils/filter-props\"\nimport { useConstant } from \"../../utils/use-constant\"\n\nexport interface MotionConfigProps extends Partial<MotionConfigContext> {\n children?: React.ReactNode\n isValidProp?: IsValidProp\n}\n\n/**\n * `MotionConfig` is used to set configuration options for all children `motion` components.\n *\n * ```jsx\n * import { motion, MotionConfig } from \"framer-motion\"\n *\n * export function App() {\n * return (\n * <MotionConfig transition={{ type: \"spring\" }}>\n * <motion.div animate={{ x: 100 }} />\n * </MotionConfig>\n * )\n * }\n * ```\n *\n * @public\n */\nexport function MotionConfig({\n children,\n isValidProp,\n ...config\n}: MotionConfigProps) {\n isValidProp && loadExternalIsValidProp(isValidProp)\n\n /**\n * Inherit props from any parent MotionConfig components\n */\n const parentConfig = useContext(MotionConfigContext)\n config = { ...parentConfig, ...config }\n\n config.transition = resolveTransition(\n config.transition,\n parentConfig.transition\n )\n\n /**\n * Don't allow isStatic to change between renders as it affects how many hooks\n * motion components fire.\n */\n config.isStatic = useConstant(() => config.isStatic)\n\n /**\n * Creating a new config context object will re-render every `motion` component\n * every time it renders. So we only want to create a new one sparingly.\n */\n const context = useMemo(\n () => config,\n [\n JSON.stringify(config.transition),\n config.transformPagePoint,\n config.reducedMotion,\n config.skipAnimations,\n ]\n )\n\n return (\n <MotionConfigContext.Provider value={context as MotionConfigContext}>\n {children}\n </MotionConfigContext.Provider>\n )\n}\n"],"names":[],"mappings":";;;;;;;;AAiBA;;;;;;;;;;;;;;;;AAgBG;AACG;AAKF;AAEA;;AAEG;AACH;;AAGA;AAKA;;;AAGG;AACH;AAEA;;;AAGG;;AAIK;AACA;AACA;AACA;AACH;AAGL;AAKJ;;"}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { forwardRef, useRef, useEffect } from 'react';
|
||||
import { ReorderContext } from '../../context/ReorderContext.mjs';
|
||||
import { motion } from '../../render/components/motion/proxy.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { checkReorder } from './utils/check-reorder.mjs';
|
||||
|
||||
function ReorderGroupComponent({ children, as = "ul", axis = "y", onReorder, values, ...props }, externalRef) {
|
||||
const Component = useConstant(() => motion[as]);
|
||||
const order = [];
|
||||
const isReordering = useRef(false);
|
||||
const groupRef = useRef(null);
|
||||
invariant(Boolean(values), "Reorder.Group must be provided a values prop", "reorder-values");
|
||||
const context = {
|
||||
axis,
|
||||
groupRef,
|
||||
registerItem: (value, layout) => {
|
||||
// If the entry was already added, update it rather than adding it again
|
||||
const idx = order.findIndex((entry) => value === entry.value);
|
||||
if (idx !== -1) {
|
||||
order[idx].layout = layout[axis];
|
||||
}
|
||||
else {
|
||||
order.push({ value: value, layout: layout[axis] });
|
||||
}
|
||||
order.sort(compareMin);
|
||||
},
|
||||
updateOrder: (item, offset, velocity) => {
|
||||
if (isReordering.current)
|
||||
return;
|
||||
const newOrder = checkReorder(order, item, offset, velocity);
|
||||
if (order !== newOrder) {
|
||||
isReordering.current = true;
|
||||
// Find which two values swapped and apply that swap
|
||||
// to the full values array. This preserves unmeasured
|
||||
// items (e.g. in virtualized lists).
|
||||
const newValues = [...values];
|
||||
for (let i = 0; i < newOrder.length; i++) {
|
||||
if (order[i].value !== newOrder[i].value) {
|
||||
const a = values.indexOf(order[i].value);
|
||||
const b = values.indexOf(newOrder[i].value);
|
||||
if (a !== -1 && b !== -1) {
|
||||
[newValues[a], newValues[b]] = [newValues[b], newValues[a]];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
onReorder(newValues);
|
||||
}
|
||||
},
|
||||
};
|
||||
useEffect(() => {
|
||||
isReordering.current = false;
|
||||
});
|
||||
// Combine refs if external ref is provided
|
||||
const setRef = (element) => {
|
||||
groupRef.current = element;
|
||||
if (typeof externalRef === "function") {
|
||||
externalRef(element);
|
||||
}
|
||||
else if (externalRef) {
|
||||
externalRef.current = element;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Disable browser scroll anchoring on the group container.
|
||||
* When items reorder, scroll anchoring can cause the browser to adjust
|
||||
* the scroll position, which interferes with drag position calculations.
|
||||
*/
|
||||
const groupStyle = {
|
||||
overflowAnchor: "none",
|
||||
...props.style,
|
||||
};
|
||||
return (jsx(Component, { ...props, style: groupStyle, ref: setRef, ignoreStrict: true, children: jsx(ReorderContext.Provider, { value: context, children: children }) }));
|
||||
}
|
||||
const ReorderGroup = /*@__PURE__*/ forwardRef(ReorderGroupComponent);
|
||||
function compareMin(a, b) {
|
||||
return a.layout.min - b.layout.min;
|
||||
}
|
||||
|
||||
export { ReorderGroup, ReorderGroupComponent };
|
||||
//# sourceMappingURL=Group.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+43
@@ -0,0 +1,43 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { isMotionValue } from 'motion-dom';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { forwardRef, useContext } from 'react';
|
||||
import { ReorderContext } from '../../context/ReorderContext.mjs';
|
||||
import { motion } from '../../render/components/motion/proxy.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
import { useMotionValue } from '../../value/use-motion-value.mjs';
|
||||
import { useTransform } from '../../value/use-transform.mjs';
|
||||
import { autoScrollIfNeeded, resetAutoScrollState } from './utils/auto-scroll.mjs';
|
||||
|
||||
function useDefaultMotionValue(value, defaultValue = 0) {
|
||||
return isMotionValue(value) ? value : useMotionValue(defaultValue);
|
||||
}
|
||||
function ReorderItemComponent({ children, style = {}, value, as = "li", onDrag, onDragEnd, layout = true, ...props }, externalRef) {
|
||||
const Component = useConstant(() => motion[as]);
|
||||
const context = useContext(ReorderContext);
|
||||
const point = {
|
||||
x: useDefaultMotionValue(style.x),
|
||||
y: useDefaultMotionValue(style.y),
|
||||
};
|
||||
const zIndex = useTransform([point.x, point.y], ([latestX, latestY]) => latestX || latestY ? 1 : "unset");
|
||||
invariant(Boolean(context), "Reorder.Item must be a child of Reorder.Group", "reorder-item-child");
|
||||
const { axis, registerItem, updateOrder, groupRef } = context;
|
||||
return (jsx(Component, { drag: axis, ...props, dragSnapToOrigin: true, style: { ...style, x: point.x, y: point.y, zIndex }, layout: layout, onDrag: (event, gesturePoint) => {
|
||||
const { velocity, point: pointerPoint } = gesturePoint;
|
||||
const offset = point[axis].get();
|
||||
// Always attempt to update order - checkReorder handles the logic
|
||||
updateOrder(value, offset, velocity[axis]);
|
||||
autoScrollIfNeeded(groupRef.current, pointerPoint[axis], axis, velocity[axis]);
|
||||
onDrag && onDrag(event, gesturePoint);
|
||||
}, onDragEnd: (event, gesturePoint) => {
|
||||
resetAutoScrollState();
|
||||
onDragEnd && onDragEnd(event, gesturePoint);
|
||||
}, onLayoutMeasure: (measured) => {
|
||||
registerItem(value, measured);
|
||||
}, ref: externalRef, ignoreStrict: true, children: children }));
|
||||
}
|
||||
const ReorderItem = /*@__PURE__*/ forwardRef(ReorderItemComponent);
|
||||
|
||||
export { ReorderItem, ReorderItemComponent };
|
||||
//# sourceMappingURL=Item.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Item.mjs","sources":["../../../../src/components/Reorder/Item.tsx"],"sourcesContent":["\"use client\"\n\nimport { isMotionValue } from \"motion-dom\"\nimport { invariant } from \"motion-utils\"\nimport * as React from \"react\"\nimport { forwardRef, FunctionComponent, useContext } from \"react\"\nimport { ReorderContext } from \"../../context/ReorderContext\"\nimport { motion } from \"../../render/components/motion/proxy\"\nimport { HTMLMotionProps } from \"../../render/html/types\"\nimport { useConstant } from \"../../utils/use-constant\"\nimport { useMotionValue } from \"../../value/use-motion-value\"\nimport { useTransform } from \"../../value/use-transform\"\n\nimport { DefaultItemElement, ReorderElementTag } from \"./types\"\nimport {\n autoScrollIfNeeded,\n resetAutoScrollState,\n} from \"./utils/auto-scroll\"\n\nexport interface Props<\n V,\n TagName extends ReorderElementTag = DefaultItemElement\n> {\n /**\n * A HTML element to render this component as. Defaults to `\"li\"`.\n *\n * @public\n */\n as?: TagName\n\n /**\n * The value in the list that this component represents.\n *\n * @public\n */\n value: V\n\n /**\n * A subset of layout options primarily used to disable layout=\"size\"\n *\n * @public\n * @default true\n */\n layout?: true | \"position\"\n}\n\nfunction useDefaultMotionValue(value: any, defaultValue: number = 0) {\n return isMotionValue(value) ? value : useMotionValue(defaultValue)\n}\n\ntype ReorderItemProps<\n V,\n TagName extends ReorderElementTag = DefaultItemElement\n> = Props<V, TagName> &\n Omit<HTMLMotionProps<TagName>, \"value\" | \"layout\"> &\n React.PropsWithChildren<{}>\n\nexport function ReorderItemComponent<\n V,\n TagName extends ReorderElementTag = DefaultItemElement\n>(\n {\n children,\n style = {},\n value,\n as = \"li\" as TagName,\n onDrag,\n onDragEnd,\n layout = true,\n ...props\n }: ReorderItemProps<V, TagName>,\n externalRef?: React.ForwardedRef<any>\n): React.JSX.Element {\n const Component = useConstant(\n () => motion[as as keyof typeof motion]\n ) as FunctionComponent<\n React.PropsWithChildren<HTMLMotionProps<any> & { ref?: React.Ref<any> }>\n >\n\n const context = useContext(ReorderContext)\n const point = {\n x: useDefaultMotionValue(style.x),\n y: useDefaultMotionValue(style.y),\n }\n\n const zIndex = useTransform([point.x, point.y], ([latestX, latestY]) =>\n latestX || latestY ? 1 : \"unset\"\n )\n\n invariant(\n Boolean(context),\n \"Reorder.Item must be a child of Reorder.Group\",\n \"reorder-item-child\"\n )\n\n const { axis, registerItem, updateOrder, groupRef } = context!\n\n return (\n <Component\n drag={axis}\n {...props}\n dragSnapToOrigin\n style={{ ...style, x: point.x, y: point.y, zIndex }}\n layout={layout}\n onDrag={(event, gesturePoint) => {\n const { velocity, point: pointerPoint } = gesturePoint\n const offset = point[axis].get()\n\n // Always attempt to update order - checkReorder handles the logic\n updateOrder(value, offset, velocity[axis])\n\n autoScrollIfNeeded(\n groupRef.current,\n pointerPoint[axis],\n axis,\n velocity[axis]\n )\n\n onDrag && onDrag(event, gesturePoint)\n }}\n onDragEnd={(event, gesturePoint) => {\n resetAutoScrollState()\n onDragEnd && onDragEnd(event, gesturePoint)\n }}\n onLayoutMeasure={(measured) => {\n registerItem(value, measured)\n }}\n ref={externalRef}\n ignoreStrict\n >\n {children}\n </Component>\n )\n}\n\nexport const ReorderItem = /*@__PURE__*/ forwardRef(ReorderItemComponent) as <\n V,\n TagName extends ReorderElementTag = DefaultItemElement\n>(\n props: ReorderItemProps<V, TagName> & { ref?: React.ForwardedRef<any> }\n) => ReturnType<typeof ReorderItemComponent>\n"],"names":[],"mappings":";;;;;;;;;;;;AA8CA;AACI;AACJ;AASM;AAgBF;AAMA;AACA;AACI;AACA;;AAGJ;;;;;;;;AA0BY;AAOA;;AAGA;AACA;AACJ;AAEI;;AAQhB;AAEO;;"}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
export { ReorderGroup as Group } from './Group.mjs';
|
||||
export { ReorderItem as Item } from './Item.mjs';
|
||||
//# sourceMappingURL=namespace.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"namespace.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
||||
Generated
Vendored
+124
@@ -0,0 +1,124 @@
|
||||
const threshold = 50;
|
||||
const maxSpeed = 25;
|
||||
const overflowStyles = new Set(["auto", "scroll"]);
|
||||
// Track initial scroll limits per scrollable element (Bug 1 fix)
|
||||
const initialScrollLimits = new WeakMap();
|
||||
const activeScrollEdge = new WeakMap();
|
||||
// Track which group element is currently dragging to clear state on end
|
||||
let currentGroupElement = null;
|
||||
function resetAutoScrollState() {
|
||||
if (currentGroupElement) {
|
||||
const scrollableAncestor = findScrollableAncestor(currentGroupElement, "y");
|
||||
if (scrollableAncestor) {
|
||||
activeScrollEdge.delete(scrollableAncestor);
|
||||
initialScrollLimits.delete(scrollableAncestor);
|
||||
}
|
||||
// Also try x axis
|
||||
const scrollableAncestorX = findScrollableAncestor(currentGroupElement, "x");
|
||||
if (scrollableAncestorX && scrollableAncestorX !== scrollableAncestor) {
|
||||
activeScrollEdge.delete(scrollableAncestorX);
|
||||
initialScrollLimits.delete(scrollableAncestorX);
|
||||
}
|
||||
currentGroupElement = null;
|
||||
}
|
||||
}
|
||||
function isScrollableElement(element, axis) {
|
||||
const style = getComputedStyle(element);
|
||||
const overflow = axis === "x" ? style.overflowX : style.overflowY;
|
||||
const isDocumentScroll = element === document.body ||
|
||||
element === document.documentElement;
|
||||
return overflowStyles.has(overflow) || isDocumentScroll;
|
||||
}
|
||||
function findScrollableAncestor(element, axis) {
|
||||
let current = element?.parentElement;
|
||||
while (current) {
|
||||
if (isScrollableElement(current, axis)) {
|
||||
return current;
|
||||
}
|
||||
current = current.parentElement;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function getScrollAmount(pointerPosition, scrollElement, axis) {
|
||||
const rect = scrollElement.getBoundingClientRect();
|
||||
const start = axis === "x" ? Math.max(0, rect.left) : Math.max(0, rect.top);
|
||||
const end = axis === "x" ? Math.min(window.innerWidth, rect.right) : Math.min(window.innerHeight, rect.bottom);
|
||||
const distanceFromStart = pointerPosition - start;
|
||||
const distanceFromEnd = end - pointerPosition;
|
||||
if (distanceFromStart < threshold) {
|
||||
const intensity = 1 - distanceFromStart / threshold;
|
||||
return { amount: -maxSpeed * intensity * intensity, edge: "start" };
|
||||
}
|
||||
else if (distanceFromEnd < threshold) {
|
||||
const intensity = 1 - distanceFromEnd / threshold;
|
||||
return { amount: maxSpeed * intensity * intensity, edge: "end" };
|
||||
}
|
||||
return { amount: 0, edge: null };
|
||||
}
|
||||
function autoScrollIfNeeded(groupElement, pointerPosition, axis, velocity) {
|
||||
if (!groupElement)
|
||||
return;
|
||||
// Track the group element for cleanup
|
||||
currentGroupElement = groupElement;
|
||||
const scrollableAncestor = findScrollableAncestor(groupElement, axis);
|
||||
if (!scrollableAncestor)
|
||||
return;
|
||||
// Convert pointer position from page coordinates to viewport coordinates.
|
||||
// The gesture system uses pageX/pageY but getBoundingClientRect() returns
|
||||
// viewport-relative coordinates, so we need to account for page scroll.
|
||||
const viewportPointerPosition = pointerPosition - (axis === "x" ? window.scrollX : window.scrollY);
|
||||
const { amount: scrollAmount, edge } = getScrollAmount(viewportPointerPosition, scrollableAncestor, axis);
|
||||
// If not in any threshold zone, clear all state
|
||||
if (edge === null) {
|
||||
activeScrollEdge.delete(scrollableAncestor);
|
||||
initialScrollLimits.delete(scrollableAncestor);
|
||||
return;
|
||||
}
|
||||
const currentActiveEdge = activeScrollEdge.get(scrollableAncestor);
|
||||
const isDocumentScroll = scrollableAncestor === document.body ||
|
||||
scrollableAncestor === document.documentElement;
|
||||
// If not currently scrolling this edge, check velocity to see if we should start
|
||||
if (currentActiveEdge !== edge) {
|
||||
// Only start scrolling if velocity is towards the edge
|
||||
const shouldStart = (edge === "start" && velocity < 0) ||
|
||||
(edge === "end" && velocity > 0);
|
||||
if (!shouldStart)
|
||||
return;
|
||||
// Activate this edge
|
||||
activeScrollEdge.set(scrollableAncestor, edge);
|
||||
// Record initial scroll limit (prevents infinite scroll)
|
||||
const maxScroll = axis === "x"
|
||||
? scrollableAncestor.scrollWidth - (isDocumentScroll ? window.innerWidth : scrollableAncestor.clientWidth)
|
||||
: scrollableAncestor.scrollHeight - (isDocumentScroll ? window.innerHeight : scrollableAncestor.clientHeight);
|
||||
initialScrollLimits.set(scrollableAncestor, maxScroll);
|
||||
}
|
||||
// Cap scrolling at initial limit (prevents infinite scroll)
|
||||
if (scrollAmount > 0) {
|
||||
const initialLimit = initialScrollLimits.get(scrollableAncestor);
|
||||
const currentScroll = axis === "x"
|
||||
? (isDocumentScroll ? window.scrollX : scrollableAncestor.scrollLeft)
|
||||
: (isDocumentScroll ? window.scrollY : scrollableAncestor.scrollTop);
|
||||
if (currentScroll >= initialLimit)
|
||||
return;
|
||||
}
|
||||
// Apply scroll
|
||||
if (axis === "x") {
|
||||
if (isDocumentScroll) {
|
||||
window.scrollBy({ left: scrollAmount });
|
||||
}
|
||||
else {
|
||||
scrollableAncestor.scrollLeft += scrollAmount;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isDocumentScroll) {
|
||||
window.scrollBy({ top: scrollAmount });
|
||||
}
|
||||
else {
|
||||
scrollableAncestor.scrollTop += scrollAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { autoScrollIfNeeded, resetAutoScrollState };
|
||||
//# sourceMappingURL=auto-scroll.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
import { mixNumber } from 'motion-dom';
|
||||
import { moveItem } from 'motion-utils';
|
||||
|
||||
function checkReorder(order, value, offset, velocity) {
|
||||
if (!velocity)
|
||||
return order;
|
||||
const index = order.findIndex((item) => item.value === value);
|
||||
if (index === -1)
|
||||
return order;
|
||||
const nextOffset = velocity > 0 ? 1 : -1;
|
||||
const nextItem = order[index + nextOffset];
|
||||
if (!nextItem)
|
||||
return order;
|
||||
const item = order[index];
|
||||
const nextLayout = nextItem.layout;
|
||||
const nextItemCenter = mixNumber(nextLayout.min, nextLayout.max, 0.5);
|
||||
if ((nextOffset === 1 && item.layout.max + offset > nextItemCenter) ||
|
||||
(nextOffset === -1 && item.layout.min + offset < nextItemCenter)) {
|
||||
return moveItem(order, index, index + nextOffset);
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
export { checkReorder };
|
||||
//# sourceMappingURL=check-reorder.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"check-reorder.mjs","sources":["../../../../../src/components/Reorder/utils/check-reorder.ts"],"sourcesContent":["import { mixNumber } from \"motion-dom\"\nimport { moveItem } from \"motion-utils\"\nimport { ItemData } from \"../types\"\n\nexport function checkReorder<T>(\n order: ItemData<T>[],\n value: T,\n offset: number,\n velocity: number\n): ItemData<T>[] {\n if (!velocity) return order\n\n const index = order.findIndex((item) => item.value === value)\n\n if (index === -1) return order\n\n const nextOffset = velocity > 0 ? 1 : -1\n const nextItem = order[index + nextOffset]\n\n if (!nextItem) return order\n\n const item = order[index]\n const nextLayout = nextItem.layout\n const nextItemCenter = mixNumber(nextLayout.min, nextLayout.max, 0.5)\n\n if (\n (nextOffset === 1 && item.layout.max + offset > nextItemCenter) ||\n (nextOffset === -1 && item.layout.min + offset < nextItemCenter)\n ) {\n return moveItem(order, index, index + nextOffset)\n }\n\n return order\n}\n"],"names":[],"mappings":";;;AAIM,SAAU,YAAY,CACxB,KAAoB,EACpB,KAAQ,EACR,MAAc,EACd,QAAgB,EAAA;AAEhB,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,KAAK;AAE3B,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;IAE7D,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,KAAK;AAE9B,IAAA,MAAM,UAAU,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE;IACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC;AAE1C,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,KAAK;AAE3B,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;AACzB,IAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM;AAClC,IAAA,MAAM,cAAc,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;AAErE,IAAA,IACI,CAAC,UAAU,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,GAAG,cAAc;AAC9D,SAAC,UAAU,KAAK,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,MAAM,GAAG,cAAc,CAAC,EAClE;QACE,OAAO,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU,CAAC;IACrD;AAEA,IAAA,OAAO,KAAK;AAChB;;;;"}
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
/**
|
||||
* Note: Still used by components generated by old versions of Framer
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
const DeprecatedLayoutGroupContext = createContext(null);
|
||||
|
||||
export { DeprecatedLayoutGroupContext };
|
||||
//# sourceMappingURL=DeprecatedLayoutGroupContext.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"DeprecatedLayoutGroupContext.mjs","sources":["../../../src/context/DeprecatedLayoutGroupContext.ts"],"sourcesContent":["\"use client\"\n\nimport { createContext } from \"react\"\n\n/**\n * Note: Still used by components generated by old versions of Framer\n *\n * @deprecated\n */\nexport const DeprecatedLayoutGroupContext = createContext<string | null>(null)\n"],"names":[],"mappings":";;;AAIA;;;;AAIG;;;"}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
const LayoutGroupContext = createContext({});
|
||||
|
||||
export { LayoutGroupContext };
|
||||
//# sourceMappingURL=LayoutGroupContext.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"LayoutGroupContext.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
const LazyContext = createContext({ strict: false });
|
||||
|
||||
export { LazyContext };
|
||||
//# sourceMappingURL=LazyContext.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"LazyContext.mjs","sources":["../../../src/context/LazyContext.ts"],"sourcesContent":["\"use client\"\n\nimport { createContext } from \"react\"\nimport { CreateVisualElement } from \"../render/types\"\n\nexport interface LazyContextProps {\n renderer?: CreateVisualElement\n strict: boolean\n}\n\nexport const LazyContext = createContext<LazyContextProps>({ strict: false })\n"],"names":[],"mappings":";;;AAUO;;"}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
const MotionConfigContext = createContext({
|
||||
transformPagePoint: (p) => p,
|
||||
isStatic: false,
|
||||
reducedMotion: "never",
|
||||
});
|
||||
|
||||
export { MotionConfigContext };
|
||||
//# sourceMappingURL=MotionConfigContext.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"MotionConfigContext.mjs","sources":["../../../src/context/MotionConfigContext.tsx"],"sourcesContent":["\"use client\"\n\nimport type { Transition } from \"motion-dom\"\nimport { TransformPoint } from \"motion-utils\"\nimport { createContext } from \"react\"\n\nexport type ReducedMotionConfig = \"always\" | \"never\" | \"user\"\n\n/**\n * @public\n */\nexport interface MotionConfigContext {\n /**\n * Internal, exported only for usage in Framer\n */\n transformPagePoint: TransformPoint\n\n /**\n * Internal. Determines whether this is a static context ie the Framer canvas. If so,\n * it'll disable all dynamic functionality.\n */\n isStatic: boolean\n\n /**\n * Defines a new default transition for the entire tree.\n *\n * @public\n */\n transition?: Transition\n\n /**\n * If true, will respect the device prefersReducedMotion setting by switching\n * transform animations off.\n *\n * @public\n */\n reducedMotion?: ReducedMotionConfig\n\n /**\n * A custom `nonce` attribute used when wanting to enforce a Content Security Policy (CSP).\n * For more details see:\n * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src#unsafe_inline_styles\n *\n * @public\n */\n nonce?: string\n\n /**\n * If true, all animations will be skipped and values will be set instantly.\n * Useful for E2E tests and visual regression testing.\n *\n * @public\n */\n skipAnimations?: boolean\n\n}\n\n/**\n * @public\n */\nexport const MotionConfigContext = createContext<MotionConfigContext>({\n transformPagePoint: (p) => p,\n isStatic: false,\n reducedMotion: \"never\",\n})\n"],"names":[],"mappings":";;;AAyDA;;AAEG;AACI;AACH;AACA;AACA;AACH;;"}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
"use client";
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { MotionContext } from './index.mjs';
|
||||
import { getCurrentTreeVariants } from './utils.mjs';
|
||||
|
||||
function useCreateMotionContext(props) {
|
||||
const { initial, animate } = getCurrentTreeVariants(props, useContext(MotionContext));
|
||||
return useMemo(() => ({ initial, animate }), [variantLabelsAsDependency(initial), variantLabelsAsDependency(animate)]);
|
||||
}
|
||||
function variantLabelsAsDependency(prop) {
|
||||
return Array.isArray(prop) ? prop.join(" ") : prop;
|
||||
}
|
||||
|
||||
export { useCreateMotionContext };
|
||||
//# sourceMappingURL=create.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"create.mjs","sources":["../../../../src/context/MotionContext/create.ts"],"sourcesContent":["\"use client\"\n\nimport { useContext, useMemo } from \"react\"\nimport { MotionContext, type MotionContextProps } from \".\"\nimport { MotionProps } from \"../../motion/types\"\nimport { getCurrentTreeVariants } from \"./utils\"\n\nexport function useCreateMotionContext<Instance>(\n props: MotionProps\n): MotionContextProps<Instance> {\n const { initial, animate } = getCurrentTreeVariants(\n props,\n useContext(MotionContext)\n )\n\n return useMemo(\n () => ({ initial, animate }),\n [variantLabelsAsDependency(initial), variantLabelsAsDependency(animate)]\n )\n}\n\nfunction variantLabelsAsDependency(\n prop: undefined | string | string[] | boolean\n) {\n return Array.isArray(prop) ? prop.join(\" \") : prop\n}\n"],"names":[],"mappings":";;;;;AAOM;AAGF;;AASJ;AAEA;AAGI;AACJ;;"}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
const MotionContext = /* @__PURE__ */ createContext({});
|
||||
|
||||
export { MotionContext };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../../../../src/context/MotionContext/index.ts"],"sourcesContent":["\"use client\"\n\nimport type { VisualElement } from \"motion-dom\"\nimport { createContext } from \"react\"\n\nexport interface MotionContextProps<Instance = unknown> {\n visualElement?: VisualElement<Instance>\n initial?: false | string | string[]\n animate?: string | string[]\n}\n\nexport const MotionContext = /* @__PURE__ */ createContext<MotionContextProps>(\n {}\n)\n"],"names":[],"mappings":";;;AAWO;;"}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { isControllingVariants, isVariantLabel } from 'motion-dom';
|
||||
|
||||
function getCurrentTreeVariants(props, context) {
|
||||
if (isControllingVariants(props)) {
|
||||
const { initial, animate } = props;
|
||||
return {
|
||||
initial: initial === false || isVariantLabel(initial)
|
||||
? initial
|
||||
: undefined,
|
||||
animate: isVariantLabel(animate) ? animate : undefined,
|
||||
};
|
||||
}
|
||||
return props.inherit !== false ? context : {};
|
||||
}
|
||||
|
||||
export { getCurrentTreeVariants };
|
||||
//# sourceMappingURL=utils.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.mjs","sources":["../../../../src/context/MotionContext/utils.ts"],"sourcesContent":["import { isControllingVariants, isVariantLabel } from \"motion-dom\"\nimport type { MotionContextProps } from \".\"\nimport { MotionProps } from \"../../motion/types\"\n\nexport function getCurrentTreeVariants(\n props: MotionProps,\n context: MotionContextProps\n): MotionContextProps {\n if (isControllingVariants(props)) {\n const { initial, animate } = props\n return {\n initial:\n initial === false || isVariantLabel(initial)\n ? (initial as any)\n : undefined,\n animate: isVariantLabel(animate) ? animate : undefined,\n }\n }\n return props.inherit !== false ? context : {}\n}\n"],"names":[],"mappings":";;AAIM,SAAU,sBAAsB,CAClC,KAAkB,EAClB,OAA2B,EAAA;AAE3B,IAAA,IAAI,qBAAqB,CAAC,KAAK,CAAC,EAAE;AAC9B,QAAA,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,KAAK;QAClC,OAAO;YACH,OAAO,EACH,OAAO,KAAK,KAAK,IAAI,cAAc,CAAC,OAAO;AACvC,kBAAG;AACH,kBAAE,SAAS;AACnB,YAAA,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,SAAS;SACzD;IACL;AACA,IAAA,OAAO,KAAK,CAAC,OAAO,KAAK,KAAK,GAAG,OAAO,GAAG,EAAE;AACjD;;;;"}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
const PresenceContext =
|
||||
/* @__PURE__ */ createContext(null);
|
||||
|
||||
export { PresenceContext };
|
||||
//# sourceMappingURL=PresenceContext.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"PresenceContext.mjs","sources":["../../../src/context/PresenceContext.ts"],"sourcesContent":["\"use client\"\n\nimport { createContext } from \"react\"\nimport type { PresenceContextProps } from \"motion-dom\"\n\nexport type { PresenceContextProps }\n\n/**\n * @public\n */\nexport const PresenceContext =\n /* @__PURE__ */ createContext<PresenceContextProps | null>(null)\n"],"names":[],"mappings":";;;AAOA;;AAEG;;AAEC;;"}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
const ReorderContext = createContext(null);
|
||||
|
||||
export { ReorderContext };
|
||||
//# sourceMappingURL=ReorderContext.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ReorderContext.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
"use client";
|
||||
import { createContext } from 'react';
|
||||
|
||||
/**
|
||||
* Internal, exported only for usage in Framer
|
||||
*/
|
||||
const SwitchLayoutGroupContext = createContext({});
|
||||
|
||||
export { SwitchLayoutGroupContext };
|
||||
//# sourceMappingURL=SwitchLayoutGroupContext.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"SwitchLayoutGroupContext.mjs","sources":["../../../src/context/SwitchLayoutGroupContext.ts"],"sourcesContent":["\"use client\"\n\nimport type { Transition, IProjectionNode } from \"motion-dom\"\nimport { createContext } from \"react\"\n\nexport interface SwitchLayoutGroup {\n register?: (member: IProjectionNode) => void\n deregister?: (member: IProjectionNode) => void\n}\n\nexport type SwitchLayoutGroupContext = SwitchLayoutGroup &\n InitialPromotionConfig\n\nexport type InitialPromotionConfig = {\n /**\n * The initial transition to use when the elements in this group mount (and automatically promoted).\n * Subsequent updates should provide a transition in the promote method.\n */\n transition?: Transition\n /**\n * If the follow tree should preserve its opacity when the lead is promoted on mount\n */\n shouldPreserveFollowOpacity?: (member: IProjectionNode) => boolean\n}\n\n/**\n * Internal, exported only for usage in Framer\n */\nexport const SwitchLayoutGroupContext = createContext<SwitchLayoutGroupContext>(\n {}\n)\n"],"names":[],"mappings":";;;AAyBA;;AAEG;;;"}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export { recordStats } from 'motion-dom';
|
||||
//# sourceMappingURL=debug.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"debug.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
export { animateSequence } from './animation/animators/waapi/animate-sequence.mjs';
|
||||
export { animateMini as animate } from './animation/animators/waapi/animate-style.mjs';
|
||||
//# sourceMappingURL=dom-mini.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"dom-mini.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
export * from 'motion-dom';
|
||||
export { delayInSeconds as delay } from 'motion-dom';
|
||||
export * from 'motion-utils';
|
||||
export { animate, createScopedAnimate } from './animation/animate/index.mjs';
|
||||
export { animateMini } from './animation/animators/waapi/animate-style.mjs';
|
||||
export { scroll } from './render/dom/scroll/index.mjs';
|
||||
export { scrollInfo } from './render/dom/scroll/track.mjs';
|
||||
export { inView } from './render/dom/viewport/index.mjs';
|
||||
export { distance, distance2D } from './utils/distance.mjs';
|
||||
//# sourceMappingURL=dom.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"dom.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { addDomEvent } from 'motion-dom';
|
||||
import { addPointerInfo } from './event-info.mjs';
|
||||
|
||||
function addPointerEvent(target, eventName, handler, options) {
|
||||
return addDomEvent(target, eventName, addPointerInfo(handler), options);
|
||||
}
|
||||
|
||||
export { addPointerEvent };
|
||||
//# sourceMappingURL=add-pointer-event.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"add-pointer-event.mjs","sources":["../../../src/events/add-pointer-event.ts"],"sourcesContent":["import { addDomEvent } from \"motion-dom\"\nimport { addPointerInfo, EventListenerWithPointInfo } from \"./event-info\"\n\nexport function addPointerEvent(\n target: EventTarget,\n eventName: string,\n handler: EventListenerWithPointInfo,\n options?: AddEventListenerOptions\n) {\n return addDomEvent(target, eventName, addPointerInfo(handler), options)\n}\n"],"names":[],"mappings":";;;AAGM,SAAU,eAAe,CAC3B,MAAmB,EACnB,SAAiB,EACjB,OAAmC,EACnC,OAAiC,EAAA;AAEjC,IAAA,OAAO,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;AAC3E;;;;"}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { isPrimaryPointer } from 'motion-dom';
|
||||
|
||||
function extractEventInfo(event) {
|
||||
return {
|
||||
point: {
|
||||
x: event.pageX,
|
||||
y: event.pageY,
|
||||
},
|
||||
};
|
||||
}
|
||||
const addPointerInfo = (handler) => (event) => isPrimaryPointer(event) && handler(event, extractEventInfo(event));
|
||||
|
||||
export { addPointerInfo, extractEventInfo };
|
||||
//# sourceMappingURL=event-info.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"event-info.mjs","sources":["../../../src/events/event-info.ts"],"sourcesContent":["import { EventInfo, isPrimaryPointer } from \"motion-dom\"\n\nexport type EventListenerWithPointInfo = (\n e: PointerEvent,\n info: EventInfo\n) => void\n\nexport function extractEventInfo(event: PointerEvent): EventInfo {\n return {\n point: {\n x: event.pageX,\n y: event.pageY,\n },\n }\n}\n\nexport const addPointerInfo =\n (handler: EventListenerWithPointInfo): EventListener =>\n (event: PointerEvent) =>\n isPrimaryPointer(event) && handler(event, extractEventInfo(event))\n"],"names":[],"mappings":";;AAOM,SAAU,gBAAgB,CAAC,KAAmB,EAAA;IAChD,OAAO;AACH,QAAA,KAAK,EAAE;YACH,CAAC,EAAE,KAAK,CAAC,KAAK;YACd,CAAC,EAAE,KAAK,CAAC,KAAK;AACjB,SAAA;KACJ;AACL;AAEO,MAAM,cAAc,GACvB,CAAC,OAAmC,KACpC,CAAC,KAAmB,KAChB,gBAAgB,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC;;;;"}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
"use client";
|
||||
import { useEffect } from 'react';
|
||||
import { addDomEvent } from 'motion-dom';
|
||||
|
||||
/**
|
||||
* Attaches an event listener directly to the provided DOM element.
|
||||
*
|
||||
* Bypassing React's event system can be desirable, for instance when attaching non-passive
|
||||
* event handlers.
|
||||
*
|
||||
* ```jsx
|
||||
* const ref = useRef(null)
|
||||
*
|
||||
* useDomEvent(ref, 'wheel', onWheel, { passive: false })
|
||||
*
|
||||
* return <div ref={ref} />
|
||||
* ```
|
||||
*
|
||||
* @param ref - React.RefObject that's been provided to the element you want to bind the listener to.
|
||||
* @param eventName - Name of the event you want listen for.
|
||||
* @param handler - Function to fire when receiving the event.
|
||||
* @param options - Options to pass to `Event.addEventListener`.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function useDomEvent(ref, eventName, handler, options) {
|
||||
useEffect(() => {
|
||||
const element = ref.current;
|
||||
if (handler && element) {
|
||||
return addDomEvent(element, eventName, handler, options);
|
||||
}
|
||||
}, [ref, eventName, handler, options]);
|
||||
}
|
||||
|
||||
export { useDomEvent };
|
||||
//# sourceMappingURL=use-dom-event.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-dom-event.mjs","sources":["../../../src/events/use-dom-event.ts"],"sourcesContent":["\"use client\"\n\nimport { RefObject, useEffect } from \"react\"\nimport { addDomEvent } from \"motion-dom\"\n\n/**\n * Attaches an event listener directly to the provided DOM element.\n *\n * Bypassing React's event system can be desirable, for instance when attaching non-passive\n * event handlers.\n *\n * ```jsx\n * const ref = useRef(null)\n *\n * useDomEvent(ref, 'wheel', onWheel, { passive: false })\n *\n * return <div ref={ref} />\n * ```\n *\n * @param ref - React.RefObject that's been provided to the element you want to bind the listener to.\n * @param eventName - Name of the event you want listen for.\n * @param handler - Function to fire when receiving the event.\n * @param options - Options to pass to `Event.addEventListener`.\n *\n * @public\n */\nexport function useDomEvent(\n ref: RefObject<EventTarget | null>,\n eventName: string,\n handler?: EventListener | undefined,\n options?: AddEventListenerOptions\n) {\n useEffect(() => {\n const element = ref.current\n\n if (handler && element) {\n return addDomEvent(element, eventName, handler, options)\n }\n }, [ref, eventName, handler, options])\n}\n"],"names":[],"mappings":";;;;AAKA;;;;;;;;;;;;;;;;;;;;AAoBG;AACG;;AAOE;AAEA;;;;AAIR;;"}
|
||||
Generated
Vendored
+573
@@ -0,0 +1,573 @@
|
||||
import { createBox, frame, eachAxis, measurePageBox, convertBoxToBoundingBox, convertBoundingBoxToBox, addValueToWillChange, animateMotionValue, mixNumber, addDomEvent, setDragLock, percent, calcLength, resize, isElementTextInput } from 'motion-dom';
|
||||
import { invariant } from 'motion-utils';
|
||||
import { addPointerEvent } from '../../events/add-pointer-event.mjs';
|
||||
import { extractEventInfo } from '../../events/event-info.mjs';
|
||||
import { getContextWindow } from '../../utils/get-context-window.mjs';
|
||||
import { isRefObject } from '../../utils/is-ref-object.mjs';
|
||||
import { PanSession } from '../pan/PanSession.mjs';
|
||||
import { applyConstraints, calcRelativeConstraints, resolveDragElastic, rebaseAxisConstraints, calcViewportConstraints, calcOrigin, defaultElastic } from './utils/constraints.mjs';
|
||||
|
||||
const elementDragControls = new WeakMap();
|
||||
class VisualElementDragControls {
|
||||
constructor(visualElement) {
|
||||
this.openDragLock = null;
|
||||
this.isDragging = false;
|
||||
this.currentDirection = null;
|
||||
this.originPoint = { x: 0, y: 0 };
|
||||
/**
|
||||
* The permitted boundaries of travel, in pixels.
|
||||
*/
|
||||
this.constraints = false;
|
||||
this.hasMutatedConstraints = false;
|
||||
/**
|
||||
* The per-axis resolved elastic values.
|
||||
*/
|
||||
this.elastic = createBox();
|
||||
/**
|
||||
* The latest pointer event. Used as fallback when the `cancel` and `stop` functions are called without arguments.
|
||||
*/
|
||||
this.latestPointerEvent = null;
|
||||
/**
|
||||
* The latest pan info. Used as fallback when the `cancel` and `stop` functions are called without arguments.
|
||||
*/
|
||||
this.latestPanInfo = null;
|
||||
this.visualElement = visualElement;
|
||||
}
|
||||
start(originEvent, { snapToCursor = false, distanceThreshold } = {}) {
|
||||
/**
|
||||
* Don't start dragging if this component is exiting
|
||||
*/
|
||||
const { presenceContext } = this.visualElement;
|
||||
if (presenceContext && presenceContext.isPresent === false)
|
||||
return;
|
||||
const onSessionStart = (event) => {
|
||||
if (snapToCursor) {
|
||||
this.snapToCursor(extractEventInfo(event).point);
|
||||
}
|
||||
this.stopAnimation();
|
||||
};
|
||||
const onStart = (event, info) => {
|
||||
// Attempt to grab the global drag gesture lock - maybe make this part of PanSession
|
||||
const { drag, dragPropagation, onDragStart } = this.getProps();
|
||||
if (drag && !dragPropagation) {
|
||||
if (this.openDragLock)
|
||||
this.openDragLock();
|
||||
this.openDragLock = setDragLock(drag);
|
||||
// If we don 't have the lock, don't start dragging
|
||||
if (!this.openDragLock)
|
||||
return;
|
||||
}
|
||||
this.latestPointerEvent = event;
|
||||
this.latestPanInfo = info;
|
||||
this.isDragging = true;
|
||||
this.currentDirection = null;
|
||||
this.resolveConstraints();
|
||||
if (this.visualElement.projection) {
|
||||
this.visualElement.projection.isAnimationBlocked = true;
|
||||
this.visualElement.projection.target = undefined;
|
||||
}
|
||||
/**
|
||||
* Record gesture origin and pointer offset
|
||||
*/
|
||||
eachAxis((axis) => {
|
||||
let current = this.getAxisMotionValue(axis).get() || 0;
|
||||
/**
|
||||
* If the MotionValue is a percentage value convert to px
|
||||
*/
|
||||
if (percent.test(current)) {
|
||||
const { projection } = this.visualElement;
|
||||
if (projection && projection.layout) {
|
||||
const measuredAxis = projection.layout.layoutBox[axis];
|
||||
if (measuredAxis) {
|
||||
const length = calcLength(measuredAxis);
|
||||
current = length * (parseFloat(current) / 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.originPoint[axis] = current;
|
||||
});
|
||||
// Fire onDragStart event
|
||||
if (onDragStart) {
|
||||
frame.update(() => onDragStart(event, info), false, true);
|
||||
}
|
||||
addValueToWillChange(this.visualElement, "transform");
|
||||
const { animationState } = this.visualElement;
|
||||
animationState && animationState.setActive("whileDrag", true);
|
||||
};
|
||||
const onMove = (event, info) => {
|
||||
this.latestPointerEvent = event;
|
||||
this.latestPanInfo = info;
|
||||
const { dragPropagation, dragDirectionLock, onDirectionLock, onDrag, } = this.getProps();
|
||||
// If we didn't successfully receive the gesture lock, early return.
|
||||
if (!dragPropagation && !this.openDragLock)
|
||||
return;
|
||||
const { offset } = info;
|
||||
// Attempt to detect drag direction if directionLock is true
|
||||
if (dragDirectionLock && this.currentDirection === null) {
|
||||
this.currentDirection = getCurrentDirection(offset);
|
||||
// If we've successfully set a direction, notify listener
|
||||
if (this.currentDirection !== null) {
|
||||
onDirectionLock && onDirectionLock(this.currentDirection);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Update each point with the latest position
|
||||
this.updateAxis("x", info.point, offset);
|
||||
this.updateAxis("y", info.point, offset);
|
||||
/**
|
||||
* Ideally we would leave the renderer to fire naturally at the end of
|
||||
* this frame but if the element is about to change layout as the result
|
||||
* of a re-render we want to ensure the browser can read the latest
|
||||
* bounding box to ensure the pointer and element don't fall out of sync.
|
||||
*/
|
||||
this.visualElement.render();
|
||||
/**
|
||||
* This must fire after the render call as it might trigger a state
|
||||
* change which itself might trigger a layout update.
|
||||
*/
|
||||
if (onDrag) {
|
||||
frame.update(() => onDrag(event, info), false, true);
|
||||
}
|
||||
};
|
||||
const onSessionEnd = (event, info) => {
|
||||
this.latestPointerEvent = event;
|
||||
this.latestPanInfo = info;
|
||||
this.stop(event, info);
|
||||
this.latestPointerEvent = null;
|
||||
this.latestPanInfo = null;
|
||||
};
|
||||
const resumeAnimation = () => {
|
||||
const { dragSnapToOrigin: snap } = this.getProps();
|
||||
if (snap || this.constraints) {
|
||||
this.startAnimation({ x: 0, y: 0 });
|
||||
}
|
||||
};
|
||||
const { dragSnapToOrigin } = this.getProps();
|
||||
this.panSession = new PanSession(originEvent, {
|
||||
onSessionStart,
|
||||
onStart,
|
||||
onMove,
|
||||
onSessionEnd,
|
||||
resumeAnimation,
|
||||
}, {
|
||||
transformPagePoint: this.visualElement.getTransformPagePoint(),
|
||||
dragSnapToOrigin,
|
||||
distanceThreshold,
|
||||
contextWindow: getContextWindow(this.visualElement),
|
||||
element: this.visualElement.current,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
stop(event, panInfo) {
|
||||
const finalEvent = event || this.latestPointerEvent;
|
||||
const finalPanInfo = panInfo || this.latestPanInfo;
|
||||
const isDragging = this.isDragging;
|
||||
this.cancel();
|
||||
if (!isDragging || !finalPanInfo || !finalEvent)
|
||||
return;
|
||||
const { velocity } = finalPanInfo;
|
||||
this.startAnimation(velocity);
|
||||
const { onDragEnd } = this.getProps();
|
||||
if (onDragEnd) {
|
||||
frame.postRender(() => onDragEnd(finalEvent, finalPanInfo));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
cancel() {
|
||||
this.isDragging = false;
|
||||
const { projection, animationState } = this.visualElement;
|
||||
if (projection) {
|
||||
projection.isAnimationBlocked = false;
|
||||
}
|
||||
this.endPanSession();
|
||||
const { dragPropagation } = this.getProps();
|
||||
if (!dragPropagation && this.openDragLock) {
|
||||
this.openDragLock();
|
||||
this.openDragLock = null;
|
||||
}
|
||||
animationState && animationState.setActive("whileDrag", false);
|
||||
}
|
||||
/**
|
||||
* Clean up the pan session without modifying other drag state.
|
||||
* This is used during unmount to ensure event listeners are removed
|
||||
* without affecting projection animations or drag locks.
|
||||
* @internal
|
||||
*/
|
||||
endPanSession() {
|
||||
this.panSession && this.panSession.end();
|
||||
this.panSession = undefined;
|
||||
}
|
||||
updateAxis(axis, _point, offset) {
|
||||
const { drag } = this.getProps();
|
||||
// If we're not dragging this axis, do an early return.
|
||||
if (!offset || !shouldDrag(axis, drag, this.currentDirection))
|
||||
return;
|
||||
const axisValue = this.getAxisMotionValue(axis);
|
||||
let next = this.originPoint[axis] + offset[axis];
|
||||
// Apply constraints
|
||||
if (this.constraints && this.constraints[axis]) {
|
||||
next = applyConstraints(next, this.constraints[axis], this.elastic[axis]);
|
||||
}
|
||||
axisValue.set(next);
|
||||
}
|
||||
resolveConstraints() {
|
||||
const { dragConstraints, dragElastic } = this.getProps();
|
||||
const layout = this.visualElement.projection &&
|
||||
!this.visualElement.projection.layout
|
||||
? this.visualElement.projection.measure(false)
|
||||
: this.visualElement.projection?.layout;
|
||||
const prevConstraints = this.constraints;
|
||||
if (dragConstraints && isRefObject(dragConstraints)) {
|
||||
if (!this.constraints) {
|
||||
this.constraints = this.resolveRefConstraints();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (dragConstraints && layout) {
|
||||
this.constraints = calcRelativeConstraints(layout.layoutBox, dragConstraints);
|
||||
}
|
||||
else {
|
||||
this.constraints = false;
|
||||
}
|
||||
}
|
||||
this.elastic = resolveDragElastic(dragElastic);
|
||||
/**
|
||||
* If we're outputting to external MotionValues, we want to rebase the measured constraints
|
||||
* from viewport-relative to component-relative. This only applies to relative (non-ref)
|
||||
* constraints, as ref-based constraints from calcViewportConstraints are already in the
|
||||
* correct coordinate space for the motion value transform offset.
|
||||
*/
|
||||
if (prevConstraints !== this.constraints &&
|
||||
!isRefObject(dragConstraints) &&
|
||||
layout &&
|
||||
this.constraints &&
|
||||
!this.hasMutatedConstraints) {
|
||||
eachAxis((axis) => {
|
||||
if (this.constraints !== false &&
|
||||
this.getAxisMotionValue(axis)) {
|
||||
this.constraints[axis] = rebaseAxisConstraints(layout.layoutBox[axis], this.constraints[axis]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
resolveRefConstraints() {
|
||||
const { dragConstraints: constraints, onMeasureDragConstraints } = this.getProps();
|
||||
if (!constraints || !isRefObject(constraints))
|
||||
return false;
|
||||
const constraintsElement = constraints.current;
|
||||
invariant(constraintsElement !== null, "If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.", "drag-constraints-ref");
|
||||
const { projection } = this.visualElement;
|
||||
// TODO
|
||||
if (!projection || !projection.layout)
|
||||
return false;
|
||||
/**
|
||||
* Refresh the root scroll offset so the constraint's viewport box
|
||||
* translates to correct page coordinates. The scroll captured at
|
||||
* drag mount can be stale if the document was scrolled afterwards —
|
||||
* e.g. via the browser restoring scroll on refresh, or an ancestor
|
||||
* layout effect running after this element's mount (#2829).
|
||||
*
|
||||
* Clear the cached scroll first so `updateScroll` bypasses its
|
||||
* per-animationId cache and re-reads the live value.
|
||||
*/
|
||||
if (projection.root) {
|
||||
projection.root.scroll = undefined;
|
||||
projection.root.updateScroll();
|
||||
}
|
||||
const constraintsBox = measurePageBox(constraintsElement, projection.root, this.visualElement.getTransformPagePoint());
|
||||
let measuredConstraints = calcViewportConstraints(projection.layout.layoutBox, constraintsBox);
|
||||
/**
|
||||
* If there's an onMeasureDragConstraints listener we call it and
|
||||
* if different constraints are returned, set constraints to that
|
||||
*/
|
||||
if (onMeasureDragConstraints) {
|
||||
const userConstraints = onMeasureDragConstraints(convertBoxToBoundingBox(measuredConstraints));
|
||||
this.hasMutatedConstraints = !!userConstraints;
|
||||
if (userConstraints) {
|
||||
measuredConstraints = convertBoundingBoxToBox(userConstraints);
|
||||
}
|
||||
}
|
||||
return measuredConstraints;
|
||||
}
|
||||
startAnimation(velocity) {
|
||||
const { drag, dragMomentum, dragElastic, dragTransition, dragSnapToOrigin, onDragTransitionEnd, } = this.getProps();
|
||||
const constraints = this.constraints || {};
|
||||
const momentumAnimations = eachAxis((axis) => {
|
||||
if (!shouldDrag(axis, drag, this.currentDirection)) {
|
||||
return;
|
||||
}
|
||||
let transition = (constraints && constraints[axis]) || {};
|
||||
if (dragSnapToOrigin === true ||
|
||||
dragSnapToOrigin === axis)
|
||||
transition = { min: 0, max: 0 };
|
||||
/**
|
||||
* Overdamp the boundary spring if `dragElastic` is disabled. There's still a frame
|
||||
* of spring animations so we should look into adding a disable spring option to `inertia`.
|
||||
* We could do something here where we affect the `bounceStiffness` and `bounceDamping`
|
||||
* using the value of `dragElastic`.
|
||||
*/
|
||||
const bounceStiffness = dragElastic ? 200 : 1000000;
|
||||
const bounceDamping = dragElastic ? 40 : 10000000;
|
||||
const inertia = {
|
||||
type: "inertia",
|
||||
velocity: dragMomentum ? velocity[axis] : 0,
|
||||
bounceStiffness,
|
||||
bounceDamping,
|
||||
timeConstant: 750,
|
||||
restDelta: 1,
|
||||
restSpeed: 10,
|
||||
...dragTransition,
|
||||
...transition,
|
||||
};
|
||||
// If we're not animating on an externally-provided `MotionValue` we can use the
|
||||
// component's animation controls which will handle interactions with whileHover (etc),
|
||||
// otherwise we just have to animate the `MotionValue` itself.
|
||||
return this.startAxisValueAnimation(axis, inertia);
|
||||
});
|
||||
// Run all animations and then resolve the new drag constraints.
|
||||
return Promise.all(momentumAnimations).then(onDragTransitionEnd);
|
||||
}
|
||||
startAxisValueAnimation(axis, transition) {
|
||||
const axisValue = this.getAxisMotionValue(axis);
|
||||
addValueToWillChange(this.visualElement, axis);
|
||||
return axisValue.start(animateMotionValue(axis, axisValue, 0, transition, this.visualElement, false));
|
||||
}
|
||||
stopAnimation() {
|
||||
eachAxis((axis) => this.getAxisMotionValue(axis).stop());
|
||||
}
|
||||
/**
|
||||
* Drag works differently depending on which props are provided.
|
||||
*
|
||||
* - If _dragX and _dragY are provided, we output the gesture delta directly to those motion values.
|
||||
* - Otherwise, we apply the delta to the x/y motion values.
|
||||
*/
|
||||
getAxisMotionValue(axis) {
|
||||
const dragKey = `_drag${axis.toUpperCase()}`;
|
||||
const props = this.visualElement.getProps();
|
||||
const externalMotionValue = props[dragKey];
|
||||
return externalMotionValue
|
||||
? externalMotionValue
|
||||
: this.visualElement.getValue(axis, this.visualElement.latestValues[axis] ?? 0);
|
||||
}
|
||||
snapToCursor(point) {
|
||||
eachAxis((axis) => {
|
||||
const { drag } = this.getProps();
|
||||
// If we're not dragging this axis, do an early return.
|
||||
if (!shouldDrag(axis, drag, this.currentDirection))
|
||||
return;
|
||||
const { projection } = this.visualElement;
|
||||
const axisValue = this.getAxisMotionValue(axis);
|
||||
if (projection && projection.layout) {
|
||||
const { min, max } = projection.layout.layoutBox[axis];
|
||||
/**
|
||||
* The layout measurement includes the current transform value,
|
||||
* so we need to add it back to get the correct snap position.
|
||||
* This fixes an issue where elements with initial coordinates
|
||||
* would snap to the wrong position on the first drag.
|
||||
*/
|
||||
const current = axisValue.get() || 0;
|
||||
axisValue.set(point[axis] - mixNumber(min, max, 0.5) + current);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* When the viewport resizes we want to check if the measured constraints
|
||||
* have changed and, if so, reposition the element within those new constraints
|
||||
* relative to where it was before the resize.
|
||||
*/
|
||||
scalePositionWithinConstraints() {
|
||||
if (!this.visualElement.current)
|
||||
return;
|
||||
const { drag, dragConstraints } = this.getProps();
|
||||
const { projection } = this.visualElement;
|
||||
if (!isRefObject(dragConstraints) || !projection || !this.constraints)
|
||||
return;
|
||||
/**
|
||||
* Stop current animations as there can be visual glitching if we try to do
|
||||
* this mid-animation
|
||||
*/
|
||||
this.stopAnimation();
|
||||
/**
|
||||
* Record the relative position of the dragged element relative to the
|
||||
* constraints box and save as a progress value.
|
||||
*/
|
||||
const boxProgress = { x: 0, y: 0 };
|
||||
eachAxis((axis) => {
|
||||
const axisValue = this.getAxisMotionValue(axis);
|
||||
if (axisValue && this.constraints !== false) {
|
||||
const latest = axisValue.get();
|
||||
boxProgress[axis] = calcOrigin({ min: latest, max: latest }, this.constraints[axis]);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Update the layout of this element and resolve the latest drag constraints
|
||||
*/
|
||||
const { transformTemplate } = this.visualElement.getProps();
|
||||
this.visualElement.current.style.transform = transformTemplate
|
||||
? transformTemplate({}, "")
|
||||
: "none";
|
||||
projection.root && projection.root.updateScroll();
|
||||
projection.updateLayout();
|
||||
/**
|
||||
* Reset constraints so resolveConstraints() will recalculate them
|
||||
* with the freshly measured layout rather than returning the cached value.
|
||||
*/
|
||||
this.constraints = false;
|
||||
this.resolveConstraints();
|
||||
/**
|
||||
* For each axis, calculate the current progress of the layout axis
|
||||
* within the new constraints.
|
||||
*/
|
||||
eachAxis((axis) => {
|
||||
if (!shouldDrag(axis, drag, null))
|
||||
return;
|
||||
/**
|
||||
* Calculate a new transform based on the previous box progress
|
||||
*/
|
||||
const axisValue = this.getAxisMotionValue(axis);
|
||||
const { min, max } = this.constraints[axis];
|
||||
axisValue.set(mixNumber(min, max, boxProgress[axis]));
|
||||
});
|
||||
/**
|
||||
* Flush the updated transform to the DOM synchronously to prevent
|
||||
* a visual flash at the element's CSS layout position (0,0) when
|
||||
* the transform was stripped for measurement.
|
||||
*/
|
||||
this.visualElement.render();
|
||||
}
|
||||
addListeners() {
|
||||
if (!this.visualElement.current)
|
||||
return;
|
||||
elementDragControls.set(this.visualElement, this);
|
||||
const element = this.visualElement.current;
|
||||
/**
|
||||
* Attach a pointerdown event listener on this DOM element to initiate drag tracking.
|
||||
*/
|
||||
const stopPointerListener = addPointerEvent(element, "pointerdown", (event) => {
|
||||
const { drag, dragListener = true } = this.getProps();
|
||||
const target = event.target;
|
||||
/**
|
||||
* Only block drag if clicking on a text input child element
|
||||
* (input, textarea, select, contenteditable) where users might
|
||||
* want to select text or interact with the control.
|
||||
*
|
||||
* Buttons and links don't block drag since they don't have
|
||||
* click-and-move actions of their own.
|
||||
*/
|
||||
const isClickingTextInputChild = target !== element && isElementTextInput(target);
|
||||
if (drag && dragListener && !isClickingTextInputChild) {
|
||||
this.start(event);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* If using ref-based constraints, observe both the draggable element
|
||||
* and the constraint container for size changes via ResizeObserver.
|
||||
* Setup is deferred because dragConstraints.current is null when
|
||||
* addListeners first runs (React hasn't committed the ref yet).
|
||||
*/
|
||||
let stopResizeObservers;
|
||||
const measureDragConstraints = () => {
|
||||
const { dragConstraints } = this.getProps();
|
||||
if (isRefObject(dragConstraints) && dragConstraints.current) {
|
||||
this.constraints = this.resolveRefConstraints();
|
||||
if (!stopResizeObservers) {
|
||||
stopResizeObservers = startResizeObservers(element, dragConstraints.current, () => this.scalePositionWithinConstraints());
|
||||
}
|
||||
}
|
||||
};
|
||||
const { projection } = this.visualElement;
|
||||
const stopMeasureLayoutListener = projection.addEventListener("measure", measureDragConstraints);
|
||||
if (projection && !projection.layout) {
|
||||
projection.root && projection.root.updateScroll();
|
||||
projection.updateLayout();
|
||||
}
|
||||
frame.read(measureDragConstraints);
|
||||
/**
|
||||
* Attach a window resize listener to scale the draggable target within its defined
|
||||
* constraints as the window resizes.
|
||||
*/
|
||||
const stopResizeListener = addDomEvent(window, "resize", () => this.scalePositionWithinConstraints());
|
||||
/**
|
||||
* If the element's layout changes, calculate the delta and apply that to
|
||||
* the drag gesture's origin point.
|
||||
*/
|
||||
const stopLayoutUpdateListener = projection.addEventListener("didUpdate", (({ delta, hasLayoutChanged }) => {
|
||||
if (this.isDragging && hasLayoutChanged) {
|
||||
eachAxis((axis) => {
|
||||
const motionValue = this.getAxisMotionValue(axis);
|
||||
if (!motionValue)
|
||||
return;
|
||||
this.originPoint[axis] += delta[axis].translate;
|
||||
motionValue.set(motionValue.get() + delta[axis].translate);
|
||||
});
|
||||
this.visualElement.render();
|
||||
}
|
||||
}));
|
||||
return () => {
|
||||
stopResizeListener();
|
||||
stopPointerListener();
|
||||
stopMeasureLayoutListener();
|
||||
stopLayoutUpdateListener && stopLayoutUpdateListener();
|
||||
stopResizeObservers && stopResizeObservers();
|
||||
};
|
||||
}
|
||||
getProps() {
|
||||
const props = this.visualElement.getProps();
|
||||
const { drag = false, dragDirectionLock = false, dragPropagation = false, dragConstraints = false, dragElastic = defaultElastic, dragMomentum = true, } = props;
|
||||
return {
|
||||
...props,
|
||||
drag,
|
||||
dragDirectionLock,
|
||||
dragPropagation,
|
||||
dragConstraints,
|
||||
dragElastic,
|
||||
dragMomentum,
|
||||
};
|
||||
}
|
||||
}
|
||||
function skipFirstCall(callback) {
|
||||
let isFirst = true;
|
||||
return () => {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
};
|
||||
}
|
||||
function startResizeObservers(element, constraintsElement, onResize) {
|
||||
const stopElement = resize(element, skipFirstCall(onResize));
|
||||
const stopContainer = resize(constraintsElement, skipFirstCall(onResize));
|
||||
return () => {
|
||||
stopElement();
|
||||
stopContainer();
|
||||
};
|
||||
}
|
||||
function shouldDrag(direction, drag, currentDirection) {
|
||||
return ((drag === true || drag === direction) &&
|
||||
(currentDirection === null || currentDirection === direction));
|
||||
}
|
||||
/**
|
||||
* Based on an x/y offset determine the current drag direction. If both axis' offsets are lower
|
||||
* than the provided threshold, return `null`.
|
||||
*
|
||||
* @param offset - The x/y offset from origin.
|
||||
* @param lockThreshold - (Optional) - the minimum absolute offset before we can determine a drag direction.
|
||||
*/
|
||||
function getCurrentDirection(offset, lockThreshold = 10) {
|
||||
let direction = null;
|
||||
if (Math.abs(offset.y) > lockThreshold) {
|
||||
direction = "y";
|
||||
}
|
||||
else if (Math.abs(offset.x) > lockThreshold) {
|
||||
direction = "x";
|
||||
}
|
||||
return direction;
|
||||
}
|
||||
|
||||
export { VisualElementDragControls, elementDragControls };
|
||||
//# sourceMappingURL=VisualElementDragControls.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+51
@@ -0,0 +1,51 @@
|
||||
import { Feature } from 'motion-dom';
|
||||
import { noop } from 'motion-utils';
|
||||
import { VisualElementDragControls } from './VisualElementDragControls.mjs';
|
||||
|
||||
class DragGesture extends Feature {
|
||||
constructor(node) {
|
||||
super(node);
|
||||
this.removeGroupControls = noop;
|
||||
this.removeListeners = noop;
|
||||
this.controls = new VisualElementDragControls(node);
|
||||
}
|
||||
mount() {
|
||||
// If we've been provided a DragControls for manual control over the drag gesture,
|
||||
// subscribe this component to it on mount.
|
||||
const { dragControls } = this.node.getProps();
|
||||
if (dragControls) {
|
||||
this.removeGroupControls = dragControls.subscribe(this.controls);
|
||||
}
|
||||
this.removeListeners = this.controls.addListeners() || noop;
|
||||
}
|
||||
update() {
|
||||
const { dragControls } = this.node.getProps();
|
||||
const { dragControls: prevDragControls } = this.node.prevProps || {};
|
||||
if (dragControls !== prevDragControls) {
|
||||
this.removeGroupControls();
|
||||
if (dragControls) {
|
||||
this.removeGroupControls = dragControls.subscribe(this.controls);
|
||||
}
|
||||
}
|
||||
}
|
||||
unmount() {
|
||||
this.removeGroupControls();
|
||||
this.removeListeners();
|
||||
/**
|
||||
* In React 19, during list reorder reconciliation, components may
|
||||
* briefly unmount and remount while the drag is still active. If we're
|
||||
* actively dragging, we should NOT end the pan session - it will
|
||||
* continue tracking pointer events via its window-level listeners.
|
||||
*
|
||||
* The pan session will be properly cleaned up when:
|
||||
* 1. The drag ends naturally (pointerup/pointercancel)
|
||||
* 2. The component is truly removed from the DOM
|
||||
*/
|
||||
if (!this.controls.isDragging) {
|
||||
this.controls.endPanSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { DragGesture };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../../../../src/gestures/drag/index.ts"],"sourcesContent":["import { Feature, type VisualElement } from \"motion-dom\"\nimport { noop } from \"motion-utils\"\nimport { VisualElementDragControls } from \"./VisualElementDragControls\"\n\nexport class DragGesture extends Feature<HTMLElement> {\n controls: VisualElementDragControls\n\n removeGroupControls: Function = noop\n removeListeners: Function = noop\n\n constructor(node: VisualElement<HTMLElement>) {\n super(node)\n this.controls = new VisualElementDragControls(node)\n }\n\n mount() {\n // If we've been provided a DragControls for manual control over the drag gesture,\n // subscribe this component to it on mount.\n const { dragControls } = this.node.getProps()\n\n if (dragControls) {\n this.removeGroupControls = dragControls.subscribe(this.controls)\n }\n\n this.removeListeners = this.controls.addListeners() || noop\n }\n\n update() {\n const { dragControls } = this.node.getProps()\n const { dragControls: prevDragControls } = this.node.prevProps || {}\n\n if (dragControls !== prevDragControls) {\n this.removeGroupControls()\n if (dragControls) {\n this.removeGroupControls = dragControls.subscribe(this.controls)\n }\n }\n }\n\n unmount() {\n this.removeGroupControls()\n this.removeListeners()\n /**\n * In React 19, during list reorder reconciliation, components may\n * briefly unmount and remount while the drag is still active. If we're\n * actively dragging, we should NOT end the pan session - it will\n * continue tracking pointer events via its window-level listeners.\n *\n * The pan session will be properly cleaned up when:\n * 1. The drag ends naturally (pointerup/pointercancel)\n * 2. The component is truly removed from the DOM\n */\n if (!this.controls.isDragging) {\n this.controls.endPanSession()\n }\n }\n}\n"],"names":[],"mappings":";;;;AAIM,MAAO,WAAY,SAAQ,OAAoB,CAAA;AAMjD,IAAA,WAAA,CAAY,IAAgC,EAAA;QACxC,KAAK,CAAC,IAAI,CAAC;QAJf,IAAA,CAAA,mBAAmB,GAAa,IAAI;QACpC,IAAA,CAAA,eAAe,GAAa,IAAI;QAI5B,IAAI,CAAC,QAAQ,GAAG,IAAI,yBAAyB,CAAC,IAAI,CAAC;IACvD;IAEA,KAAK,GAAA;;;QAGD,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;QAE7C,IAAI,YAAY,EAAE;YACd,IAAI,CAAC,mBAAmB,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;QACpE;QAEA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,IAAI;IAC/D;IAEA,MAAM,GAAA;QACF,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AAC7C,QAAA,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE;AAEpE,QAAA,IAAI,YAAY,KAAK,gBAAgB,EAAE;YACnC,IAAI,CAAC,mBAAmB,EAAE;YAC1B,IAAI,YAAY,EAAE;gBACd,IAAI,CAAC,mBAAmB,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;YACpE;QACJ;IACJ;IAEA,OAAO,GAAA;QACH,IAAI,CAAC,mBAAmB,EAAE;QAC1B,IAAI,CAAC,eAAe,EAAE;AACtB;;;;;;;;;AASG;AACH,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE;AAC3B,YAAA,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE;QACjC;IACJ;AACH;;;;"}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
|
||||
/**
|
||||
* Can manually trigger a drag gesture on one or more `drag`-enabled `motion` components.
|
||||
*
|
||||
* ```jsx
|
||||
* const dragControls = useDragControls()
|
||||
*
|
||||
* function startDrag(event) {
|
||||
* dragControls.start(event, { snapToCursor: true })
|
||||
* }
|
||||
*
|
||||
* return (
|
||||
* <>
|
||||
* <div onPointerDown={startDrag} />
|
||||
* <motion.div drag="x" dragControls={dragControls} />
|
||||
* </>
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
class DragControls {
|
||||
constructor() {
|
||||
this.componentControls = new Set();
|
||||
}
|
||||
/**
|
||||
* Subscribe a component's internal `VisualElementDragControls` to the user-facing API.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
subscribe(controls) {
|
||||
this.componentControls.add(controls);
|
||||
return () => this.componentControls.delete(controls);
|
||||
}
|
||||
/**
|
||||
* Start a drag gesture on every `motion` component that has this set of drag controls
|
||||
* passed into it via the `dragControls` prop.
|
||||
*
|
||||
* ```jsx
|
||||
* dragControls.start(e, {
|
||||
* snapToCursor: true
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param event - PointerEvent
|
||||
* @param options - Options
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
start(event, options) {
|
||||
this.componentControls.forEach((controls) => {
|
||||
controls.start(event.nativeEvent || event, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Cancels a drag gesture.
|
||||
*
|
||||
* ```jsx
|
||||
* dragControls.cancel()
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
cancel() {
|
||||
this.componentControls.forEach((controls) => {
|
||||
controls.cancel();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Stops a drag gesture.
|
||||
*
|
||||
* ```jsx
|
||||
* dragControls.stop()
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
stop() {
|
||||
this.componentControls.forEach((controls) => {
|
||||
controls.stop();
|
||||
});
|
||||
}
|
||||
}
|
||||
const createDragControls = () => new DragControls();
|
||||
/**
|
||||
* Usually, dragging is initiated by pressing down on a `motion` component with a `drag` prop
|
||||
* and moving it. For some use-cases, for instance clicking at an arbitrary point on a video scrubber, we
|
||||
* might want to initiate that dragging from a different component than the draggable one.
|
||||
*
|
||||
* By creating a `dragControls` using the `useDragControls` hook, we can pass this into
|
||||
* the draggable component's `dragControls` prop. It exposes a `start` method
|
||||
* that can start dragging from pointer events on other components.
|
||||
*
|
||||
* ```jsx
|
||||
* const dragControls = useDragControls()
|
||||
*
|
||||
* function startDrag(event) {
|
||||
* dragControls.start(event, { snapToCursor: true })
|
||||
* }
|
||||
*
|
||||
* return (
|
||||
* <>
|
||||
* <div onPointerDown={startDrag} />
|
||||
* <motion.div drag="x" dragControls={dragControls} />
|
||||
* </>
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function useDragControls() {
|
||||
return useConstant(createDragControls);
|
||||
}
|
||||
|
||||
export { DragControls, useDragControls };
|
||||
//# sourceMappingURL=use-drag-controls.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-drag-controls.mjs","sources":["../../../../src/gestures/drag/use-drag-controls.ts"],"sourcesContent":["import * as React from \"react\"\nimport { useConstant } from \"../../utils/use-constant\"\nimport {\n DragControlOptions,\n VisualElementDragControls,\n} from \"./VisualElementDragControls\"\n\n/**\n * Can manually trigger a drag gesture on one or more `drag`-enabled `motion` components.\n *\n * ```jsx\n * const dragControls = useDragControls()\n *\n * function startDrag(event) {\n * dragControls.start(event, { snapToCursor: true })\n * }\n *\n * return (\n * <>\n * <div onPointerDown={startDrag} />\n * <motion.div drag=\"x\" dragControls={dragControls} />\n * </>\n * )\n * ```\n *\n * @public\n */\nexport class DragControls {\n private componentControls = new Set<VisualElementDragControls>()\n\n /**\n * Subscribe a component's internal `VisualElementDragControls` to the user-facing API.\n *\n * @internal\n */\n subscribe(controls: VisualElementDragControls): () => void {\n this.componentControls.add(controls)\n\n return () => this.componentControls.delete(controls)\n }\n\n /**\n * Start a drag gesture on every `motion` component that has this set of drag controls\n * passed into it via the `dragControls` prop.\n *\n * ```jsx\n * dragControls.start(e, {\n * snapToCursor: true\n * })\n * ```\n *\n * @param event - PointerEvent\n * @param options - Options\n *\n * @public\n */\n start(\n event: React.PointerEvent | PointerEvent,\n options?: DragControlOptions\n ) {\n this.componentControls.forEach((controls) => {\n controls.start(\n (event as React.PointerEvent).nativeEvent || event,\n options\n )\n })\n }\n\n /**\n * Cancels a drag gesture.\n *\n * ```jsx\n * dragControls.cancel()\n * ```\n *\n * @public\n */\n cancel() {\n this.componentControls.forEach((controls) => {\n controls.cancel()\n })\n }\n\n /**\n * Stops a drag gesture.\n *\n * ```jsx\n * dragControls.stop()\n * ```\n *\n * @public\n */\n stop() {\n this.componentControls.forEach((controls) => {\n controls.stop()\n })\n }\n}\n\nconst createDragControls = () => new DragControls()\n\n/**\n * Usually, dragging is initiated by pressing down on a `motion` component with a `drag` prop\n * and moving it. For some use-cases, for instance clicking at an arbitrary point on a video scrubber, we\n * might want to initiate that dragging from a different component than the draggable one.\n *\n * By creating a `dragControls` using the `useDragControls` hook, we can pass this into\n * the draggable component's `dragControls` prop. It exposes a `start` method\n * that can start dragging from pointer events on other components.\n *\n * ```jsx\n * const dragControls = useDragControls()\n *\n * function startDrag(event) {\n * dragControls.start(event, { snapToCursor: true })\n * }\n *\n * return (\n * <>\n * <div onPointerDown={startDrag} />\n * <motion.div drag=\"x\" dragControls={dragControls} />\n * </>\n * )\n * ```\n *\n * @public\n */\nexport function useDragControls() {\n return useConstant(createDragControls)\n}\n"],"names":[],"mappings":";;AAOA;;;;;;;;;;;;;;;;;;;AAmBG;MACU,YAAY,CAAA;AAAzB,IAAA,WAAA,GAAA;AACY,QAAA,IAAA,CAAA,iBAAiB,GAAG,IAAI,GAAG,EAA6B;IAqEpE;AAnEI;;;;AAIG;AACH,IAAA,SAAS,CAAC,QAAmC,EAAA;AACzC,QAAA,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC;QAEpC,OAAO,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC;IACxD;AAEA;;;;;;;;;;;;;;AAcG;IACH,KAAK,CACD,KAAwC,EACxC,OAA4B,EAAA;QAE5B,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAI;YACxC,QAAQ,CAAC,KAAK,CACT,KAA4B,CAAC,WAAW,IAAI,KAAK,EAClD,OAAO,CACV;AACL,QAAA,CAAC,CAAC;IACN;AAEA;;;;;;;;AAQG;IACH,MAAM,GAAA;QACF,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAI;YACxC,QAAQ,CAAC,MAAM,EAAE;AACrB,QAAA,CAAC,CAAC;IACN;AAEA;;;;;;;;AAQG;IACH,IAAI,GAAA;QACA,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAI;YACxC,QAAQ,CAAC,IAAI,EAAE;AACnB,QAAA,CAAC,CAAC;IACN;AACH;AAED,MAAM,kBAAkB,GAAG,MAAM,IAAI,YAAY,EAAE;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;SACa,eAAe,GAAA;AAC3B,IAAA,OAAO,WAAW,CAAC,kBAAkB,CAAC;AAC1C;;;;"}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
import { mixNumber, calcLength } from 'motion-dom';
|
||||
import { progress, clamp } from 'motion-utils';
|
||||
|
||||
/**
|
||||
* Apply constraints to a point. These constraints are both physical along an
|
||||
* axis, and an elastic factor that determines how much to constrain the point
|
||||
* by if it does lie outside the defined parameters.
|
||||
*/
|
||||
function applyConstraints(point, { min, max }, elastic) {
|
||||
if (min !== undefined && point < min) {
|
||||
// If we have a min point defined, and this is outside of that, constrain
|
||||
point = elastic
|
||||
? mixNumber(min, point, elastic.min)
|
||||
: Math.max(point, min);
|
||||
}
|
||||
else if (max !== undefined && point > max) {
|
||||
// If we have a max point defined, and this is outside of that, constrain
|
||||
point = elastic
|
||||
? mixNumber(max, point, elastic.max)
|
||||
: Math.min(point, max);
|
||||
}
|
||||
return point;
|
||||
}
|
||||
/**
|
||||
* Calculate constraints in terms of the viewport when defined relatively to the
|
||||
* measured axis. This is measured from the nearest edge, so a max constraint of 200
|
||||
* on an axis with a max value of 300 would return a constraint of 500 - axis length
|
||||
*/
|
||||
function calcRelativeAxisConstraints(axis, min, max) {
|
||||
return {
|
||||
min: min !== undefined ? axis.min + min : undefined,
|
||||
max: max !== undefined
|
||||
? axis.max + max - (axis.max - axis.min)
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Calculate constraints in terms of the viewport when
|
||||
* defined relatively to the measured bounding box.
|
||||
*/
|
||||
function calcRelativeConstraints(layoutBox, { top, left, bottom, right }) {
|
||||
return {
|
||||
x: calcRelativeAxisConstraints(layoutBox.x, left, right),
|
||||
y: calcRelativeAxisConstraints(layoutBox.y, top, bottom),
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Calculate viewport constraints when defined as another viewport-relative axis
|
||||
*/
|
||||
function calcViewportAxisConstraints(layoutAxis, constraintsAxis) {
|
||||
let min = constraintsAxis.min - layoutAxis.min;
|
||||
let max = constraintsAxis.max - layoutAxis.max;
|
||||
// If the constraints axis is actually smaller than the layout axis then we can
|
||||
// flip the constraints
|
||||
if (constraintsAxis.max - constraintsAxis.min <
|
||||
layoutAxis.max - layoutAxis.min) {
|
||||
[min, max] = [max, min];
|
||||
}
|
||||
return { min, max };
|
||||
}
|
||||
/**
|
||||
* Calculate viewport constraints when defined as another viewport-relative box
|
||||
*/
|
||||
function calcViewportConstraints(layoutBox, constraintsBox) {
|
||||
return {
|
||||
x: calcViewportAxisConstraints(layoutBox.x, constraintsBox.x),
|
||||
y: calcViewportAxisConstraints(layoutBox.y, constraintsBox.y),
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Calculate a transform origin relative to the source axis, between 0-1, that results
|
||||
* in an asthetically pleasing scale/transform needed to project from source to target.
|
||||
*/
|
||||
function calcOrigin(source, target) {
|
||||
let origin = 0.5;
|
||||
const sourceLength = calcLength(source);
|
||||
const targetLength = calcLength(target);
|
||||
if (targetLength > sourceLength) {
|
||||
origin = progress(target.min, target.max - sourceLength, source.min);
|
||||
}
|
||||
else if (sourceLength > targetLength) {
|
||||
origin = progress(source.min, source.max - targetLength, target.min);
|
||||
}
|
||||
return clamp(0, 1, origin);
|
||||
}
|
||||
/**
|
||||
* Rebase the calculated viewport constraints relative to the layout.min point.
|
||||
*/
|
||||
function rebaseAxisConstraints(layout, constraints) {
|
||||
const relativeConstraints = {};
|
||||
if (constraints.min !== undefined) {
|
||||
relativeConstraints.min = constraints.min - layout.min;
|
||||
}
|
||||
if (constraints.max !== undefined) {
|
||||
relativeConstraints.max = constraints.max - layout.min;
|
||||
}
|
||||
return relativeConstraints;
|
||||
}
|
||||
const defaultElastic = 0.35;
|
||||
/**
|
||||
* Accepts a dragElastic prop and returns resolved elastic values for each axis.
|
||||
*/
|
||||
function resolveDragElastic(dragElastic = defaultElastic) {
|
||||
if (dragElastic === false) {
|
||||
dragElastic = 0;
|
||||
}
|
||||
else if (dragElastic === true) {
|
||||
dragElastic = defaultElastic;
|
||||
}
|
||||
return {
|
||||
x: resolveAxisElastic(dragElastic, "left", "right"),
|
||||
y: resolveAxisElastic(dragElastic, "top", "bottom"),
|
||||
};
|
||||
}
|
||||
function resolveAxisElastic(dragElastic, minLabel, maxLabel) {
|
||||
return {
|
||||
min: resolvePointElastic(dragElastic, minLabel),
|
||||
max: resolvePointElastic(dragElastic, maxLabel),
|
||||
};
|
||||
}
|
||||
function resolvePointElastic(dragElastic, label) {
|
||||
return typeof dragElastic === "number"
|
||||
? dragElastic
|
||||
: dragElastic[label] || 0;
|
||||
}
|
||||
|
||||
export { applyConstraints, calcOrigin, calcRelativeAxisConstraints, calcRelativeConstraints, calcViewportAxisConstraints, calcViewportConstraints, defaultElastic, rebaseAxisConstraints, resolveAxisElastic, resolveDragElastic, resolvePointElastic };
|
||||
//# sourceMappingURL=constraints.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+41
@@ -0,0 +1,41 @@
|
||||
import { Feature, addDomEvent } from 'motion-dom';
|
||||
import { pipe } from 'motion-utils';
|
||||
|
||||
class FocusGesture extends Feature {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.isActive = false;
|
||||
}
|
||||
onFocus() {
|
||||
let isFocusVisible = false;
|
||||
/**
|
||||
* If this element doesn't match focus-visible then don't
|
||||
* apply whileHover. But, if matches throws that focus-visible
|
||||
* is not a valid selector then in that browser outline styles will be applied
|
||||
* to the element by default and we want to match that behaviour with whileFocus.
|
||||
*/
|
||||
try {
|
||||
isFocusVisible = this.node.current.matches(":focus-visible");
|
||||
}
|
||||
catch (e) {
|
||||
isFocusVisible = true;
|
||||
}
|
||||
if (!isFocusVisible || !this.node.animationState)
|
||||
return;
|
||||
this.node.animationState.setActive("whileFocus", true);
|
||||
this.isActive = true;
|
||||
}
|
||||
onBlur() {
|
||||
if (!this.isActive || !this.node.animationState)
|
||||
return;
|
||||
this.node.animationState.setActive("whileFocus", false);
|
||||
this.isActive = false;
|
||||
}
|
||||
mount() {
|
||||
this.unmount = pipe(addDomEvent(this.node.current, "focus", () => this.onFocus()), addDomEvent(this.node.current, "blur", () => this.onBlur()));
|
||||
}
|
||||
unmount() { }
|
||||
}
|
||||
|
||||
export { FocusGesture };
|
||||
//# sourceMappingURL=focus.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"focus.mjs","sources":["../../../src/gestures/focus.ts"],"sourcesContent":["import { Feature, addDomEvent } from \"motion-dom\"\nimport { pipe } from \"motion-utils\"\n\nexport class FocusGesture extends Feature<Element> {\n private isActive = false\n\n onFocus() {\n let isFocusVisible = false\n\n /**\n * If this element doesn't match focus-visible then don't\n * apply whileHover. But, if matches throws that focus-visible\n * is not a valid selector then in that browser outline styles will be applied\n * to the element by default and we want to match that behaviour with whileFocus.\n */\n try {\n isFocusVisible = this.node.current!.matches(\":focus-visible\")\n } catch (e) {\n isFocusVisible = true\n }\n\n if (!isFocusVisible || !this.node.animationState) return\n\n this.node.animationState.setActive(\"whileFocus\", true)\n this.isActive = true\n }\n\n onBlur() {\n if (!this.isActive || !this.node.animationState) return\n this.node.animationState.setActive(\"whileFocus\", false)\n this.isActive = false\n }\n\n mount() {\n this.unmount = pipe(\n addDomEvent(this.node.current!, \"focus\", () => this.onFocus()),\n addDomEvent(this.node.current!, \"blur\", () => this.onBlur())\n ) as VoidFunction\n }\n\n unmount() {}\n}\n"],"names":[],"mappings":";;;AAGM,MAAO,YAAa,SAAQ,OAAgB,CAAA;AAAlD,IAAA,WAAA,GAAA;;QACY,IAAA,CAAA,QAAQ,GAAG,KAAK;IAqC5B;IAnCI,OAAO,GAAA;QACH,IAAI,cAAc,GAAG,KAAK;AAE1B;;;;;AAKG;AACH,QAAA,IAAI;YACA,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,OAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACjE;QAAE,OAAO,CAAC,EAAE;YACR,cAAc,GAAG,IAAI;QACzB;QAEA,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE;QAElD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC;AACtD,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;IACxB;IAEA,MAAM,GAAA;QACF,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE;QACjD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC;AACvD,QAAA,IAAI,CAAC,QAAQ,GAAG,KAAK;IACzB;IAEA,KAAK,GAAA;AACD,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CACf,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,OAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,EAC9D,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,OAAQ,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAC/C;IACrB;AAEA,IAAA,OAAO,KAAI;AACd;;;;"}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import { Feature, hover, frame } from 'motion-dom';
|
||||
import { extractEventInfo } from '../events/event-info.mjs';
|
||||
|
||||
function handleHoverEvent(node, event, lifecycle) {
|
||||
const { props } = node;
|
||||
if (node.animationState && props.whileHover) {
|
||||
node.animationState.setActive("whileHover", lifecycle === "Start");
|
||||
}
|
||||
const eventName = ("onHover" + lifecycle);
|
||||
const callback = props[eventName];
|
||||
if (callback) {
|
||||
frame.postRender(() => callback(event, extractEventInfo(event)));
|
||||
}
|
||||
}
|
||||
class HoverGesture extends Feature {
|
||||
mount() {
|
||||
const { current } = this.node;
|
||||
if (!current)
|
||||
return;
|
||||
this.unmount = hover(current, (_element, startEvent) => {
|
||||
handleHoverEvent(this.node, startEvent, "Start");
|
||||
return (endEvent) => handleHoverEvent(this.node, endEvent, "End");
|
||||
});
|
||||
}
|
||||
unmount() { }
|
||||
}
|
||||
|
||||
export { HoverGesture };
|
||||
//# sourceMappingURL=hover.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"hover.mjs","sources":["../../../src/gestures/hover.ts"],"sourcesContent":["import { Feature, frame, hover, type VisualElement } from \"motion-dom\"\nimport { extractEventInfo } from \"../events/event-info\"\n\nfunction handleHoverEvent(\n node: VisualElement<Element>,\n event: PointerEvent,\n lifecycle: \"Start\" | \"End\"\n) {\n const { props } = node\n\n if (node.animationState && props.whileHover) {\n node.animationState.setActive(\"whileHover\", lifecycle === \"Start\")\n }\n\n const eventName = (\"onHover\" + lifecycle) as \"onHoverStart\" | \"onHoverEnd\"\n const callback = props[eventName]\n if (callback) {\n frame.postRender(() => callback(event, extractEventInfo(event)))\n }\n}\n\nexport class HoverGesture extends Feature<Element> {\n mount() {\n const { current } = this.node\n if (!current) return\n\n this.unmount = hover(current, (_element, startEvent) => {\n handleHoverEvent(this.node, startEvent, \"Start\")\n\n return (endEvent) => handleHoverEvent(this.node, endEvent, \"End\")\n })\n }\n\n unmount() {}\n}\n"],"names":[],"mappings":";;;AAGA,SAAS,gBAAgB,CACrB,IAA4B,EAC5B,KAAmB,EACnB,SAA0B,EAAA;AAE1B,IAAA,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI;IAEtB,IAAI,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,UAAU,EAAE;QACzC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,EAAE,SAAS,KAAK,OAAO,CAAC;IACtE;AAEA,IAAA,MAAM,SAAS,IAAI,SAAS,GAAG,SAAS,CAAkC;AAC1E,IAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC;IACjC,IAAI,QAAQ,EAAE;AACV,QAAA,KAAK,CAAC,UAAU,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;IACpE;AACJ;AAEM,MAAO,YAAa,SAAQ,OAAgB,CAAA;IAC9C,KAAK,GAAA;AACD,QAAA,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI;AAC7B,QAAA,IAAI,CAAC,OAAO;YAAE;AAEd,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,UAAU,KAAI;YACnD,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC;AAEhD,YAAA,OAAO,CAAC,QAAQ,KAAK,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC;AACrE,QAAA,CAAC,CAAC;IACN;AAEA,IAAA,OAAO,KAAI;AACd;;;;"}
|
||||
+283
@@ -0,0 +1,283 @@
|
||||
import { frameData, frame, isPrimaryPointer, cancelFrame } from 'motion-dom';
|
||||
import { pipe, secondsToMilliseconds, millisecondsToSeconds } from 'motion-utils';
|
||||
import { addPointerEvent } from '../../events/add-pointer-event.mjs';
|
||||
import { extractEventInfo } from '../../events/event-info.mjs';
|
||||
import { distance2D } from '../../utils/distance.mjs';
|
||||
|
||||
const overflowStyles = /*#__PURE__*/ new Set(["auto", "scroll"]);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class PanSession {
|
||||
constructor(event, handlers, { transformPagePoint, contextWindow = window, dragSnapToOrigin = false, distanceThreshold = 3, element, } = {}) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.startEvent = null;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.lastMoveEvent = null;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.lastMoveEventInfo = null;
|
||||
/**
|
||||
* Raw (untransformed) event info, re-transformed each frame
|
||||
* so transformPagePoint sees the current parent matrix.
|
||||
* @internal
|
||||
*/
|
||||
this.lastRawMoveEventInfo = null;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.handlers = {};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.contextWindow = window;
|
||||
/**
|
||||
* Scroll positions of scrollable ancestors and window.
|
||||
* @internal
|
||||
*/
|
||||
this.scrollPositions = new Map();
|
||||
/**
|
||||
* Cleanup function for scroll listeners.
|
||||
* @internal
|
||||
*/
|
||||
this.removeScrollListeners = null;
|
||||
this.onElementScroll = (event) => {
|
||||
this.handleScroll(event.target);
|
||||
};
|
||||
this.onWindowScroll = () => {
|
||||
this.handleScroll(window);
|
||||
};
|
||||
this.updatePoint = () => {
|
||||
if (!(this.lastMoveEvent && this.lastMoveEventInfo))
|
||||
return;
|
||||
// Re-transform raw point through current transformPagePoint so
|
||||
// animated parent transforms (e.g. rotation) are picked up each frame
|
||||
if (this.lastRawMoveEventInfo) {
|
||||
this.lastMoveEventInfo = transformPoint(this.lastRawMoveEventInfo, this.transformPagePoint);
|
||||
}
|
||||
const info = getPanInfo(this.lastMoveEventInfo, this.history);
|
||||
const isPanStarted = this.startEvent !== null;
|
||||
// Only start panning if the offset is larger than 3 pixels. If we make it
|
||||
// any larger than this we'll want to reset the pointer history
|
||||
// on the first update to avoid visual snapping to the cursor.
|
||||
const isDistancePastThreshold = distance2D(info.offset, { x: 0, y: 0 }) >= this.distanceThreshold;
|
||||
if (!isPanStarted && !isDistancePastThreshold)
|
||||
return;
|
||||
const { point } = info;
|
||||
const { timestamp } = frameData;
|
||||
this.history.push({ ...point, timestamp });
|
||||
const { onStart, onMove } = this.handlers;
|
||||
if (!isPanStarted) {
|
||||
onStart && onStart(this.lastMoveEvent, info);
|
||||
this.startEvent = this.lastMoveEvent;
|
||||
}
|
||||
onMove && onMove(this.lastMoveEvent, info);
|
||||
};
|
||||
this.handlePointerMove = (event, info) => {
|
||||
this.lastMoveEvent = event;
|
||||
this.lastRawMoveEventInfo = info;
|
||||
this.lastMoveEventInfo = transformPoint(info, this.transformPagePoint);
|
||||
// Throttle mouse move event to once per frame
|
||||
frame.update(this.updatePoint, true);
|
||||
};
|
||||
this.handlePointerUp = (event, info) => {
|
||||
this.end();
|
||||
const { onEnd, onSessionEnd, resumeAnimation } = this.handlers;
|
||||
// Resume animation if dragSnapToOrigin is set OR if no drag started (user just clicked)
|
||||
// This ensures constraint animations continue when interrupted by a click
|
||||
if (this.dragSnapToOrigin || !this.startEvent) {
|
||||
resumeAnimation && resumeAnimation();
|
||||
}
|
||||
if (!(this.lastMoveEvent && this.lastMoveEventInfo))
|
||||
return;
|
||||
const panInfo = getPanInfo(event.type === "pointercancel"
|
||||
? this.lastMoveEventInfo
|
||||
: transformPoint(info, this.transformPagePoint), this.history);
|
||||
if (this.startEvent && onEnd) {
|
||||
onEnd(event, panInfo);
|
||||
}
|
||||
onSessionEnd && onSessionEnd(event, panInfo);
|
||||
};
|
||||
// If we have more than one touch, don't start detecting this gesture
|
||||
if (!isPrimaryPointer(event))
|
||||
return;
|
||||
this.dragSnapToOrigin = dragSnapToOrigin;
|
||||
this.handlers = handlers;
|
||||
this.transformPagePoint = transformPagePoint;
|
||||
this.distanceThreshold = distanceThreshold;
|
||||
this.contextWindow = contextWindow || window;
|
||||
const info = extractEventInfo(event);
|
||||
const initialInfo = transformPoint(info, this.transformPagePoint);
|
||||
const { point } = initialInfo;
|
||||
const { timestamp } = frameData;
|
||||
this.history = [{ ...point, timestamp }];
|
||||
const { onSessionStart } = handlers;
|
||||
onSessionStart &&
|
||||
onSessionStart(event, getPanInfo(initialInfo, this.history));
|
||||
// Listen in the capture phase so a descendant calling
|
||||
// stopPropagation() (e.g. in its own pointerup handler) can't
|
||||
// prevent the gesture from ending. See #2794.
|
||||
const eventOptions = { passive: true, capture: true };
|
||||
this.removeListeners = pipe(addPointerEvent(this.contextWindow, "pointermove", this.handlePointerMove, eventOptions), addPointerEvent(this.contextWindow, "pointerup", this.handlePointerUp, eventOptions), addPointerEvent(this.contextWindow, "pointercancel", this.handlePointerUp, eventOptions));
|
||||
// Start scroll tracking if element provided
|
||||
if (element) {
|
||||
this.startScrollTracking(element);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Start tracking scroll on ancestors and window.
|
||||
*/
|
||||
startScrollTracking(element) {
|
||||
// Store initial scroll positions for scrollable ancestors
|
||||
let current = element.parentElement;
|
||||
while (current) {
|
||||
const style = getComputedStyle(current);
|
||||
if (overflowStyles.has(style.overflowX) ||
|
||||
overflowStyles.has(style.overflowY)) {
|
||||
this.scrollPositions.set(current, {
|
||||
x: current.scrollLeft,
|
||||
y: current.scrollTop,
|
||||
});
|
||||
}
|
||||
current = current.parentElement;
|
||||
}
|
||||
// Track window scroll
|
||||
this.scrollPositions.set(window, {
|
||||
x: window.scrollX,
|
||||
y: window.scrollY,
|
||||
});
|
||||
// Capture listener catches element scroll events as they bubble
|
||||
window.addEventListener("scroll", this.onElementScroll, {
|
||||
capture: true,
|
||||
});
|
||||
// Direct window scroll listener (window scroll doesn't bubble)
|
||||
window.addEventListener("scroll", this.onWindowScroll);
|
||||
this.removeScrollListeners = () => {
|
||||
window.removeEventListener("scroll", this.onElementScroll, {
|
||||
capture: true,
|
||||
});
|
||||
window.removeEventListener("scroll", this.onWindowScroll);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Handle scroll compensation during drag.
|
||||
*
|
||||
* For element scroll: adjusts history origin since pageX/pageY doesn't change.
|
||||
* For window scroll: adjusts lastMoveEventInfo since pageX/pageY would change.
|
||||
*/
|
||||
handleScroll(target) {
|
||||
const initial = this.scrollPositions.get(target);
|
||||
if (!initial)
|
||||
return;
|
||||
const isWindow = target === window;
|
||||
const current = isWindow
|
||||
? { x: window.scrollX, y: window.scrollY }
|
||||
: {
|
||||
x: target.scrollLeft,
|
||||
y: target.scrollTop,
|
||||
};
|
||||
const delta = { x: current.x - initial.x, y: current.y - initial.y };
|
||||
if (delta.x === 0 && delta.y === 0)
|
||||
return;
|
||||
if (isWindow) {
|
||||
// Window scroll: pageX/pageY changes, so update lastMoveEventInfo
|
||||
if (this.lastMoveEventInfo) {
|
||||
this.lastMoveEventInfo.point.x += delta.x;
|
||||
this.lastMoveEventInfo.point.y += delta.y;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Element scroll: pageX/pageY unchanged, so adjust history origin
|
||||
if (this.history.length > 0) {
|
||||
this.history[0].x -= delta.x;
|
||||
this.history[0].y -= delta.y;
|
||||
}
|
||||
}
|
||||
this.scrollPositions.set(target, current);
|
||||
frame.update(this.updatePoint, true);
|
||||
}
|
||||
updateHandlers(handlers) {
|
||||
this.handlers = handlers;
|
||||
}
|
||||
end() {
|
||||
this.removeListeners && this.removeListeners();
|
||||
this.removeScrollListeners && this.removeScrollListeners();
|
||||
this.scrollPositions.clear();
|
||||
cancelFrame(this.updatePoint);
|
||||
}
|
||||
}
|
||||
function transformPoint(info, transformPagePoint) {
|
||||
return transformPagePoint ? { point: transformPagePoint(info.point) } : info;
|
||||
}
|
||||
function subtractPoint(a, b) {
|
||||
return { x: a.x - b.x, y: a.y - b.y };
|
||||
}
|
||||
function getPanInfo({ point }, history) {
|
||||
return {
|
||||
point,
|
||||
delta: subtractPoint(point, lastDevicePoint(history)),
|
||||
offset: subtractPoint(point, startDevicePoint(history)),
|
||||
velocity: getVelocity(history, 0.1),
|
||||
};
|
||||
}
|
||||
function startDevicePoint(history) {
|
||||
return history[0];
|
||||
}
|
||||
function lastDevicePoint(history) {
|
||||
return history[history.length - 1];
|
||||
}
|
||||
function getVelocity(history, timeDelta) {
|
||||
if (history.length < 2) {
|
||||
return { x: 0, y: 0 };
|
||||
}
|
||||
let i = history.length - 1;
|
||||
let timestampedPoint = null;
|
||||
const lastPoint = lastDevicePoint(history);
|
||||
while (i >= 0) {
|
||||
timestampedPoint = history[i];
|
||||
if (lastPoint.timestamp - timestampedPoint.timestamp >
|
||||
secondsToMilliseconds(timeDelta)) {
|
||||
break;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
if (!timestampedPoint) {
|
||||
return { x: 0, y: 0 };
|
||||
}
|
||||
/**
|
||||
* If the selected point is the pointer-down origin (history[0]),
|
||||
* there are better movement points available, and the time gap
|
||||
* is suspiciously large (>2x timeDelta), use the next point instead.
|
||||
* This prevents stale pointer-down points from diluting velocity
|
||||
* in hold-then-flick gestures.
|
||||
*/
|
||||
if (timestampedPoint === history[0] &&
|
||||
history.length > 2 &&
|
||||
lastPoint.timestamp - timestampedPoint.timestamp >
|
||||
secondsToMilliseconds(timeDelta) * 2) {
|
||||
timestampedPoint = history[1];
|
||||
}
|
||||
const time = millisecondsToSeconds(lastPoint.timestamp - timestampedPoint.timestamp);
|
||||
if (time === 0) {
|
||||
return { x: 0, y: 0 };
|
||||
}
|
||||
const currentVelocity = {
|
||||
x: (lastPoint.x - timestampedPoint.x) / time,
|
||||
y: (lastPoint.y - timestampedPoint.y) / time,
|
||||
};
|
||||
if (currentVelocity.x === Infinity) {
|
||||
currentVelocity.x = 0;
|
||||
}
|
||||
if (currentVelocity.y === Infinity) {
|
||||
currentVelocity.y = 0;
|
||||
}
|
||||
return currentVelocity;
|
||||
}
|
||||
|
||||
export { PanSession };
|
||||
//# sourceMappingURL=PanSession.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+50
@@ -0,0 +1,50 @@
|
||||
import { Feature, frame } from 'motion-dom';
|
||||
import { noop } from 'motion-utils';
|
||||
import { addPointerEvent } from '../../events/add-pointer-event.mjs';
|
||||
import { getContextWindow } from '../../utils/get-context-window.mjs';
|
||||
import { PanSession } from './PanSession.mjs';
|
||||
|
||||
const asyncHandler = (handler) => (event, info) => {
|
||||
if (handler) {
|
||||
frame.update(() => handler(event, info), false, true);
|
||||
}
|
||||
};
|
||||
class PanGesture extends Feature {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.removePointerDownListener = noop;
|
||||
}
|
||||
onPointerDown(pointerDownEvent) {
|
||||
this.session = new PanSession(pointerDownEvent, this.createPanHandlers(), {
|
||||
transformPagePoint: this.node.getTransformPagePoint(),
|
||||
contextWindow: getContextWindow(this.node),
|
||||
});
|
||||
}
|
||||
createPanHandlers() {
|
||||
const { onPanSessionStart, onPanStart, onPan, onPanEnd } = this.node.getProps();
|
||||
return {
|
||||
onSessionStart: asyncHandler(onPanSessionStart),
|
||||
onStart: asyncHandler(onPanStart),
|
||||
onMove: asyncHandler(onPan),
|
||||
onEnd: (event, info) => {
|
||||
delete this.session;
|
||||
if (onPanEnd) {
|
||||
frame.postRender(() => onPanEnd(event, info));
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
mount() {
|
||||
this.removePointerDownListener = addPointerEvent(this.node.current, "pointerdown", (event) => this.onPointerDown(event));
|
||||
}
|
||||
update() {
|
||||
this.session && this.session.updateHandlers(this.createPanHandlers());
|
||||
}
|
||||
unmount() {
|
||||
this.removePointerDownListener();
|
||||
this.session && this.session.end();
|
||||
}
|
||||
}
|
||||
|
||||
export { PanGesture };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../../../../src/gestures/pan/index.ts"],"sourcesContent":["import { Feature, frame, type PanInfo } from \"motion-dom\"\nimport { noop } from \"motion-utils\"\nimport { addPointerEvent } from \"../../events/add-pointer-event\"\nimport { getContextWindow } from \"../../utils/get-context-window\"\nimport { PanSession } from \"./PanSession\"\n\ntype PanEventHandler = (event: PointerEvent, info: PanInfo) => void\nconst asyncHandler =\n (handler?: PanEventHandler) => (event: PointerEvent, info: PanInfo) => {\n if (handler) {\n frame.update(() => handler(event, info), false, true)\n }\n }\n\nexport class PanGesture extends Feature<Element> {\n private session?: PanSession\n\n private removePointerDownListener: Function = noop\n\n onPointerDown(pointerDownEvent: PointerEvent) {\n this.session = new PanSession(\n pointerDownEvent,\n this.createPanHandlers(),\n {\n transformPagePoint: this.node.getTransformPagePoint(),\n contextWindow: getContextWindow(this.node),\n }\n )\n }\n\n createPanHandlers() {\n const { onPanSessionStart, onPanStart, onPan, onPanEnd } =\n this.node.getProps()\n\n return {\n onSessionStart: asyncHandler(onPanSessionStart),\n onStart: asyncHandler(onPanStart),\n onMove: asyncHandler(onPan),\n onEnd: (event: PointerEvent, info: PanInfo) => {\n delete this.session\n if (onPanEnd) {\n frame.postRender(() => onPanEnd(event, info))\n }\n },\n }\n }\n\n mount() {\n this.removePointerDownListener = addPointerEvent(\n this.node.current!,\n \"pointerdown\",\n (event: PointerEvent) => this.onPointerDown(event)\n )\n }\n\n update() {\n this.session && this.session.updateHandlers(this.createPanHandlers())\n }\n\n unmount() {\n this.removePointerDownListener()\n this.session && this.session.end()\n }\n}\n"],"names":[],"mappings":";;;;;;AAOA,MAAM,YAAY,GACd,CAAC,OAAyB,KAAK,CAAC,KAAmB,EAAE,IAAa,KAAI;IAClE,IAAI,OAAO,EAAE;AACT,QAAA,KAAK,CAAC,MAAM,CAAC,MAAM,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC;IACzD;AACJ,CAAC;AAEC,MAAO,UAAW,SAAQ,OAAgB,CAAA;AAAhD,IAAA,WAAA,GAAA;;QAGY,IAAA,CAAA,yBAAyB,GAAa,IAAI;IA8CtD;AA5CI,IAAA,aAAa,CAAC,gBAA8B,EAAA;AACxC,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CACzB,gBAAgB,EAChB,IAAI,CAAC,iBAAiB,EAAE,EACxB;AACI,YAAA,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE;AACrD,YAAA,aAAa,EAAE,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;AAC7C,SAAA,CACJ;IACL;IAEA,iBAAiB,GAAA;AACb,QAAA,MAAM,EAAE,iBAAiB,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,GACpD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;QAExB,OAAO;AACH,YAAA,cAAc,EAAE,YAAY,CAAC,iBAAiB,CAAC;AAC/C,YAAA,OAAO,EAAE,YAAY,CAAC,UAAU,CAAC;AACjC,YAAA,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC;AAC3B,YAAA,KAAK,EAAE,CAAC,KAAmB,EAAE,IAAa,KAAI;gBAC1C,OAAO,IAAI,CAAC,OAAO;gBACnB,IAAI,QAAQ,EAAE;AACV,oBAAA,KAAK,CAAC,UAAU,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBACjD;YACJ,CAAC;SACJ;IACL;IAEA,KAAK,GAAA;QACD,IAAI,CAAC,yBAAyB,GAAG,eAAe,CAC5C,IAAI,CAAC,IAAI,CAAC,OAAQ,EAClB,aAAa,EACb,CAAC,KAAmB,KAAK,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CACrD;IACL;IAEA,MAAM,GAAA;AACF,QAAA,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACzE;IAEA,OAAO,GAAA;QACH,IAAI,CAAC,yBAAyB,EAAE;QAChC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE;IACtC;AACH;;;;"}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import { Feature, press, frame } from 'motion-dom';
|
||||
import { extractEventInfo } from '../events/event-info.mjs';
|
||||
|
||||
function handlePressEvent(node, event, lifecycle) {
|
||||
const { props } = node;
|
||||
if (node.current instanceof HTMLButtonElement && node.current.disabled) {
|
||||
return;
|
||||
}
|
||||
if (node.animationState && props.whileTap) {
|
||||
node.animationState.setActive("whileTap", lifecycle === "Start");
|
||||
}
|
||||
const eventName = ("onTap" + (lifecycle === "End" ? "" : lifecycle));
|
||||
const callback = props[eventName];
|
||||
if (callback) {
|
||||
frame.postRender(() => callback(event, extractEventInfo(event)));
|
||||
}
|
||||
}
|
||||
class PressGesture extends Feature {
|
||||
mount() {
|
||||
const { current } = this.node;
|
||||
if (!current)
|
||||
return;
|
||||
const { globalTapTarget, propagate } = this.node.props;
|
||||
this.unmount = press(current, (_element, startEvent) => {
|
||||
handlePressEvent(this.node, startEvent, "Start");
|
||||
return (endEvent, { success }) => handlePressEvent(this.node, endEvent, success ? "End" : "Cancel");
|
||||
}, {
|
||||
useGlobalTarget: globalTapTarget,
|
||||
stopPropagation: propagate?.tap === false,
|
||||
});
|
||||
}
|
||||
unmount() { }
|
||||
}
|
||||
|
||||
export { PressGesture };
|
||||
//# sourceMappingURL=press.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"press.mjs","sources":["../../../src/gestures/press.ts"],"sourcesContent":["import { Feature, frame, press, type VisualElement } from \"motion-dom\"\nimport { extractEventInfo } from \"../events/event-info\"\n\nfunction handlePressEvent(\n node: VisualElement<Element>,\n event: PointerEvent,\n lifecycle: \"Start\" | \"End\" | \"Cancel\"\n) {\n const { props } = node\n\n if (node.current instanceof HTMLButtonElement && node.current.disabled) {\n return\n }\n\n if (node.animationState && props.whileTap) {\n node.animationState.setActive(\"whileTap\", lifecycle === \"Start\")\n }\n\n const eventName = (\"onTap\" + (lifecycle === \"End\" ? \"\" : lifecycle)) as\n | \"onTapStart\"\n | \"onTap\"\n | \"onTapCancel\"\n\n const callback = props[eventName]\n if (callback) {\n frame.postRender(() => callback(event, extractEventInfo(event)))\n }\n}\n\nexport class PressGesture extends Feature<Element> {\n mount() {\n const { current } = this.node\n if (!current) return\n\n const { globalTapTarget, propagate } = this.node.props\n\n this.unmount = press(\n current,\n (_element, startEvent) => {\n handlePressEvent(this.node, startEvent, \"Start\")\n\n return (endEvent, { success }) =>\n handlePressEvent(\n this.node,\n endEvent,\n success ? \"End\" : \"Cancel\"\n )\n },\n {\n useGlobalTarget: globalTapTarget,\n stopPropagation: propagate?.tap === false,\n }\n )\n }\n\n unmount() {}\n}\n"],"names":[],"mappings":";;;AAGA,SAAS,gBAAgB,CACrB,IAA4B,EAC5B,KAAmB,EACnB,SAAqC,EAAA;AAErC,IAAA,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI;AAEtB,IAAA,IAAI,IAAI,CAAC,OAAO,YAAY,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;QACpE;IACJ;IAEA,IAAI,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,QAAQ,EAAE;QACvC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,KAAK,OAAO,CAAC;IACpE;AAEA,IAAA,MAAM,SAAS,IAAI,OAAO,IAAI,SAAS,KAAK,KAAK,GAAG,EAAE,GAAG,SAAS,CAAC,CAGhD;AAEnB,IAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC;IACjC,IAAI,QAAQ,EAAE;AACV,QAAA,KAAK,CAAC,UAAU,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;IACpE;AACJ;AAEM,MAAO,YAAa,SAAQ,OAAgB,CAAA;IAC9C,KAAK,GAAA;AACD,QAAA,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI;AAC7B,QAAA,IAAI,CAAC,OAAO;YAAE;QAEd,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK;AAEtD,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK,CAChB,OAAO,EACP,CAAC,QAAQ,EAAE,UAAU,KAAI;YACrB,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC;YAEhD,OAAO,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,KACzB,gBAAgB,CACZ,IAAI,CAAC,IAAI,EACT,QAAQ,EACR,OAAO,GAAG,KAAK,GAAG,QAAQ,CAC7B;AACT,QAAA,CAAC,EACD;AACI,YAAA,eAAe,EAAE,eAAe;AAChC,YAAA,eAAe,EAAE,SAAS,EAAE,GAAG,KAAK,KAAK;AAC5C,SAAA,CACJ;IACL;AAEA,IAAA,OAAO,KAAI;AACd;;;;"}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
export { AnimatePresence } from './components/AnimatePresence/index.mjs';
|
||||
export { PopChild } from './components/AnimatePresence/PopChild.mjs';
|
||||
export { PresenceChild } from './components/AnimatePresence/PresenceChild.mjs';
|
||||
export { LayoutGroup } from './components/LayoutGroup/index.mjs';
|
||||
export { LazyMotion } from './components/LazyMotion/index.mjs';
|
||||
export { MotionConfig } from './components/MotionConfig/index.mjs';
|
||||
export { m } from './render/components/m/proxy.mjs';
|
||||
export { motion } from './render/components/motion/proxy.mjs';
|
||||
export { addPointerEvent } from './events/add-pointer-event.mjs';
|
||||
export { addPointerInfo } from './events/event-info.mjs';
|
||||
export { animations } from './motion/features/animations.mjs';
|
||||
export { makeUseVisualState } from './motion/utils/use-visual-state.mjs';
|
||||
export * from 'motion-dom';
|
||||
export { VisualElement, addScaleCorrector, animateVisualElement, arc, buildTransform, calcLength, createBox, delay, optimizedAppearDataAttribute, resolveMotionValue, visualElementStore } from 'motion-dom';
|
||||
export { filterProps } from './render/dom/utils/filter-props.mjs';
|
||||
export { isBrowser } from './utils/is-browser.mjs';
|
||||
export { useComposedRefs } from './utils/use-composed-ref.mjs';
|
||||
export { useForceUpdate } from './utils/use-force-update.mjs';
|
||||
export { useIsomorphicLayoutEffect } from './utils/use-isomorphic-effect.mjs';
|
||||
export { useUnmountEffect } from './utils/use-unmount-effect.mjs';
|
||||
export { domAnimation } from './render/dom/features-animation.mjs';
|
||||
export { domMax } from './render/dom/features-max.mjs';
|
||||
export { domMin } from './render/dom/features-min.mjs';
|
||||
export { useMotionValueEvent } from './utils/use-motion-value-event.mjs';
|
||||
export { useElementScroll } from './value/scroll/use-element-scroll.mjs';
|
||||
export { useViewportScroll } from './value/scroll/use-viewport-scroll.mjs';
|
||||
export { useMotionTemplate } from './value/use-motion-template.mjs';
|
||||
export { useMotionValue } from './value/use-motion-value.mjs';
|
||||
export { useScroll } from './value/use-scroll.mjs';
|
||||
export { useFollowValue } from './value/use-follow-value.mjs';
|
||||
export { useSpring } from './value/use-spring.mjs';
|
||||
export { useTime } from './value/use-time.mjs';
|
||||
export { useTransform } from './value/use-transform.mjs';
|
||||
export { useVelocity } from './value/use-velocity.mjs';
|
||||
export { useWillChange } from './value/use-will-change/index.mjs';
|
||||
export { WillChangeMotionValue } from './value/use-will-change/WillChangeMotionValue.mjs';
|
||||
export { useReducedMotion } from './utils/reduced-motion/use-reduced-motion.mjs';
|
||||
export { useReducedMotionConfig } from './utils/reduced-motion/use-reduced-motion-config.mjs';
|
||||
export * from 'motion-utils';
|
||||
export { MotionGlobalConfig } from 'motion-utils';
|
||||
export { animationControls } from './animation/hooks/animation-controls.mjs';
|
||||
export { useAnimate } from './animation/hooks/use-animate.mjs';
|
||||
export { useAnimateMini } from './animation/hooks/use-animate-style.mjs';
|
||||
export { useAnimation, useAnimationControls } from './animation/hooks/use-animation.mjs';
|
||||
export { useIsPresent, usePresence } from './components/AnimatePresence/use-presence.mjs';
|
||||
export { usePresenceData } from './components/AnimatePresence/use-presence-data.mjs';
|
||||
export { useDomEvent } from './events/use-dom-event.mjs';
|
||||
export { DragControls, useDragControls } from './gestures/drag/use-drag-controls.mjs';
|
||||
export { isMotionComponent } from './motion/utils/is-motion-component.mjs';
|
||||
export { unwrapMotionComponent } from './motion/utils/unwrap-motion-component.mjs';
|
||||
export { isValidMotionProp } from './motion/utils/valid-prop.mjs';
|
||||
export { useInstantLayoutTransition } from './projection/use-instant-layout-transition.mjs';
|
||||
export { useResetProjection } from './projection/use-reset-projection.mjs';
|
||||
export { useAnimationFrame } from './utils/use-animation-frame.mjs';
|
||||
export { useCycle } from './utils/use-cycle.mjs';
|
||||
export { useInView } from './utils/use-in-view.mjs';
|
||||
export { disableInstantTransitions, useInstantTransition } from './utils/use-instant-transition.mjs';
|
||||
export { usePageInView } from './utils/use-page-in-view.mjs';
|
||||
export { transformViewBoxPoint } from './utils/transform-viewbox-point.mjs';
|
||||
export { correctParentTransform } from './utils/transform-rotated-parent.mjs';
|
||||
export { startOptimizedAppearAnimation } from './animation/optimized-appear/start.mjs';
|
||||
export { LayoutGroupContext } from './context/LayoutGroupContext.mjs';
|
||||
export { MotionConfigContext } from './context/MotionConfigContext.mjs';
|
||||
export { MotionContext } from './context/MotionContext/index.mjs';
|
||||
export { PresenceContext } from './context/PresenceContext.mjs';
|
||||
export { SwitchLayoutGroupContext } from './context/SwitchLayoutGroupContext.mjs';
|
||||
export { useAnimatedState as useDeprecatedAnimatedState } from './animation/hooks/use-animated-state.mjs';
|
||||
export { AnimateSharedLayout } from './components/AnimateSharedLayout.mjs';
|
||||
export { DeprecatedLayoutGroupContext } from './context/DeprecatedLayoutGroupContext.mjs';
|
||||
export { useInvertedScale as useDeprecatedInvertedScale } from './value/use-inverted-scale.mjs';
|
||||
import * as namespace from './components/Reorder/namespace.mjs';
|
||||
export { namespace as Reorder };
|
||||
export { animate, createScopedAnimate } from './animation/animate/index.mjs';
|
||||
export { animateMini } from './animation/animators/waapi/animate-style.mjs';
|
||||
export { distance, distance2D } from './utils/distance.mjs';
|
||||
export { inView } from './render/dom/viewport/index.mjs';
|
||||
export { scroll } from './render/dom/scroll/index.mjs';
|
||||
export { scrollInfo } from './render/dom/scroll/track.mjs';
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
export { MotionA as a, MotionAbbr as abbr, MotionAddress as address, MotionAnimate as animate, MotionArea as area, MotionArticle as article, MotionAside as aside, MotionAudio as audio, MotionB as b, MotionBase as base, MotionBdi as bdi, MotionBdo as bdo, MotionBig as big, MotionBlockquote as blockquote, MotionBody as body, MotionButton as button, MotionCanvas as canvas, MotionCaption as caption, MotionCircle as circle, MotionCite as cite, MotionClipPath as clipPath, MotionCode as code, MotionCol as col, MotionColgroup as colgroup, MotionData as data, MotionDatalist as datalist, MotionDd as dd, MotionDefs as defs, MotionDel as del, MotionDesc as desc, MotionDetails as details, MotionDfn as dfn, MotionDialog as dialog, MotionDiv as div, MotionDl as dl, MotionDt as dt, MotionEllipse as ellipse, MotionEm as em, MotionEmbed as embed, MotionFeBlend as feBlend, MotionFeColorMatrix as feColorMatrix, MotionFeComponentTransfer as feComponentTransfer, MotionFeComposite as feComposite, MotionFeConvolveMatrix as feConvolveMatrix, MotionFeDiffuseLighting as feDiffuseLighting, MotionFeDisplacementMap as feDisplacementMap, MotionFeDistantLight as feDistantLight, MotionFeDropShadow as feDropShadow, MotionFeFlood as feFlood, MotionFeFuncA as feFuncA, MotionFeFuncB as feFuncB, MotionFeFuncG as feFuncG, MotionFeFuncR as feFuncR, MotionFeGaussianBlur as feGaussianBlur, MotionFeImage as feImage, MotionFeMerge as feMerge, MotionFeMergeNode as feMergeNode, MotionFeMorphology as feMorphology, MotionFeOffset as feOffset, MotionFePointLight as fePointLight, MotionFeSpecularLighting as feSpecularLighting, MotionFeSpotLight as feSpotLight, MotionFeTile as feTile, MotionFeTurbulence as feTurbulence, MotionFieldset as fieldset, MotionFigcaption as figcaption, MotionFigure as figure, MotionFilter as filter, MotionFooter as footer, MotionForeignObject as foreignObject, MotionForm as form, MotionG as g, MotionH1 as h1, MotionH2 as h2, MotionH3 as h3, MotionH4 as h4, MotionH5 as h5, MotionH6 as h6, MotionHead as head, MotionHeader as header, MotionHgroup as hgroup, MotionHr as hr, MotionHtml as html, MotionI as i, MotionIframe as iframe, MotionImage as image, MotionImg as img, MotionInput as input, MotionIns as ins, MotionKbd as kbd, MotionKeygen as keygen, MotionLabel as label, MotionLegend as legend, MotionLi as li, MotionLine as line, MotionLinearGradient as linearGradient, MotionLink as link, MotionMain as main, MotionMap as map, MotionMark as mark, MotionMarker as marker, MotionMask as mask, MotionMenu as menu, MotionMenuitem as menuitem, MotionMetadata as metadata, MotionMeter as meter, MotionNav as nav, MotionObject as object, MotionOl as ol, MotionOptgroup as optgroup, MotionOption as option, MotionOutput as output, MotionP as p, MotionParam as param, MotionPath as path, MotionPattern as pattern, MotionPicture as picture, MotionPolygon as polygon, MotionPolyline as polyline, MotionPre as pre, MotionProgress as progress, MotionQ as q, MotionRadialGradient as radialGradient, MotionRect as rect, MotionRp as rp, MotionRt as rt, MotionRuby as ruby, MotionS as s, MotionSamp as samp, MotionScript as script, MotionSection as section, MotionSelect as select, MotionSmall as small, MotionSource as source, MotionSpan as span, MotionStop as stop, MotionStrong as strong, MotionStyle as style, MotionSub as sub, MotionSummary as summary, MotionSup as sup, MotionSvg as svg, MotionSymbol as symbol, MotionTable as table, MotionTbody as tbody, MotionTd as td, MotionText as text, MotionTextPath as textPath, MotionTextarea as textarea, MotionTfoot as tfoot, MotionTh as th, MotionThead as thead, MotionTime as time, MotionTitle as title, MotionTr as tr, MotionTrack as track, MotionTspan as tspan, MotionU as u, MotionUl as ul, MotionUse as use, MotionVideo as video, MotionView as view, MotionWbr as wbr, MotionWebview as webview } from './render/components/m/elements.mjs';
|
||||
export { createMinimalMotionComponent as create } from './render/components/m/create.mjs';
|
||||
//# sourceMappingURL=m.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"m.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export { useAnimateMini as useAnimate } from './animation/hooks/use-animate-style.mjs';
|
||||
//# sourceMappingURL=mini.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"mini.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { Feature, resolveVariant } from 'motion-dom';
|
||||
|
||||
let id = 0;
|
||||
class ExitAnimationFeature extends Feature {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.id = id++;
|
||||
this.isExitComplete = false;
|
||||
}
|
||||
update() {
|
||||
if (!this.node.presenceContext)
|
||||
return;
|
||||
const { isPresent, onExitComplete } = this.node.presenceContext;
|
||||
const { isPresent: prevIsPresent } = this.node.prevPresenceContext || {};
|
||||
if (!this.node.animationState || isPresent === prevIsPresent) {
|
||||
return;
|
||||
}
|
||||
if (isPresent && prevIsPresent === false) {
|
||||
/**
|
||||
* When re-entering, if the exit animation already completed
|
||||
* (element is at rest), reset to initial values so the enter
|
||||
* animation replays from the correct position.
|
||||
*/
|
||||
if (this.isExitComplete) {
|
||||
const { initial, custom } = this.node.getProps();
|
||||
if (typeof initial === "string" ||
|
||||
(typeof initial === "object" &&
|
||||
initial !== null &&
|
||||
!Array.isArray(initial))) {
|
||||
const resolved = resolveVariant(this.node, initial, custom);
|
||||
if (resolved) {
|
||||
const { transition, transitionEnd, ...target } = resolved;
|
||||
for (const key in target) {
|
||||
this.node
|
||||
.getValue(key)
|
||||
?.jump(target[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.node.animationState.reset();
|
||||
this.node.animationState.animateChanges();
|
||||
}
|
||||
else {
|
||||
this.node.animationState.setActive("exit", false);
|
||||
}
|
||||
this.isExitComplete = false;
|
||||
return;
|
||||
}
|
||||
const exitAnimation = this.node.animationState.setActive("exit", !isPresent);
|
||||
if (onExitComplete && !isPresent) {
|
||||
exitAnimation.then(() => {
|
||||
this.isExitComplete = true;
|
||||
onExitComplete(this.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
mount() {
|
||||
const { register, onExitComplete } = this.node.presenceContext || {};
|
||||
if (onExitComplete) {
|
||||
onExitComplete(this.id);
|
||||
}
|
||||
if (register) {
|
||||
this.unmount = register(this.id);
|
||||
}
|
||||
}
|
||||
unmount() { }
|
||||
}
|
||||
|
||||
export { ExitAnimationFeature };
|
||||
//# sourceMappingURL=exit.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"exit.mjs","sources":["../../../../../src/motion/features/animation/exit.ts"],"sourcesContent":["import { Feature, resolveVariant } from \"motion-dom\"\n\nlet id = 0\n\nexport class ExitAnimationFeature extends Feature<unknown> {\n private id: number = id++\n private isExitComplete = false\n\n update() {\n if (!this.node.presenceContext) return\n\n const { isPresent, onExitComplete } = this.node.presenceContext\n const { isPresent: prevIsPresent } = this.node.prevPresenceContext || {}\n\n if (!this.node.animationState || isPresent === prevIsPresent) {\n return\n }\n\n if (isPresent && prevIsPresent === false) {\n /**\n * When re-entering, if the exit animation already completed\n * (element is at rest), reset to initial values so the enter\n * animation replays from the correct position.\n */\n if (this.isExitComplete) {\n const { initial, custom } = this.node.getProps()\n\n if (\n typeof initial === \"string\" ||\n (typeof initial === \"object\" &&\n initial !== null &&\n !Array.isArray(initial))\n ) {\n const resolved = resolveVariant(\n this.node,\n initial,\n custom\n )\n if (resolved) {\n const { transition, transitionEnd, ...target } =\n resolved\n for (const key in target) {\n this.node\n .getValue(key)\n ?.jump(\n target[\n key as keyof typeof target\n ] as any\n )\n }\n }\n }\n\n this.node.animationState.reset()\n this.node.animationState.animateChanges()\n } else {\n this.node.animationState.setActive(\"exit\", false)\n }\n\n this.isExitComplete = false\n return\n }\n\n const exitAnimation = this.node.animationState.setActive(\n \"exit\",\n !isPresent\n )\n\n if (onExitComplete && !isPresent) {\n exitAnimation.then(() => {\n this.isExitComplete = true\n onExitComplete(this.id)\n })\n }\n }\n\n mount() {\n const { register, onExitComplete } = this.node.presenceContext || {}\n\n if (onExitComplete) {\n onExitComplete(this.id)\n }\n\n if (register) {\n this.unmount = register(this.id)\n }\n }\n\n unmount() {}\n}\n"],"names":[],"mappings":";;AAEA,IAAI,EAAE,GAAG,CAAC;AAEJ,MAAO,oBAAqB,SAAQ,OAAgB,CAAA;AAA1D,IAAA,WAAA,GAAA;;QACY,IAAA,CAAA,EAAE,GAAW,EAAE,EAAE;QACjB,IAAA,CAAA,cAAc,GAAG,KAAK;IAmFlC;IAjFI,MAAM,GAAA;AACF,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE;QAEhC,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe;AAC/D,QAAA,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,IAAI,EAAE;QAExE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,SAAS,KAAK,aAAa,EAAE;YAC1D;QACJ;AAEA,QAAA,IAAI,SAAS,IAAI,aAAa,KAAK,KAAK,EAAE;AACtC;;;;AAIG;AACH,YAAA,IAAI,IAAI,CAAC,cAAc,EAAE;AACrB,gBAAA,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAEhD,IACI,OAAO,OAAO,KAAK,QAAQ;qBAC1B,OAAO,OAAO,KAAK,QAAQ;AACxB,wBAAA,OAAO,KAAK,IAAI;wBAChB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAC9B;AACE,oBAAA,MAAM,QAAQ,GAAG,cAAc,CAC3B,IAAI,CAAC,IAAI,EACT,OAAO,EACP,MAAM,CACT;oBACD,IAAI,QAAQ,EAAE;wBACV,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,GAC1C,QAAQ;AACZ,wBAAA,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;AACtB,4BAAA,IAAI,CAAC;iCACA,QAAQ,CAAC,GAAG;AACb,kCAAE,IAAI,CACF,MAAM,CACF,GAA0B,CACtB,CACX;wBACT;oBACJ;gBACJ;AAEA,gBAAA,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;AAChC,gBAAA,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE;YAC7C;iBAAO;gBACH,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC;YACrD;AAEA,YAAA,IAAI,CAAC,cAAc,GAAG,KAAK;YAC3B;QACJ;AAEA,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CACpD,MAAM,EACN,CAAC,SAAS,CACb;AAED,QAAA,IAAI,cAAc,IAAI,CAAC,SAAS,EAAE;AAC9B,YAAA,aAAa,CAAC,IAAI,CAAC,MAAK;AACpB,gBAAA,IAAI,CAAC,cAAc,GAAG,IAAI;AAC1B,gBAAA,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;AAC3B,YAAA,CAAC,CAAC;QACN;IACJ;IAEA,KAAK,GAAA;AACD,QAAA,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,EAAE;QAEpE,IAAI,cAAc,EAAE;AAChB,YAAA,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B;QAEA,IAAI,QAAQ,EAAE;YACV,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC;IACJ;AAEA,IAAA,OAAO,KAAI;AACd;;;;"}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import { Feature, createAnimationState, isAnimationControls } from 'motion-dom';
|
||||
|
||||
class AnimationFeature extends Feature {
|
||||
/**
|
||||
* We dynamically generate the AnimationState manager as it contains a reference
|
||||
* to the underlying animation library. We only want to load that if we load this,
|
||||
* so people can optionally code split it out using the `m` component.
|
||||
*/
|
||||
constructor(node) {
|
||||
super(node);
|
||||
node.animationState || (node.animationState = createAnimationState(node));
|
||||
}
|
||||
updateAnimationControlsSubscription() {
|
||||
const { animate } = this.node.getProps();
|
||||
if (isAnimationControls(animate)) {
|
||||
this.unmountControls = animate.subscribe(this.node);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Subscribe any provided AnimationControls to the component's VisualElement
|
||||
*/
|
||||
mount() {
|
||||
this.updateAnimationControlsSubscription();
|
||||
}
|
||||
update() {
|
||||
const { animate } = this.node.getProps();
|
||||
const { animate: prevAnimate } = this.node.prevProps || {};
|
||||
if (animate !== prevAnimate) {
|
||||
this.updateAnimationControlsSubscription();
|
||||
}
|
||||
}
|
||||
unmount() {
|
||||
this.node.animationState.reset();
|
||||
this.unmountControls?.();
|
||||
}
|
||||
}
|
||||
|
||||
export { AnimationFeature };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.mjs","sources":["../../../../../src/motion/features/animation/index.ts"],"sourcesContent":["import {\n createAnimationState,\n Feature,\n isAnimationControls,\n type VisualElement,\n} from \"motion-dom\"\n\nexport class AnimationFeature extends Feature<unknown> {\n unmountControls?: () => void\n\n /**\n * We dynamically generate the AnimationState manager as it contains a reference\n * to the underlying animation library. We only want to load that if we load this,\n * so people can optionally code split it out using the `m` component.\n */\n constructor(node: VisualElement) {\n super(node)\n node.animationState ||= createAnimationState(node)\n }\n\n updateAnimationControlsSubscription() {\n const { animate } = this.node.getProps()\n if (isAnimationControls(animate)) {\n this.unmountControls = animate.subscribe(this.node)\n }\n }\n\n /**\n * Subscribe any provided AnimationControls to the component's VisualElement\n */\n mount() {\n this.updateAnimationControlsSubscription()\n }\n\n update() {\n const { animate } = this.node.getProps()\n const { animate: prevAnimate } = this.node.prevProps || {}\n if (animate !== prevAnimate) {\n this.updateAnimationControlsSubscription()\n }\n }\n\n unmount() {\n this.node.animationState!.reset()\n this.unmountControls?.()\n }\n}\n"],"names":[],"mappings":";;AAOM,MAAO,gBAAiB,SAAQ,OAAgB,CAAA;AAGlD;;;;AAIG;AACH,IAAA,WAAA,CAAY,IAAmB,EAAA;QAC3B,KAAK,CAAC,IAAI,CAAC;QACX,IAAI,CAAC,cAAc,KAAnB,IAAI,CAAC,cAAc,GAAK,oBAAoB,CAAC,IAAI,CAAC,CAAA;IACtD;IAEA,mCAAmC,GAAA;QAC/B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AACxC,QAAA,IAAI,mBAAmB,CAAC,OAAO,CAAC,EAAE;YAC9B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QACvD;IACJ;AAEA;;AAEG;IACH,KAAK,GAAA;QACD,IAAI,CAAC,mCAAmC,EAAE;IAC9C;IAEA,MAAM,GAAA;QACF,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AACxC,QAAA,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE;AAC1D,QAAA,IAAI,OAAO,KAAK,WAAW,EAAE;YACzB,IAAI,CAAC,mCAAmC,EAAE;QAC9C;IACJ;IAEA,OAAO,GAAA;AACH,QAAA,IAAI,CAAC,IAAI,CAAC,cAAe,CAAC,KAAK,EAAE;AACjC,QAAA,IAAI,CAAC,eAAe,IAAI;IAC5B;AACH;;;;"}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { AnimationFeature } from './animation/index.mjs';
|
||||
import { ExitAnimationFeature } from './animation/exit.mjs';
|
||||
|
||||
const animations = {
|
||||
animation: {
|
||||
Feature: AnimationFeature,
|
||||
},
|
||||
exit: {
|
||||
Feature: ExitAnimationFeature,
|
||||
},
|
||||
};
|
||||
|
||||
export { animations };
|
||||
//# sourceMappingURL=animations.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"animations.mjs","sources":["../../../../src/motion/features/animations.ts"],"sourcesContent":["import { AnimationFeature } from \"./animation\"\nimport { ExitAnimationFeature } from \"./animation/exit\"\nimport { FeaturePackages } from \"./types\"\n\nexport const animations: FeaturePackages = {\n animation: {\n Feature: AnimationFeature,\n },\n exit: {\n Feature: ExitAnimationFeature,\n },\n}\n"],"names":[],"mappings":";;;AAIO,MAAM,UAAU,GAAoB;AACvC,IAAA,SAAS,EAAE;AACP,QAAA,OAAO,EAAE,gBAAgB;AAC5B,KAAA;AACD,IAAA,IAAI,EAAE;AACF,QAAA,OAAO,EAAE,oBAAoB;AAChC,KAAA;;;;;"}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import { getFeatureDefinitions, setFeatureDefinitions } from 'motion-dom';
|
||||
|
||||
const featureProps = {
|
||||
animation: [
|
||||
"animate",
|
||||
"variants",
|
||||
"whileHover",
|
||||
"whileTap",
|
||||
"exit",
|
||||
"whileInView",
|
||||
"whileFocus",
|
||||
"whileDrag",
|
||||
],
|
||||
exit: ["exit"],
|
||||
drag: ["drag", "dragControls"],
|
||||
focus: ["whileFocus"],
|
||||
hover: ["whileHover", "onHoverStart", "onHoverEnd"],
|
||||
tap: ["whileTap", "onTap", "onTapStart", "onTapCancel"],
|
||||
pan: ["onPan", "onPanStart", "onPanSessionStart", "onPanEnd"],
|
||||
inView: ["whileInView", "onViewportEnter", "onViewportLeave"],
|
||||
layout: ["layout", "layoutId"],
|
||||
};
|
||||
let isInitialized = false;
|
||||
/**
|
||||
* Initialize feature definitions with isEnabled checks.
|
||||
* This must be called before any motion components are rendered.
|
||||
*/
|
||||
function initFeatureDefinitions() {
|
||||
if (isInitialized)
|
||||
return;
|
||||
const initialFeatureDefinitions = {};
|
||||
for (const key in featureProps) {
|
||||
initialFeatureDefinitions[key] = {
|
||||
isEnabled: (props) => featureProps[key].some((name) => !!props[name]),
|
||||
};
|
||||
}
|
||||
setFeatureDefinitions(initialFeatureDefinitions);
|
||||
isInitialized = true;
|
||||
}
|
||||
/**
|
||||
* Get the current feature definitions, initializing if needed.
|
||||
*/
|
||||
function getInitializedFeatureDefinitions() {
|
||||
initFeatureDefinitions();
|
||||
return getFeatureDefinitions();
|
||||
}
|
||||
|
||||
export { getInitializedFeatureDefinitions, initFeatureDefinitions };
|
||||
//# sourceMappingURL=definitions.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"definitions.mjs","sources":["../../../../src/motion/features/definitions.ts"],"sourcesContent":["import { getFeatureDefinitions, setFeatureDefinitions } from \"motion-dom\"\nimport { MotionProps } from \"../types\"\nimport { FeatureDefinitions } from \"./types\"\n\nconst featureProps = {\n animation: [\n \"animate\",\n \"variants\",\n \"whileHover\",\n \"whileTap\",\n \"exit\",\n \"whileInView\",\n \"whileFocus\",\n \"whileDrag\",\n ],\n exit: [\"exit\"],\n drag: [\"drag\", \"dragControls\"],\n focus: [\"whileFocus\"],\n hover: [\"whileHover\", \"onHoverStart\", \"onHoverEnd\"],\n tap: [\"whileTap\", \"onTap\", \"onTapStart\", \"onTapCancel\"],\n pan: [\"onPan\", \"onPanStart\", \"onPanSessionStart\", \"onPanEnd\"],\n inView: [\"whileInView\", \"onViewportEnter\", \"onViewportLeave\"],\n layout: [\"layout\", \"layoutId\"],\n}\n\nlet isInitialized = false\n\n/**\n * Initialize feature definitions with isEnabled checks.\n * This must be called before any motion components are rendered.\n */\nexport function initFeatureDefinitions() {\n if (isInitialized) return\n\n const initialFeatureDefinitions: Partial<FeatureDefinitions> = {}\n\n for (const key in featureProps) {\n initialFeatureDefinitions[\n key as keyof typeof initialFeatureDefinitions\n ] = {\n isEnabled: (props: MotionProps) =>\n featureProps[key as keyof typeof featureProps].some(\n (name: string) => !!props[name as keyof typeof props]\n ),\n }\n }\n\n setFeatureDefinitions(initialFeatureDefinitions)\n isInitialized = true\n}\n\n/**\n * Get the current feature definitions, initializing if needed.\n */\nexport function getInitializedFeatureDefinitions(): Partial<FeatureDefinitions> {\n initFeatureDefinitions()\n return getFeatureDefinitions()\n}\n"],"names":[],"mappings":";;AAIA,MAAM,YAAY,GAAG;AACjB,IAAA,SAAS,EAAE;QACP,SAAS;QACT,UAAU;QACV,YAAY;QACZ,UAAU;QACV,MAAM;QACN,aAAa;QACb,YAAY;QACZ,WAAW;AACd,KAAA;IACD,IAAI,EAAE,CAAC,MAAM,CAAC;AACd,IAAA,IAAI,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC;IAC9B,KAAK,EAAE,CAAC,YAAY,CAAC;AACrB,IAAA,KAAK,EAAE,CAAC,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC;IACnD,GAAG,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,aAAa,CAAC;IACvD,GAAG,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,UAAU,CAAC;AAC7D,IAAA,MAAM,EAAE,CAAC,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;AAC7D,IAAA,MAAM,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC;CACjC;AAED,IAAI,aAAa,GAAG,KAAK;AAEzB;;;AAGG;SACa,sBAAsB,GAAA;AAClC,IAAA,IAAI,aAAa;QAAE;IAEnB,MAAM,yBAAyB,GAAgC,EAAE;AAEjE,IAAA,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE;QAC5B,yBAAyB,CACrB,GAA6C,CAChD,GAAG;YACA,SAAS,EAAE,CAAC,KAAkB,KAC1B,YAAY,CAAC,GAAgC,CAAC,CAAC,IAAI,CAC/C,CAAC,IAAY,KAAK,CAAC,CAAC,KAAK,CAAC,IAA0B,CAAC,CACxD;SACR;IACL;IAEA,qBAAqB,CAAC,yBAAyB,CAAC;IAChD,aAAa,GAAG,IAAI;AACxB;AAEA;;AAEG;SACa,gCAAgC,GAAA;AAC5C,IAAA,sBAAsB,EAAE;IACxB,OAAO,qBAAqB,EAAE;AAClC;;;;"}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { DragGesture } from '../../gestures/drag/index.mjs';
|
||||
import { PanGesture } from '../../gestures/pan/index.mjs';
|
||||
import { MeasureLayout } from './layout/MeasureLayout.mjs';
|
||||
import { HTMLProjectionNode } from 'motion-dom';
|
||||
|
||||
const drag = {
|
||||
pan: {
|
||||
Feature: PanGesture,
|
||||
},
|
||||
drag: {
|
||||
Feature: DragGesture,
|
||||
ProjectionNode: HTMLProjectionNode,
|
||||
MeasureLayout,
|
||||
},
|
||||
};
|
||||
|
||||
export { drag };
|
||||
//# sourceMappingURL=drag.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"drag.mjs","sources":["../../../../src/motion/features/drag.ts"],"sourcesContent":["import { DragGesture } from \"../../gestures/drag\"\nimport { PanGesture } from \"../../gestures/pan\"\nimport { HTMLProjectionNode } from \"../../projection\"\nimport { MeasureLayout } from \"./layout/MeasureLayout\"\nimport { FeaturePackages } from \"./types\"\n\nexport const drag: FeaturePackages = {\n pan: {\n Feature: PanGesture,\n },\n drag: {\n Feature: DragGesture,\n ProjectionNode: HTMLProjectionNode,\n MeasureLayout,\n },\n}\n"],"names":[],"mappings":";;;;;AAMO,MAAM,IAAI,GAAoB;AACjC,IAAA,GAAG,EAAE;AACD,QAAA,OAAO,EAAE,UAAU;AACtB,KAAA;AACD,IAAA,IAAI,EAAE;AACF,QAAA,OAAO,EAAE,WAAW;AACpB,QAAA,cAAc,EAAE,kBAAkB;QAClC,aAAa;AAChB,KAAA;;;;;"}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { HoverGesture } from '../../gestures/hover.mjs';
|
||||
import { FocusGesture } from '../../gestures/focus.mjs';
|
||||
import { PressGesture } from '../../gestures/press.mjs';
|
||||
import { InViewFeature } from './viewport/index.mjs';
|
||||
|
||||
const gestureAnimations = {
|
||||
inView: {
|
||||
Feature: InViewFeature,
|
||||
},
|
||||
tap: {
|
||||
Feature: PressGesture,
|
||||
},
|
||||
focus: {
|
||||
Feature: FocusGesture,
|
||||
},
|
||||
hover: {
|
||||
Feature: HoverGesture,
|
||||
},
|
||||
};
|
||||
|
||||
export { gestureAnimations };
|
||||
//# sourceMappingURL=gestures.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"gestures.mjs","sources":["../../../../src/motion/features/gestures.ts"],"sourcesContent":["import { HoverGesture } from \"../../gestures/hover\"\nimport { FocusGesture } from \"../../gestures/focus\"\nimport { PressGesture } from \"../../gestures/press\"\nimport { InViewFeature } from \"./viewport\"\nimport { FeaturePackages } from \"./types\"\n\nexport const gestureAnimations: FeaturePackages = {\n inView: {\n Feature: InViewFeature,\n },\n tap: {\n Feature: PressGesture,\n },\n focus: {\n Feature: FocusGesture,\n },\n hover: {\n Feature: HoverGesture,\n },\n}\n"],"names":[],"mappings":";;;;;AAMO,MAAM,iBAAiB,GAAoB;AAC9C,IAAA,MAAM,EAAE;AACJ,QAAA,OAAO,EAAE,aAAa;AACzB,KAAA;AACD,IAAA,GAAG,EAAE;AACD,QAAA,OAAO,EAAE,YAAY;AACxB,KAAA;AACD,IAAA,KAAK,EAAE;AACH,QAAA,OAAO,EAAE,YAAY;AACxB,KAAA;AACD,IAAA,KAAK,EAAE;AACH,QAAA,OAAO,EAAE,YAAY;AACxB,KAAA;;;;;"}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import { HTMLProjectionNode } from 'motion-dom';
|
||||
import { MeasureLayout } from './layout/MeasureLayout.mjs';
|
||||
|
||||
const layout = {
|
||||
layout: {
|
||||
ProjectionNode: HTMLProjectionNode,
|
||||
MeasureLayout,
|
||||
},
|
||||
};
|
||||
|
||||
export { layout };
|
||||
//# sourceMappingURL=layout.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"layout.mjs","sources":["../../../../src/motion/features/layout.ts"],"sourcesContent":["import { HTMLProjectionNode } from \"motion-dom\"\nimport { MeasureLayout } from \"./layout/MeasureLayout\"\nimport { FeaturePackages } from \"./types\"\n\nexport const layout: FeaturePackages = {\n layout: {\n ProjectionNode: HTMLProjectionNode,\n MeasureLayout,\n },\n}\n"],"names":[],"mappings":";;;AAIO,MAAM,MAAM,GAAoB;AACnC,IAAA,MAAM,EAAE;AACJ,QAAA,cAAc,EAAE,kBAAkB;QAClC,aAAa;AAChB,KAAA;;;;;"}
|
||||
Generated
Vendored
+136
@@ -0,0 +1,136 @@
|
||||
"use client";
|
||||
import { jsx } from 'react/jsx-runtime';
|
||||
import { globalProjectionState, frame, microtask } from 'motion-dom';
|
||||
import { useContext, Component } from 'react';
|
||||
import { usePresence } from '../../../components/AnimatePresence/use-presence.mjs';
|
||||
import { LayoutGroupContext } from '../../../context/LayoutGroupContext.mjs';
|
||||
import { SwitchLayoutGroupContext } from '../../../context/SwitchLayoutGroupContext.mjs';
|
||||
|
||||
/**
|
||||
* Track whether we've taken any snapshots yet. If not,
|
||||
* we can safely skip notification of didUpdate.
|
||||
*
|
||||
* Difficult to capture in a test but to prevent flickering
|
||||
* we must set this to true either on update or unmount.
|
||||
* Running `next-env/layout-id` in Safari will show this behaviour if broken.
|
||||
*/
|
||||
let hasTakenAnySnapshot = false;
|
||||
class MeasureLayoutWithContext extends Component {
|
||||
/**
|
||||
* This only mounts projection nodes for components that
|
||||
* need measuring, we might want to do it for all components
|
||||
* in order to incorporate transforms
|
||||
*/
|
||||
componentDidMount() {
|
||||
const { visualElement, layoutGroup, switchLayoutGroup, layoutId } = this.props;
|
||||
const { projection } = visualElement;
|
||||
if (projection) {
|
||||
if (layoutGroup.group)
|
||||
layoutGroup.group.add(projection);
|
||||
if (switchLayoutGroup && switchLayoutGroup.register && layoutId) {
|
||||
switchLayoutGroup.register(projection);
|
||||
}
|
||||
if (hasTakenAnySnapshot) {
|
||||
projection.root.didUpdate();
|
||||
}
|
||||
projection.addEventListener("animationComplete", () => {
|
||||
this.safeToRemove();
|
||||
});
|
||||
projection.setOptions({
|
||||
...projection.options,
|
||||
layoutDependency: this.props.layoutDependency,
|
||||
onExitComplete: () => this.safeToRemove(),
|
||||
});
|
||||
}
|
||||
globalProjectionState.hasEverUpdated = true;
|
||||
}
|
||||
getSnapshotBeforeUpdate(prevProps) {
|
||||
const { layoutDependency, visualElement, drag, isPresent } = this.props;
|
||||
const { projection } = visualElement;
|
||||
if (!projection)
|
||||
return null;
|
||||
/**
|
||||
* TODO: We use this data in relegate to determine whether to
|
||||
* promote a previous element. There's no guarantee its presence data
|
||||
* will have updated by this point - if a bug like this arises it will
|
||||
* have to be that we markForRelegation and then find a new lead some other way,
|
||||
* perhaps in didUpdate
|
||||
*/
|
||||
projection.isPresent = isPresent;
|
||||
if (prevProps.layoutDependency !== layoutDependency) {
|
||||
projection.setOptions({
|
||||
...projection.options,
|
||||
layoutDependency,
|
||||
});
|
||||
}
|
||||
hasTakenAnySnapshot = true;
|
||||
if (drag ||
|
||||
prevProps.layoutDependency !== layoutDependency ||
|
||||
layoutDependency === undefined ||
|
||||
prevProps.isPresent !== isPresent) {
|
||||
projection.willUpdate();
|
||||
}
|
||||
else {
|
||||
this.safeToRemove();
|
||||
}
|
||||
if (prevProps.isPresent !== isPresent) {
|
||||
if (isPresent) {
|
||||
projection.promote();
|
||||
}
|
||||
else if (!projection.relegate()) {
|
||||
/**
|
||||
* If there's another stack member taking over from this one,
|
||||
* it's in charge of the exit animation and therefore should
|
||||
* be in charge of the safe to remove. Otherwise we call it here.
|
||||
*/
|
||||
frame.postRender(() => {
|
||||
const stack = projection.getStack();
|
||||
if (!stack || !stack.members.length) {
|
||||
this.safeToRemove();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
componentDidUpdate() {
|
||||
const { visualElement, layoutAnchor } = this.props;
|
||||
const { projection } = visualElement;
|
||||
if (projection) {
|
||||
projection.options.layoutAnchor = layoutAnchor;
|
||||
projection.root.didUpdate();
|
||||
microtask.postRender(() => {
|
||||
if (!projection.currentAnimation && projection.isLead()) {
|
||||
this.safeToRemove();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
componentWillUnmount() {
|
||||
const { visualElement, layoutGroup, switchLayoutGroup: promoteContext, } = this.props;
|
||||
const { projection } = visualElement;
|
||||
hasTakenAnySnapshot = true;
|
||||
if (projection) {
|
||||
projection.scheduleCheckAfterUnmount();
|
||||
if (layoutGroup && layoutGroup.group)
|
||||
layoutGroup.group.remove(projection);
|
||||
if (promoteContext && promoteContext.deregister)
|
||||
promoteContext.deregister(projection);
|
||||
}
|
||||
}
|
||||
safeToRemove() {
|
||||
const { safeToRemove } = this.props;
|
||||
safeToRemove && safeToRemove();
|
||||
}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function MeasureLayout(props) {
|
||||
const [isPresent, safeToRemove] = usePresence();
|
||||
const layoutGroup = useContext(LayoutGroupContext);
|
||||
return (jsx(MeasureLayoutWithContext, { ...props, layoutGroup: layoutGroup, switchLayoutGroup: useContext(SwitchLayoutGroupContext), isPresent: isPresent, safeToRemove: safeToRemove }));
|
||||
}
|
||||
|
||||
export { MeasureLayout };
|
||||
//# sourceMappingURL=MeasureLayout.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+16
@@ -0,0 +1,16 @@
|
||||
import { setFeatureDefinitions } from 'motion-dom';
|
||||
import { getInitializedFeatureDefinitions } from './definitions.mjs';
|
||||
|
||||
function loadFeatures(features) {
|
||||
const featureDefinitions = getInitializedFeatureDefinitions();
|
||||
for (const key in features) {
|
||||
featureDefinitions[key] = {
|
||||
...featureDefinitions[key],
|
||||
...features[key],
|
||||
};
|
||||
}
|
||||
setFeatureDefinitions(featureDefinitions);
|
||||
}
|
||||
|
||||
export { loadFeatures };
|
||||
//# sourceMappingURL=load-features.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"load-features.mjs","sources":["../../../../src/motion/features/load-features.ts"],"sourcesContent":["import { setFeatureDefinitions } from \"motion-dom\"\nimport { getInitializedFeatureDefinitions } from \"./definitions\"\nimport { FeaturePackages } from \"./types\"\n\nexport function loadFeatures(features: FeaturePackages) {\n const featureDefinitions = getInitializedFeatureDefinitions()\n\n for (const key in features) {\n featureDefinitions[key as keyof typeof featureDefinitions] = {\n ...featureDefinitions[key as keyof typeof featureDefinitions],\n ...features[key as keyof typeof features],\n } as any\n }\n\n setFeatureDefinitions(featureDefinitions)\n}\n"],"names":[],"mappings":";;;AAIM,SAAU,YAAY,CAAC,QAAyB,EAAA;AAClD,IAAA,MAAM,kBAAkB,GAAG,gCAAgC,EAAE;AAE7D,IAAA,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE;QACxB,kBAAkB,CAAC,GAAsC,CAAC,GAAG;YACzD,GAAG,kBAAkB,CAAC,GAAsC,CAAC;YAC7D,GAAG,QAAQ,CAAC,GAA4B,CAAC;SACrC;IACZ;IAEA,qBAAqB,CAAC,kBAAkB,CAAC;AAC7C;;;;"}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
import { Feature } from 'motion-dom';
|
||||
import { observeIntersection } from './observers.mjs';
|
||||
|
||||
const thresholdNames = {
|
||||
some: 0,
|
||||
all: 1,
|
||||
};
|
||||
class InViewFeature extends Feature {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.hasEnteredView = false;
|
||||
this.isInView = false;
|
||||
}
|
||||
startObserver() {
|
||||
this.stopObserver?.();
|
||||
const { viewport = {} } = this.node.getProps();
|
||||
const { root, margin: rootMargin, amount = "some", once } = viewport;
|
||||
const options = {
|
||||
root: root ? root.current : undefined,
|
||||
rootMargin,
|
||||
threshold: typeof amount === "number" ? amount : thresholdNames[amount],
|
||||
};
|
||||
const onIntersectionUpdate = (entry) => {
|
||||
const { isIntersecting } = entry;
|
||||
/**
|
||||
* If there's been no change in the viewport state, early return.
|
||||
*/
|
||||
if (this.isInView === isIntersecting)
|
||||
return;
|
||||
this.isInView = isIntersecting;
|
||||
/**
|
||||
* Handle hasEnteredView. If this is only meant to run once, and
|
||||
* element isn't visible, early return. Otherwise set hasEnteredView to true.
|
||||
*/
|
||||
if (once && !isIntersecting && this.hasEnteredView) {
|
||||
return;
|
||||
}
|
||||
else if (isIntersecting) {
|
||||
this.hasEnteredView = true;
|
||||
}
|
||||
if (this.node.animationState) {
|
||||
this.node.animationState.setActive("whileInView", isIntersecting);
|
||||
}
|
||||
/**
|
||||
* Use the latest committed props rather than the ones in scope
|
||||
* when this observer is created
|
||||
*/
|
||||
const { onViewportEnter, onViewportLeave } = this.node.getProps();
|
||||
const callback = isIntersecting ? onViewportEnter : onViewportLeave;
|
||||
callback && callback(entry);
|
||||
};
|
||||
this.stopObserver = observeIntersection(this.node.current, options, onIntersectionUpdate);
|
||||
}
|
||||
mount() {
|
||||
this.startObserver();
|
||||
}
|
||||
update() {
|
||||
if (typeof IntersectionObserver === "undefined")
|
||||
return;
|
||||
const { props, prevProps } = this.node;
|
||||
const hasOptionsChanged = ["amount", "margin", "root"].some(hasViewportOptionChanged(props, prevProps));
|
||||
if (hasOptionsChanged) {
|
||||
this.startObserver();
|
||||
}
|
||||
}
|
||||
unmount() {
|
||||
this.stopObserver?.();
|
||||
this.hasEnteredView = false;
|
||||
this.isInView = false;
|
||||
}
|
||||
}
|
||||
function hasViewportOptionChanged({ viewport = {} }, { viewport: prevViewport = {} } = {}) {
|
||||
return (name) => viewport[name] !== prevViewport[name];
|
||||
}
|
||||
|
||||
export { InViewFeature };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+50
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Map an IntersectionHandler callback to an element. We only ever make one handler for one
|
||||
* element, so even though these handlers might all be triggered by different
|
||||
* observers, we can keep them in the same map.
|
||||
*/
|
||||
const observerCallbacks = new WeakMap();
|
||||
/**
|
||||
* Multiple observers can be created for multiple element/document roots. Each with
|
||||
* different settings. So here we store dictionaries of observers to each root,
|
||||
* using serialised settings (threshold/margin) as lookup keys.
|
||||
*/
|
||||
const observers = new WeakMap();
|
||||
const fireObserverCallback = (entry) => {
|
||||
const callback = observerCallbacks.get(entry.target);
|
||||
callback && callback(entry);
|
||||
};
|
||||
const fireAllObserverCallbacks = (entries) => {
|
||||
entries.forEach(fireObserverCallback);
|
||||
};
|
||||
function initIntersectionObserver({ root, ...options }) {
|
||||
const lookupRoot = root || document;
|
||||
/**
|
||||
* If we don't have an observer lookup map for this root, create one.
|
||||
*/
|
||||
if (!observers.has(lookupRoot)) {
|
||||
observers.set(lookupRoot, {});
|
||||
}
|
||||
const rootObservers = observers.get(lookupRoot);
|
||||
const key = JSON.stringify(options);
|
||||
/**
|
||||
* If we don't have an observer for this combination of root and settings,
|
||||
* create one.
|
||||
*/
|
||||
if (!rootObservers[key]) {
|
||||
rootObservers[key] = new IntersectionObserver(fireAllObserverCallbacks, { root, ...options });
|
||||
}
|
||||
return rootObservers[key];
|
||||
}
|
||||
function observeIntersection(element, options, callback) {
|
||||
const rootInteresectionObserver = initIntersectionObserver(options);
|
||||
observerCallbacks.set(element, callback);
|
||||
rootInteresectionObserver.observe(element);
|
||||
return () => {
|
||||
observerCallbacks.delete(element);
|
||||
rootInteresectionObserver.unobserve(element);
|
||||
};
|
||||
}
|
||||
|
||||
export { observeIntersection };
|
||||
//# sourceMappingURL=observers.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"observers.mjs","sources":["../../../../../src/motion/features/viewport/observers.ts"],"sourcesContent":["type IntersectionHandler = (entry: IntersectionObserverEntry) => void\n\ninterface ElementIntersectionObservers {\n [key: string]: IntersectionObserver\n}\n\n/**\n * Map an IntersectionHandler callback to an element. We only ever make one handler for one\n * element, so even though these handlers might all be triggered by different\n * observers, we can keep them in the same map.\n */\nconst observerCallbacks = new WeakMap<Element, IntersectionHandler>()\n\n/**\n * Multiple observers can be created for multiple element/document roots. Each with\n * different settings. So here we store dictionaries of observers to each root,\n * using serialised settings (threshold/margin) as lookup keys.\n */\nconst observers = new WeakMap<\n Element | Document,\n ElementIntersectionObservers\n>()\n\nconst fireObserverCallback = (entry: IntersectionObserverEntry) => {\n const callback = observerCallbacks.get(entry.target)\n callback && callback(entry)\n}\n\nconst fireAllObserverCallbacks: IntersectionObserverCallback = (entries) => {\n entries.forEach(fireObserverCallback)\n}\n\nfunction initIntersectionObserver({\n root,\n ...options\n}: IntersectionObserverInit): IntersectionObserver {\n const lookupRoot = root || document\n\n /**\n * If we don't have an observer lookup map for this root, create one.\n */\n if (!observers.has(lookupRoot)) {\n observers.set(lookupRoot, {})\n }\n const rootObservers = observers.get(lookupRoot)!\n\n const key = JSON.stringify(options)\n\n /**\n * If we don't have an observer for this combination of root and settings,\n * create one.\n */\n if (!rootObservers[key]) {\n rootObservers[key] = new IntersectionObserver(\n fireAllObserverCallbacks,\n { root, ...options }\n )\n }\n\n return rootObservers[key]\n}\n\nexport function observeIntersection(\n element: Element,\n options: IntersectionObserverInit,\n callback: IntersectionHandler\n) {\n const rootInteresectionObserver = initIntersectionObserver(options)\n\n observerCallbacks.set(element, callback)\n rootInteresectionObserver.observe(element)\n\n return () => {\n observerCallbacks.delete(element)\n rootInteresectionObserver.unobserve(element)\n }\n}\n"],"names":[],"mappings":"AAMA;;;;AAIG;AACH,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAAgC;AAErE;;;;AAIG;AACH,MAAM,SAAS,GAAG,IAAI,OAAO,EAG1B;AAEH,MAAM,oBAAoB,GAAG,CAAC,KAAgC,KAAI;IAC9D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;AACpD,IAAA,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC;AAC/B,CAAC;AAED,MAAM,wBAAwB,GAAiC,CAAC,OAAO,KAAI;AACvE,IAAA,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC;AACzC,CAAC;AAED,SAAS,wBAAwB,CAAC,EAC9B,IAAI,EACJ,GAAG,OAAO,EACa,EAAA;AACvB,IAAA,MAAM,UAAU,GAAG,IAAI,IAAI,QAAQ;AAEnC;;AAEG;IACH,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;AAC5B,QAAA,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC;IACjC;IACA,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,UAAU,CAAE;IAEhD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;AAEnC;;;AAGG;AACH,IAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;AACrB,QAAA,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI,oBAAoB,CACzC,wBAAwB,EACxB,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CACvB;IACL;AAEA,IAAA,OAAO,aAAa,CAAC,GAAG,CAAC;AAC7B;SAEgB,mBAAmB,CAC/B,OAAgB,EAChB,OAAiC,EACjC,QAA6B,EAAA;AAE7B,IAAA,MAAM,yBAAyB,GAAG,wBAAwB,CAAC,OAAO,CAAC;AAEnE,IAAA,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC;AACxC,IAAA,yBAAyB,CAAC,OAAO,CAAC,OAAO,CAAC;AAE1C,IAAA,OAAO,MAAK;AACR,QAAA,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC;AACjC,QAAA,yBAAyB,CAAC,SAAS,CAAC,OAAO,CAAC;AAChD,IAAA,CAAC;AACL;;;;"}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
"use client";
|
||||
import { jsxs, jsx } from 'react/jsx-runtime';
|
||||
import { warning, invariant } from 'motion-utils';
|
||||
import { forwardRef, useContext } from 'react';
|
||||
import { LayoutGroupContext } from '../context/LayoutGroupContext.mjs';
|
||||
import { LazyContext } from '../context/LazyContext.mjs';
|
||||
import { MotionConfigContext } from '../context/MotionConfigContext.mjs';
|
||||
import { MotionContext } from '../context/MotionContext/index.mjs';
|
||||
import { useCreateMotionContext } from '../context/MotionContext/create.mjs';
|
||||
import { useRender } from '../render/dom/use-render.mjs';
|
||||
import { isSVGComponent } from '../render/dom/utils/is-svg-component.mjs';
|
||||
import { useHTMLVisualState } from '../render/html/use-html-visual-state.mjs';
|
||||
import { useSVGVisualState } from '../render/svg/use-svg-visual-state.mjs';
|
||||
import { getInitializedFeatureDefinitions } from './features/definitions.mjs';
|
||||
import { loadFeatures } from './features/load-features.mjs';
|
||||
import { motionComponentSymbol } from './utils/symbol.mjs';
|
||||
import { useMotionRef } from './utils/use-motion-ref.mjs';
|
||||
import { useVisualElement } from './utils/use-visual-element.mjs';
|
||||
|
||||
/**
|
||||
* Create a `motion` component.
|
||||
*
|
||||
* This function accepts a Component argument, which can be either a string (ie "div"
|
||||
* for `motion.div`), or an actual React component.
|
||||
*
|
||||
* Alongside this is a config option which provides a way of rendering the provided
|
||||
* component "offline", or outside the React render cycle.
|
||||
*/
|
||||
function createMotionComponent(Component, { forwardMotionProps = false, type } = {}, preloadedFeatures, createVisualElement) {
|
||||
preloadedFeatures && loadFeatures(preloadedFeatures);
|
||||
/**
|
||||
* Determine whether to use SVG or HTML rendering based on:
|
||||
* 1. Explicit `type` option (highest priority)
|
||||
* 2. Auto-detection via `isSVGComponent`
|
||||
*/
|
||||
const isSVG = type ? type === "svg" : isSVGComponent(Component);
|
||||
const useVisualState = isSVG ? useSVGVisualState : useHTMLVisualState;
|
||||
function MotionDOMComponent(props, externalRef) {
|
||||
/**
|
||||
* If we need to measure the element we load this functionality in a
|
||||
* separate class component in order to gain access to getSnapshotBeforeUpdate.
|
||||
*/
|
||||
let MeasureLayout;
|
||||
const configAndProps = {
|
||||
...useContext(MotionConfigContext),
|
||||
...props,
|
||||
layoutId: useLayoutId(props),
|
||||
};
|
||||
const { isStatic } = configAndProps;
|
||||
const context = useCreateMotionContext(props);
|
||||
const visualState = useVisualState(props, isStatic);
|
||||
if (!isStatic && typeof window !== "undefined") {
|
||||
useStrictMode(configAndProps, preloadedFeatures);
|
||||
const layoutProjection = getProjectionFunctionality(configAndProps);
|
||||
MeasureLayout = layoutProjection.MeasureLayout;
|
||||
/**
|
||||
* Create a VisualElement for this component. A VisualElement provides a common
|
||||
* interface to renderer-specific APIs (ie DOM/Three.js etc) as well as
|
||||
* providing a way of rendering to these APIs outside of the React render loop
|
||||
* for more performant animations and interactions
|
||||
*/
|
||||
context.visualElement = useVisualElement(Component, visualState, configAndProps, createVisualElement, layoutProjection.ProjectionNode, isSVG);
|
||||
}
|
||||
/**
|
||||
* The mount order and hierarchy is specific to ensure our element ref
|
||||
* is hydrated by the time features fire their effects.
|
||||
*/
|
||||
return (jsxs(MotionContext.Provider, { value: context, children: [MeasureLayout && context.visualElement ? (jsx(MeasureLayout, { visualElement: context.visualElement, ...configAndProps })) : null, useRender(Component, props, useMotionRef(visualState, context.visualElement, externalRef), visualState, isStatic, forwardMotionProps, isSVG)] }));
|
||||
}
|
||||
MotionDOMComponent.displayName = `motion.${typeof Component === "string"
|
||||
? Component
|
||||
: `create(${Component.displayName ?? Component.name ?? ""})`}`;
|
||||
const ForwardRefMotionComponent = forwardRef(MotionDOMComponent);
|
||||
ForwardRefMotionComponent[motionComponentSymbol] = Component;
|
||||
return ForwardRefMotionComponent;
|
||||
}
|
||||
function useLayoutId({ layoutId }) {
|
||||
const layoutGroupId = useContext(LayoutGroupContext).id;
|
||||
return layoutGroupId && layoutId !== undefined
|
||||
? layoutGroupId + "-" + layoutId
|
||||
: layoutId;
|
||||
}
|
||||
function useStrictMode(configAndProps, preloadedFeatures) {
|
||||
const isStrict = useContext(LazyContext).strict;
|
||||
/**
|
||||
* If we're in development mode, check to make sure we're not rendering a motion component
|
||||
* as a child of LazyMotion, as this will break the file-size benefits of using it.
|
||||
*/
|
||||
if (process.env.NODE_ENV !== "production" &&
|
||||
preloadedFeatures &&
|
||||
isStrict) {
|
||||
const strictMessage = "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.";
|
||||
configAndProps.ignoreStrict
|
||||
? warning(false, strictMessage, "lazy-strict-mode")
|
||||
: invariant(false, strictMessage, "lazy-strict-mode");
|
||||
}
|
||||
}
|
||||
function getProjectionFunctionality(props) {
|
||||
const featureDefinitions = getInitializedFeatureDefinitions();
|
||||
const { drag, layout } = featureDefinitions;
|
||||
if (!drag && !layout)
|
||||
return {};
|
||||
const combined = { ...drag, ...layout };
|
||||
return {
|
||||
MeasureLayout: drag?.isEnabled(props) || layout?.isEnabled(props)
|
||||
? combined.MeasureLayout
|
||||
: undefined,
|
||||
ProjectionNode: combined.ProjectionNode,
|
||||
};
|
||||
}
|
||||
|
||||
export { createMotionComponent };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+13
@@ -0,0 +1,13 @@
|
||||
import { motionComponentSymbol } from './symbol.mjs';
|
||||
|
||||
/**
|
||||
* Checks if a component is a `motion` component.
|
||||
*/
|
||||
function isMotionComponent(component) {
|
||||
return (component !== null &&
|
||||
typeof component === "object" &&
|
||||
motionComponentSymbol in component);
|
||||
}
|
||||
|
||||
export { isMotionComponent };
|
||||
//# sourceMappingURL=is-motion-component.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"is-motion-component.mjs","sources":["../../../../src/motion/utils/is-motion-component.ts"],"sourcesContent":["import { motionComponentSymbol } from \"./symbol\"\n\n/**\n * Checks if a component is a `motion` component.\n */\nexport function isMotionComponent(component: React.ComponentType | string) {\n return (\n component !== null &&\n typeof component === \"object\" &&\n motionComponentSymbol in component\n )\n}\n"],"names":[],"mappings":";;AAEA;;AAEG;AACG,SAAU,iBAAiB,CAAC,SAAuC,EAAA;IACrE,QACI,SAAS,KAAK,IAAI;QAClB,OAAO,SAAS,KAAK,QAAQ;QAC7B,qBAAqB,IAAI,SAAS;AAE1C;;;;"}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
const motionComponentSymbol = Symbol.for("motionComponentSymbol");
|
||||
|
||||
export { motionComponentSymbol };
|
||||
//# sourceMappingURL=symbol.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"symbol.mjs","sources":["../../../../src/motion/utils/symbol.ts"],"sourcesContent":["export const motionComponentSymbol = Symbol.for(\"motionComponentSymbol\")\n"],"names":[],"mappings":"AAAO,MAAM,qBAAqB,GAAG,MAAM,CAAC,GAAG,CAAC,uBAAuB;;;;"}
|
||||
Generated
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
import { isMotionComponent } from './is-motion-component.mjs';
|
||||
import { motionComponentSymbol } from './symbol.mjs';
|
||||
|
||||
/**
|
||||
* Unwraps a `motion` component and returns either a string for `motion.div` or
|
||||
* the React component for `motion(Component)`.
|
||||
*
|
||||
* If the component is not a `motion` component it returns undefined.
|
||||
*/
|
||||
function unwrapMotionComponent(component) {
|
||||
if (isMotionComponent(component)) {
|
||||
return component[motionComponentSymbol];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export { unwrapMotionComponent };
|
||||
//# sourceMappingURL=unwrap-motion-component.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"unwrap-motion-component.mjs","sources":["../../../../src/motion/utils/unwrap-motion-component.ts"],"sourcesContent":["import { isMotionComponent } from \"./is-motion-component\"\nimport { motionComponentSymbol } from \"./symbol\"\n\n/**\n * Unwraps a `motion` component and returns either a string for `motion.div` or\n * the React component for `motion(Component)`.\n *\n * If the component is not a `motion` component it returns undefined.\n */\nexport function unwrapMotionComponent(\n component: React.ComponentType | string\n): React.ComponentType | string | undefined {\n if (isMotionComponent(component)) {\n return component[motionComponentSymbol as keyof typeof component]\n }\n\n return undefined\n}\n"],"names":[],"mappings":";;;AAGA;;;;;AAKG;AACG,SAAU,qBAAqB,CACjC,SAAuC,EAAA;AAEvC,IAAA,IAAI,iBAAiB,CAAC,SAAS,CAAC,EAAE;AAC9B,QAAA,OAAO,SAAS,CAAC,qBAA+C,CAAC;IACrE;AAEA,IAAA,OAAO,SAAS;AACpB;;;;"}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
"use client";
|
||||
import { useRef, useInsertionEffect, useCallback } from 'react';
|
||||
|
||||
/**
|
||||
* Creates a ref function that, when called, hydrates the provided
|
||||
* external ref and VisualElement.
|
||||
*/
|
||||
function useMotionRef(visualState, visualElement, externalRef) {
|
||||
/**
|
||||
* Store externalRef in a ref to avoid including it in the useCallback
|
||||
* dependency array. Including externalRef in dependencies causes issues
|
||||
* with libraries like Radix UI that create new callback refs on each render
|
||||
* when using asChild - this would cause the callback to be recreated,
|
||||
* triggering element remounts and breaking AnimatePresence exit animations.
|
||||
*/
|
||||
const externalRefContainer = useRef(externalRef);
|
||||
useInsertionEffect(() => {
|
||||
externalRefContainer.current = externalRef;
|
||||
});
|
||||
// Store cleanup function returned by callback refs (React 19 feature)
|
||||
const refCleanup = useRef(null);
|
||||
return useCallback((instance) => {
|
||||
if (instance) {
|
||||
visualState.onMount?.(instance);
|
||||
}
|
||||
if (visualElement) {
|
||||
instance ? visualElement.mount(instance) : visualElement.unmount();
|
||||
}
|
||||
const ref = externalRefContainer.current;
|
||||
if (typeof ref === "function") {
|
||||
if (instance) {
|
||||
const cleanup = ref(instance);
|
||||
if (typeof cleanup === "function") {
|
||||
refCleanup.current = cleanup;
|
||||
}
|
||||
}
|
||||
else if (refCleanup.current) {
|
||||
refCleanup.current();
|
||||
refCleanup.current = null;
|
||||
}
|
||||
else {
|
||||
ref(instance);
|
||||
}
|
||||
}
|
||||
else if (ref) {
|
||||
ref.current = instance;
|
||||
}
|
||||
}, [visualElement]);
|
||||
}
|
||||
|
||||
export { useMotionRef };
|
||||
//# sourceMappingURL=use-motion-ref.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-motion-ref.mjs","sources":["../../../../src/motion/utils/use-motion-ref.ts"],"sourcesContent":["\"use client\"\n\nimport type { VisualElement } from \"motion-dom\"\nimport * as React from \"react\"\nimport { useCallback, useInsertionEffect, useRef } from \"react\"\nimport { VisualState } from \"./use-visual-state\"\n\n/**\n * Creates a ref function that, when called, hydrates the provided\n * external ref and VisualElement.\n */\nexport function useMotionRef<Instance, RenderState>(\n visualState: VisualState<Instance, RenderState>,\n visualElement?: VisualElement<Instance> | null,\n externalRef?: React.Ref<Instance>\n): React.Ref<Instance> {\n /**\n * Store externalRef in a ref to avoid including it in the useCallback\n * dependency array. Including externalRef in dependencies causes issues\n * with libraries like Radix UI that create new callback refs on each render\n * when using asChild - this would cause the callback to be recreated,\n * triggering element remounts and breaking AnimatePresence exit animations.\n */\n const externalRefContainer = useRef(externalRef)\n useInsertionEffect(() => {\n externalRefContainer.current = externalRef\n })\n\n // Store cleanup function returned by callback refs (React 19 feature)\n const refCleanup = useRef<(() => void) | null>(null)\n\n return useCallback(\n (instance: Instance) => {\n if (instance) {\n visualState.onMount?.(instance)\n }\n\n if (visualElement) {\n instance ? visualElement.mount(instance) : visualElement.unmount()\n }\n\n const ref = externalRefContainer.current\n if (typeof ref === \"function\") {\n if (instance) {\n const cleanup = ref(instance)\n if (typeof cleanup === \"function\") {\n refCleanup.current = cleanup\n }\n } else if (refCleanup.current) {\n refCleanup.current()\n refCleanup.current = null\n } else {\n ref(instance)\n }\n } else if (ref) {\n ;(ref as React.MutableRefObject<Instance>).current = instance\n }\n },\n [visualElement]\n )\n}\n"],"names":[],"mappings":";;;AAOA;;;AAGG;;AAMC;;;;;;AAMG;AACH;;AAEI;AACJ;;AAGA;AAEA;;AAGY;;;AAIA;;AAGJ;AACA;;AAEQ;AACA;AACI;;;AAED;;AAEH;;;;;;;AAKF;;AAEV;AAGR;;"}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
"use client";
|
||||
import { optimizedAppearDataAttribute } from 'motion-dom';
|
||||
import { useContext, useRef, useInsertionEffect, useEffect } from 'react';
|
||||
import { LazyContext } from '../../context/LazyContext.mjs';
|
||||
import { MotionConfigContext } from '../../context/MotionConfigContext.mjs';
|
||||
import { MotionContext } from '../../context/MotionContext/index.mjs';
|
||||
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
||||
import { SwitchLayoutGroupContext } from '../../context/SwitchLayoutGroupContext.mjs';
|
||||
import { isRefObject } from '../../utils/is-ref-object.mjs';
|
||||
import { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';
|
||||
|
||||
function useVisualElement(Component, visualState, props, createVisualElement, ProjectionNodeConstructor, isSVG) {
|
||||
const { visualElement: parent } = useContext(MotionContext);
|
||||
const lazyContext = useContext(LazyContext);
|
||||
const presenceContext = useContext(PresenceContext);
|
||||
const motionConfig = useContext(MotionConfigContext);
|
||||
const reducedMotionConfig = motionConfig.reducedMotion;
|
||||
const skipAnimations = motionConfig.skipAnimations;
|
||||
const visualElementRef = useRef(null);
|
||||
/**
|
||||
* Track whether the component has been through React's commit phase.
|
||||
* Used to detect when LazyMotion features load after the component has mounted.
|
||||
*/
|
||||
const hasMountedOnce = useRef(false);
|
||||
/**
|
||||
* If we haven't preloaded a renderer, check to see if we have one lazy-loaded
|
||||
*/
|
||||
createVisualElement =
|
||||
createVisualElement ||
|
||||
lazyContext.renderer;
|
||||
if (!visualElementRef.current && createVisualElement) {
|
||||
visualElementRef.current = createVisualElement(Component, {
|
||||
visualState,
|
||||
parent,
|
||||
props,
|
||||
presenceContext,
|
||||
blockInitialAnimation: presenceContext
|
||||
? presenceContext.initial === false
|
||||
: false,
|
||||
reducedMotionConfig,
|
||||
skipAnimations,
|
||||
isSVG,
|
||||
});
|
||||
/**
|
||||
* If the component has already mounted before features loaded (e.g. via
|
||||
* LazyMotion with async feature loading), we need to force the initial
|
||||
* animation to run. Otherwise state changes that occurred before features
|
||||
* loaded will be lost and the element will snap to its final state.
|
||||
*/
|
||||
if (hasMountedOnce.current && visualElementRef.current) {
|
||||
visualElementRef.current.manuallyAnimateOnMount = true;
|
||||
}
|
||||
}
|
||||
const visualElement = visualElementRef.current;
|
||||
/**
|
||||
* Load Motion gesture and animation features. These are rendered as renderless
|
||||
* components so each feature can optionally make use of React lifecycle methods.
|
||||
*/
|
||||
const initialLayoutGroupConfig = useContext(SwitchLayoutGroupContext);
|
||||
if (visualElement &&
|
||||
!visualElement.projection &&
|
||||
ProjectionNodeConstructor &&
|
||||
(visualElement.type === "html" || visualElement.type === "svg")) {
|
||||
createProjectionNode(visualElementRef.current, props, ProjectionNodeConstructor, initialLayoutGroupConfig);
|
||||
}
|
||||
const isMounted = useRef(false);
|
||||
useInsertionEffect(() => {
|
||||
/**
|
||||
* Check the component has already mounted before calling
|
||||
* `update` unnecessarily. This ensures we skip the initial update.
|
||||
*/
|
||||
if (visualElement && isMounted.current) {
|
||||
visualElement.update(props, presenceContext);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Cache this value as we want to know whether HandoffAppearAnimations
|
||||
* was present on initial render - it will be deleted after this.
|
||||
*/
|
||||
const optimisedAppearId = props[optimizedAppearDataAttribute];
|
||||
const wantsHandoff = useRef(Boolean(optimisedAppearId) &&
|
||||
typeof window !== "undefined" &&
|
||||
!window.MotionHandoffIsComplete?.(optimisedAppearId) &&
|
||||
window.MotionHasOptimisedAnimation?.(optimisedAppearId));
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
/**
|
||||
* Track that this component has mounted. This is used to detect when
|
||||
* LazyMotion features load after the component has already committed.
|
||||
*/
|
||||
hasMountedOnce.current = true;
|
||||
if (!visualElement)
|
||||
return;
|
||||
isMounted.current = true;
|
||||
window.MotionIsMounted = true;
|
||||
visualElement.updateFeatures();
|
||||
visualElement.scheduleRenderMicrotask();
|
||||
/**
|
||||
* Ideally this function would always run in a useEffect.
|
||||
*
|
||||
* However, if we have optimised appear animations to handoff from,
|
||||
* it needs to happen synchronously to ensure there's no flash of
|
||||
* incorrect styles in the event of a hydration error.
|
||||
*
|
||||
* So if we detect a situtation where optimised appear animations
|
||||
* are running, we use useLayoutEffect to trigger animations.
|
||||
*/
|
||||
if (wantsHandoff.current && visualElement.animationState) {
|
||||
visualElement.animationState.animateChanges();
|
||||
}
|
||||
});
|
||||
useEffect(() => {
|
||||
if (!visualElement)
|
||||
return;
|
||||
if (!wantsHandoff.current && visualElement.animationState) {
|
||||
visualElement.animationState.animateChanges();
|
||||
}
|
||||
if (wantsHandoff.current) {
|
||||
// This ensures all future calls to animateChanges() in this component will run in useEffect
|
||||
queueMicrotask(() => {
|
||||
window.MotionHandoffMarkAsComplete?.(optimisedAppearId);
|
||||
});
|
||||
wantsHandoff.current = false;
|
||||
}
|
||||
/**
|
||||
* Now we've finished triggering animations for this element we
|
||||
* can wipe the enteringChildren set for the next render.
|
||||
*/
|
||||
visualElement.enteringChildren = undefined;
|
||||
});
|
||||
return visualElement;
|
||||
}
|
||||
function createProjectionNode(visualElement, props, ProjectionNodeConstructor, initialPromotionConfig) {
|
||||
const { layoutId, layout, drag, dragConstraints, layoutScroll, layoutRoot, layoutAnchor, layoutCrossfade, } = props;
|
||||
visualElement.projection = new ProjectionNodeConstructor(visualElement.latestValues, props["data-framer-portal-id"]
|
||||
? undefined
|
||||
: getClosestProjectingNode(visualElement.parent));
|
||||
visualElement.projection.setOptions({
|
||||
layoutId,
|
||||
layout,
|
||||
alwaysMeasureLayout: Boolean(drag) || (dragConstraints && isRefObject(dragConstraints)),
|
||||
visualElement,
|
||||
/**
|
||||
* TODO: Update options in an effect. This could be tricky as it'll be too late
|
||||
* to update by the time layout animations run.
|
||||
* We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
|
||||
* ensuring it gets called if there's no potential layout animations.
|
||||
*
|
||||
*/
|
||||
animationType: typeof layout === "string" ? layout : "both",
|
||||
initialPromotionConfig,
|
||||
crossfade: layoutCrossfade,
|
||||
layoutScroll,
|
||||
layoutRoot,
|
||||
layoutAnchor,
|
||||
});
|
||||
}
|
||||
function getClosestProjectingNode(visualElement) {
|
||||
if (!visualElement)
|
||||
return undefined;
|
||||
return visualElement.options.allowProjection !== false
|
||||
? visualElement.projection
|
||||
: getClosestProjectingNode(visualElement.parent);
|
||||
}
|
||||
|
||||
export { useVisualElement };
|
||||
//# sourceMappingURL=use-visual-element.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
+78
@@ -0,0 +1,78 @@
|
||||
"use client";
|
||||
import { resolveMotionValue, isControllingVariants, isVariantNode, isAnimationControls, resolveVariantFromProps } from 'motion-dom';
|
||||
import { useContext } from 'react';
|
||||
import { MotionContext } from '../../context/MotionContext/index.mjs';
|
||||
import { PresenceContext } from '../../context/PresenceContext.mjs';
|
||||
import { useConstant } from '../../utils/use-constant.mjs';
|
||||
|
||||
function makeState({ scrapeMotionValuesFromProps, createRenderState, }, props, context, presenceContext) {
|
||||
const state = {
|
||||
latestValues: makeLatestValues(props, context, presenceContext, scrapeMotionValuesFromProps),
|
||||
renderState: createRenderState(),
|
||||
};
|
||||
return state;
|
||||
}
|
||||
function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
|
||||
const values = {};
|
||||
const motionValues = scrapeMotionValues(props, {});
|
||||
for (const key in motionValues) {
|
||||
values[key] = resolveMotionValue(motionValues[key]);
|
||||
}
|
||||
let { initial, animate } = props;
|
||||
const isControllingVariants$1 = isControllingVariants(props);
|
||||
const isVariantNode$1 = isVariantNode(props);
|
||||
if (context &&
|
||||
isVariantNode$1 &&
|
||||
!isControllingVariants$1 &&
|
||||
props.inherit !== false) {
|
||||
if (initial === undefined)
|
||||
initial = context.initial;
|
||||
if (animate === undefined)
|
||||
animate = context.animate;
|
||||
}
|
||||
let isInitialAnimationBlocked = presenceContext
|
||||
? presenceContext.initial === false
|
||||
: false;
|
||||
isInitialAnimationBlocked = isInitialAnimationBlocked || initial === false;
|
||||
const variantToSet = isInitialAnimationBlocked ? animate : initial;
|
||||
if (variantToSet &&
|
||||
typeof variantToSet !== "boolean" &&
|
||||
!isAnimationControls(variantToSet)) {
|
||||
const list = Array.isArray(variantToSet) ? variantToSet : [variantToSet];
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const resolved = resolveVariantFromProps(props, list[i]);
|
||||
if (resolved) {
|
||||
const { transitionEnd, transition, ...target } = resolved;
|
||||
for (const key in target) {
|
||||
let valueTarget = target[key];
|
||||
if (Array.isArray(valueTarget)) {
|
||||
/**
|
||||
* Take final keyframe if the initial animation is blocked because
|
||||
* we want to initialise at the end of that blocked animation.
|
||||
*/
|
||||
const index = isInitialAnimationBlocked
|
||||
? valueTarget.length - 1
|
||||
: 0;
|
||||
valueTarget = valueTarget[index];
|
||||
}
|
||||
if (valueTarget !== null) {
|
||||
values[key] = valueTarget;
|
||||
}
|
||||
}
|
||||
for (const key in transitionEnd) {
|
||||
values[key] = transitionEnd[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
const makeUseVisualState = (config) => (props, isStatic) => {
|
||||
const context = useContext(MotionContext);
|
||||
const presenceContext = useContext(PresenceContext);
|
||||
const make = () => makeState(config, props, context, presenceContext);
|
||||
return isStatic ? make() : useConstant(make);
|
||||
};
|
||||
|
||||
export { makeUseVisualState };
|
||||
//# sourceMappingURL=use-visual-state.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* A list of all valid MotionProps.
|
||||
*
|
||||
* @privateRemarks
|
||||
* This doesn't throw if a `MotionProp` name is missing - it should.
|
||||
*/
|
||||
const validMotionProps = new Set([
|
||||
"animate",
|
||||
"exit",
|
||||
"variants",
|
||||
"initial",
|
||||
"style",
|
||||
"values",
|
||||
"variants",
|
||||
"transition",
|
||||
"transformTemplate",
|
||||
"custom",
|
||||
"inherit",
|
||||
"onBeforeLayoutMeasure",
|
||||
"onAnimationStart",
|
||||
"onAnimationComplete",
|
||||
"onUpdate",
|
||||
"onDragStart",
|
||||
"onDrag",
|
||||
"onDragEnd",
|
||||
"onMeasureDragConstraints",
|
||||
"onDirectionLock",
|
||||
"onDragTransitionEnd",
|
||||
"_dragX",
|
||||
"_dragY",
|
||||
"onHoverStart",
|
||||
"onHoverEnd",
|
||||
"onViewportEnter",
|
||||
"onViewportLeave",
|
||||
"globalTapTarget",
|
||||
"propagate",
|
||||
"ignoreStrict",
|
||||
"viewport",
|
||||
]);
|
||||
/**
|
||||
* Check whether a prop name is a valid `MotionProp` key.
|
||||
*
|
||||
* @param key - Name of the property to check
|
||||
* @returns `true` is key is a valid `MotionProp`.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
function isValidMotionProp(key) {
|
||||
return (key.startsWith("while") ||
|
||||
(key.startsWith("drag") && key !== "draggable") ||
|
||||
key.startsWith("layout") ||
|
||||
key.startsWith("onTap") ||
|
||||
key.startsWith("onPan") ||
|
||||
key.startsWith("onLayout") ||
|
||||
validMotionProps.has(key));
|
||||
}
|
||||
|
||||
export { isValidMotionProp };
|
||||
//# sourceMappingURL=valid-prop.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"valid-prop.mjs","sources":["../../../../src/motion/utils/valid-prop.ts"],"sourcesContent":["import { MotionProps } from \"../types\"\n\n/**\n * A list of all valid MotionProps.\n *\n * @privateRemarks\n * This doesn't throw if a `MotionProp` name is missing - it should.\n */\nconst validMotionProps = new Set<keyof MotionProps>([\n \"animate\",\n \"exit\",\n \"variants\",\n \"initial\",\n \"style\",\n \"values\",\n \"variants\",\n \"transition\",\n \"transformTemplate\",\n \"custom\",\n \"inherit\",\n \"onBeforeLayoutMeasure\",\n \"onAnimationStart\",\n \"onAnimationComplete\",\n \"onUpdate\",\n \"onDragStart\",\n \"onDrag\",\n \"onDragEnd\",\n \"onMeasureDragConstraints\",\n \"onDirectionLock\",\n \"onDragTransitionEnd\",\n \"_dragX\",\n \"_dragY\",\n \"onHoverStart\",\n \"onHoverEnd\",\n \"onViewportEnter\",\n \"onViewportLeave\",\n \"globalTapTarget\",\n \"propagate\",\n \"ignoreStrict\",\n \"viewport\",\n])\n\n/**\n * Check whether a prop name is a valid `MotionProp` key.\n *\n * @param key - Name of the property to check\n * @returns `true` is key is a valid `MotionProp`.\n *\n * @public\n */\nexport function isValidMotionProp(key: string) {\n return (\n key.startsWith(\"while\") ||\n (key.startsWith(\"drag\") && key !== \"draggable\") ||\n key.startsWith(\"layout\") ||\n key.startsWith(\"onTap\") ||\n key.startsWith(\"onPan\") ||\n key.startsWith(\"onLayout\") ||\n validMotionProps.has(key as keyof MotionProps)\n )\n}\n"],"names":[],"mappings":"AAEA;;;;;AAKG;AACH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAoB;IAChD,SAAS;IACT,MAAM;IACN,UAAU;IACV,SAAS;IACT,OAAO;IACP,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,mBAAmB;IACnB,QAAQ;IACR,SAAS;IACT,uBAAuB;IACvB,kBAAkB;IAClB,qBAAqB;IACrB,UAAU;IACV,aAAa;IACb,QAAQ;IACR,WAAW;IACX,0BAA0B;IAC1B,iBAAiB;IACjB,qBAAqB;IACrB,QAAQ;IACR,QAAQ;IACR,cAAc;IACd,YAAY;IACZ,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,WAAW;IACX,cAAc;IACd,UAAU;AACb,CAAA,CAAC;AAEF;;;;;;;AAOG;AACG,SAAU,iBAAiB,CAAC,GAAW,EAAA;AACzC,IAAA,QACI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;SACtB,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,WAAW,CAAC;AAC/C,QAAA,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;AACxB,QAAA,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;AACvB,QAAA,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;AACvB,QAAA,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC;AAC1B,QAAA,gBAAgB,CAAC,GAAG,CAAC,GAAwB,CAAC;AAEtD;;;;"}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export { HTMLProjectionNode, HTMLVisualElement, addScaleCorrector, buildTransform, calcBoxDelta, correctBorderRadius, correctBoxShadow, frame, frameData, mix, nodeGroup, recordStats, statsBuffer } from 'motion-dom';
|
||||
//# sourceMappingURL=projection.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"projection.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
Generated
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
import { rootProjectionNode } from 'motion-dom';
|
||||
|
||||
function useInstantLayoutTransition() {
|
||||
return startTransition;
|
||||
}
|
||||
function startTransition(callback) {
|
||||
if (!rootProjectionNode.current)
|
||||
return;
|
||||
rootProjectionNode.current.isUpdating = false;
|
||||
rootProjectionNode.current.blockUpdate();
|
||||
callback && callback();
|
||||
}
|
||||
|
||||
export { useInstantLayoutTransition };
|
||||
//# sourceMappingURL=use-instant-layout-transition.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-instant-layout-transition.mjs","sources":["../../../src/projection/use-instant-layout-transition.ts"],"sourcesContent":["import { rootProjectionNode } from \"motion-dom\"\n\nexport function useInstantLayoutTransition(): (\n cb?: (() => void) | undefined\n) => void {\n return startTransition\n}\n\nfunction startTransition(callback?: () => void) {\n if (!rootProjectionNode.current) return\n rootProjectionNode.current.isUpdating = false\n rootProjectionNode.current.blockUpdate()\n callback && callback()\n}\n"],"names":[],"mappings":";;SAEgB,0BAA0B,GAAA;AAGtC,IAAA,OAAO,eAAe;AAC1B;AAEA,SAAS,eAAe,CAAC,QAAqB,EAAA;IAC1C,IAAI,CAAC,kBAAkB,CAAC,OAAO;QAAE;AACjC,IAAA,kBAAkB,CAAC,OAAO,CAAC,UAAU,GAAG,KAAK;AAC7C,IAAA,kBAAkB,CAAC,OAAO,CAAC,WAAW,EAAE;IACxC,QAAQ,IAAI,QAAQ,EAAE;AAC1B;;;;"}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { useCallback } from 'react';
|
||||
import { rootProjectionNode } from 'motion-dom';
|
||||
|
||||
function useResetProjection() {
|
||||
const reset = useCallback(() => {
|
||||
const root = rootProjectionNode.current;
|
||||
if (!root)
|
||||
return;
|
||||
root.resetTree();
|
||||
}, []);
|
||||
return reset;
|
||||
}
|
||||
|
||||
export { useResetProjection };
|
||||
//# sourceMappingURL=use-reset-projection.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"use-reset-projection.mjs","sources":["../../../src/projection/use-reset-projection.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { rootProjectionNode } from \"motion-dom\"\n\nexport function useResetProjection() {\n const reset = useCallback(() => {\n const root = rootProjectionNode.current\n if (!root) return\n root.resetTree()\n }, [])\n\n return reset\n}\n"],"names":[],"mappings":";;;SAGgB,kBAAkB,GAAA;AAC9B,IAAA,MAAM,KAAK,GAAG,WAAW,CAAC,MAAK;AAC3B,QAAA,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO;AACvC,QAAA,IAAI,CAAC,IAAI;YAAE;QACX,IAAI,CAAC,SAAS,EAAE;IACpB,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,OAAO,KAAK;AAChB;;;;"}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
import { warnOnce } from 'motion-utils';
|
||||
import { createMotionComponent } from '../../motion/index.mjs';
|
||||
|
||||
function createMotionProxy(preloadedFeatures, createVisualElement) {
|
||||
if (typeof Proxy === "undefined") {
|
||||
return createMotionComponent;
|
||||
}
|
||||
/**
|
||||
* A cache of generated `motion` components, e.g `motion.div`, `motion.input` etc.
|
||||
* Rather than generating them anew every render.
|
||||
*/
|
||||
const componentCache = new Map();
|
||||
const factory = (Component, options) => {
|
||||
return createMotionComponent(Component, options, preloadedFeatures, createVisualElement);
|
||||
};
|
||||
/**
|
||||
* Support for deprecated`motion(Component)` pattern
|
||||
*/
|
||||
const deprecatedFactoryFunction = (Component, options) => {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
warnOnce(false, "motion() is deprecated. Use motion.create() instead.");
|
||||
}
|
||||
return factory(Component, options);
|
||||
};
|
||||
return new Proxy(deprecatedFactoryFunction, {
|
||||
/**
|
||||
* Called when `motion` is referenced with a prop: `motion.div`, `motion.input` etc.
|
||||
* The prop name is passed through as `key` and we can use that to generate a `motion`
|
||||
* DOM component with that name.
|
||||
*/
|
||||
get: (_target, key) => {
|
||||
if (key === "create")
|
||||
return factory;
|
||||
/**
|
||||
* If this element doesn't exist in the component cache, create it and cache.
|
||||
*/
|
||||
if (!componentCache.has(key)) {
|
||||
componentCache.set(key, createMotionComponent(key, undefined, preloadedFeatures, createVisualElement));
|
||||
}
|
||||
return componentCache.get(key);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export { createMotionProxy };
|
||||
//# sourceMappingURL=create-proxy.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"create-proxy.mjs","sources":["../../../../src/render/components/create-proxy.ts"],"sourcesContent":["import { warnOnce } from \"motion-utils\"\nimport { createMotionComponent, MotionComponentOptions } from \"../../motion\"\nimport { FeaturePackages } from \"../../motion/features/types\"\nimport { MotionProps } from \"../../motion/types\"\nimport { DOMMotionComponents } from \"../dom/types\"\nimport { CreateVisualElement } from \"../types\"\n\n/**\n * I'd rather the return type of `custom` to be implicit but this throws\n * incorrect relative paths in the exported types and API Extractor throws\n * a wobbly.\n */\ntype ComponentProps<Props> = React.PropsWithoutRef<Props & MotionProps> &\n React.RefAttributes<SVGElement | HTMLElement>\nexport type CustomDomComponent<Props> = React.ComponentType<\n ComponentProps<Props>\n>\n\ntype MotionProxy = typeof createMotionComponent &\n DOMMotionComponents & { create: typeof createMotionComponent }\n\nexport function createMotionProxy(\n preloadedFeatures?: FeaturePackages,\n createVisualElement?: CreateVisualElement<any, any>\n): MotionProxy {\n if (typeof Proxy === \"undefined\") {\n return createMotionComponent as MotionProxy\n }\n\n /**\n * A cache of generated `motion` components, e.g `motion.div`, `motion.input` etc.\n * Rather than generating them anew every render.\n */\n const componentCache = new Map<string, any>()\n\n const factory = (Component: string, options?: MotionComponentOptions) => {\n return createMotionComponent(\n Component,\n options,\n preloadedFeatures,\n createVisualElement\n )\n }\n\n /**\n * Support for deprecated`motion(Component)` pattern\n */\n const deprecatedFactoryFunction = (\n Component: string,\n options?: MotionComponentOptions\n ) => {\n if (process.env.NODE_ENV !== \"production\") {\n warnOnce(\n false,\n \"motion() is deprecated. Use motion.create() instead.\"\n )\n }\n return factory(Component, options)\n }\n\n return new Proxy(deprecatedFactoryFunction, {\n /**\n * Called when `motion` is referenced with a prop: `motion.div`, `motion.input` etc.\n * The prop name is passed through as `key` and we can use that to generate a `motion`\n * DOM component with that name.\n */\n get: (_target, key: string) => {\n if (key === \"create\") return factory\n\n /**\n * If this element doesn't exist in the component cache, create it and cache.\n */\n if (!componentCache.has(key)) {\n componentCache.set(\n key,\n createMotionComponent(\n key,\n undefined,\n preloadedFeatures,\n createVisualElement\n )\n )\n }\n\n return componentCache.get(key)!\n },\n }) as MotionProxy\n}\n"],"names":[],"mappings":";;;AAqBM,SAAU,iBAAiB,CAC7B,iBAAmC,EACnC,mBAAmD,EAAA;AAEnD,IAAA,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE;AAC9B,QAAA,OAAO,qBAAoC;IAC/C;AAEA;;;AAGG;AACH,IAAA,MAAM,cAAc,GAAG,IAAI,GAAG,EAAe;AAE7C,IAAA,MAAM,OAAO,GAAG,CAAC,SAAiB,EAAE,OAAgC,KAAI;QACpE,OAAO,qBAAqB,CACxB,SAAS,EACT,OAAO,EACP,iBAAiB,EACjB,mBAAmB,CACtB;AACL,IAAA,CAAC;AAED;;AAEG;AACH,IAAA,MAAM,yBAAyB,GAAG,CAC9B,SAAiB,EACjB,OAAgC,KAChC;QACA,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE;AACvC,YAAA,QAAQ,CACJ,KAAK,EACL,sDAAsD,CACzD;QACL;AACA,QAAA,OAAO,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC;AACtC,IAAA,CAAC;AAED,IAAA,OAAO,IAAI,KAAK,CAAC,yBAAyB,EAAE;AACxC;;;;AAIG;AACH,QAAA,GAAG,EAAE,CAAC,OAAO,EAAE,GAAW,KAAI;YAC1B,IAAI,GAAG,KAAK,QAAQ;AAAE,gBAAA,OAAO,OAAO;AAEpC;;AAEG;YACH,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AAC1B,gBAAA,cAAc,CAAC,GAAG,CACd,GAAG,EACH,qBAAqB,CACjB,GAAG,EACH,SAAS,EACT,iBAAiB,EACjB,mBAAmB,CACtB,CACJ;YACL;AAEA,YAAA,OAAO,cAAc,CAAC,GAAG,CAAC,GAAG,CAAE;QACnC,CAAC;AACJ,KAAA,CAAgB;AACrB;;;;"}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { createMotionComponent } from '../../../motion/index.mjs';
|
||||
|
||||
function createMinimalMotionComponent(Component, options) {
|
||||
return createMotionComponent(Component, options);
|
||||
}
|
||||
|
||||
export { createMinimalMotionComponent };
|
||||
//# sourceMappingURL=create.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"create.mjs","sources":["../../../../../src/render/components/m/create.ts"],"sourcesContent":["import { createMotionComponent, MotionComponentOptions } from \"../../../motion\"\nimport { DOMMotionComponents } from \"../../dom/types\"\n\nexport function createMinimalMotionComponent<\n Props,\n TagName extends keyof DOMMotionComponents | string = \"div\"\n>(\n Component: TagName | string | React.ComponentType<Props>,\n options?: MotionComponentOptions\n) {\n return createMotionComponent(Component, options)\n}\n"],"names":[],"mappings":";;AAGM,SAAU,4BAA4B,CAIxC,SAAwD,EACxD,OAAgC,EAAA;AAEhC,IAAA,OAAO,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC;AACpD;;;;"}
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
"use client";
|
||||
import { createMinimalMotionComponent } from './create.mjs';
|
||||
|
||||
/**
|
||||
* HTML components
|
||||
*/
|
||||
const MotionA = /*@__PURE__*/ createMinimalMotionComponent("a");
|
||||
const MotionAbbr = /*@__PURE__*/ createMinimalMotionComponent("abbr");
|
||||
const MotionAddress =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("address");
|
||||
const MotionArea = /*@__PURE__*/ createMinimalMotionComponent("area");
|
||||
const MotionArticle =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("article");
|
||||
const MotionAside = /*@__PURE__*/ createMinimalMotionComponent("aside");
|
||||
const MotionAudio = /*@__PURE__*/ createMinimalMotionComponent("audio");
|
||||
const MotionB = /*@__PURE__*/ createMinimalMotionComponent("b");
|
||||
const MotionBase = /*@__PURE__*/ createMinimalMotionComponent("base");
|
||||
const MotionBdi = /*@__PURE__*/ createMinimalMotionComponent("bdi");
|
||||
const MotionBdo = /*@__PURE__*/ createMinimalMotionComponent("bdo");
|
||||
const MotionBig = /*@__PURE__*/ createMinimalMotionComponent("big");
|
||||
const MotionBlockquote =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("blockquote");
|
||||
const MotionBody = /*@__PURE__*/ createMinimalMotionComponent("body");
|
||||
const MotionButton = /*@__PURE__*/ createMinimalMotionComponent("button");
|
||||
const MotionCanvas = /*@__PURE__*/ createMinimalMotionComponent("canvas");
|
||||
const MotionCaption =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("caption");
|
||||
const MotionCite = /*@__PURE__*/ createMinimalMotionComponent("cite");
|
||||
const MotionCode = /*@__PURE__*/ createMinimalMotionComponent("code");
|
||||
const MotionCol = /*@__PURE__*/ createMinimalMotionComponent("col");
|
||||
const MotionColgroup =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("colgroup");
|
||||
const MotionData = /*@__PURE__*/ createMinimalMotionComponent("data");
|
||||
const MotionDatalist =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("datalist");
|
||||
const MotionDd = /*@__PURE__*/ createMinimalMotionComponent("dd");
|
||||
const MotionDel = /*@__PURE__*/ createMinimalMotionComponent("del");
|
||||
const MotionDetails =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("details");
|
||||
const MotionDfn = /*@__PURE__*/ createMinimalMotionComponent("dfn");
|
||||
const MotionDialog = /*@__PURE__*/ createMinimalMotionComponent("dialog");
|
||||
const MotionDiv = /*@__PURE__*/ createMinimalMotionComponent("div");
|
||||
const MotionDl = /*@__PURE__*/ createMinimalMotionComponent("dl");
|
||||
const MotionDt = /*@__PURE__*/ createMinimalMotionComponent("dt");
|
||||
const MotionEm = /*@__PURE__*/ createMinimalMotionComponent("em");
|
||||
const MotionEmbed = /*@__PURE__*/ createMinimalMotionComponent("embed");
|
||||
const MotionFieldset =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("fieldset");
|
||||
const MotionFigcaption =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("figcaption");
|
||||
const MotionFigure = /*@__PURE__*/ createMinimalMotionComponent("figure");
|
||||
const MotionFooter = /*@__PURE__*/ createMinimalMotionComponent("footer");
|
||||
const MotionForm = /*@__PURE__*/ createMinimalMotionComponent("form");
|
||||
const MotionH1 = /*@__PURE__*/ createMinimalMotionComponent("h1");
|
||||
const MotionH2 = /*@__PURE__*/ createMinimalMotionComponent("h2");
|
||||
const MotionH3 = /*@__PURE__*/ createMinimalMotionComponent("h3");
|
||||
const MotionH4 = /*@__PURE__*/ createMinimalMotionComponent("h4");
|
||||
const MotionH5 = /*@__PURE__*/ createMinimalMotionComponent("h5");
|
||||
const MotionH6 = /*@__PURE__*/ createMinimalMotionComponent("h6");
|
||||
const MotionHead = /*@__PURE__*/ createMinimalMotionComponent("head");
|
||||
const MotionHeader = /*@__PURE__*/ createMinimalMotionComponent("header");
|
||||
const MotionHgroup = /*@__PURE__*/ createMinimalMotionComponent("hgroup");
|
||||
const MotionHr = /*@__PURE__*/ createMinimalMotionComponent("hr");
|
||||
const MotionHtml = /*@__PURE__*/ createMinimalMotionComponent("html");
|
||||
const MotionI = /*@__PURE__*/ createMinimalMotionComponent("i");
|
||||
const MotionIframe = /*@__PURE__*/ createMinimalMotionComponent("iframe");
|
||||
const MotionImg = /*@__PURE__*/ createMinimalMotionComponent("img");
|
||||
const MotionInput = /*@__PURE__*/ createMinimalMotionComponent("input");
|
||||
const MotionIns = /*@__PURE__*/ createMinimalMotionComponent("ins");
|
||||
const MotionKbd = /*@__PURE__*/ createMinimalMotionComponent("kbd");
|
||||
const MotionKeygen = /*@__PURE__*/ createMinimalMotionComponent("keygen");
|
||||
const MotionLabel = /*@__PURE__*/ createMinimalMotionComponent("label");
|
||||
const MotionLegend = /*@__PURE__*/ createMinimalMotionComponent("legend");
|
||||
const MotionLi = /*@__PURE__*/ createMinimalMotionComponent("li");
|
||||
const MotionLink = /*@__PURE__*/ createMinimalMotionComponent("link");
|
||||
const MotionMain = /*@__PURE__*/ createMinimalMotionComponent("main");
|
||||
const MotionMap = /*@__PURE__*/ createMinimalMotionComponent("map");
|
||||
const MotionMark = /*@__PURE__*/ createMinimalMotionComponent("mark");
|
||||
const MotionMenu = /*@__PURE__*/ createMinimalMotionComponent("menu");
|
||||
const MotionMenuitem =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("menuitem");
|
||||
const MotionMeter = /*@__PURE__*/ createMinimalMotionComponent("meter");
|
||||
const MotionNav = /*@__PURE__*/ createMinimalMotionComponent("nav");
|
||||
const MotionObject = /*@__PURE__*/ createMinimalMotionComponent("object");
|
||||
const MotionOl = /*@__PURE__*/ createMinimalMotionComponent("ol");
|
||||
const MotionOptgroup =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("optgroup");
|
||||
const MotionOption = /*@__PURE__*/ createMinimalMotionComponent("option");
|
||||
const MotionOutput = /*@__PURE__*/ createMinimalMotionComponent("output");
|
||||
const MotionP = /*@__PURE__*/ createMinimalMotionComponent("p");
|
||||
const MotionParam = /*@__PURE__*/ createMinimalMotionComponent("param");
|
||||
const MotionPicture =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("picture");
|
||||
const MotionPre = /*@__PURE__*/ createMinimalMotionComponent("pre");
|
||||
const MotionProgress =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("progress");
|
||||
const MotionQ = /*@__PURE__*/ createMinimalMotionComponent("q");
|
||||
const MotionRp = /*@__PURE__*/ createMinimalMotionComponent("rp");
|
||||
const MotionRt = /*@__PURE__*/ createMinimalMotionComponent("rt");
|
||||
const MotionRuby = /*@__PURE__*/ createMinimalMotionComponent("ruby");
|
||||
const MotionS = /*@__PURE__*/ createMinimalMotionComponent("s");
|
||||
const MotionSamp = /*@__PURE__*/ createMinimalMotionComponent("samp");
|
||||
const MotionScript = /*@__PURE__*/ createMinimalMotionComponent("script");
|
||||
const MotionSection =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("section");
|
||||
const MotionSelect = /*@__PURE__*/ createMinimalMotionComponent("select");
|
||||
const MotionSmall = /*@__PURE__*/ createMinimalMotionComponent("small");
|
||||
const MotionSource = /*@__PURE__*/ createMinimalMotionComponent("source");
|
||||
const MotionSpan = /*@__PURE__*/ createMinimalMotionComponent("span");
|
||||
const MotionStrong = /*@__PURE__*/ createMinimalMotionComponent("strong");
|
||||
const MotionStyle = /*@__PURE__*/ createMinimalMotionComponent("style");
|
||||
const MotionSub = /*@__PURE__*/ createMinimalMotionComponent("sub");
|
||||
const MotionSummary =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("summary");
|
||||
const MotionSup = /*@__PURE__*/ createMinimalMotionComponent("sup");
|
||||
const MotionTable = /*@__PURE__*/ createMinimalMotionComponent("table");
|
||||
const MotionTbody = /*@__PURE__*/ createMinimalMotionComponent("tbody");
|
||||
const MotionTd = /*@__PURE__*/ createMinimalMotionComponent("td");
|
||||
const MotionTextarea =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("textarea");
|
||||
const MotionTfoot = /*@__PURE__*/ createMinimalMotionComponent("tfoot");
|
||||
const MotionTh = /*@__PURE__*/ createMinimalMotionComponent("th");
|
||||
const MotionThead = /*@__PURE__*/ createMinimalMotionComponent("thead");
|
||||
const MotionTime = /*@__PURE__*/ createMinimalMotionComponent("time");
|
||||
const MotionTitle = /*@__PURE__*/ createMinimalMotionComponent("title");
|
||||
const MotionTr = /*@__PURE__*/ createMinimalMotionComponent("tr");
|
||||
const MotionTrack = /*@__PURE__*/ createMinimalMotionComponent("track");
|
||||
const MotionU = /*@__PURE__*/ createMinimalMotionComponent("u");
|
||||
const MotionUl = /*@__PURE__*/ createMinimalMotionComponent("ul");
|
||||
const MotionVideo = /*@__PURE__*/ createMinimalMotionComponent("video");
|
||||
const MotionWbr = /*@__PURE__*/ createMinimalMotionComponent("wbr");
|
||||
const MotionWebview =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("webview");
|
||||
/**
|
||||
* SVG components
|
||||
*/
|
||||
const MotionAnimate =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("animate");
|
||||
const MotionCircle = /*@__PURE__*/ createMinimalMotionComponent("circle");
|
||||
const MotionDefs = /*@__PURE__*/ createMinimalMotionComponent("defs");
|
||||
const MotionDesc = /*@__PURE__*/ createMinimalMotionComponent("desc");
|
||||
const MotionEllipse =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("ellipse");
|
||||
const MotionG = /*@__PURE__*/ createMinimalMotionComponent("g");
|
||||
const MotionImage = /*@__PURE__*/ createMinimalMotionComponent("image");
|
||||
const MotionLine = /*@__PURE__*/ createMinimalMotionComponent("line");
|
||||
const MotionFilter = /*@__PURE__*/ createMinimalMotionComponent("filter");
|
||||
const MotionMarker = /*@__PURE__*/ createMinimalMotionComponent("marker");
|
||||
const MotionMask = /*@__PURE__*/ createMinimalMotionComponent("mask");
|
||||
const MotionMetadata =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("metadata");
|
||||
const MotionPath = /*@__PURE__*/ createMinimalMotionComponent("path");
|
||||
const MotionPattern =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("pattern");
|
||||
const MotionPolygon =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("polygon");
|
||||
const MotionPolyline =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("polyline");
|
||||
const MotionRect = /*@__PURE__*/ createMinimalMotionComponent("rect");
|
||||
const MotionStop = /*@__PURE__*/ createMinimalMotionComponent("stop");
|
||||
const MotionSvg = /*@__PURE__*/ createMinimalMotionComponent("svg");
|
||||
const MotionSymbol = /*@__PURE__*/ createMinimalMotionComponent("symbol");
|
||||
const MotionText = /*@__PURE__*/ createMinimalMotionComponent("text");
|
||||
const MotionTspan = /*@__PURE__*/ createMinimalMotionComponent("tspan");
|
||||
const MotionUse = /*@__PURE__*/ createMinimalMotionComponent("use");
|
||||
const MotionView = /*@__PURE__*/ createMinimalMotionComponent("view");
|
||||
const MotionClipPath =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("clipPath");
|
||||
const MotionFeBlend =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feBlend");
|
||||
const MotionFeColorMatrix =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feColorMatrix");
|
||||
const MotionFeComponentTransfer =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feComponentTransfer");
|
||||
const MotionFeComposite =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feComposite");
|
||||
const MotionFeConvolveMatrix =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feConvolveMatrix");
|
||||
const MotionFeDiffuseLighting =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feDiffuseLighting");
|
||||
const MotionFeDisplacementMap =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feDisplacementMap");
|
||||
const MotionFeDistantLight =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feDistantLight");
|
||||
const MotionFeDropShadow =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feDropShadow");
|
||||
const MotionFeFlood =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feFlood");
|
||||
const MotionFeFuncA =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feFuncA");
|
||||
const MotionFeFuncB =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feFuncB");
|
||||
const MotionFeFuncG =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feFuncG");
|
||||
const MotionFeFuncR =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feFuncR");
|
||||
const MotionFeGaussianBlur =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feGaussianBlur");
|
||||
const MotionFeImage =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feImage");
|
||||
const MotionFeMerge =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feMerge");
|
||||
const MotionFeMergeNode =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feMergeNode");
|
||||
const MotionFeMorphology =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feMorphology");
|
||||
const MotionFeOffset =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feOffset");
|
||||
const MotionFePointLight =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("fePointLight");
|
||||
const MotionFeSpecularLighting =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feSpecularLighting");
|
||||
const MotionFeSpotLight =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feSpotLight");
|
||||
const MotionFeTile = /*@__PURE__*/ createMinimalMotionComponent("feTile");
|
||||
const MotionFeTurbulence =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("feTurbulence");
|
||||
const MotionForeignObject =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("foreignObject");
|
||||
const MotionLinearGradient =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("linearGradient");
|
||||
const MotionRadialGradient =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("radialGradient");
|
||||
const MotionTextPath =
|
||||
/*@__PURE__*/ createMinimalMotionComponent("textPath");
|
||||
|
||||
export { MotionA, MotionAbbr, MotionAddress, MotionAnimate, MotionArea, MotionArticle, MotionAside, MotionAudio, MotionB, MotionBase, MotionBdi, MotionBdo, MotionBig, MotionBlockquote, MotionBody, MotionButton, MotionCanvas, MotionCaption, MotionCircle, MotionCite, MotionClipPath, MotionCode, MotionCol, MotionColgroup, MotionData, MotionDatalist, MotionDd, MotionDefs, MotionDel, MotionDesc, MotionDetails, MotionDfn, MotionDialog, MotionDiv, MotionDl, MotionDt, MotionEllipse, MotionEm, MotionEmbed, MotionFeBlend, MotionFeColorMatrix, MotionFeComponentTransfer, MotionFeComposite, MotionFeConvolveMatrix, MotionFeDiffuseLighting, MotionFeDisplacementMap, MotionFeDistantLight, MotionFeDropShadow, MotionFeFlood, MotionFeFuncA, MotionFeFuncB, MotionFeFuncG, MotionFeFuncR, MotionFeGaussianBlur, MotionFeImage, MotionFeMerge, MotionFeMergeNode, MotionFeMorphology, MotionFeOffset, MotionFePointLight, MotionFeSpecularLighting, MotionFeSpotLight, MotionFeTile, MotionFeTurbulence, MotionFieldset, MotionFigcaption, MotionFigure, MotionFilter, MotionFooter, MotionForeignObject, MotionForm, MotionG, MotionH1, MotionH2, MotionH3, MotionH4, MotionH5, MotionH6, MotionHead, MotionHeader, MotionHgroup, MotionHr, MotionHtml, MotionI, MotionIframe, MotionImage, MotionImg, MotionInput, MotionIns, MotionKbd, MotionKeygen, MotionLabel, MotionLegend, MotionLi, MotionLine, MotionLinearGradient, MotionLink, MotionMain, MotionMap, MotionMark, MotionMarker, MotionMask, MotionMenu, MotionMenuitem, MotionMetadata, MotionMeter, MotionNav, MotionObject, MotionOl, MotionOptgroup, MotionOption, MotionOutput, MotionP, MotionParam, MotionPath, MotionPattern, MotionPicture, MotionPolygon, MotionPolyline, MotionPre, MotionProgress, MotionQ, MotionRadialGradient, MotionRect, MotionRp, MotionRt, MotionRuby, MotionS, MotionSamp, MotionScript, MotionSection, MotionSelect, MotionSmall, MotionSource, MotionSpan, MotionStop, MotionStrong, MotionStyle, MotionSub, MotionSummary, MotionSup, MotionSvg, MotionSymbol, MotionTable, MotionTbody, MotionTd, MotionText, MotionTextPath, MotionTextarea, MotionTfoot, MotionTh, MotionThead, MotionTime, MotionTitle, MotionTr, MotionTrack, MotionTspan, MotionU, MotionUl, MotionUse, MotionVideo, MotionView, MotionWbr, MotionWebview };
|
||||
//# sourceMappingURL=elements.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+6
@@ -0,0 +1,6 @@
|
||||
import { createMotionProxy } from '../create-proxy.mjs';
|
||||
|
||||
const m = /*@__PURE__*/ createMotionProxy();
|
||||
|
||||
export { m };
|
||||
//# sourceMappingURL=proxy.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"proxy.mjs","sources":["../../../../../src/render/components/m/proxy.ts"],"sourcesContent":["import { createMotionProxy } from \"../create-proxy\"\n\nexport const m = /*@__PURE__*/ createMotionProxy()\n"],"names":[],"mappings":";;MAEa,CAAC,iBAAiB,iBAAiB;;;;"}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import { createMotionComponent } from '../../../motion/index.mjs';
|
||||
import { createDomVisualElement } from '../../dom/create-visual-element.mjs';
|
||||
import { featureBundle } from './feature-bundle.mjs';
|
||||
|
||||
function createMotionComponentWithFeatures(Component, options) {
|
||||
return createMotionComponent(Component, options, featureBundle, createDomVisualElement);
|
||||
}
|
||||
|
||||
export { createMotionComponentWithFeatures };
|
||||
//# sourceMappingURL=create.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"create.mjs","sources":["../../../../../src/render/components/motion/create.ts"],"sourcesContent":["import { createMotionComponent, MotionComponentOptions } from \"../../../motion\"\nimport { createDomVisualElement } from \"../../dom/create-visual-element\"\nimport { DOMMotionComponents } from \"../../dom/types\"\nimport { CreateVisualElement } from \"../../types\"\nimport { featureBundle } from \"./feature-bundle\"\n\nexport function createMotionComponentWithFeatures<\n Props,\n TagName extends keyof DOMMotionComponents | string = \"div\"\n>(\n Component: TagName | string | React.ComponentType<Props>,\n options?: MotionComponentOptions\n) {\n return createMotionComponent(\n Component,\n options,\n featureBundle,\n createDomVisualElement as CreateVisualElement<Props, TagName>\n )\n}\n"],"names":[],"mappings":";;;;AAMM,SAAU,iCAAiC,CAI7C,SAAwD,EACxD,OAAgC,EAAA;IAEhC,OAAO,qBAAqB,CACxB,SAAS,EACT,OAAO,EACP,aAAa,EACb,sBAA6D,CAChE;AACL;;;;"}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
"use client";
|
||||
import { createMotionComponentWithFeatures } from './create.mjs';
|
||||
|
||||
/**
|
||||
* HTML components
|
||||
*/
|
||||
const MotionA = /*@__PURE__*/ createMotionComponentWithFeatures("a");
|
||||
const MotionAbbr = /*@__PURE__*/ createMotionComponentWithFeatures("abbr");
|
||||
const MotionAddress = /*@__PURE__*/ createMotionComponentWithFeatures("address");
|
||||
const MotionArea = /*@__PURE__*/ createMotionComponentWithFeatures("area");
|
||||
const MotionArticle = /*@__PURE__*/ createMotionComponentWithFeatures("article");
|
||||
const MotionAside = /*@__PURE__*/ createMotionComponentWithFeatures("aside");
|
||||
const MotionAudio = /*@__PURE__*/ createMotionComponentWithFeatures("audio");
|
||||
const MotionB = /*@__PURE__*/ createMotionComponentWithFeatures("b");
|
||||
const MotionBase = /*@__PURE__*/ createMotionComponentWithFeatures("base");
|
||||
const MotionBdi = /*@__PURE__*/ createMotionComponentWithFeatures("bdi");
|
||||
const MotionBdo = /*@__PURE__*/ createMotionComponentWithFeatures("bdo");
|
||||
const MotionBig = /*@__PURE__*/ createMotionComponentWithFeatures("big");
|
||||
const MotionBlockquote =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("blockquote");
|
||||
const MotionBody = /*@__PURE__*/ createMotionComponentWithFeatures("body");
|
||||
const MotionButton = /*@__PURE__*/ createMotionComponentWithFeatures("button");
|
||||
const MotionCanvas = /*@__PURE__*/ createMotionComponentWithFeatures("canvas");
|
||||
const MotionCaption = /*@__PURE__*/ createMotionComponentWithFeatures("caption");
|
||||
const MotionCite = /*@__PURE__*/ createMotionComponentWithFeatures("cite");
|
||||
const MotionCode = /*@__PURE__*/ createMotionComponentWithFeatures("code");
|
||||
const MotionCol = /*@__PURE__*/ createMotionComponentWithFeatures("col");
|
||||
const MotionColgroup = /*@__PURE__*/ createMotionComponentWithFeatures("colgroup");
|
||||
const MotionData = /*@__PURE__*/ createMotionComponentWithFeatures("data");
|
||||
const MotionDatalist = /*@__PURE__*/ createMotionComponentWithFeatures("datalist");
|
||||
const MotionDd = /*@__PURE__*/ createMotionComponentWithFeatures("dd");
|
||||
const MotionDel = /*@__PURE__*/ createMotionComponentWithFeatures("del");
|
||||
const MotionDetails = /*@__PURE__*/ createMotionComponentWithFeatures("details");
|
||||
const MotionDfn = /*@__PURE__*/ createMotionComponentWithFeatures("dfn");
|
||||
const MotionDialog = /*@__PURE__*/ createMotionComponentWithFeatures("dialog");
|
||||
const MotionDiv = /*@__PURE__*/ createMotionComponentWithFeatures("div");
|
||||
const MotionDl = /*@__PURE__*/ createMotionComponentWithFeatures("dl");
|
||||
const MotionDt = /*@__PURE__*/ createMotionComponentWithFeatures("dt");
|
||||
const MotionEm = /*@__PURE__*/ createMotionComponentWithFeatures("em");
|
||||
const MotionEmbed = /*@__PURE__*/ createMotionComponentWithFeatures("embed");
|
||||
const MotionFieldset = /*@__PURE__*/ createMotionComponentWithFeatures("fieldset");
|
||||
const MotionFigcaption =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("figcaption");
|
||||
const MotionFigure = /*@__PURE__*/ createMotionComponentWithFeatures("figure");
|
||||
const MotionFooter = /*@__PURE__*/ createMotionComponentWithFeatures("footer");
|
||||
const MotionForm = /*@__PURE__*/ createMotionComponentWithFeatures("form");
|
||||
const MotionH1 = /*@__PURE__*/ createMotionComponentWithFeatures("h1");
|
||||
const MotionH2 = /*@__PURE__*/ createMotionComponentWithFeatures("h2");
|
||||
const MotionH3 = /*@__PURE__*/ createMotionComponentWithFeatures("h3");
|
||||
const MotionH4 = /*@__PURE__*/ createMotionComponentWithFeatures("h4");
|
||||
const MotionH5 = /*@__PURE__*/ createMotionComponentWithFeatures("h5");
|
||||
const MotionH6 = /*@__PURE__*/ createMotionComponentWithFeatures("h6");
|
||||
const MotionHead = /*@__PURE__*/ createMotionComponentWithFeatures("head");
|
||||
const MotionHeader = /*@__PURE__*/ createMotionComponentWithFeatures("header");
|
||||
const MotionHgroup = /*@__PURE__*/ createMotionComponentWithFeatures("hgroup");
|
||||
const MotionHr = /*@__PURE__*/ createMotionComponentWithFeatures("hr");
|
||||
const MotionHtml = /*@__PURE__*/ createMotionComponentWithFeatures("html");
|
||||
const MotionI = /*@__PURE__*/ createMotionComponentWithFeatures("i");
|
||||
const MotionIframe = /*@__PURE__*/ createMotionComponentWithFeatures("iframe");
|
||||
const MotionImg = /*@__PURE__*/ createMotionComponentWithFeatures("img");
|
||||
const MotionInput = /*@__PURE__*/ createMotionComponentWithFeatures("input");
|
||||
const MotionIns = /*@__PURE__*/ createMotionComponentWithFeatures("ins");
|
||||
const MotionKbd = /*@__PURE__*/ createMotionComponentWithFeatures("kbd");
|
||||
const MotionKeygen = /*@__PURE__*/ createMotionComponentWithFeatures("keygen");
|
||||
const MotionLabel = /*@__PURE__*/ createMotionComponentWithFeatures("label");
|
||||
const MotionLegend = /*@__PURE__*/ createMotionComponentWithFeatures("legend");
|
||||
const MotionLi = /*@__PURE__*/ createMotionComponentWithFeatures("li");
|
||||
const MotionLink = /*@__PURE__*/ createMotionComponentWithFeatures("link");
|
||||
const MotionMain = /*@__PURE__*/ createMotionComponentWithFeatures("main");
|
||||
const MotionMap = /*@__PURE__*/ createMotionComponentWithFeatures("map");
|
||||
const MotionMark = /*@__PURE__*/ createMotionComponentWithFeatures("mark");
|
||||
const MotionMenu = /*@__PURE__*/ createMotionComponentWithFeatures("menu");
|
||||
const MotionMenuitem = /*@__PURE__*/ createMotionComponentWithFeatures("menuitem");
|
||||
const MotionMeter = /*@__PURE__*/ createMotionComponentWithFeatures("meter");
|
||||
const MotionNav = /*@__PURE__*/ createMotionComponentWithFeatures("nav");
|
||||
const MotionObject = /*@__PURE__*/ createMotionComponentWithFeatures("object");
|
||||
const MotionOl = /*@__PURE__*/ createMotionComponentWithFeatures("ol");
|
||||
const MotionOptgroup = /*@__PURE__*/ createMotionComponentWithFeatures("optgroup");
|
||||
const MotionOption = /*@__PURE__*/ createMotionComponentWithFeatures("option");
|
||||
const MotionOutput = /*@__PURE__*/ createMotionComponentWithFeatures("output");
|
||||
const MotionP = /*@__PURE__*/ createMotionComponentWithFeatures("p");
|
||||
const MotionParam = /*@__PURE__*/ createMotionComponentWithFeatures("param");
|
||||
const MotionPicture = /*@__PURE__*/ createMotionComponentWithFeatures("picture");
|
||||
const MotionPre = /*@__PURE__*/ createMotionComponentWithFeatures("pre");
|
||||
const MotionProgress = /*@__PURE__*/ createMotionComponentWithFeatures("progress");
|
||||
const MotionQ = /*@__PURE__*/ createMotionComponentWithFeatures("q");
|
||||
const MotionRp = /*@__PURE__*/ createMotionComponentWithFeatures("rp");
|
||||
const MotionRt = /*@__PURE__*/ createMotionComponentWithFeatures("rt");
|
||||
const MotionRuby = /*@__PURE__*/ createMotionComponentWithFeatures("ruby");
|
||||
const MotionS = /*@__PURE__*/ createMotionComponentWithFeatures("s");
|
||||
const MotionSamp = /*@__PURE__*/ createMotionComponentWithFeatures("samp");
|
||||
const MotionScript = /*@__PURE__*/ createMotionComponentWithFeatures("script");
|
||||
const MotionSection = /*@__PURE__*/ createMotionComponentWithFeatures("section");
|
||||
const MotionSelect = /*@__PURE__*/ createMotionComponentWithFeatures("select");
|
||||
const MotionSmall = /*@__PURE__*/ createMotionComponentWithFeatures("small");
|
||||
const MotionSource = /*@__PURE__*/ createMotionComponentWithFeatures("source");
|
||||
const MotionSpan = /*@__PURE__*/ createMotionComponentWithFeatures("span");
|
||||
const MotionStrong = /*@__PURE__*/ createMotionComponentWithFeatures("strong");
|
||||
const MotionStyle = /*@__PURE__*/ createMotionComponentWithFeatures("style");
|
||||
const MotionSub = /*@__PURE__*/ createMotionComponentWithFeatures("sub");
|
||||
const MotionSummary = /*@__PURE__*/ createMotionComponentWithFeatures("summary");
|
||||
const MotionSup = /*@__PURE__*/ createMotionComponentWithFeatures("sup");
|
||||
const MotionTable = /*@__PURE__*/ createMotionComponentWithFeatures("table");
|
||||
const MotionTbody = /*@__PURE__*/ createMotionComponentWithFeatures("tbody");
|
||||
const MotionTd = /*@__PURE__*/ createMotionComponentWithFeatures("td");
|
||||
const MotionTextarea = /*@__PURE__*/ createMotionComponentWithFeatures("textarea");
|
||||
const MotionTfoot = /*@__PURE__*/ createMotionComponentWithFeatures("tfoot");
|
||||
const MotionTh = /*@__PURE__*/ createMotionComponentWithFeatures("th");
|
||||
const MotionThead = /*@__PURE__*/ createMotionComponentWithFeatures("thead");
|
||||
const MotionTime = /*@__PURE__*/ createMotionComponentWithFeatures("time");
|
||||
const MotionTitle = /*@__PURE__*/ createMotionComponentWithFeatures("title");
|
||||
const MotionTr = /*@__PURE__*/ createMotionComponentWithFeatures("tr");
|
||||
const MotionTrack = /*@__PURE__*/ createMotionComponentWithFeatures("track");
|
||||
const MotionU = /*@__PURE__*/ createMotionComponentWithFeatures("u");
|
||||
const MotionUl = /*@__PURE__*/ createMotionComponentWithFeatures("ul");
|
||||
const MotionVideo = /*@__PURE__*/ createMotionComponentWithFeatures("video");
|
||||
const MotionWbr = /*@__PURE__*/ createMotionComponentWithFeatures("wbr");
|
||||
const MotionWebview = /*@__PURE__*/ createMotionComponentWithFeatures("webview");
|
||||
/**
|
||||
* SVG components
|
||||
*/
|
||||
const MotionAnimate = /*@__PURE__*/ createMotionComponentWithFeatures("animate");
|
||||
const MotionCircle = /*@__PURE__*/ createMotionComponentWithFeatures("circle");
|
||||
const MotionDefs = /*@__PURE__*/ createMotionComponentWithFeatures("defs");
|
||||
const MotionDesc = /*@__PURE__*/ createMotionComponentWithFeatures("desc");
|
||||
const MotionEllipse = /*@__PURE__*/ createMotionComponentWithFeatures("ellipse");
|
||||
const MotionG = /*@__PURE__*/ createMotionComponentWithFeatures("g");
|
||||
const MotionImage = /*@__PURE__*/ createMotionComponentWithFeatures("image");
|
||||
const MotionLine = /*@__PURE__*/ createMotionComponentWithFeatures("line");
|
||||
const MotionFilter = /*@__PURE__*/ createMotionComponentWithFeatures("filter");
|
||||
const MotionMarker = /*@__PURE__*/ createMotionComponentWithFeatures("marker");
|
||||
const MotionMask = /*@__PURE__*/ createMotionComponentWithFeatures("mask");
|
||||
const MotionMetadata = /*@__PURE__*/ createMotionComponentWithFeatures("metadata");
|
||||
const MotionPath = /*@__PURE__*/ createMotionComponentWithFeatures("path");
|
||||
const MotionPattern = /*@__PURE__*/ createMotionComponentWithFeatures("pattern");
|
||||
const MotionPolygon = /*@__PURE__*/ createMotionComponentWithFeatures("polygon");
|
||||
const MotionPolyline = /*@__PURE__*/ createMotionComponentWithFeatures("polyline");
|
||||
const MotionRect = /*@__PURE__*/ createMotionComponentWithFeatures("rect");
|
||||
const MotionStop = /*@__PURE__*/ createMotionComponentWithFeatures("stop");
|
||||
const MotionSvg = /*@__PURE__*/ createMotionComponentWithFeatures("svg");
|
||||
const MotionSymbol = /*@__PURE__*/ createMotionComponentWithFeatures("symbol");
|
||||
const MotionText = /*@__PURE__*/ createMotionComponentWithFeatures("text");
|
||||
const MotionTspan = /*@__PURE__*/ createMotionComponentWithFeatures("tspan");
|
||||
const MotionUse = /*@__PURE__*/ createMotionComponentWithFeatures("use");
|
||||
const MotionView = /*@__PURE__*/ createMotionComponentWithFeatures("view");
|
||||
const MotionClipPath = /*@__PURE__*/ createMotionComponentWithFeatures("clipPath");
|
||||
const MotionFeBlend = /*@__PURE__*/ createMotionComponentWithFeatures("feBlend");
|
||||
const MotionFeColorMatrix =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feColorMatrix");
|
||||
const MotionFeComponentTransfer = /*@__PURE__*/ createMotionComponentWithFeatures("feComponentTransfer");
|
||||
const MotionFeComposite =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feComposite");
|
||||
const MotionFeConvolveMatrix =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feConvolveMatrix");
|
||||
const MotionFeDiffuseLighting =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feDiffuseLighting");
|
||||
const MotionFeDisplacementMap =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feDisplacementMap");
|
||||
const MotionFeDistantLight =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feDistantLight");
|
||||
const MotionFeDropShadow =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feDropShadow");
|
||||
const MotionFeFlood = /*@__PURE__*/ createMotionComponentWithFeatures("feFlood");
|
||||
const MotionFeFuncA = /*@__PURE__*/ createMotionComponentWithFeatures("feFuncA");
|
||||
const MotionFeFuncB = /*@__PURE__*/ createMotionComponentWithFeatures("feFuncB");
|
||||
const MotionFeFuncG = /*@__PURE__*/ createMotionComponentWithFeatures("feFuncG");
|
||||
const MotionFeFuncR = /*@__PURE__*/ createMotionComponentWithFeatures("feFuncR");
|
||||
const MotionFeGaussianBlur =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feGaussianBlur");
|
||||
const MotionFeImage = /*@__PURE__*/ createMotionComponentWithFeatures("feImage");
|
||||
const MotionFeMerge = /*@__PURE__*/ createMotionComponentWithFeatures("feMerge");
|
||||
const MotionFeMergeNode =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feMergeNode");
|
||||
const MotionFeMorphology =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feMorphology");
|
||||
const MotionFeOffset = /*@__PURE__*/ createMotionComponentWithFeatures("feOffset");
|
||||
const MotionFePointLight =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("fePointLight");
|
||||
const MotionFeSpecularLighting =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feSpecularLighting");
|
||||
const MotionFeSpotLight =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feSpotLight");
|
||||
const MotionFeTile = /*@__PURE__*/ createMotionComponentWithFeatures("feTile");
|
||||
const MotionFeTurbulence =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("feTurbulence");
|
||||
const MotionForeignObject =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("foreignObject");
|
||||
const MotionLinearGradient =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("linearGradient");
|
||||
const MotionRadialGradient =
|
||||
/*@__PURE__*/ createMotionComponentWithFeatures("radialGradient");
|
||||
const MotionTextPath = /*@__PURE__*/ createMotionComponentWithFeatures("textPath");
|
||||
|
||||
export { MotionA, MotionAbbr, MotionAddress, MotionAnimate, MotionArea, MotionArticle, MotionAside, MotionAudio, MotionB, MotionBase, MotionBdi, MotionBdo, MotionBig, MotionBlockquote, MotionBody, MotionButton, MotionCanvas, MotionCaption, MotionCircle, MotionCite, MotionClipPath, MotionCode, MotionCol, MotionColgroup, MotionData, MotionDatalist, MotionDd, MotionDefs, MotionDel, MotionDesc, MotionDetails, MotionDfn, MotionDialog, MotionDiv, MotionDl, MotionDt, MotionEllipse, MotionEm, MotionEmbed, MotionFeBlend, MotionFeColorMatrix, MotionFeComponentTransfer, MotionFeComposite, MotionFeConvolveMatrix, MotionFeDiffuseLighting, MotionFeDisplacementMap, MotionFeDistantLight, MotionFeDropShadow, MotionFeFlood, MotionFeFuncA, MotionFeFuncB, MotionFeFuncG, MotionFeFuncR, MotionFeGaussianBlur, MotionFeImage, MotionFeMerge, MotionFeMergeNode, MotionFeMorphology, MotionFeOffset, MotionFePointLight, MotionFeSpecularLighting, MotionFeSpotLight, MotionFeTile, MotionFeTurbulence, MotionFieldset, MotionFigcaption, MotionFigure, MotionFilter, MotionFooter, MotionForeignObject, MotionForm, MotionG, MotionH1, MotionH2, MotionH3, MotionH4, MotionH5, MotionH6, MotionHead, MotionHeader, MotionHgroup, MotionHr, MotionHtml, MotionI, MotionIframe, MotionImage, MotionImg, MotionInput, MotionIns, MotionKbd, MotionKeygen, MotionLabel, MotionLegend, MotionLi, MotionLine, MotionLinearGradient, MotionLink, MotionMain, MotionMap, MotionMark, MotionMarker, MotionMask, MotionMenu, MotionMenuitem, MotionMetadata, MotionMeter, MotionNav, MotionObject, MotionOl, MotionOptgroup, MotionOption, MotionOutput, MotionP, MotionParam, MotionPath, MotionPattern, MotionPicture, MotionPolygon, MotionPolyline, MotionPre, MotionProgress, MotionQ, MotionRadialGradient, MotionRect, MotionRp, MotionRt, MotionRuby, MotionS, MotionSamp, MotionScript, MotionSection, MotionSelect, MotionSmall, MotionSource, MotionSpan, MotionStop, MotionStrong, MotionStyle, MotionSub, MotionSummary, MotionSup, MotionSvg, MotionSymbol, MotionTable, MotionTbody, MotionTd, MotionText, MotionTextPath, MotionTextarea, MotionTfoot, MotionTh, MotionThead, MotionTime, MotionTitle, MotionTr, MotionTrack, MotionTspan, MotionU, MotionUl, MotionUse, MotionVideo, MotionView, MotionWbr, MotionWebview };
|
||||
//# sourceMappingURL=elements.mjs.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
import { animations } from '../../../motion/features/animations.mjs';
|
||||
import { drag } from '../../../motion/features/drag.mjs';
|
||||
import { gestureAnimations } from '../../../motion/features/gestures.mjs';
|
||||
import { layout } from '../../../motion/features/layout.mjs';
|
||||
|
||||
const featureBundle = {
|
||||
...animations,
|
||||
...gestureAnimations,
|
||||
...drag,
|
||||
...layout,
|
||||
};
|
||||
|
||||
export { featureBundle };
|
||||
//# sourceMappingURL=feature-bundle.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"feature-bundle.mjs","sources":["../../../../../src/render/components/motion/feature-bundle.ts"],"sourcesContent":["import { animations } from \"../../../motion/features/animations\"\nimport { drag } from \"../../../motion/features/drag\"\nimport { gestureAnimations } from \"../../../motion/features/gestures\"\nimport { layout } from \"../../../motion/features/layout\"\n\nexport const featureBundle = {\n ...animations,\n ...gestureAnimations,\n ...drag,\n ...layout,\n}\n"],"names":[],"mappings":";;;;;AAKO,MAAM,aAAa,GAAG;AACzB,IAAA,GAAG,UAAU;AACb,IAAA,GAAG,iBAAiB;AACpB,IAAA,GAAG,IAAI;AACP,IAAA,GAAG,MAAM;;;;;"}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { createDomVisualElement } from '../../dom/create-visual-element.mjs';
|
||||
import { createMotionProxy } from '../create-proxy.mjs';
|
||||
import { featureBundle } from './feature-bundle.mjs';
|
||||
|
||||
const motion = /*@__PURE__*/ createMotionProxy(featureBundle, createDomVisualElement);
|
||||
|
||||
export { motion };
|
||||
//# sourceMappingURL=proxy.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"proxy.mjs","sources":["../../../../../src/render/components/motion/proxy.ts"],"sourcesContent":["import { createDomVisualElement } from \"../../dom/create-visual-element\"\nimport { createMotionProxy } from \"../create-proxy\"\nimport { featureBundle } from \"./feature-bundle\"\n\nexport const motion = /*@__PURE__*/ createMotionProxy(\n featureBundle,\n createDomVisualElement\n)\n"],"names":[],"mappings":";;;;AAIO,MAAM,MAAM,iBAAiB,iBAAiB,CACjD,aAAa,EACb,sBAAsB;;;;"}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { SVGVisualElement, HTMLVisualElement } from 'motion-dom';
|
||||
import { Fragment } from 'react';
|
||||
import { isSVGComponent } from './utils/is-svg-component.mjs';
|
||||
|
||||
const createDomVisualElement = (Component, options) => {
|
||||
/**
|
||||
* Use explicit isSVG override if provided, otherwise auto-detect
|
||||
*/
|
||||
const isSVG = options.isSVG ?? isSVGComponent(Component);
|
||||
return isSVG
|
||||
? new SVGVisualElement(options)
|
||||
: new HTMLVisualElement(options, {
|
||||
allowProjection: Component !== Fragment,
|
||||
});
|
||||
};
|
||||
|
||||
export { createDomVisualElement };
|
||||
//# sourceMappingURL=create-visual-element.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"create-visual-element.mjs","sources":["../../../../src/render/dom/create-visual-element.ts"],"sourcesContent":["import { HTMLVisualElement, SVGVisualElement } from \"motion-dom\"\nimport { ComponentType, Fragment } from \"react\"\nimport { CreateVisualElement, VisualElementOptions } from \"../types\"\nimport { isSVGComponent } from \"./utils/is-svg-component\"\n\nexport const createDomVisualElement: CreateVisualElement = (\n Component: string | ComponentType<React.PropsWithChildren<unknown>>,\n options: VisualElementOptions<HTMLElement | SVGElement>\n) => {\n /**\n * Use explicit isSVG override if provided, otherwise auto-detect\n */\n const isSVG = options.isSVG ?? isSVGComponent(Component)\n\n return isSVG\n ? new SVGVisualElement(options)\n : new HTMLVisualElement(options, {\n allowProjection: Component !== Fragment,\n })\n}\n"],"names":[],"mappings":";;;;MAKa,sBAAsB,GAAwB,CACvD,SAAmE,EACnE,OAAuD,KACvD;AACA;;AAEG;IACH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC,SAAS,CAAC;AAExD,IAAA,OAAO;AACH,UAAE,IAAI,gBAAgB,CAAC,OAAO;AAC9B,UAAE,IAAI,iBAAiB,CAAC,OAAO,EAAE;YAC3B,eAAe,EAAE,SAAS,KAAK,QAAQ;AAC1C,SAAA,CAAC;AACZ;;;;"}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
"use client";
|
||||
import { animations } from '../../motion/features/animations.mjs';
|
||||
import { gestureAnimations } from '../../motion/features/gestures.mjs';
|
||||
import { createDomVisualElement } from './create-visual-element.mjs';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
const domAnimation = {
|
||||
renderer: createDomVisualElement,
|
||||
...animations,
|
||||
...gestureAnimations,
|
||||
};
|
||||
|
||||
export { domAnimation };
|
||||
//# sourceMappingURL=features-animation.mjs.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"features-animation.mjs","sources":["../../../../src/render/dom/features-animation.ts"],"sourcesContent":["\"use client\"\n\nimport { animations } from \"../../motion/features/animations\"\nimport { gestureAnimations } from \"../../motion/features/gestures\"\nimport { FeatureBundle } from \"../../motion/features/types\"\nimport { createDomVisualElement } from \"./create-visual-element\"\n\n/**\n * @public\n */\nexport const domAnimation: FeatureBundle = {\n renderer: createDomVisualElement,\n ...animations,\n ...gestureAnimations,\n}\n"],"names":[],"mappings":";;;;;AAOA;;AAEG;AACI;AACH;AACA;AACA;;;"}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user