main repo

This commit is contained in:
Basilosaurusrex
2025-11-24 18:09:40 +01:00
parent b636ee5e70
commit f027651f9b
34146 changed files with 4436636 additions and 0 deletions

View 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
View 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 };

View 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 };

View 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 };

View 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
View 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 };

View 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 };

View 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 };