tweak-tools
Version:
Tweak your React projects until awesomeness
169 lines (168 loc) • 7.15 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getVectorPlugin = exports.normalizeVector = exports.formatVector = exports.sanitizeVector = exports.getVectorType = exports.getVectorSchema = void 0;
const v8n_1 = __importDefault(require("v8n"));
const utils_1 = require("../../utils");
const number_plugin_1 = require("../Number/number-plugin");
const vector_utils_1 = require("./vector-utils");
function getVectorSchema(dimension) {
// Check if vector matches dimension and that every item is a number
// prettier-ignore
const isVectorArray = (0, v8n_1.default)().array().length(dimension).every.number();
// check if vector is an object and that all its keys are finite numbers
const isVectorObject = (o) => {
if (!o || typeof o !== 'object')
return false;
const values = Object.values(o);
return values.length === dimension && values.every((v) => isFinite(v));
};
return (o) => {
return isVectorArray.test(o) || isVectorObject(o);
};
}
exports.getVectorSchema = getVectorSchema;
/**
* Returns 'array' if value is an array, 'object' if it's an object.
* @param value
* @returns
*/
function getVectorType(value) {
return Array.isArray(value) ? 'array' : 'object';
}
exports.getVectorType = getVectorType;
/**
* Converts a value to either an object or an array.
* @param value
* @param format
* @param keys
* @returns
*/
function convert(value, format, keys) {
if (getVectorType(value) === format)
return value;
return (format === 'array' ? Object.values(value) : (0, utils_1.mapArrayToKeys)(value, keys));
}
/**
* This function will check if the value argument is the full vector or only
* a slice of it. If it's only a slice, then it will merge it with the
* previousValue, preserving ratio if settings.lock is set.
* @param value
* @param settings
* @param previousValue
* @returns
*/
const sanitizeVector = (value, settings, previousValue) => {
// 1. We convert the value to a keyed object
const _value = convert(value, 'object', settings.keys);
for (let key in _value)
_value[key] = (0, number_plugin_1.sanitize)(_value[key], settings[key]);
// 2. We extract the keys
const _valueKeys = Object.keys(_value);
// will be the new value
let newValue = {};
// 3.a. if _value includes all keys of the vector input then _value is
// complete and can be considered as the new value.
if (_valueKeys.length === settings.keys.length)
newValue = _value;
// 3.b if _value is only a slice of the vector, therefore we need to merge
// it with the previous value.
else {
// 3.b.i We convert the previous value to an object.
const _previousValue = convert(previousValue, 'object', settings.keys);
// 3.b.i.1 if there's only one key and lock is true we keep the aspect ratio
// on all keys, then we keep the aspect ratio on all keys.
if (_valueKeys.length === 1 && settings.locked) {
// the only key from _value, which holds the base value for aspect ratio.
const lockedKey = _valueKeys[0];
// the base value for aspect ratio.
const lockedCoordinate = _value[lockedKey];
// the previous base value for aspect ratio
const previousLockedCoordinate = _previousValue[lockedKey];
// iterate through the previous value keys
const ratio = previousLockedCoordinate !== 0 ? lockedCoordinate / previousLockedCoordinate : 1;
for (let key in _previousValue) {
// if key is the lockedKey, then its new value should be the locked
// value.
if (key === lockedKey)
newValue[lockedKey] = lockedCoordinate;
// if not then the other key should change by the same ratio as the
// lockedValue
else
newValue[key] = _previousValue[key] * ratio;
}
}
else {
// _value is incomplete so we merge the previous value with the new one
newValue = Object.assign(Object.assign({}, _previousValue), _value);
}
}
return convert(newValue, settings.format, settings.keys);
};
exports.sanitizeVector = sanitizeVector;
/**
* Formats a vector into an object to be displayed.
* @param value
* @param settings
* @returns
*/
const formatVector = (value, settings) => convert(value, 'object', settings.keys);
exports.formatVector = formatVector;
/**
* Checks if an object matches the format of the settings object for a number
* input.
* @param o
* @returns
*/
const isNumberSettings = (o) => !!o && ('step' in o || 'min' in o || 'max' in o);
/**
* Normalizes a vector by extracting its keys and creating a number settings
* for each of them.
* @param _value
* @param settings
* @param defaultKeys
* @returns
*/
function normalizeVector(value, settings, defaultKeys = []) {
const { lock = false } = settings, _settings = __rest(settings, ["lock"]);
const format = Array.isArray(value) ? 'array' : 'object';
const keys = format === 'object' ? Object.keys(value) : defaultKeys;
const _value = convert(value, 'object', keys);
// vector can accept either { value: { x, y }, { x: settings, y: settings } }
// or { value: { x, y }, { settings } } where settings will apply to both keys
// merged settings will recognize a unified settings and dispatch it to all keys
const mergedSettings = isNumberSettings(_settings)
? keys.reduce((acc, k) => Object.assign(acc, { [k]: _settings }), {})
: _settings;
const numberSettings = (0, vector_utils_1.normalizeKeyedNumberSettings)(_value, mergedSettings);
return {
value: (format === 'array' ? value : _value),
settings: Object.assign(Object.assign({}, numberSettings), { format, keys, lock, locked: false }),
};
}
exports.normalizeVector = normalizeVector;
function getVectorPlugin(defaultKeys) {
return {
schema: getVectorSchema(defaultKeys.length),
normalize: (_a) => {
var { value } = _a, settings = __rest(_a, ["value"]);
return normalizeVector(value, settings, defaultKeys);
},
format: (value, settings) => (0, exports.formatVector)(value, settings),
sanitize: (value, settings, prevValue) => (0, exports.sanitizeVector)(value, settings, prevValue),
};
}
exports.getVectorPlugin = getVectorPlugin;