1.4.2 • Published 2 years ago

use-utility-classes v1.4.2

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

🧱 useUtilityClasses

Make your component's class-names reactive to your component state. Ideally used in conjunction with a utility-CSS framework like Tailwind or Tachyons.


  1. Install
  2. Use
  3. HOC
  4. Prefixes
  5. Debugging

Install

  • npm install use-utility-classes or
  • yarn add use-utility-classes

Use

Pass your props to the useUtilityClasses hook, then pass conditions to the function it returns to conditionally render certain props:

import useUtilityClasses from 'use-utility-classes'

const Component = ({ color }) => {
  // Watch the value for the prop `color`
  const setClassName = useUtilityClasses({ color })
  // Set the class `text-red-500` when the value is `red`
  const className = setClassName({
    when: { color: 'red' },
    use: 'text-red-500'
  })

  return <span className={className} />
}
<Component color='red' /> // <span class="text-red-500" />
<Component color='blue' />  // <span />

You can add multiple criteria:

import useUtilityClasses from 'use-utility-classes'

const Component = ({ color, isDisabled }) => {
  // Watch the value for the following props:
  const setClassName = useUtilityClasses({ color, isDisabled })
  // Only set the class when the color is red *and* the component is not disabled
  const className = setClassName({
    when: {
      color: 'red',
      isDisabled: false
    },
    use: 'text-red-500'
  })

  return <span className={className} />
}
<Component color='red' isDisabled={true} /> // <span class="text-red-500" /> 
<Component color='red' isDisabled={false} /> => <span />

You can also pass more than one condition to the setClassName function:

import useUtilityClasses from 'use-utility-classes'

const redEnabledVariant = {
  when: {
    color: 'red',
    isDisabled: false
  },
  use: 'text-red-500'
}

const redDisabledVariant = {
  when: {
    color: 'red',
    isDisabled: true
  },
  use: 'text-red-300 cursor-not-allowed'
}

const Component = ({ color, isDisabled }) => {
  const setClassName = useUtilityClasses({ color, isDisabled })
  const className = setClassName(redEnabledVariant, redDisabledVariant)

  return <span className={className} />
}
<Component color='red' isDisabled={false} /> // <span class="text-red-500" />
<Component color='red' isDisabled={true} /> // <span class="text-red-300 cursor-not-allowed" />

For class-names that should always display, just pass a string:

import useUtilityClasses from 'use-utility-classes'

const redEnabledVariant = {
  when: {
    color: 'red',
    isDisabled: false
  },
  use: 'text-red-500'
}

const redDisabledVariant = {
  when: {
    color: 'red',
    isDisabled: true
  },
  use: 'text-red-300 cursor-not-allowed'
}

const defaultClasses = 'font-semibold text-xs uppercase'

const Component = ({ color, isDisabled }) => {
  const setClassName = useUtilityClasses({ color, isDisabled })
  const className = setClassName(
    redEnabledVariant,
    redDisabledVariant,
    defaultClasses
  )

  return <span className={className} />
}
<Component color='red' isDisabled={true} /> // <span class="text-red-300 cursor-not-allowed font-semibold text-xs uppercase" />
<Component color='red' isDisabled={false} /> // <span class="text-red-500 font-semibold text-xs uppercase" />
<Component /> // <span class="font-semibold text-xs uppercase" />

HOC

An HOC helper is also included in this package which will pass the hook via props:

import withSetClassName from 'use-utility-classes/react'

const Component = props => {
  const className = props.setClassName({
    when: {
      color: 'red',
      isDisabled: false
    },
    use: 'text-red-500'
  })
  
  return <span className={className} />
}

const WrappedComponent = withSetClassName(Component /*, { debug: true, prefix: 'tw-' } */)
<WrappedComponent color='red' isDisabled={false} /> // <span class="text-red-500"></span>

Prefixes

You can pass a prefix option if you'd like one appended to your classes:

import useUtilityClasses from 'use-utility-classes'

const Component = props => {
  const setClassName = useUtilityClasses(props, { prefix: 'tw-' })
  const className = setClassName('border-black bg-black hover:bg-gray-700 text-white')

  return <button className={className} />
}
<Component /> // <span class="tw-border-black tw-bg-black hover:tw-bg-gray-700 tw-text-white" />

Debugging

You can pass an option to make the classes more legible while you're doing development:

import useUtilityClasses from 'use-utility-classes'

const Component = props => {
  const setClassName = useUtilityClasses(props, { debug: true })
  
  const className = setClassName(
    'uppercase text-xs font-semibold tracking-wide',
    { when: { isLoading: true }, use: 'text-gray-300 cursor-not-allowed' },
    { when: { isLoading: false }, use: 'text-black cursor-pointer' }
  )

  return <span className={className} />
}

The outputs of your conditions will be listed and marked as enabled or disabled:

<Component isLoading={false} />

/*
<span class="
• uppercase text-xs font-semibold tracking-wide
Ă—â €text-gray-300â €cursor-not-allowed
• text-black cursor-pointer"></span>
*/

<Component isLoading={true} />

/*
<span class="
• uppercase text-xs font-semibold tracking-wide
• text-gray-300 cursor-not-allowed
Ă—â €text-blackâ €cursor-pointer"></span>
*/
1.4.2

2 years ago

1.4.1

2 years ago

1.4.0

2 years ago

1.2.2

2 years ago

1.3.0

2 years ago

1.2.1

2 years ago

1.2.0

2 years ago

1.1.0

2 years ago

1.0.0

2 years ago