npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

use-utility-classes

v1.4.2

Published

A react hook for dynamic class names from props

Downloads

14

Readme

🧱 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>
*/