Skip to content
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

How can we change the expression delimiters for some of our components? #74

Open
Danilo-Araujo-Silva opened this issue Mar 8, 2017 · 4 comments

Comments

@Danilo-Araujo-Silva
Copy link

Danilo-Araujo-Silva commented Mar 8, 2017

How can we change the javascript expression delimiters?

For now JSX uses { and } as expression delimiters, but how could we change this delimiters for some of our components? For example, how could we write expressions like ${ 1+1 } or {{ 1+1 }} instead of { 1+ 1}?

The main motivation for this is to use the power of JSX to not just create powerfull HTML-JS-like components but to create CSS-JS-like components too.

For example, I wrote this example in codepen:

function Style(props) {
  return <div>
    <h1>
      {props.children}
    </h1>
    <style>
      {props.children}
      h1 {'{'}
        color: {props.color};
      {'{'}
    </style>
  </div>;
}

ReactDOM.render(
  <Style
    color="white"
  >
    * {'{'}
      background-color: red;
    {'}'}
  </Style>,
  document.getElementById('root')
);

This works fine and it's awesome. I think we can create very interesting things with this strategy, for example, do several complex calculations to achive some powerfull style that even css or scss (for example) can't give it to us. We can use the full power of javascript to write our styles if we need this.

But this example will be more readable if JSX just have a little new option to parse expressions using another delimiters like the listed ones above. For example, we could write the same code like this:

function Style(props) {
  return <div>
    <h1>
      ${props.children}
    </h1>
    <style>
      ${props.children}
      h1 {
        color: ${props.color};
      }
    </style>
  </div>;
}

ReactDOM.render(
  <Style
    color="white"
  >
    * {
      background-color: red;
    }
  </Style>,
  document.getElementById('root')
);

So, how can we change the expression delimiters?
Or how can we extend JSX to have this behavior for some special of our components (like Style above)?

@syranide
Copy link
Contributor

syranide commented Mar 8, 2017

Unless it has been changed (don't think so), then you should use dangerouslySetInnerHTML with style for React, not provide a string child.

But to the point, with ES6 the solution to this is simple, use template strings:

<style>{`
  foo bar ${foobar} { .. }
`}</style>
var html = {_html: `
  foo bar ${foobar} { .. }
`};
<style dangerouslySetInnerHTML={html} />

@sebmarkbage
Copy link
Contributor

The template literal solution indeed solve this. If we go down the route of #35 then the template literal solution might seem more natural to go for.

Although I might also suggest that we should support an object as the child of style in React which has all the selectors as properties. That is already how the style attribute works in React. It simply uses the existing syntax for data structures that already exist in JS.

<style>{{
  '*': {
    'background-color': 'red'
  }
}}</style>

This allows you to specify structured data that could even be type specific using CSSOM instead of having to parse a string.

@giuseppeg
Copy link

giuseppeg commented Jun 16, 2017

Ideally it would be great if style's content could be parsed as TemplateLiteral when it is just text and doesn't start with {:

<style>
  div { color: red; }
  span { background: ${ color } }
</style>

// parsed like

<style>{`
  div { color: red; }
  span { background: ${ color } }
`}</style>

For styled-jsx this would be amazing.

@Buslowicz
Copy link

Sorry for digging this up, but are there any plans to implement something to solve this? Custom delimiters would be great, or at least a way to specify which tags content should not be parsed.

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

5 participants