style-value-types
Advanced tools
Comparing version 2.0.1 to 3.0.0
@@ -5,2 +5,8 @@ # Changelog | ||
## [3.0.0] 2018-06-22 | ||
### Removed | ||
- Removed new `combo` in favour of a single unified `complex` value type that can handle mixed number and color strings. | ||
## [2.0.1] 2018-06-21 | ||
@@ -7,0 +13,0 @@ |
@@ -5,5 +5,4 @@ import { Transformer, ValueType, NumberMap, RGBA, HSLA, Color } from './types'; | ||
import { degrees, percent, px, vw, vh } from './value-types/units'; | ||
import { rgba, rgbUnit, hsla, hex, color } from './value-types/color'; | ||
import complex from './value-types/complex'; | ||
import { rgba, rgbUnit, hsla, hex, color } from './value-types/color'; | ||
import combo from './value-types/combo'; | ||
export { number, scale, alpha, complex, degrees, percent, px, vw, vh, rgba, rgbUnit, hex, hsla, color, combo }; | ||
export { number, scale, alpha, degrees, percent, px, vw, vh, rgba, rgbUnit, hex, hsla, color, complex }; |
@@ -29,34 +29,4 @@ const clamp = (min, max) => (v) => Math.max(Math.min(v, max), min); | ||
const FLOAT_REGEX = /(-)?(\d[\d\.]*)/g; | ||
const generateToken = (token) => '${' + token + '}'; | ||
const complex = { | ||
test: v => { | ||
const matches = v.match && v.match(FLOAT_REGEX); | ||
return (matches !== undefined && | ||
matches.constructor === Array && | ||
matches.length > 1); | ||
}, | ||
parse: v => { | ||
const parsedValue = {}; | ||
v.match(FLOAT_REGEX).forEach((value, i) => (parsedValue[i] = parseFloat(value))); | ||
return parsedValue; | ||
}, | ||
createTransformer: (prop) => { | ||
let counter = 0; | ||
const template = prop.replace(FLOAT_REGEX, () => generateToken(`${counter++}`)); | ||
return (v) => { | ||
let output = template; | ||
for (const key in v) { | ||
if (v.hasOwnProperty(key)) { | ||
output = output.replace(generateToken(key), v[key].toString()); | ||
} | ||
} | ||
return output; | ||
}; | ||
} | ||
}; | ||
const clampRgbUnit = clamp(0, 255); | ||
const onlyColorRegex = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))$/i; | ||
const containsColorRegex = /(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi; | ||
const isRgba = (v) => v.red !== undefined; | ||
@@ -155,52 +125,58 @@ const isHsla = (v) => v.hue !== undefined; | ||
const testOrder = [px, percent, degrees, vh, vw, color]; | ||
const addIfAnimatable = (acc, val) => { | ||
const valueType = testOrder.find(({ test }) => test(val)); | ||
if (valueType) | ||
acc.push(valueType.parse(val)); | ||
return acc; | ||
}; | ||
const splitCommas = (acc, token) => { | ||
token.slice(-1) === ',' ? acc.push(token.slice(0, -1), ',') : acc.push(token); | ||
return acc; | ||
}; | ||
const stripSpaces = (v) => v.replace(/ /g, ''); | ||
const splitComboString = (comboStr) => comboStr | ||
.replace(containsColorRegex, stripSpaces) | ||
.split(' ') | ||
.reduce(splitCommas, []); | ||
const getValueType = (v) => { | ||
if (v === ',') | ||
return false; | ||
return testOrder.find(valueType => valueType.test(v)) || false; | ||
}; | ||
const floatRegex = /(-)?(\d[\d\.]*)/g; | ||
const colorRegex = /(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi; | ||
const COLOR_TOKEN = '${c}'; | ||
const NUMBER_TOKEN = '${n}'; | ||
const combo = { | ||
test: (v) => typeof v === 'string' && v.split(' ').length > 1, | ||
parse: v => splitComboString(v).reduce(addIfAnimatable, []), | ||
test: (v) => { | ||
if (typeof v !== 'string') | ||
return false; | ||
let numValues = 0; | ||
const foundNumbers = v.match(floatRegex); | ||
const foundColors = v.match(colorRegex); | ||
if (foundNumbers) | ||
numValues += foundNumbers.length; | ||
if (foundColors) | ||
numValues += foundColors.length; | ||
return numValues > 1; | ||
}, | ||
parse: (v) => { | ||
let input = v; | ||
const parsed = []; | ||
const foundColors = input.match(colorRegex); | ||
if (foundColors) { | ||
input = input.replace(colorRegex, COLOR_TOKEN); | ||
parsed.push(...foundColors.map(color.parse)); | ||
} | ||
const foundNumbers = input.match(floatRegex); | ||
if (foundNumbers) { | ||
parsed.push(...foundNumbers.map(number.parse)); | ||
} | ||
return parsed; | ||
}, | ||
createTransformer: (prop) => { | ||
const splitValues = splitComboString(prop); | ||
const valueTypes = splitValues.map(getValueType); | ||
let template = prop; | ||
let token = 0; | ||
const template = valueTypes.map((valueType, i) => { | ||
const templateValue = valueType ? token : splitValues[i]; | ||
if (valueType) | ||
const foundColors = prop.match(colorRegex); | ||
const numColors = foundColors ? foundColors.length : 0; | ||
if (foundColors) { | ||
for (let i = 0; i < numColors; i++) { | ||
template = template.replace(foundColors[i], COLOR_TOKEN); | ||
token++; | ||
return templateValue; | ||
}); | ||
const templateLength = template.length; | ||
return (output) => { | ||
let built = ''; | ||
for (let i = 0; i < templateLength; i++) { | ||
const valueType = valueTypes[i]; | ||
if (valueType) { | ||
built += `${valueType.transform(output[template[i]])} `; | ||
} | ||
else { | ||
if (template[i] === ',') { | ||
built = built.trim(); | ||
} | ||
built += `${template[i]} `; | ||
} | ||
} | ||
return built.trim(); | ||
} | ||
const foundNumbers = prop.match(floatRegex); | ||
const numNumbers = foundNumbers ? foundNumbers.length : 0; | ||
if (foundNumbers) { | ||
for (let i = 0; i < numNumbers; i++) { | ||
template = template.replace(foundNumbers[i], NUMBER_TOKEN); | ||
token++; | ||
} | ||
} | ||
return (v) => { | ||
let output = template; | ||
for (let i = 0; i < token; i++) { | ||
output = output.replace(i < numColors ? COLOR_TOKEN : NUMBER_TOKEN, i < numColors ? color.transform(v[i]) : v[i]); | ||
} | ||
return output; | ||
}; | ||
@@ -210,2 +186,2 @@ } | ||
export { number, scale, alpha, complex, degrees, percent, px, vw, vh, rgba, rgbUnit, hex, hsla, color, combo }; | ||
export { number, scale, alpha, degrees, percent, px, vw, vh, rgba, rgbUnit, hex, hsla, color, combo as complex }; |
@@ -35,34 +35,4 @@ (function (global, factory) { | ||
const FLOAT_REGEX = /(-)?(\d[\d\.]*)/g; | ||
const generateToken = (token) => '${' + token + '}'; | ||
const complex = { | ||
test: v => { | ||
const matches = v.match && v.match(FLOAT_REGEX); | ||
return (matches !== undefined && | ||
matches.constructor === Array && | ||
matches.length > 1); | ||
}, | ||
parse: v => { | ||
const parsedValue = {}; | ||
v.match(FLOAT_REGEX).forEach((value, i) => (parsedValue[i] = parseFloat(value))); | ||
return parsedValue; | ||
}, | ||
createTransformer: (prop) => { | ||
let counter = 0; | ||
const template = prop.replace(FLOAT_REGEX, () => generateToken(`${counter++}`)); | ||
return (v) => { | ||
let output = template; | ||
for (const key in v) { | ||
if (v.hasOwnProperty(key)) { | ||
output = output.replace(generateToken(key), v[key].toString()); | ||
} | ||
} | ||
return output; | ||
}; | ||
} | ||
}; | ||
const clampRgbUnit = clamp(0, 255); | ||
const onlyColorRegex = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))$/i; | ||
const containsColorRegex = /(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi; | ||
const isRgba = (v) => v.red !== undefined; | ||
@@ -161,52 +131,58 @@ const isHsla = (v) => v.hue !== undefined; | ||
const testOrder = [px, percent, degrees, vh, vw, color]; | ||
const addIfAnimatable = (acc, val) => { | ||
const valueType = testOrder.find(({ test }) => test(val)); | ||
if (valueType) | ||
acc.push(valueType.parse(val)); | ||
return acc; | ||
}; | ||
const splitCommas = (acc, token) => { | ||
token.slice(-1) === ',' ? acc.push(token.slice(0, -1), ',') : acc.push(token); | ||
return acc; | ||
}; | ||
const stripSpaces = (v) => v.replace(/ /g, ''); | ||
const splitComboString = (comboStr) => comboStr | ||
.replace(containsColorRegex, stripSpaces) | ||
.split(' ') | ||
.reduce(splitCommas, []); | ||
const getValueType = (v) => { | ||
if (v === ',') | ||
return false; | ||
return testOrder.find(valueType => valueType.test(v)) || false; | ||
}; | ||
const floatRegex = /(-)?(\d[\d\.]*)/g; | ||
const colorRegex = /(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi; | ||
const COLOR_TOKEN = '${c}'; | ||
const NUMBER_TOKEN = '${n}'; | ||
const combo = { | ||
test: (v) => typeof v === 'string' && v.split(' ').length > 1, | ||
parse: v => splitComboString(v).reduce(addIfAnimatable, []), | ||
test: (v) => { | ||
if (typeof v !== 'string') | ||
return false; | ||
let numValues = 0; | ||
const foundNumbers = v.match(floatRegex); | ||
const foundColors = v.match(colorRegex); | ||
if (foundNumbers) | ||
numValues += foundNumbers.length; | ||
if (foundColors) | ||
numValues += foundColors.length; | ||
return numValues > 1; | ||
}, | ||
parse: (v) => { | ||
let input = v; | ||
const parsed = []; | ||
const foundColors = input.match(colorRegex); | ||
if (foundColors) { | ||
input = input.replace(colorRegex, COLOR_TOKEN); | ||
parsed.push(...foundColors.map(color.parse)); | ||
} | ||
const foundNumbers = input.match(floatRegex); | ||
if (foundNumbers) { | ||
parsed.push(...foundNumbers.map(number.parse)); | ||
} | ||
return parsed; | ||
}, | ||
createTransformer: (prop) => { | ||
const splitValues = splitComboString(prop); | ||
const valueTypes = splitValues.map(getValueType); | ||
let template = prop; | ||
let token = 0; | ||
const template = valueTypes.map((valueType, i) => { | ||
const templateValue = valueType ? token : splitValues[i]; | ||
if (valueType) | ||
const foundColors = prop.match(colorRegex); | ||
const numColors = foundColors ? foundColors.length : 0; | ||
if (foundColors) { | ||
for (let i = 0; i < numColors; i++) { | ||
template = template.replace(foundColors[i], COLOR_TOKEN); | ||
token++; | ||
return templateValue; | ||
}); | ||
const templateLength = template.length; | ||
return (output) => { | ||
let built = ''; | ||
for (let i = 0; i < templateLength; i++) { | ||
const valueType = valueTypes[i]; | ||
if (valueType) { | ||
built += `${valueType.transform(output[template[i]])} `; | ||
} | ||
else { | ||
if (template[i] === ',') { | ||
built = built.trim(); | ||
} | ||
built += `${template[i]} `; | ||
} | ||
} | ||
return built.trim(); | ||
} | ||
const foundNumbers = prop.match(floatRegex); | ||
const numNumbers = foundNumbers ? foundNumbers.length : 0; | ||
if (foundNumbers) { | ||
for (let i = 0; i < numNumbers; i++) { | ||
template = template.replace(foundNumbers[i], NUMBER_TOKEN); | ||
token++; | ||
} | ||
} | ||
return (v) => { | ||
let output = template; | ||
for (let i = 0; i < token; i++) { | ||
output = output.replace(i < numColors ? COLOR_TOKEN : NUMBER_TOKEN, i < numColors ? color.transform(v[i]) : v[i]); | ||
} | ||
return output; | ||
}; | ||
@@ -219,3 +195,2 @@ } | ||
exports.alpha = alpha; | ||
exports.complex = complex; | ||
exports.degrees = degrees; | ||
@@ -231,3 +206,3 @@ exports.percent = percent; | ||
exports.color = color; | ||
exports.combo = combo; | ||
exports.complex = combo; | ||
@@ -234,0 +209,0 @@ Object.defineProperty(exports, '__esModule', { value: true }); |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.valueTypes={})}(this,function(t){"use strict";const e=(t,e)=>r=>Math.max(Math.min(r,e),t),r=t=>e=>"string"==typeof e&&0===e.indexOf(t),s={test:t=>"number"==typeof t,parse:parseFloat,transform:t=>t},n=Object.assign({},s,{transform:e(0,1)}),a=Object.assign({},s,{default:1}),o=t=>{const e=(t=>e=>"string"==typeof e&&-1!==e.indexOf(t))(t);return{test:t=>"string"==typeof t&&e(t)&&1===t.split(" ").length,parse:parseFloat,transform:e=>`${e}${t}`}},p=o("deg"),l=o("%"),i=o("px"),f=o("vh"),u=o("vw"),h=/(-)?(\d[\d\.]*)/g,c=t=>"${"+t+"}",g={test:t=>{const e=t.match&&t.match(h);return void 0!==e&&e.constructor===Array&&e.length>1},parse:t=>{const e={};return t.match(h).forEach((t,r)=>e[r]=parseFloat(t)),e},createTransformer:t=>{let e=0;const r=t.replace(h,()=>c(`${e++}`));return t=>{let e=r;for(const r in t)t.hasOwnProperty(r)&&(e=e.replace(c(r),t[r].toString()));return e}}},d=e(0,255),m=/^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))$/i,b=/(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi,$=t=>void 0!==t.red,y=t=>void 0!==t.hue,x=t=>{const e=t.length;return r=>{if("string"!=typeof r)return r;const s={},n=(t=>"string"==typeof t?t.split(/,\s*/):[t])((t=>t.substring(t.indexOf("(")+1,t.lastIndexOf(")")))(r));for(let r=0;r<e;r++)s[t[r]]=void 0!==n[r]?parseFloat(n[r]):1;return s}},v=Object.assign({},s,{transform:t=>Math.round(d(t))}),O=r("rgb"),j={test:t=>"string"==typeof t?O(t):$(t),parse:x(["red","green","blue","alpha"]),transform:({red:t,green:e,blue:r,alpha:s})=>(({red:t,green:e,blue:r,alpha$$1:s=1})=>`rgba(${t}, ${e}, ${r}, ${s})`)({red:v.transform(t),green:v.transform(e),blue:v.transform(r),alpha:s})},M=r("hsl"),F={test:t=>"string"==typeof t?M(t):y(t),parse:x(["hue","saturation","lightness","alpha"]),transform:({hue:t,saturation:e,lightness:r,alpha:s})=>(({hue:t,saturation:e,lightness:r,alpha$$1:s=1})=>`hsla(${t}, ${e}, ${r}, ${s})`)({hue:Math.round(t),saturation:l.transform(e),lightness:l.transform(r),alpha:s})},I=Object.assign({},j,{test:r("#"),parse:t=>{let e="",r="",s="";return t.length>4?(e=t.substr(1,2),r=t.substr(3,2),s=t.substr(5,2)):(e=t.substr(1,1),r=t.substr(2,1),s=t.substr(3,1),e+=e,r+=r,s+=s),{red:parseInt(e,16),green:parseInt(r,16),blue:parseInt(s,16),alpha:1}}}),w={test:t=>"string"==typeof t&&m.test(t)||j.test(t)||F.test(t)||I.test(t),parse:t=>j.test(t)?j.parse(t):F.test(t)?F.parse(t):I.test(t)?I.parse(t):t,transform:t=>$(t)?j.transform(t):y(t)?F.transform(t):t},T=[i,l,p,f,u,w],P=(t,e)=>{const r=T.find(({test:t})=>t(e));return r&&t.push(r.parse(e)),t},_=(t,e)=>(","===e.slice(-1)?t.push(e.slice(0,-1),","):t.push(e),t),A=t=>t.replace(/ /g,""),E=t=>t.replace(b,A).split(" ").reduce(_,[]),S=t=>","!==t&&(T.find(e=>e.test(t))||!1),U={test:t=>"string"==typeof t&&t.split(" ").length>1,parse:t=>E(t).reduce(P,[]),createTransformer:t=>{const e=E(t),r=e.map(S);let s=0;const n=r.map((t,r)=>{const n=t?s:e[r];return t&&s++,n}),a=n.length;return t=>{let e="";for(let s=0;s<a;s++){const a=r[s];a?e+=`${a.transform(t[n[s]])} `:(","===n[s]&&(e=e.trim()),e+=`${n[s]} `)}return e.trim()}}};t.number=s,t.scale=a,t.alpha=n,t.complex=g,t.degrees=p,t.percent=l,t.px=i,t.vw=u,t.vh=f,t.rgba=j,t.rgbUnit=v,t.hex=I,t.hsla=F,t.color=w,t.combo=U,Object.defineProperty(t,"__esModule",{value:!0})}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.valueTypes={})}(this,function(t){"use strict";const e=(t,e)=>r=>Math.max(Math.min(r,e),t),r=t=>e=>"string"==typeof e&&0===e.indexOf(t),s={test:t=>"number"==typeof t,parse:parseFloat,transform:t=>t},a=Object.assign({},s,{transform:e(0,1)}),n=Object.assign({},s,{default:1}),o=t=>{const e=(t=>e=>"string"==typeof e&&-1!==e.indexOf(t))(t);return{test:t=>"string"==typeof t&&e(t)&&1===t.split(" ").length,parse:parseFloat,transform:e=>`${e}${t}`}},p=o("deg"),l=o("%"),f=o("px"),i=o("vh"),h=o("vw"),u=e(0,255),g=/^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))$/i,c=t=>void 0!==t.red,d=t=>void 0!==t.hue,m=t=>{const e=t.length;return r=>{if("string"!=typeof r)return r;const s={},a=(t=>"string"==typeof t?t.split(/,\s*/):[t])((t=>t.substring(t.indexOf("(")+1,t.lastIndexOf(")")))(r));for(let r=0;r<e;r++)s[t[r]]=void 0!==a[r]?parseFloat(a[r]):1;return s}},b=Object.assign({},s,{transform:t=>Math.round(u(t))}),$=r("rgb"),y={test:t=>"string"==typeof t?$(t):c(t),parse:m(["red","green","blue","alpha"]),transform:({red:t,green:e,blue:r,alpha:s})=>(({red:t,green:e,blue:r,alpha$$1:s=1})=>`rgba(${t}, ${e}, ${r}, ${s})`)({red:b.transform(t),green:b.transform(e),blue:b.transform(r),alpha:s})},x=r("hsl"),v={test:t=>"string"==typeof t?x(t):d(t),parse:m(["hue","saturation","lightness","alpha"]),transform:({hue:t,saturation:e,lightness:r,alpha:s})=>(({hue:t,saturation:e,lightness:r,alpha$$1:s=1})=>`hsla(${t}, ${e}, ${r}, ${s})`)({hue:Math.round(t),saturation:l.transform(e),lightness:l.transform(r),alpha:s})},O=Object.assign({},y,{test:r("#"),parse:t=>{let e="",r="",s="";return t.length>4?(e=t.substr(1,2),r=t.substr(3,2),s=t.substr(5,2)):(e=t.substr(1,1),r=t.substr(2,1),s=t.substr(3,1),e+=e,r+=r,s+=s),{red:parseInt(e,16),green:parseInt(r,16),blue:parseInt(s,16),alpha:1}}}),j={test:t=>"string"==typeof t&&g.test(t)||y.test(t)||v.test(t)||O.test(t),parse:t=>y.test(t)?y.parse(t):v.test(t)?v.parse(t):O.test(t)?O.parse(t):t,transform:t=>c(t)?y.transform(t):d(t)?v.transform(t):t},M=/(-)?(\d[\d\.]*)/g,I=/(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi,F={test:t=>{if("string"!=typeof t)return!1;let e=0;const r=t.match(M),s=t.match(I);return r&&(e+=r.length),s&&(e+=s.length),e>1},parse:t=>{let e=t;const r=[],a=e.match(I);a&&(e=e.replace(I,"${c}"),r.push(...a.map(j.parse)));const n=e.match(M);return n&&r.push(...n.map(s.parse)),r},createTransformer:t=>{let e=t,r=0;const s=t.match(I),a=s?s.length:0;if(s)for(let t=0;t<a;t++)e=e.replace(s[t],"${c}"),r++;const n=t.match(M),o=n?n.length:0;if(n)for(let t=0;t<o;t++)e=e.replace(n[t],"${n}"),r++;return t=>{let s=e;for(let e=0;e<r;e++)s=s.replace(e<a?"${c}":"${n}",e<a?j.transform(t[e]):t[e]);return s}}};t.number=s,t.scale=n,t.alpha=a,t.degrees=p,t.percent=l,t.px=f,t.vw=h,t.vh=i,t.rgba=y,t.rgbUnit=b,t.hex=O,t.hsla=v,t.color=j,t.complex=F,Object.defineProperty(t,"__esModule",{value:!0})}); |
import { ValueType } from '../types'; | ||
export declare const containsColorRegex: RegExp; | ||
export declare const rgbUnit: ValueType; | ||
@@ -4,0 +3,0 @@ export declare const rgba: ValueType; |
import { ValueType } from '../types'; | ||
declare const complex: ValueType; | ||
export default complex; | ||
declare const combo: ValueType; | ||
export default combo; |
@@ -5,5 +5,4 @@ import { Transformer, ValueType, NumberMap, RGBA, HSLA, Color } from './types'; | ||
import { degrees, percent, px, vw, vh } from './value-types/units'; | ||
import { rgba, rgbUnit, hsla, hex, color } from './value-types/color'; | ||
import complex from './value-types/complex'; | ||
import { rgba, rgbUnit, hsla, hex, color } from './value-types/color'; | ||
import combo from './value-types/combo'; | ||
export { number, scale, alpha, complex, degrees, percent, px, vw, vh, rgba, rgbUnit, hex, hsla, color, combo }; | ||
export { number, scale, alpha, degrees, percent, px, vw, vh, rgba, rgbUnit, hex, hsla, color, complex }; |
129
lib/index.js
@@ -33,34 +33,4 @@ 'use strict'; | ||
const FLOAT_REGEX = /(-)?(\d[\d\.]*)/g; | ||
const generateToken = (token) => '${' + token + '}'; | ||
const complex = { | ||
test: v => { | ||
const matches = v.match && v.match(FLOAT_REGEX); | ||
return (matches !== undefined && | ||
matches.constructor === Array && | ||
matches.length > 1); | ||
}, | ||
parse: v => { | ||
const parsedValue = {}; | ||
v.match(FLOAT_REGEX).forEach((value, i) => (parsedValue[i] = parseFloat(value))); | ||
return parsedValue; | ||
}, | ||
createTransformer: (prop) => { | ||
let counter = 0; | ||
const template = prop.replace(FLOAT_REGEX, () => generateToken(`${counter++}`)); | ||
return (v) => { | ||
let output = template; | ||
for (const key in v) { | ||
if (v.hasOwnProperty(key)) { | ||
output = output.replace(generateToken(key), v[key].toString()); | ||
} | ||
} | ||
return output; | ||
}; | ||
} | ||
}; | ||
const clampRgbUnit = clamp(0, 255); | ||
const onlyColorRegex = /^(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))$/i; | ||
const containsColorRegex = /(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi; | ||
const isRgba = (v) => v.red !== undefined; | ||
@@ -159,52 +129,58 @@ const isHsla = (v) => v.hue !== undefined; | ||
const testOrder = [px, percent, degrees, vh, vw, color]; | ||
const addIfAnimatable = (acc, val) => { | ||
const valueType = testOrder.find(({ test }) => test(val)); | ||
if (valueType) | ||
acc.push(valueType.parse(val)); | ||
return acc; | ||
}; | ||
const splitCommas = (acc, token) => { | ||
token.slice(-1) === ',' ? acc.push(token.slice(0, -1), ',') : acc.push(token); | ||
return acc; | ||
}; | ||
const stripSpaces = (v) => v.replace(/ /g, ''); | ||
const splitComboString = (comboStr) => comboStr | ||
.replace(containsColorRegex, stripSpaces) | ||
.split(' ') | ||
.reduce(splitCommas, []); | ||
const getValueType = (v) => { | ||
if (v === ',') | ||
return false; | ||
return testOrder.find(valueType => valueType.test(v)) || false; | ||
}; | ||
const floatRegex = /(-)?(\d[\d\.]*)/g; | ||
const colorRegex = /(#[0-9a-f]{3}|#(?:[0-9a-f]{2}){2,4}|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi; | ||
const COLOR_TOKEN = '${c}'; | ||
const NUMBER_TOKEN = '${n}'; | ||
const combo = { | ||
test: (v) => typeof v === 'string' && v.split(' ').length > 1, | ||
parse: v => splitComboString(v).reduce(addIfAnimatable, []), | ||
test: (v) => { | ||
if (typeof v !== 'string') | ||
return false; | ||
let numValues = 0; | ||
const foundNumbers = v.match(floatRegex); | ||
const foundColors = v.match(colorRegex); | ||
if (foundNumbers) | ||
numValues += foundNumbers.length; | ||
if (foundColors) | ||
numValues += foundColors.length; | ||
return numValues > 1; | ||
}, | ||
parse: (v) => { | ||
let input = v; | ||
const parsed = []; | ||
const foundColors = input.match(colorRegex); | ||
if (foundColors) { | ||
input = input.replace(colorRegex, COLOR_TOKEN); | ||
parsed.push(...foundColors.map(color.parse)); | ||
} | ||
const foundNumbers = input.match(floatRegex); | ||
if (foundNumbers) { | ||
parsed.push(...foundNumbers.map(number.parse)); | ||
} | ||
return parsed; | ||
}, | ||
createTransformer: (prop) => { | ||
const splitValues = splitComboString(prop); | ||
const valueTypes = splitValues.map(getValueType); | ||
let template = prop; | ||
let token = 0; | ||
const template = valueTypes.map((valueType, i) => { | ||
const templateValue = valueType ? token : splitValues[i]; | ||
if (valueType) | ||
const foundColors = prop.match(colorRegex); | ||
const numColors = foundColors ? foundColors.length : 0; | ||
if (foundColors) { | ||
for (let i = 0; i < numColors; i++) { | ||
template = template.replace(foundColors[i], COLOR_TOKEN); | ||
token++; | ||
return templateValue; | ||
}); | ||
const templateLength = template.length; | ||
return (output) => { | ||
let built = ''; | ||
for (let i = 0; i < templateLength; i++) { | ||
const valueType = valueTypes[i]; | ||
if (valueType) { | ||
built += `${valueType.transform(output[template[i]])} `; | ||
} | ||
else { | ||
if (template[i] === ',') { | ||
built = built.trim(); | ||
} | ||
built += `${template[i]} `; | ||
} | ||
} | ||
return built.trim(); | ||
} | ||
const foundNumbers = prop.match(floatRegex); | ||
const numNumbers = foundNumbers ? foundNumbers.length : 0; | ||
if (foundNumbers) { | ||
for (let i = 0; i < numNumbers; i++) { | ||
template = template.replace(foundNumbers[i], NUMBER_TOKEN); | ||
token++; | ||
} | ||
} | ||
return (v) => { | ||
let output = template; | ||
for (let i = 0; i < token; i++) { | ||
output = output.replace(i < numColors ? COLOR_TOKEN : NUMBER_TOKEN, i < numColors ? color.transform(v[i]) : v[i]); | ||
} | ||
return output; | ||
}; | ||
@@ -217,3 +193,2 @@ } | ||
exports.alpha = alpha; | ||
exports.complex = complex; | ||
exports.degrees = degrees; | ||
@@ -229,2 +204,2 @@ exports.percent = percent; | ||
exports.color = color; | ||
exports.combo = combo; | ||
exports.complex = combo; |
import { ValueType } from '../types'; | ||
export declare const containsColorRegex: RegExp; | ||
export declare const rgbUnit: ValueType; | ||
@@ -4,0 +3,0 @@ export declare const rgba: ValueType; |
import { ValueType } from '../types'; | ||
declare const complex: ValueType; | ||
export default complex; | ||
declare const combo: ValueType; | ||
export default combo; |
{ | ||
"name": "style-value-types", | ||
"version": "2.0.1", | ||
"version": "3.0.0", | ||
"description": "Parsers, transformers and tests for special value types, eg: %, hex codes etc.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -44,4 +44,3 @@ # Style Value Types | ||
- `alpha`: `Number` between `0` and `1` | ||
- `complex`: `String` containing arbitrary sequence of numbers mixed with other characters. See below. | ||
- `combo`: Handles space and comma delimited values, like CSS box-shadow: `'10px 10px inset #f00, 5px 5px 30px #fff'` | ||
- `complex`: Handles space and comma delimited values, like CSS box-shadow: `'10px 10px inset #f00, 5px 5px 30px #fff'`, gradient or a path definition. | ||
- `color`: `String` of either `hex`, `hsla` or `rgba` type | ||
@@ -57,5 +56,5 @@ - `degrees`: `String` ending in `deg` | ||
## Complex and combo types | ||
## complex | ||
The `complex` and `combo` value types are slightly different to the others. Instead of a `transform` method, they have a `createTransformer` method which returns the `transform` method: | ||
The `complex` value type is slightly different to the others. Instead of a `transform` method, it has a `createTransformer` method which returns the `transform` method: | ||
@@ -68,12 +67,1 @@ ```javascript | ||
The returned `transform` function is unique to the string given to it. When this function is provided an object of the same format as returned by `complex.parse()` (in this example `complex.parse(svgPath)`), it will use the original string as a template. | ||
Example: | ||
```javascript | ||
transform({ | ||
'0': 300, | ||
'1': 0, | ||
'2': 100, | ||
'3': 200 | ||
}); // Returns 'M300 0 L100 200' | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
33277
700
65