Mission Control Dashboard - Initial implementation

This commit is contained in:
Daniel Arroyo
2026-03-27 18:36:05 +00:00
parent 257cea2c7d
commit a8fb4d4555
12516 changed files with 2307128 additions and 2 deletions

View File

@@ -0,0 +1,43 @@
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;
}
}
export { MotionValueState };
//# sourceMappingURL=MotionValueState.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"MotionValueState.mjs","sources":["../../../src/effects/MotionValueState.ts"],"sourcesContent":["import { AnyResolvedKeyframe } from \"../animation/types\"\nimport { cancelFrame, frame } from \"../frameloop/frame\"\nimport { MotionValue } from \"../value\"\nimport { numberValueTypes } from \"../value/types/maps/number\"\nimport { getValueAsType } from \"../value/types/utils/get-as-type\"\n\nexport class MotionValueState {\n latest: { [name: string]: AnyResolvedKeyframe } = {}\n\n private values = new Map<\n string,\n { value: MotionValue; onRemove: VoidFunction }\n >()\n\n set(\n name: string,\n value: MotionValue,\n render?: VoidFunction,\n computed?: MotionValue,\n useDefaultValueType = true\n ) {\n const existingValue = this.values.get(name)\n\n if (existingValue) {\n existingValue.onRemove()\n }\n\n const onChange = () => {\n const v = value.get()\n\n if (useDefaultValueType) {\n this.latest[name] = getValueAsType(v, numberValueTypes[name])\n } else {\n this.latest[name] = v\n }\n\n render && frame.render(render)\n }\n\n onChange()\n\n const cancelOnChange = value.on(\"change\", onChange)\n\n computed && value.addDependent(computed)\n\n const remove = () => {\n cancelOnChange()\n render && cancelFrame(render)\n this.values.delete(name)\n computed && value.removeDependent(computed)\n }\n\n this.values.set(name, { value, onRemove: remove })\n\n return remove\n }\n\n get(name: string): MotionValue | undefined {\n return this.values.get(name)?.value\n }\n}\n"],"names":[],"mappings":";;;;MAMa,gBAAgB,CAAA;AAA7B,IAAA,WAAA,GAAA;QACI,IAAA,CAAA,MAAM,GAA4C,EAAE;AAE5C,QAAA,IAAA,CAAA,MAAM,GAAG,IAAI,GAAG,EAGrB;IAgDP;IA9CI,GAAG,CACC,IAAY,EACZ,KAAkB,EAClB,MAAqB,EACrB,QAAsB,EACtB,mBAAmB,GAAG,IAAI,EAAA;QAE1B,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QAE3C,IAAI,aAAa,EAAE;YACf,aAAa,CAAC,QAAQ,EAAE;QAC5B;QAEA,MAAM,QAAQ,GAAG,MAAK;AAClB,YAAA,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE;YAErB,IAAI,mBAAmB,EAAE;AACrB,gBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACjE;iBAAO;AACH,gBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;YACzB;AAEA,YAAA,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;AAClC,QAAA,CAAC;AAED,QAAA,QAAQ,EAAE;QAEV,MAAM,cAAc,GAAG,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;AAEnD,QAAA,QAAQ,IAAI,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC;QAExC,MAAM,MAAM,GAAG,MAAK;AAChB,YAAA,cAAc,EAAE;AAChB,YAAA,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC;AAC7B,YAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;AACxB,YAAA,QAAQ,IAAI,KAAK,CAAC,eAAe,CAAC,QAAQ,CAAC;AAC/C,QAAA,CAAC;AAED,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAElD,QAAA,OAAO,MAAM;IACjB;AAEA,IAAA,GAAG,CAAC,IAAY,EAAA;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK;IACvC;AACH;;;;"}

42
node_modules/motion-dom/dist/es/effects/attr/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,42 @@
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 };
//# sourceMappingURL=index.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":["../../../../src/effects/attr/index.ts"],"sourcesContent":["import { camelToDash } from \"../../render/dom/utils/camel-to-dash\"\nimport { MotionValue } from \"../../value\"\nimport { MotionValueState } from \"../MotionValueState\"\nimport { createSelectorEffect } from \"../utils/create-dom-effect\"\nimport { createEffect } from \"../utils/create-effect\"\n\nfunction canSetAsProperty(element: HTMLElement | SVGElement, name: string) {\n if (!(name in element)) return false\n\n const descriptor =\n Object.getOwnPropertyDescriptor(Object.getPrototypeOf(element), name) ||\n Object.getOwnPropertyDescriptor(element, name)\n\n // Check if it has a setter\n return descriptor && typeof descriptor.set === \"function\"\n}\n\nexport const addAttrValue = (\n element: HTMLElement | SVGElement,\n state: MotionValueState,\n key: string,\n value: MotionValue\n) => {\n const isProp = canSetAsProperty(element, key)\n const name = isProp\n ? key\n : key.startsWith(\"data\") || key.startsWith(\"aria\")\n ? camelToDash(key)\n : key\n\n /**\n * Set attribute directly via property if available\n */\n const render = isProp\n ? () => {\n ;(element as any)[name] = state.latest[key]\n }\n : () => {\n const v = state.latest[key]\n if (v === null || v === undefined) {\n element.removeAttribute(name)\n } else {\n element.setAttribute(name, String(v))\n }\n }\n\n return state.set(key, value, render)\n}\n\nexport const attrEffect = /*@__PURE__*/ createSelectorEffect(\n /*@__PURE__*/ createEffect(addAttrValue)\n)\n"],"names":[],"mappings":";;;;AAMA,SAAS,gBAAgB,CAAC,OAAiC,EAAE,IAAY,EAAA;AACrE,IAAA,IAAI,EAAE,IAAI,IAAI,OAAO,CAAC;AAAE,QAAA,OAAO,KAAK;AAEpC,IAAA,MAAM,UAAU,GACZ,MAAM,CAAC,wBAAwB,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC;AACrE,QAAA,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,IAAI,CAAC;;IAGlD,OAAO,UAAU,IAAI,OAAO,UAAU,CAAC,GAAG,KAAK,UAAU;AAC7D;AAEO,MAAM,YAAY,GAAG,CACxB,OAAiC,EACjC,KAAuB,EACvB,GAAW,EACX,KAAkB,KAClB;IACA,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC;IAC7C,MAAM,IAAI,GAAG;AACT,UAAE;AACF,UAAE,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM;AACjD,cAAE,WAAW,CAAC,GAAG;cACf,GAAG;AAET;;AAEG;IACH,MAAM,MAAM,GAAG;UACT,MAAK;YACC,OAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;QAC/C;UACA,MAAK;YACD,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;YAC3B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,EAAE;AAC/B,gBAAA,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC;YACjC;iBAAO;gBACH,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;YACzC;AACJ,QAAA,CAAC;IAEP,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC;AACxC;AAEO,MAAM,UAAU,iBAAiB,oBAAoB;AACxD,cAAc,YAAY,CAAC,YAAY,CAAC;;;;"}

10
node_modules/motion-dom/dist/es/effects/prop/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,10 @@
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 };
//# sourceMappingURL=index.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":["../../../../src/effects/prop/index.ts"],"sourcesContent":["import { MotionValue } from \"../../value\"\nimport { MotionValueState } from \"../MotionValueState\"\nimport { createEffect } from \"../utils/create-effect\"\n\nexport const propEffect = /*@__PURE__*/ createEffect(\n (\n subject: { [key: string]: any },\n state: MotionValueState,\n key: string,\n value: MotionValue\n ) => {\n return state.set(\n key,\n value,\n () => {\n subject[key] = state.latest[key]\n },\n undefined,\n false\n )\n }\n)\n"],"names":[],"mappings":";;AAIO,MAAM,UAAU,iBAAiB,YAAY,CAChD,CACI,OAA+B,EAC/B,KAAuB,EACvB,GAAW,EACX,KAAkB,KAClB;IACA,OAAO,KAAK,CAAC,GAAG,CACZ,GAAG,EACH,KAAK,EACL,MAAK;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;AACpC,IAAA,CAAC,EACD,SAAS,EACT,KAAK,CACR;AACL,CAAC;;;;"}

View File

@@ -0,0 +1,53 @@
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 };
//# sourceMappingURL=index.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":["../../../../src/effects/style/index.ts"],"sourcesContent":["import { isCSSVar } from \"../../render/dom/is-css-var\"\nimport { transformProps } from \"../../render/utils/keys-transform\"\nimport { isHTMLElement } from \"../../utils/is-html-element\"\nimport { MotionValue } from \"../../value\"\nimport { MotionValueState } from \"../MotionValueState\"\nimport { createSelectorEffect } from \"../utils/create-dom-effect\"\nimport { createEffect } from \"../utils/create-effect\"\nimport { buildTransform } from \"./transform\"\n\nconst originProps = new Set([\"originX\", \"originY\", \"originZ\"])\n\nexport const addStyleValue = (\n element: HTMLElement | SVGElement,\n state: MotionValueState,\n key: string,\n value: MotionValue\n) => {\n let render: VoidFunction | undefined = undefined\n let computed: MotionValue | undefined = undefined\n\n if (transformProps.has(key)) {\n if (!state.get(\"transform\")) {\n // If this is an HTML element, we need to set the transform-box to fill-box\n // to normalise the transform relative to the element's bounding box\n if (!isHTMLElement(element) && !state.get(\"transformBox\")) {\n addStyleValue(\n element,\n state,\n \"transformBox\",\n new MotionValue(\"fill-box\")\n )\n }\n\n state.set(\"transform\", new MotionValue(\"none\"), () => {\n element.style.transform = buildTransform(state)\n })\n }\n\n computed = state.get(\"transform\")\n } else if (originProps.has(key)) {\n if (!state.get(\"transformOrigin\")) {\n state.set(\"transformOrigin\", new MotionValue(\"\"), () => {\n const originX = state.latest.originX ?? \"50%\"\n const originY = state.latest.originY ?? \"50%\"\n const originZ = state.latest.originZ ?? 0\n element.style.transformOrigin = `${originX} ${originY} ${originZ}`\n })\n }\n\n computed = state.get(\"transformOrigin\")\n } else if (isCSSVar(key)) {\n render = () => {\n element.style.setProperty(key, state.latest[key] as string)\n }\n } else {\n render = () => {\n element.style[key as any] = state.latest[key] as string\n }\n }\n\n return state.set(key, value, render, computed)\n}\n\nexport const styleEffect = /*@__PURE__*/ createSelectorEffect(\n /*@__PURE__*/ createEffect(addStyleValue)\n)\n"],"names":[],"mappings":";;;;;;;;AASA,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAEvD,MAAM,aAAa,GAAG,CACzB,OAAiC,EACjC,KAAuB,EACvB,GAAW,EACX,KAAkB,KAClB;IACA,IAAI,MAAM,GAA6B,SAAS;IAChD,IAAI,QAAQ,GAA4B,SAAS;AAEjD,IAAA,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;;;AAGzB,YAAA,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE;AACvD,gBAAA,aAAa,CACT,OAAO,EACP,KAAK,EACL,cAAc,EACd,IAAI,WAAW,CAAC,UAAU,CAAC,CAC9B;YACL;AAEA,YAAA,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,MAAK;gBACjD,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC;AACnD,YAAA,CAAC,CAAC;QACN;AAEA,QAAA,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;IACrC;AAAO,SAAA,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE;AAC/B,YAAA,KAAK,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE,MAAK;gBACnD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,KAAK;gBAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,KAAK;gBAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC;AACzC,gBAAA,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE;AACtE,YAAA,CAAC,CAAC;QACN;AAEA,QAAA,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC3C;AAAO,SAAA,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE;QACtB,MAAM,GAAG,MAAK;AACV,YAAA,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAW,CAAC;AAC/D,QAAA,CAAC;IACL;SAAO;QACH,MAAM,GAAG,MAAK;AACV,YAAA,OAAO,CAAC,KAAK,CAAC,GAAU,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAW;AAC3D,QAAA,CAAC;IACL;AAEA,IAAA,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC;AAClD;AAEO,MAAM,WAAW,iBAAiB,oBAAoB;AACzD,cAAc,YAAY,CAAC,aAAa,CAAC;;;;"}

View File

@@ -0,0 +1,39 @@
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 {
const parsed = parseFloat(value);
valueIsDefault = key.startsWith("scale") ? parsed === 1 : parsed === 0;
}
if (!valueIsDefault) {
transformIsDefault = false;
const transformName = translateAlias[key] || key;
transform += `${transformName}(${value}) `;
}
}
return transformIsDefault ? "none" : transform.trim();
}
export { buildTransform };
//# sourceMappingURL=transform.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform.mjs","sources":["../../../../src/effects/style/transform.ts"],"sourcesContent":["import { transformPropOrder } from \"../../render/utils/keys-transform\"\nimport { MotionValueState } from \"../MotionValueState\"\n\nconst translateAlias = {\n x: \"translateX\",\n y: \"translateY\",\n z: \"translateZ\",\n transformPerspective: \"perspective\",\n}\n\nexport function buildTransform(state: MotionValueState) {\n let transform = \"\"\n let transformIsDefault = true\n\n /**\n * Loop over all possible transforms in order, adding the ones that\n * are present to the transform string.\n */\n for (let i = 0; i < transformPropOrder.length; i++) {\n const key = transformPropOrder[i] as keyof typeof translateAlias\n const value = state.latest[key]\n\n if (value === undefined) continue\n\n let valueIsDefault = true\n if (typeof value === \"number\") {\n valueIsDefault = value === (key.startsWith(\"scale\") ? 1 : 0)\n } else {\n const parsed = parseFloat(value)\n valueIsDefault = key.startsWith(\"scale\") ? parsed === 1 : parsed === 0\n }\n\n if (!valueIsDefault) {\n transformIsDefault = false\n const transformName = translateAlias[key] || key\n transform += `${transformName}(${value}) `\n }\n }\n\n return transformIsDefault ? \"none\" : transform.trim()\n}\n"],"names":[],"mappings":";;AAGA,MAAM,cAAc,GAAG;AACnB,IAAA,CAAC,EAAE,YAAY;AACf,IAAA,CAAC,EAAE,YAAY;AACf,IAAA,CAAC,EAAE,YAAY;AACf,IAAA,oBAAoB,EAAE,aAAa;CACtC;AAEK,SAAU,cAAc,CAAC,KAAuB,EAAA;IAClD,IAAI,SAAS,GAAG,EAAE;IAClB,IAAI,kBAAkB,GAAG,IAAI;AAE7B;;;AAGG;AACH,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAChD,QAAA,MAAM,GAAG,GAAG,kBAAkB,CAAC,CAAC,CAAgC;QAChE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;QAE/B,IAAI,KAAK,KAAK,SAAS;YAAE;QAEzB,IAAI,cAAc,GAAG,IAAI;AACzB,QAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC3B,YAAA,cAAc,GAAG,KAAK,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChE;aAAO;AACH,YAAA,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC;AAChC,YAAA,cAAc,GAAG,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC;QAC1E;QAEA,IAAI,CAAC,cAAc,EAAE;YACjB,kBAAkB,GAAG,KAAK;YAC1B,MAAM,aAAa,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,GAAG;AAChD,YAAA,SAAS,IAAI,CAAA,EAAG,aAAa,CAAA,CAAA,EAAI,KAAK,IAAI;QAC9C;IACJ;AAEA,IAAA,OAAO,kBAAkB,GAAG,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE;AACzD;;;;"}

45
node_modules/motion-dom/dist/es/effects/svg/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,45 @@
import { MotionValue } from '../../value/index.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';
function addSVGPathValue(element, state, key, value) {
frame.render(() => element.setAttribute("pathLength", "1"));
if (key === "pathOffset") {
return state.set(key, value, () => {
// Use unitless value to avoid Safari zoom bug
const offset = state.latest[key];
element.setAttribute("stroke-dashoffset", `${-offset}`);
});
}
else {
if (!state.get("stroke-dasharray")) {
state.set("stroke-dasharray", new MotionValue("1 1"), () => {
const { pathLength = 1, pathSpacing } = state.latest;
// Use unitless values to avoid Safari zoom bug
element.setAttribute("stroke-dasharray", `${pathLength} ${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 };
//# sourceMappingURL=index.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":["../../../../src/effects/svg/index.ts"],"sourcesContent":["import { frame } from \"../../frameloop\"\nimport { MotionValue } from \"../../value\"\nimport { addAttrValue } from \"../attr\"\nimport { MotionValueState } from \"../MotionValueState\"\nimport { addStyleValue } from \"../style\"\nimport { createSelectorEffect } from \"../utils/create-dom-effect\"\nimport { createEffect } from \"../utils/create-effect\"\n\nfunction addSVGPathValue(\n element: SVGElement,\n state: MotionValueState,\n key: string,\n value: MotionValue\n) {\n frame.render(() => element.setAttribute(\"pathLength\", \"1\"))\n\n if (key === \"pathOffset\") {\n return state.set(key, value, () => {\n // Use unitless value to avoid Safari zoom bug\n const offset = state.latest[key]\n element.setAttribute(\"stroke-dashoffset\", `${-offset}`)\n })\n } else {\n if (!state.get(\"stroke-dasharray\")) {\n state.set(\"stroke-dasharray\", new MotionValue(\"1 1\"), () => {\n const { pathLength = 1, pathSpacing } = state.latest\n\n // Use unitless values to avoid Safari zoom bug\n element.setAttribute(\n \"stroke-dasharray\",\n `${pathLength} ${pathSpacing ?? 1 - Number(pathLength)}`\n )\n })\n }\n\n return state.set(key, value, undefined, state.get(\"stroke-dasharray\"))\n }\n}\n\nconst addSVGValue = (\n element: SVGElement,\n state: MotionValueState,\n key: string,\n value: MotionValue\n) => {\n if (key.startsWith(\"path\")) {\n return addSVGPathValue(element, state, key, value)\n } else if (key.startsWith(\"attr\")) {\n return addAttrValue(element, state, convertAttrKey(key), value)\n }\n\n const handler = key in element.style ? addStyleValue : addAttrValue\n return handler(element, state, key, value)\n}\n\nexport const svgEffect = /*@__PURE__*/ createSelectorEffect(\n /*@__PURE__*/ createEffect(addSVGValue)\n)\n\nfunction convertAttrKey(key: string) {\n return key.replace(/^attr([A-Z])/, (_, firstChar) =>\n firstChar.toLowerCase()\n )\n}\n"],"names":[],"mappings":";;;;;;;AAQA,SAAS,eAAe,CACpB,OAAmB,EACnB,KAAuB,EACvB,GAAW,EACX,KAAkB,EAAA;AAElB,IAAA,KAAK,CAAC,MAAM,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAE3D,IAAA,IAAI,GAAG,KAAK,YAAY,EAAE;QACtB,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,MAAK;;YAE9B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;YAChC,OAAO,CAAC,YAAY,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAA,CAAE,CAAC;AAC3D,QAAA,CAAC,CAAC;IACN;SAAO;QACH,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE;AAChC,YAAA,KAAK,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,MAAK;gBACvD,MAAM,EAAE,UAAU,GAAG,CAAC,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,MAAM;;AAGpD,gBAAA,OAAO,CAAC,YAAY,CAChB,kBAAkB,EAClB,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,WAAW,IAAI,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA,CAAE,CAC3D;AACL,YAAA,CAAC,CAAC;QACN;AAEA,QAAA,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC1E;AACJ;AAEA,MAAM,WAAW,GAAG,CAChB,OAAmB,EACnB,KAAuB,EACvB,GAAW,EACX,KAAkB,KAClB;AACA,IAAA,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;QACxB,OAAO,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC;IACtD;AAAO,SAAA,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;AAC/B,QAAA,OAAO,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IACnE;AAEA,IAAA,MAAM,OAAO,GAAG,GAAG,IAAI,OAAO,CAAC,KAAK,GAAG,aAAa,GAAG,YAAY;IACnE,OAAO,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC;AAC9C,CAAC;AAEM,MAAM,SAAS,iBAAiB,oBAAoB;AACvD,cAAc,YAAY,CAAC,WAAW,CAAC;AAG3C,SAAS,cAAc,CAAC,GAAW,EAAA;AAC/B,IAAA,OAAO,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,SAAS,KAC5C,SAAS,CAAC,WAAW,EAAE,CAC1B;AACL;;;;"}

View File

@@ -0,0 +1,19 @@
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 };
//# sourceMappingURL=create-dom-effect.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"create-dom-effect.mjs","sources":["../../../../src/effects/utils/create-dom-effect.ts"],"sourcesContent":["import {\n ElementOrSelector,\n resolveElements,\n} from \"../../utils/resolve-elements\"\nimport { MotionValue } from \"../../value\"\n\nexport function createSelectorEffect<T>(\n subjectEffect: (\n subject: T,\n values: Record<string, MotionValue>\n ) => VoidFunction\n) {\n return (\n subject: ElementOrSelector,\n values: Record<string, MotionValue>\n ) => {\n const elements = resolveElements(subject)\n const subscriptions: VoidFunction[] = []\n\n for (const element of elements) {\n const remove = subjectEffect(element as T, values)\n subscriptions.push(remove)\n }\n\n return () => {\n for (const remove of subscriptions) remove()\n }\n }\n}\n"],"names":[],"mappings":";;AAMM,SAAU,oBAAoB,CAChC,aAGiB,EAAA;AAEjB,IAAA,OAAO,CACH,OAA0B,EAC1B,MAAmC,KACnC;AACA,QAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC;QACzC,MAAM,aAAa,GAAmB,EAAE;AAExC,QAAA,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC5B,MAAM,MAAM,GAAG,aAAa,CAAC,OAAY,EAAE,MAAM,CAAC;AAClD,YAAA,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9B;AAEA,QAAA,OAAO,MAAK;YACR,KAAK,MAAM,MAAM,IAAI,aAAa;AAAE,gBAAA,MAAM,EAAE;AAChD,QAAA,CAAC;AACL,IAAA,CAAC;AACL;;;;"}

View File

@@ -0,0 +1,22 @@
import { MotionValueState } from '../MotionValueState.mjs';
function createEffect(addValue) {
const stateCache = new WeakMap();
return (subject, values) => {
const state = stateCache.get(subject) ?? new MotionValueState();
stateCache.set(subject, state);
const subscriptions = [];
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 };
//# sourceMappingURL=create-effect.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"create-effect.mjs","sources":["../../../../src/effects/utils/create-effect.ts"],"sourcesContent":["import { MotionValue } from \"../../value\"\nimport { MotionValueState } from \"../MotionValueState\"\n\nexport function createEffect<Subject extends object>(\n addValue: (\n subject: Subject,\n state: MotionValueState,\n key: string,\n value: MotionValue\n ) => VoidFunction\n) {\n const stateCache = new WeakMap<Subject, MotionValueState>()\n\n return (\n subject: Subject,\n values: Record<string, MotionValue>\n ): VoidFunction => {\n const state = stateCache.get(subject) ?? new MotionValueState()\n\n stateCache.set(subject, state)\n\n const subscriptions: VoidFunction[] = []\n\n for (const key in values) {\n const value = values[key]\n const remove = addValue(subject, state, key, value)\n subscriptions.push(remove)\n }\n\n return () => {\n for (const cancel of subscriptions) cancel()\n }\n }\n}\n"],"names":[],"mappings":";;AAGM,SAAU,YAAY,CACxB,QAKiB,EAAA;AAEjB,IAAA,MAAM,UAAU,GAAG,IAAI,OAAO,EAA6B;AAE3D,IAAA,OAAO,CACH,OAAgB,EAChB,MAAmC,KACrB;AACd,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,gBAAgB,EAAE;AAE/D,QAAA,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC;QAE9B,MAAM,aAAa,GAAmB,EAAE;AAExC,QAAA,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;AACtB,YAAA,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC;AACzB,YAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC;AACnD,YAAA,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9B;AAEA,QAAA,OAAO,MAAK;YACR,KAAK,MAAM,MAAM,IAAI,aAAa;AAAE,gBAAA,MAAM,EAAE;AAChD,QAAA,CAAC;AACL,IAAA,CAAC;AACL;;;;"}