one
Version:
One is a React framework for web, iOS, and Android apps.
165 lines (164 loc) • 6.36 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var animatorStyle_exports = {};
__export(animatorStyle_exports, {
animatedSwiftStyle: () => animatedSwiftStyle,
animatorStyleNative: () => animatorStyleNative,
animatorStyleOf: () => animatorStyleOf
});
module.exports = __toCommonJS(animatorStyle_exports);
const animatorKey = /* @__PURE__ */ Symbol.for("one.native.animator");
function animatedSwiftStyle(animator) {
return {
...animator.samples[0],
[animatorKey]: animator
};
}
function animatorStyleOf(style) {
return style[animatorKey];
}
const colorFields = /* @__PURE__ */ new Set([
"foregroundStyle",
"tint",
"background",
"borderColor",
"glassEffectTint"
]);
function same(a, b) {
return a === b || JSON.stringify(a) === JSON.stringify(b);
}
function sdkPairs(style) {
return style.sdkModifiers ? JSON.parse(style.sdkModifiers) : [];
}
function withPayload(base, payload) {
return {
...base,
sdkModifiers: JSON.stringify([...sdkPairs(base), ["oneNativeAnimator", JSON.stringify(payload)]])
};
}
function phaseNative(animator, natives) {
const keys = [...new Set(natives.flatMap((native) => Object.keys(native)))];
const varying = keys.filter((key) => natives.some((native) => !same(native[key], natives[0][key])));
for (const key of varying) {
if (colorFields.has(key) && natives.some((native) => native[key] !== void 0 && typeof native[key] !== "number")) throw new Error(`${animator.owner} content can vary ${key} by phase only with plain colors, not platform colors`);
}
const phases = natives.map((native) => Object.fromEntries(varying.filter((key) => native[key] !== void 0).map((key) => [key, native[key]])));
return withPayload(natives[0], {
id: animator.id,
kind: "phase",
varying,
phases
});
}
const numericText = /^-?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i;
function leavesOf(value) {
const leaves = [];
const texts = [];
const leaf = (number, text, quoted) => {
leaves.push(number);
texts.push(text);
return quoted ? `__oneKS${leaves.length - 1}__` : `__oneKN${leaves.length - 1}__`;
};
if (numericText.test(value)) return {
shape: leaf(Number(value), value, true),
leaves,
texts
};
let parsed;
try {
parsed = /^[[{]/.test(value) ? JSON.parse(value) : void 0;
} catch {
parsed = void 0;
}
if (parsed === void 0) return {
shape: value,
leaves,
texts
};
const walk = (item) => {
if (typeof item === "number") return leaf(item, JSON.stringify(item), false);
if (typeof item === "string" && numericText.test(item)) return leaf(Number(item), item, true);
if (Array.isArray(item)) return item.map(walk);
if (item && typeof item === "object") return Object.fromEntries(Object.entries(item).map(([key, entry]) => [key, walk(entry)]));
return item;
};
return {
shape: JSON.stringify(walk(parsed)),
leaves,
texts
};
}
function keyframeNative(animator, natives) {
const { owner, values } = animator;
const fieldCount = values[0].length;
const tokens = [];
const bind = (samples, where) => {
if (samples.every((sample) => sample === samples[0])) return void 0;
const coefficients = Array.from({ length: fieldCount }, (_, field) => samples[field + 1] - samples[0]);
const check = values[fieldCount + 1];
let predicted = samples[0];
for (let field = 0; field < fieldCount; field++) predicted += coefficients[field] * (check[field] - values[0][field]);
const actual = samples[fieldCount + 1];
if (!(Math.abs(predicted - actual) <= 1e-6 * Math.max(1, Math.abs(actual)))) throw new Error(`${owner} content must map its value linearly to swiftStyle numbers; ${where} does not`);
let base = samples[0];
for (let field = 0; field < fieldCount; field++) base -= coefficients[field] * values[0][field];
tokens.push({
base,
coefficients
});
return tokens.length - 1;
};
const keys = [...new Set(natives.flatMap((native) => Object.keys(native)))].filter((key) => key !== "sdkModifiers");
const fields = {};
for (const key of keys) {
const samples = natives.map((native) => native[key]);
if (samples.every((sample) => same(sample, samples[0]))) continue;
if (colorFields.has(key) || !samples.every((sample) => typeof sample === "number")) throw new Error(`${owner} content can follow its value only through swiftStyle numbers; ${key} changed`);
const token = bind(samples, key);
if (token !== void 0) fields[key] = token;
}
const pairs = natives.map(sdkPairs);
const names = pairs[0].map(([name]) => name);
if (pairs.some((list) => !same(list.map(([name]) => name), names))) throw new Error(`${owner} content must apply the same swiftStyle modifiers at every value`);
const template = names.map((name, index) => {
const parts = pairs.map((list) => leavesOf(list[index][1]));
if (parts.some((part) => part.shape !== parts[0].shape)) throw new Error(`${owner} content can follow its value only through swiftStyle numbers; ${name} changed`);
let value = parts[0].shape;
parts[0].leaves.forEach((_, leaf) => {
const token = bind(parts.map((part) => part.leaves[leaf]), name);
const text = token === void 0 ? parts[0].texts[leaf] : `@@${token}@@`;
value = value.replace(`"__oneKN${leaf}__"`, text).replace(`__oneKS${leaf}__`, text);
});
return [name, value];
});
return withPayload(natives[0], {
id: animator.id,
kind: "keyframe",
fields,
sdkModifiers: template.length ? JSON.stringify(template) : void 0,
tokens
});
}
function animatorStyleNative(animator, convert) {
const natives = animator.samples.map((sample) => convert(sample) ?? {});
const native = animator.kind === "phase" ? phaseNative(animator, natives) : keyframeNative(animator, natives);
return native;
}