Skip to main content

Introduction

Motivation

A simple request to add a component variation should not become a battle of specificities. The issues starts to pop especially when components are wrapped (or better say trapped) within other components.

Fixing visual issues becomes complex and the "solution" is usually to use a stronger selector. It is understandable, because there is no UI component that could support all of the use-cases you might come across. Touching the code of the UI component to fix the issue is not ideal either as your fix might break something else. Hence, you are left with only sane option to add an extra class selector to target your case.

At that very point any component will become hard to extend and hard to maintain. And it will bite you later.

When to use

Components created with @unwind/class-name library gives you full control of the component look with a single prop.

You can create UI components that allow consumers:

  • replace only the pieces that need to be changed
  • redefine everything from the scratch

All that without touching the original code of the component aligned with the open–closed principle. This makes creating sharable UI components that allows changing provided styles a breeze. No more being unable to remove that one selector that causes you headaches in your case without fear of breaking someone elses code.

Instead of default string | undefined values, with @unwind/class-name you can create components that can accept also other types of values:

Note that if your components rely on other than CSS class selectors to define their looks, you might not need this library at all.

Adoption in 2 (or 3) steps

Rewriting you components will consist of:

Step 1: Re-define class names

Redefining the class name (selectors) the component provides depending on how the class selectors are generated:

Step 2: Resolve class names back to string

Depending on your component needs you might either want to resolve passed prop immediately or delegate resolution forward to a sub-component.

Step 3: Update types (Typescript)

In case you use Typescript, third step is to update the public API of your component to accept new types of values through the className prop (or any other of your choice).

import type { ClassNameProp } from '@unwind/class-name'

type Props = {
...
className?: ClassNameProp<typeof ...>
...
}