React: Convert CSSProperties to Styled-Component

Viewed 2375

I have an object in following format:


    let style:React.CSSProperties|object = {
        marginLeft: '0',
        borderRadius: '20px',
        display: 'flex',
        justifyContent: 'center',
    }

I need to convert the React CSSProperties into corresponding string format for instance:


    let string_styles:string = `{
        margin-left: 0;
        border-radius: 20px;
        display: flex;
        justify-content: center;
    }`

since I can't find a tangible syntax to write css such as :hover, ::before, ::before:hover inline, the purpose use it as a styled component for now, meanwhile leave the CSSProperties object alone for future import.

inelegantly, I hard coded the transforming method.

    deQuote(dict:object):string{
        return JSON.stringify(dict).replace(/['"]+/g, '');
    }
    // passin: {marginLeft: '0', borderRadius: '20px'} 
    // return: `{marginLeft: 0, borderRadius: 20px}`

    deBraces(str:string):string{
        return str.substring(1, str.length-1);
    }
    // passin: `{marginLeft: 0, borderRadius: 20px}`
    // return: `marginLeft: 0, borderRadius: 20px`

    deComma(str:string):string{
        return str.split(',').join(';');
    }
    // passin: `marginLeft: 0, borderRadius: 20px`
    // return: `marginLeft: 0; borderRadius: 20px`

    deBase(dict:object):string{
        return deComma(deBraces(deQuote(dict)));
    }
    // passin: {marginLeft: '0', borderRadius: '20px'} 
    // return: `marginLeft: 0; borderRadius: 20px`
    

But here comes the part that is tricky, it takes lot of effort to convert

    marginLeft -> margin-left

Solved by customised function,

    CSSPropertiesToComponent(dict:React.CSSProperties){
        let str = '';
        for(const [key, value] of Object.entries(dict)){
            let clo = '';
            key.split('').forEach(lt=>{
                if(lt.toUpperCase() === lt){
                    clo += '-' + lt.toLowerCase();
                }else{
                    clo += lt;
                }
            });
            str += clo + ':' + value + ';';
        }
        return str;
    }

However, if there is a better way to convert React.CSSProperties into Styled Component string, please let me know.

2 Answers

Why you need to convert your object to string?

You can map through it and build your final string by using Object.keys and Array.reduce methods.

const style = {
    marginLeft: '0',
    borderRadius: '20px',
    display: 'flex',
    justifyContent: 'center',
}

const finalResult = Object.keys(style).reduce((accumulator, key) => {
    // transform the key from camelCase to kebab-case
    const cssKey = kebabCase(key)
    // remove ' in value
    const cssValue = style[key].replace("'", "")
    // build the result
    // you can break the line, add indent for it if you need
    return `${accumulator}${cssKey}:${cssValue};`
}, '')

If you don't want to use kebabCase library, you can use a simple regex to find all upper case and convert it to lower case with - before it.

const regex = new RegExp(/[A-Z]/g)
const kebabCase = (str) => str.replace(regex, v => `-${v.toLowerCase()}`)

You can use lodash.kebabCase package to solve that exact problem.

Here is an example

import kebabCase from 'lodash.kebabcase';

kebabCase('Foo Bar');
// => 'foo-bar'
 
kebabCase('fooBar');
// => 'foo-bar'
 
kebabCase('__FOO_BAR__');
// => 'foo-bar'
Related