Skip to content

Handling css as "string" to react as "object" conversion #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Vadorequest opened this issue Jun 5, 2019 · 4 comments
Closed

Handling css as "string" to react as "object" conversion #107

Vadorequest opened this issue Jun 5, 2019 · 4 comments

Comments

@Vadorequest
Copy link

I was looking for a lib to convert a string to react object.

I used this lib to do so, I believe the following function could be a good addition to the current library. Feel free to add it!

import isPlainObject from 'lodash.isplainobject';
import map from 'lodash.map';
import { getPropertyName } from 'css-to-react-native';

/**
 * Takes a standard css string and returns an object of {"key": "value"} that is react-compatible
 * Relies on https://github.com/styled-components/css-to-react-native#api to resolve the property name (getPropertyName)
 *
 * @example getPropertyName('border-width'); // => 'borderWidth'
 *
 * If the given "css" param is an object, it will be returned untouched
 * Any unexpected type/value will return an empty object
 *
 * @param css
 * @return {{}|*}
 */
export const cssToReactStyle = (css) => {
  // If object is given, return object (could be react style object mistakenly provided)
  if (isPlainObject(css)) {
    return css;
  }

  // If falsy, then probably empty string or null, nothing to be done there
  if (!css) {
    return {};
  }

  // Only accepts strings
  if (typeof css !== 'string') {
    // TODO sentry
    console.error(`Unexpected type "${typeof css}" when expecting string, with value "${css}"`);
    return {};
  }

  const style = {};
  const rules = css.split(';');
  map(rules, (rule) => {
    let [key, value] = rule.split(':');

    if (key && value) {
      key = key.trim();
      value = value.trim();

      style[getPropertyName(key)] = value;
    }
  });

  return style;
};
@jacobp100
Copy link
Contributor

Yeah, you just need to Object.assign the result of this library to style. Should work then

@Vadorequest
Copy link
Author

Honestly, an example of that in the readme would just save people's time. I didn't quite understand how to use your main function from the examples.

@jacobp100
Copy link
Contributor

jacobp100 commented Jun 7, 2019

Sorry, ignore my previous answer - it's not the best way to be doing things

The real answer is you want a CSS parser, because your code doesn't handle things like semi-colons appearing in comments or strings. There's no example like you posted in the readme for this reason

But if you're happy with that edge case, you were almost there with your code. This library accepts an array of [key, value] arrays - like [['color', 'red'], ['font-size', '16px']]. So in your map function, just return these tuples, then pass the whole thing into this library

const rules = css.split(';');
const tuples = map(rules, (rule) => {
  let [key, value] = rule.split(':');

  if (key && value) {
    key = key.trim();
    value = value.trim();
    return [key, value];
  } else {
    return null;
  }
}).filter((x) => {
  return x != null;
});

cssToReactNative(tuples);

@jacobp100
Copy link
Contributor

Closing, but feel free to continue the discussion if you want

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants