first commit
This commit is contained in:
47
node_modules/motion-dom/dist/es/effects/MotionValueState.mjs
generated
vendored
Normal file
47
node_modules/motion-dom/dist/es/effects/MotionValueState.mjs
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import { frame, cancelFrame } from '../frameloop/frame.mjs';
|
||||
import { numberValueTypes } from '../value/types/maps/number.mjs';
|
||||
import { getValueAsType } from '../value/types/utils/get-as-type.mjs';
|
||||
|
||||
class MotionValueState {
|
||||
constructor() {
|
||||
this.latest = {};
|
||||
this.values = new Map();
|
||||
}
|
||||
set(name, value, render, computed, useDefaultValueType = true) {
|
||||
const existingValue = this.values.get(name);
|
||||
if (existingValue) {
|
||||
existingValue.onRemove();
|
||||
}
|
||||
const onChange = () => {
|
||||
const v = value.get();
|
||||
if (useDefaultValueType) {
|
||||
this.latest[name] = getValueAsType(v, numberValueTypes[name]);
|
||||
}
|
||||
else {
|
||||
this.latest[name] = v;
|
||||
}
|
||||
render && frame.render(render);
|
||||
};
|
||||
onChange();
|
||||
const cancelOnChange = value.on("change", onChange);
|
||||
computed && value.addDependent(computed);
|
||||
const remove = () => {
|
||||
cancelOnChange();
|
||||
render && cancelFrame(render);
|
||||
this.values.delete(name);
|
||||
computed && value.removeDependent(computed);
|
||||
};
|
||||
this.values.set(name, { value, onRemove: remove });
|
||||
return remove;
|
||||
}
|
||||
get(name) {
|
||||
return this.values.get(name)?.value;
|
||||
}
|
||||
destroy() {
|
||||
for (const value of this.values.values()) {
|
||||
value.onRemove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { MotionValueState };
|
||||
41
node_modules/motion-dom/dist/es/effects/attr/index.mjs
generated
vendored
Normal file
41
node_modules/motion-dom/dist/es/effects/attr/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import { camelToDash } from '../../render/dom/utils/camel-to-dash.mjs';
|
||||
import { createSelectorEffect } from '../utils/create-dom-effect.mjs';
|
||||
import { createEffect } from '../utils/create-effect.mjs';
|
||||
|
||||
function canSetAsProperty(element, name) {
|
||||
if (!(name in element))
|
||||
return false;
|
||||
const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(element), name) ||
|
||||
Object.getOwnPropertyDescriptor(element, name);
|
||||
// Check if it has a setter
|
||||
return descriptor && typeof descriptor.set === "function";
|
||||
}
|
||||
const addAttrValue = (element, state, key, value) => {
|
||||
const isProp = canSetAsProperty(element, key);
|
||||
const name = isProp
|
||||
? key
|
||||
: key.startsWith("data") || key.startsWith("aria")
|
||||
? camelToDash(key)
|
||||
: key;
|
||||
/**
|
||||
* Set attribute directly via property if available
|
||||
*/
|
||||
const render = isProp
|
||||
? () => {
|
||||
element[name] = state.latest[key];
|
||||
}
|
||||
: () => {
|
||||
const v = state.latest[key];
|
||||
if (v === null || v === undefined) {
|
||||
element.removeAttribute(name);
|
||||
}
|
||||
else {
|
||||
element.setAttribute(name, String(v));
|
||||
}
|
||||
};
|
||||
return state.set(key, value, render);
|
||||
};
|
||||
const attrEffect = /*@__PURE__*/ createSelectorEffect(
|
||||
/*@__PURE__*/ createEffect(addAttrValue));
|
||||
|
||||
export { addAttrValue, attrEffect };
|
||||
9
node_modules/motion-dom/dist/es/effects/prop/index.mjs
generated
vendored
Normal file
9
node_modules/motion-dom/dist/es/effects/prop/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import { createEffect } from '../utils/create-effect.mjs';
|
||||
|
||||
const propEffect = /*@__PURE__*/ createEffect((subject, state, key, value) => {
|
||||
return state.set(key, value, () => {
|
||||
subject[key] = state.latest[key];
|
||||
}, undefined, false);
|
||||
});
|
||||
|
||||
export { propEffect };
|
||||
52
node_modules/motion-dom/dist/es/effects/style/index.mjs
generated
vendored
Normal file
52
node_modules/motion-dom/dist/es/effects/style/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
import { isCSSVar } from '../../render/dom/is-css-var.mjs';
|
||||
import { transformProps } from '../../render/utils/keys-transform.mjs';
|
||||
import { isHTMLElement } from '../../utils/is-html-element.mjs';
|
||||
import { MotionValue } from '../../value/index.mjs';
|
||||
import { createSelectorEffect } from '../utils/create-dom-effect.mjs';
|
||||
import { createEffect } from '../utils/create-effect.mjs';
|
||||
import { buildTransform } from './transform.mjs';
|
||||
|
||||
const originProps = new Set(["originX", "originY", "originZ"]);
|
||||
const addStyleValue = (element, state, key, value) => {
|
||||
let render = undefined;
|
||||
let computed = undefined;
|
||||
if (transformProps.has(key)) {
|
||||
if (!state.get("transform")) {
|
||||
// If this is an HTML element, we need to set the transform-box to fill-box
|
||||
// to normalise the transform relative to the element's bounding box
|
||||
if (!isHTMLElement(element) && !state.get("transformBox")) {
|
||||
addStyleValue(element, state, "transformBox", new MotionValue("fill-box"));
|
||||
}
|
||||
state.set("transform", new MotionValue("none"), () => {
|
||||
element.style.transform = buildTransform(state);
|
||||
});
|
||||
}
|
||||
computed = state.get("transform");
|
||||
}
|
||||
else if (originProps.has(key)) {
|
||||
if (!state.get("transformOrigin")) {
|
||||
state.set("transformOrigin", new MotionValue(""), () => {
|
||||
const originX = state.latest.originX ?? "50%";
|
||||
const originY = state.latest.originY ?? "50%";
|
||||
const originZ = state.latest.originZ ?? 0;
|
||||
element.style.transformOrigin = `${originX} ${originY} ${originZ}`;
|
||||
});
|
||||
}
|
||||
computed = state.get("transformOrigin");
|
||||
}
|
||||
else if (isCSSVar(key)) {
|
||||
render = () => {
|
||||
element.style.setProperty(key, state.latest[key]);
|
||||
};
|
||||
}
|
||||
else {
|
||||
render = () => {
|
||||
element.style[key] = state.latest[key];
|
||||
};
|
||||
}
|
||||
return state.set(key, value, render, computed);
|
||||
};
|
||||
const styleEffect = /*@__PURE__*/ createSelectorEffect(
|
||||
/*@__PURE__*/ createEffect(addStyleValue));
|
||||
|
||||
export { addStyleValue, styleEffect };
|
||||
38
node_modules/motion-dom/dist/es/effects/style/transform.mjs
generated
vendored
Normal file
38
node_modules/motion-dom/dist/es/effects/style/transform.mjs
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import { transformPropOrder } from '../../render/utils/keys-transform.mjs';
|
||||
|
||||
const translateAlias = {
|
||||
x: "translateX",
|
||||
y: "translateY",
|
||||
z: "translateZ",
|
||||
transformPerspective: "perspective",
|
||||
};
|
||||
function buildTransform(state) {
|
||||
let transform = "";
|
||||
let transformIsDefault = true;
|
||||
/**
|
||||
* Loop over all possible transforms in order, adding the ones that
|
||||
* are present to the transform string.
|
||||
*/
|
||||
for (let i = 0; i < transformPropOrder.length; i++) {
|
||||
const key = transformPropOrder[i];
|
||||
const value = state.latest[key];
|
||||
if (value === undefined)
|
||||
continue;
|
||||
let valueIsDefault = true;
|
||||
if (typeof value === "number") {
|
||||
valueIsDefault = value === (key.startsWith("scale") ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
valueIsDefault = parseFloat(value) === 0;
|
||||
}
|
||||
if (!valueIsDefault) {
|
||||
transformIsDefault = false;
|
||||
const transformName = translateAlias[key] || key;
|
||||
const valueToRender = state.latest[key];
|
||||
transform += `${transformName}(${valueToRender}) `;
|
||||
}
|
||||
}
|
||||
return transformIsDefault ? "none" : transform.trim();
|
||||
}
|
||||
|
||||
export { buildTransform };
|
||||
41
node_modules/motion-dom/dist/es/effects/svg/index.mjs
generated
vendored
Normal file
41
node_modules/motion-dom/dist/es/effects/svg/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import { MotionValue } from '../../value/index.mjs';
|
||||
import { px } from '../../value/types/numbers/units.mjs';
|
||||
import { addAttrValue } from '../attr/index.mjs';
|
||||
import { addStyleValue } from '../style/index.mjs';
|
||||
import { createSelectorEffect } from '../utils/create-dom-effect.mjs';
|
||||
import { createEffect } from '../utils/create-effect.mjs';
|
||||
import { frame } from '../../frameloop/frame.mjs';
|
||||
|
||||
const toPx = px.transform;
|
||||
function addSVGPathValue(element, state, key, value) {
|
||||
frame.render(() => element.setAttribute("pathLength", "1"));
|
||||
if (key === "pathOffset") {
|
||||
return state.set(key, value, () => element.setAttribute("stroke-dashoffset", toPx(-state.latest[key])));
|
||||
}
|
||||
else {
|
||||
if (!state.get("stroke-dasharray")) {
|
||||
state.set("stroke-dasharray", new MotionValue("1 1"), () => {
|
||||
const { pathLength = 1, pathSpacing } = state.latest;
|
||||
element.setAttribute("stroke-dasharray", `${toPx(pathLength)} ${toPx(pathSpacing ?? 1 - Number(pathLength))}`);
|
||||
});
|
||||
}
|
||||
return state.set(key, value, undefined, state.get("stroke-dasharray"));
|
||||
}
|
||||
}
|
||||
const addSVGValue = (element, state, key, value) => {
|
||||
if (key.startsWith("path")) {
|
||||
return addSVGPathValue(element, state, key, value);
|
||||
}
|
||||
else if (key.startsWith("attr")) {
|
||||
return addAttrValue(element, state, convertAttrKey(key), value);
|
||||
}
|
||||
const handler = key in element.style ? addStyleValue : addAttrValue;
|
||||
return handler(element, state, key, value);
|
||||
};
|
||||
const svgEffect = /*@__PURE__*/ createSelectorEffect(
|
||||
/*@__PURE__*/ createEffect(addSVGValue));
|
||||
function convertAttrKey(key) {
|
||||
return key.replace(/^attr([A-Z])/, (_, firstChar) => firstChar.toLowerCase());
|
||||
}
|
||||
|
||||
export { svgEffect };
|
||||
18
node_modules/motion-dom/dist/es/effects/utils/create-dom-effect.mjs
generated
vendored
Normal file
18
node_modules/motion-dom/dist/es/effects/utils/create-dom-effect.mjs
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import { resolveElements } from '../../utils/resolve-elements.mjs';
|
||||
|
||||
function createSelectorEffect(subjectEffect) {
|
||||
return (subject, values) => {
|
||||
const elements = resolveElements(subject);
|
||||
const subscriptions = [];
|
||||
for (const element of elements) {
|
||||
const remove = subjectEffect(element, values);
|
||||
subscriptions.push(remove);
|
||||
}
|
||||
return () => {
|
||||
for (const remove of subscriptions)
|
||||
remove();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export { createSelectorEffect };
|
||||
21
node_modules/motion-dom/dist/es/effects/utils/create-effect.mjs
generated
vendored
Normal file
21
node_modules/motion-dom/dist/es/effects/utils/create-effect.mjs
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import { MotionValueState } from '../MotionValueState.mjs';
|
||||
|
||||
function createEffect(addValue) {
|
||||
const stateCache = new WeakMap();
|
||||
const subscriptions = [];
|
||||
return (subject, values) => {
|
||||
const state = stateCache.get(subject) ?? new MotionValueState();
|
||||
stateCache.set(subject, state);
|
||||
for (const key in values) {
|
||||
const value = values[key];
|
||||
const remove = addValue(subject, state, key, value);
|
||||
subscriptions.push(remove);
|
||||
}
|
||||
return () => {
|
||||
for (const cancel of subscriptions)
|
||||
cancel();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export { createEffect };
|
||||
Reference in New Issue
Block a user