/suit-up

:necktie: css-in-js with template strings. For React.

Primary LanguageJavaScriptMIT LicenseMIT

👔 suit-up

css-in-js with template strings. For React.

travis build version js-standard-style

Benefits

  • Scoped selectors
  • Automatic vendor prefixing
  • Support global CSS
  • All CSS features included
  • Share constants between js and styles
  • Only load the styles that a component have used
  • Easily themeable

Example

import React, {Component} from 'react'
import {render} from 'react-dom'
import suitup from 'suit-up'

// it works with CSS Modules syntax for globals
const style = `
  :global .container {
    color: red;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
  }
`

// local composes works too!
const buttonStyle = `
  .base {
    border: none;
    border-radius: 4px;
    cursor: pointer;
    padding: 10px 20px;
  }

  .default {
    composes: base;
    background-color: lightgray;
    color: black;
  }

  .primary {
    composes: base;
    background-color: blue;
    color: white;
  }
`

let Button = ({children, styles, primary, ...rest}) => {
  return (
    <button
      className={primary ? styles.primary : styles.default}
      {...rest}
    >
      {children}
    </button>
  )
}

Button = suitup(buttonStyle)(Button)

@suitup(style)
class App extends Component {
  render () {
    return (
      <div className='container'>
        <span>Red Text</span>
        <Button>Default Button</Button>
        <Button primary>Primary Button</Button>
      </div>
    )
  }
}

render(<App />, document.getElementById('app'))

Theme Example

import React, {Component} from 'react'
import {render} from 'react-dom'
import suitup, {ThemeProvider} from 'suit-up'

const buttonStyle = theme => `
  .base {
    border: none;
    border-radius: ${theme.sizes.borderRadius}px;
    cursor: pointer;
    padding: ${theme.sizes.verticalPadding}px ${theme.sizes.horizontalPadding}px;
  }

  .default {
    composes: base;
    background-color: ${theme.colors.default};
    color: ${theme.colors.text};
  }

  .primary {
    composes: base;
    background-color: ${theme.colors.primary};
    color: ${theme.colors.invertedText};
  }
`

let Button = ({children, styles, primary, ...rest}) => {
  return (
    <button
      className={primary ? styles.primary : styles.default}
      {...rest}
    >
      {children}
    </button>
  )
}

Button = suitup(buttonStyle)(Button)

const someTheme = {
  colors: {
    default: 'lightgray',
    primary: 'darkblue',
    text: 'black',
    invertedText: 'white',
  },
  sizes: {
    borderRadius: 4,
    verticalPadding: 10,
    horizontalPadding: 20
  }
}

class App extends Component {
  render () {
    return (
      <ThemeProvider theme={someTheme}>
        <div>
          <Button>Default Button</Button>
          <Button primary>Primary Button</Button>
        </div>
      </ThemeProvider>
    )
  }
}

render(<App />, document.getElementById('app'))

Acknowledgements

This is HIGHLY inspired by some amazing work: