@cheesebit/classy

Apply CSS classes or conditional CSS properties based on props more easily.

Usage no npm install needed!

<script type="module">
  import cheesebitClassy from 'https://cdn.skypack.dev/@cheesebit/classy';
</script>

README

classy

This library helps you to handle assigning style that relies on multiple combinations of props or conditionals.

Coverage Status npm package

What problem do we want to solve here?

Let's say you have a React component with props such as colorScheme, variant, validationStatus, disabled, and so on.

If you to style your component conditionally according to these props, you would have to write something like:

  import clsx from 'clsx'

  // ...
  const { colorScheme, variant, validationStatus, disabled } = props

  <Button
    className={clsx({
      'some class combination a': colorScheme == 'dark' && variant == 'primary',
      'some class combination b': (colorScheme == 'light' || colorScheme == 'dark') && variant == 'secondary' && validationStatus == 'valid',
      'some class combination c': colorScheme == 'dark' || variant == 'terciary',
      'some class combination d': !disabled
    })}
  >
    My Cool Button
  </Button>

Well, what if you could write something like:

  import { useClassy } from '@cheesebit/classy'

  // ...
  const { prop, classy } = useClassy(props)
  const { disabled } = props

  <Button
    className={classy({
      'some class combination a': prop({ colorScheme:'dark', variant == 'primary' }),
      'some class combination b': prop({ colorScheme: ['light', 'dark'], variant: 'secondary', validationStatus: 'valid' }),
      'some class combination c': prop([{ colorScheme: 'dark' }, { variant: 'terciary' }],
      'some class combination d': !disabled, // or prop({ disabled: false })
    })}
  >
    My Cool Button
  </Button>

Or if you were using some CSS-in-JS library like styled-components, you would have something like:

import styled from 'styled-components'

const Button = styled.button`
  background: ${({ variant, scheme }) => ({
    '$button-primary-background': variant == 'primary',
    '$button-secondary-background': variant == 'secondary' && scheme == 'light',
    '$button-secondary-dark-background': variant == 'secondary' && scheme == 'dark',
    '$button-terciary-background': variant == 'terciary',
  })};

  border-color: ${({ variant, scheme }) => ({
    '$button-primary-border-color': variant == 'primary',
    '$button-secondary-border-color': variant == 'secondary' && scheme == 'light',
    '$button-secondary-dark-border-color': variant == 'secondary' && scheme == 'dark',
    '$button-terciary-border-color': variant == 'terciary',
  })};

  color: ${({ variant, scheme }) => ({
    '$button-primary-color': variant == 'primary',
    '$button-secondary-color': variant == 'secondary' && scheme == 'light',
    '$button-secondary-dark-color': variant == 'secondary' && scheme == 'dark',
    '$button-terciary-color': variant == 'terciary',
  })};
`

Well, what about something simpler like:

import styled from 'styled-components'
import { classy, prop } from '@cheesebit/classy'

const Button = styled.button`
  background: ${classy({
    '$button-primary-background': prop({ variant: 'primary' }),
    '$button-secondary-background': prop({ variant: 'secondary', scheme: 'light' }),
    '$button-secondary-dark-background': prop({ variant: 'secondary', scheme: 'dark' }),
    '$button-terciary-background': prop({ variant: 'terciary' }),
  })};

  border-color: ${classy({
    '$button-primary-border-color': prop({ variant: 'primary' }),
    '$button-secondary-border-color': prop({ variant: 'secondary', scheme: 'light' }),
    '$button-secondary-dark-border-color': prop({ variant: 'secondary', scheme: 'dark' }),
    '$button-terciary-border-color': prop({ variant: 'terciary' }),
  })};

  color: ${classy({
    '$button-primary-color': prop({ variant: 'primary' }),
    '$button-secondary-color': prop({ variant: 'secondary', scheme: 'light' }),
    '$button-secondary-dark-color': prop({ variant: 'secondary', scheme: 'dark' }),
    '$button-terciary-color': prop({ variant: 'terciary' }),
  })};
`

classy gives you more power to represent conditionals and declutters you code, making it more purposeful.