Reputation: 409
I need to create a function that parses a CSS string, that will be used on a inline js style.
E.g: what I get is something like const styles = "background-color:#FFFFFF;color:#000000"
and I need to transform in:
<h1
className={classes}
style={{ color: fontColor, background: backgroundColor }}
>
{copy}
</h1>
what I do for now is this
const [backgroundColor, setBackgroundColor] = useState();
const [fontColor, setFontColor] = useState();
const colors = styles?.match(/(#)([^;]*)/g);
useEffect(() => {
if (colors) {
if (colors.length > 1) {
setBackgroundColor(colors[0]);
setFontColor(colors[1]);
}
if (colors.length === 1) {
setFontColor(colors[0]);
}
}
}, [colors]);
But I was asked to create pure seperate function that parses the styles string.
So I was wondering if there's a solution where I don't need to "regex" each specific selector and then its value. If there's something like whatever is before the colon is the selector than after that until the semicolon is its value.
Any tips?
Thanks
Upvotes: 0
Views: 1494
Reputation: 328
Maybe something like this (which converts the css string to an object) (doesn't work on Safari):
const convertCssToObject = value => {
const regex = /(?<=^|;)\s*([^:]+)\s*:\s*([^;]+)\s*/g, o = {};
value.replace(regex, (m,p,v) => o[p] = v);
return o;
}
console.log( convertCssToObject("background-color:#FFFFFF;color:#000000;") )
I've edited the regex so it works also on Safari:
const convertCssToObject = value => {
// Without the look behind
const regex = /([\w-.]+)\s*:([^;]+);?/g, o = {}; // Heck I think this should also work for Chrome as well
value.replace(regex, (m,p,v) => o[p] = v);
return o;
}
console.log( convertCssToObject("background-color:#FFFFFF;color:#000000;") )
Upvotes: 2
Reputation: 19652
You can do it like this and after that map your function with it
const styles = "background-color:#FFFFFF;color:#000000";
const css = styles.split(';').map(cur => cur.split(':'));
console.log(css);
const cssInObject = styles.split(';').map(cur => cur.split(':')).reduce((acc, val) => {
let [key, value] = val;
key = key.replace(/-./g, css => css.toUpperCase()[1])
acc[key] = value;
return acc;
}, {});
console.log(cssInObject);
Upvotes: 2