How to switch between global CSS onclick in Gatsby?

Viewed 135

I'm building a portfolio site in Gatsby, and as I work more on the illustration and design side, would like to serve up multiple design options to showcase that work, based on a user selection via click. I've found some similar questions, but none that are specific to Gatsby.

I'm using styled components to create the layout, so It seems to me that just swapping between multiple Global stylesheets (with fonts, colors, etc) via a button would be the way to go, so the layout remains intact, but I'm honestly not sure how to go about this as I'm pretty beginner in Gatsby and Javascript in general.

Thanks in advance!

1 Answers

Given a simply <Layout> structure like:

import React from "react"
import { createGlobalStyle } from "styled-components"

const GlobalStyle = createGlobalStyle`
  body {
    color: ${props => (props.theme === "purple" ? "purple" : "white")};
  }
`
export default function Layout({ children }) {
  return (
    <React.Fragment>
      <GlobalStyle theme="purple" />
      {children}
    </React.Fragment>
  )
}

You can easily attach an onClick event to the children by adding a boolean operator to switch your <GlobalStyle>, for example:

export default function somePage(){
   const [defaultStyles, setDefaultStyles]=useState(false);

   const handleChange=()=>setDefaultStyles(!defaultStyles)
   
   return <Layout defaultStyles={defaultStyles}>
      <h1 onClick={handleChange}> Click me to toggle the global styles</h1>
   </Layout>

}

Basically, you are creating a boolean state (initially set as false) to change between default styles. The result of that state (toggled by clicking the <h1>) will be sent upwards to your <Layout> so, there:

import React from "react"
import { createGlobalStyle } from "styled-components"

const GlobalStyle = createGlobalStyle`
  body {
    color: ${props => (props.theme === "purple" ? "purple" : "white")};
  }
`
export default function Layout({ children, defaultStyles }) {
  return (
    <React.Fragment>
      {defaultStyles && <GlobalStyle theme="purple" />}
      {children}
    </React.Fragment>
  )
}

The && operator will only render <GlobalStyle> if defaultStyles is true. Adapt it to your needs or add a ternary condition if needed.

Related