Skip to content
New issue

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

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

Already on GitHub? # to your account

[question] Why can't we insert premade CSS classes in <style jsx>? #175

Closed
soulchainer opened this issue Apr 25, 2017 · 1 comment
Closed

Comments

@soulchainer
Copy link

soulchainer commented Apr 25, 2017

<style jsx> doesn't allow us to create dinamic styles for a component.
The className toggling or inline style options available are not useful if you don't know previously all the elements you want to style.

I mean, in my case, I want to style some social network icons. The data of the icons is in an object that we import.

So, the logic way (to me) of styling this was, well, generate the classes for each icon (each of whose have unique styles) and then, add the classes inside <style jsx>.

Just because we can't do it inside <style jsx>:

Only constants defined outside of the component scope are allowed here.

So it's the only way I could think that seems reasonable right now.

And yes: we could add every class manually, but that isn't a very good solution. We have four icons now, but we don't know if tomorrow we will be adding more or deleting others. Having to manually add or remove classes manually for every change we made isn't ideal.

So... It's there any reason why doesn't this work at all? Example of what I'm trying:

/*
 * socialIcons is a imported constant object, with a signature as
 * { socialName1: {color: ..., url: ..., ...} }
 */

let socialIconsClasses = '';
// generate the classes for the social icons
Object.keys(socialIcons).forEach((socialName) => {
  socialIconsClasses = `
    ${socialIconsClasses}
    .SocialIconList-icon--${socialName}:hover {
      fill: ${socialIcons[socialName].color};
    }
  `;
});

// generate the markup for the social icons
const generateSocialIcons = Object.keys(socialIcons).map(socialName => (
  <a ... >
    <svg
      className={`SocialIconList-icon SocialIconList-icon--${socialName}`}
    >
      <use xlinkHref={`#icon-${socialName}`} />
    </svg>
    <style jsx>{`
      /* some other classes*/
      ${socialIconsClasses} /* THIS DOESN'T WORK (and doesn't throw any error either)  */
    `}</style>
  </a>
));

const SocialIconList = () => (
  <div className="SocialIconList">
    ...
    <div className="SocialIconList-icons">
      {generateSocialIcons} // here will insert the social icons markup in our component
      <style jsx>{` some other styles `}</style>
    </div>
  </div>
);

I also try importing the classes (as a string) from other module. And some combinations. Nothing works :(. I'm out of ideas.

Thanks for your time 👍.

@giuseppeg
Copy link
Collaborator

Currently this is not possible because CSS is static.
That's why we throw the "Only constants defined outside of the component scope are allowed here" error.

We are planning on adding support for dynamic values in the future but we want to make sure that whatever solution we come up with is fast – I will probably tackle this after #148 ships. You can subscribe to #81 if you want to stay updated.

For now I would use inline styles onMouseEnter it requires a bit of extra work but it is not complicated.

FWIW in your generateSocialIcons you are looping and outputting ${socialIconsClasses} which leads to duplication since that var contains all of the styles :)

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

No branches or pull requests

2 participants