We\'d like to convert a CSS style entered as string into a JS object.
E.g.,
var input = \" border:solid 1px; color:red \";
expec
You could use the Javascript split function: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/split
First split the string with ;
as the separator, and then for each result split with :
, placing the items in an object as you go.
e.g.
var result = {},
attributes = input.split(';');
for (var i = 0; i < attributes.length; i++) {
var entry = attributes[i].split(':');
result[entry.splice(0,1)[0]] = entry.join(':');
}
Now you can use a third-party library such as style-to-object. For example:
import parse from 'style-to-object';
const input = " border:solid 1px; color:red ";
parse(input); // => {border: "solid 1px", color: "red"}
something like this should get you pretty close:
var input = " border:solid 1px; color:red ";
var output = '{' + input.replace(/([\w-.]+)\s*:([^;]+);?/g, '\n $1:"$2",') + '\n}';
...turns
" border:solid 1px; color:red "
into
{
border:"solid 1px",
color:"red ",
}
A very simple one:
var regex = /([\w-]*)\s*:\s*([^;]*)/g;
var match, properties={};
while(match=regex.exec(cssText)) properties[match[1]] = match[2].trim();
https://regex101.com/r/nZ4eX5/1
Just for fun and for completeness…
I haven't checked cross-browser compatibility (only tried in Chrome), and it has some quirks:
var input = "font-weight:bold; color: blue; margin: 0 15px";
var e = document.createElement("div");
e.setAttribute("style", input);
var output = {};
for (var i = 0; i < e.style.length; i++) {
var name = e.style[i];
var value = e.style.getPropertyValue(name);
output[name] = value;
}
The quirk is that even though we passed in a single margin
declaration, we get an object like
{
color: "blue",
font-weight: "bold",
margin-bottom: "0px",
margin-left: "15px",
margin-right: "15px",
margin-top: "0px",
}
This might be a good or a bad thing depending on what you're after.
If you want a tagged template literal syntax that works easily with React, you could do
const camelCase = str => str.replace(/-(.)/g, (_,p) => p.toUpperCase())
const css2obj = (strings, ...vals) => {
const css = strings.reduce((acc, str, i) => acc + str + (vals[i] || ''), '')
const r = /(?<=^|;)\s*([^:]+)\s*:\s*([^;]+)\s*/g, o = {}
css.replace(r, (m,p,v) => o[camelCase(p)] = v)
return o
}
const center = 'center'
const reactInlineCSS = css2obj`
align-items: ${center};
justify-content: ${center};
`
console.log(reactInlineCSS)