UNPKG

style-value-types

Version:

Parsers, transformers and tests for special value types, eg: %, hex codes etc.

222 lines (209 loc) 6.95 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const clamp = (min, max) => (v) => Math.max(Math.min(v, max), min); const sanitize = (v) => (v % 1 ? Number(v.toFixed(5)) : v); const floatRegex = /(-)?([\d]*\.?[\d])+/g; const colorRegex = /(#[0-9a-f]{6}|#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2}(-?[\d\.]+%?)\s*[\,\/]?\s*[\d\.]*%?\))/gi; const singleColorRegex = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?[\d\.]+%?[,\s]+){2}(-?[\d\.]+%?)\s*[\,\/]?\s*[\d\.]*%?\))$/i; function isString(v) { return typeof v === 'string'; } const number = { test: (v) => typeof v === 'number', parse: parseFloat, transform: (v) => v, }; const alpha = Object.assign(Object.assign({}, number), { transform: clamp(0, 1) }); const scale = Object.assign(Object.assign({}, number), { default: 1 }); const createUnitType = (unit) => ({ test: (v) => isString(v) && v.endsWith(unit) && v.split(' ').length === 1, parse: parseFloat, transform: (v) => `${v}${unit}`, }); const degrees = createUnitType('deg'); const percent = createUnitType('%'); const px = createUnitType('px'); const vh = createUnitType('vh'); const vw = createUnitType('vw'); const progressPercentage = Object.assign(Object.assign({}, percent), { parse: (v) => percent.parse(v) / 100, transform: (v) => percent.transform(v * 100) }); const isColorString = (type, testProp) => (v) => { return Boolean((isString(v) && singleColorRegex.test(v) && v.startsWith(type)) || (testProp && Object.prototype.hasOwnProperty.call(v, testProp))); }; const splitColor = (aName, bName, cName) => (v) => { if (!isString(v)) return v; const [a, b, c, alpha] = v.match(floatRegex); return { [aName]: parseFloat(a), [bName]: parseFloat(b), [cName]: parseFloat(c), alpha: alpha !== undefined ? parseFloat(alpha) : 1, }; }; const hsla = { test: isColorString('hsl', 'hue'), parse: splitColor('hue', 'saturation', 'lightness'), transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => { return ('hsla(' + Math.round(hue) + ', ' + percent.transform(sanitize(saturation)) + ', ' + percent.transform(sanitize(lightness)) + ', ' + sanitize(alpha.transform(alpha$1)) + ')'); }, }; const clampRgbUnit = clamp(0, 255); const rgbUnit = Object.assign(Object.assign({}, number), { transform: (v) => Math.round(clampRgbUnit(v)) }); const rgba = { test: isColorString('rgb', 'red'), parse: splitColor('red', 'green', 'blue'), transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => 'rgba(' + rgbUnit.transform(red) + ', ' + rgbUnit.transform(green) + ', ' + rgbUnit.transform(blue) + ', ' + sanitize(alpha.transform(alpha$1)) + ')', }; function parseHex(v) { let r = ''; let g = ''; let b = ''; let a = ''; if (v.length > 5) { r = v.substr(1, 2); g = v.substr(3, 2); b = v.substr(5, 2); a = v.substr(7, 2); } else { r = v.substr(1, 1); g = v.substr(2, 1); b = v.substr(3, 1); a = v.substr(4, 1); r += r; g += g; b += b; a += a; } return { red: parseInt(r, 16), green: parseInt(g, 16), blue: parseInt(b, 16), alpha: a ? parseInt(a, 16) / 255 : 1, }; } const hex = { test: isColorString('#'), parse: parseHex, transform: rgba.transform, }; const color = { test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v), parse: (v) => { if (rgba.test(v)) { return rgba.parse(v); } else if (hsla.test(v)) { return hsla.parse(v); } else { return hex.parse(v); } }, transform: (v) => { return isString(v) ? v : v.hasOwnProperty('red') ? rgba.transform(v) : hsla.transform(v); }, }; const colorToken = '${c}'; const numberToken = '${n}'; function test(v) { var _a, _b, _c, _d; return (isNaN(v) && isString(v) && ((_b = (_a = v.match(floatRegex)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) + ((_d = (_c = v.match(colorRegex)) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) > 0); } function analyse(v) { if (typeof v === 'number') v = `${v}`; const values = []; let numColors = 0; const colors = v.match(colorRegex); if (colors) { numColors = colors.length; v = v.replace(colorRegex, colorToken); values.push(...colors.map(color.parse)); } const numbers = v.match(floatRegex); if (numbers) { v = v.replace(floatRegex, numberToken); values.push(...numbers.map(number.parse)); } return { values, numColors, tokenised: v }; } function parse(v) { return analyse(v).values; } function createTransformer(v) { const { values, numColors, tokenised } = analyse(v); const numValues = values.length; return (v) => { let output = tokenised; for (let i = 0; i < numValues; i++) { output = output.replace(i < numColors ? colorToken : numberToken, i < numColors ? color.transform(v[i]) : sanitize(v[i])); } return output; }; } const convertNumbersToZero = (v) => typeof v === 'number' ? 0 : v; function getAnimatableNone(v) { const parsed = parse(v); const transformer = createTransformer(v); return transformer(parsed.map(convertNumbersToZero)); } const complex = { test, parse, createTransformer, getAnimatableNone }; const maxDefaults = new Set(['brightness', 'contrast', 'saturate', 'opacity']); function applyDefaultFilter(v) { let [name, value] = v.slice(0, -1).split('('); if (name === 'drop-shadow') return v; const [number] = value.match(floatRegex) || []; if (!number) return v; const unit = value.replace(number, ''); let defaultValue = maxDefaults.has(name) ? 1 : 0; if (number !== value) defaultValue *= 100; return name + '(' + defaultValue + unit + ')'; } const functionRegex = /([a-z-]*)\(.*?\)/g; const filter = Object.assign(Object.assign({}, complex), { getAnimatableNone: (v) => { const functions = v.match(functionRegex); return functions ? functions.map(applyDefaultFilter).join(' ') : v; } }); exports.alpha = alpha; exports.color = color; exports.complex = complex; exports.degrees = degrees; exports.filter = filter; exports.hex = hex; exports.hsla = hsla; exports.number = number; exports.percent = percent; exports.progressPercentage = progressPercentage; exports.px = px; exports.rgbUnit = rgbUnit; exports.rgba = rgba; exports.scale = scale; exports.vh = vh; exports.vw = vw;