Skip to content
Advertisement

How to render custom generated ruleset in styled-jsx

TL;DR

How does one insert a variable that contains one or more CSS rules into styled-jsx (using styled-jsx-plugin-sass under the hood)?


I have the following JSX style:

// src/pages/index.tsx
...
<style jsx>
  {`
    .test {
      height: 100vh;
      width: 100vw;
      background-color: green;
      ${contained}
     }
  `}
</style>

And contained is a variable that I’m trying to insert into it the mentioned rule:

// src/styles/break.ts

export const contained = `
margin: 0 auto;
${breakAt("sm")(`
  width: calc(100% - 10vw);
`)}
${breakAt("md")(`
  width: calc(100% - 15vw);
`)}
@media screen and (min-width: calc(960px + 10vw)) {
  width: 960px;
}`;
...

Notes:

breakAt is a function that generates a specific media query (breakpoint: string) => (content: string) => string

I have ensured that styled-jsx-plugin-sass is configured correctly – writing the generated CSS in raw acts as intended.

I’ve also looked into how I believe styled-jsx behaves – it seems to do some literal parsing of the code I put in as I wrote a generator ((content: string) => string acting on contained) and called it, and the parser recognised that I wrote a CallExpression, but failed to render anything because of that.

I understand that this could be solved using @mixin/@include but I’m picking and choosing features of Sass that I like at this point (mainly embedded rules), and was curious to see what was possible.

Your input and correction is greatly appreciated. Please read the full question before answering!

Advertisement

Answer

I’m not a fan of styled-components (yet!) but it seems to be the valid situation in this scenario:

import styled from "styled-components"
// ... other imports

const Wrapper = styled.div`
  /* ... scoped styles */
  ${contained} /* mixin */
`

export default SomeComponent({ children }) {
  return <Wrapper>This component was mixed in<Wrapper/>
}
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement