0.1.3 • Published 1 year ago

clsx-variants v0.1.3

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

About the project

A tiny utility for constructing className variants conditionally. It uses the excellent clsx package under the hood.

Installation

  • npm

    npm i clsx-variants
  • pnpm

    pnpm i clsx-variants
  • yarn

    yarn add clsx-variants

Usage

import type { ReactNode } from "react";
import { clsxVariants, VariantProps } from "clsx-variants";

const buttonVariants = clsxVariants({
  compoundVariants: [
    {
      variant: "primary",
      size: "sm",
      // apply a custom class for any combination of variants
      className: "bg-blue-500 text-white px-2 py-1 text-sm",
    },
  ],
  defaultVariant: {
    size: "md",
    variant: "primary",
  },
  variants: {
    // 'true' and 'false' are reserved for boolean variants. The `false` styles will only be applied if the variant is explicitly set to `false`.
    outline: {
      false: "border-none",
      true: "border-2 border-blue-500",
    },
    size: {
      sm: "px-2 py-1 text-sm",
      md: "px-4 py-2 text-base",
      lg: "px-6 py-3 text-lg",
    },
    variant: {
      primary: "bg-blue-500 text-white",
      secondary: "bg-gray-500 text-white",
    },
  },
});

type Props = VariantProps<typeof buttonVariants> & { children: ReactNode };

const Button = ({ children, outline, size, variant }: Props) => {
  return (
    <button
      className={buttonVariants({
        outline,
        size,
        variant,
      })}
    >
      {children}
    </button>
  );
};

const App = () => {
  return (
    <div>
      {/* { outline: undefined, size: 'md', variant: 'primary' } */}
      <Button />

      {/* { outline: undefined, size: 'md', variant: 'secondary' } */}
      <Button variant="secondary" />

      {/* { outline: undefined, size: 'lg', variant: 'primary' } */}
      <Button size="lg" variant="primary" />

      {/* { outline: true, size: 'sm', variant: 'primary' } */}
      <Button size="sm" variant="primary" outline />

      {/* { outline: false, size: 'sm', variant: 'primary' } */}
      <Button size="sm" variant="primary" outline={false} />
    </div>
  );
};

// VariantProps takes a second argument that specifies which of the variants are required
type AllPropsAreOptional = VariantProps<typeof buttonVariants>;
/* 
  {
    outline?: boolean | undefined;
    size?: "sm" | "md" | "lg" | undefined;
    variant?: "primary" | "secondary" | undefined;
  }
*/

type SomePropsAreRequired = VariantProps<
  typeof buttonVariants,
  "size" | "variant"
>;
/* 
  {
    outline?: boolean | undefined;
    size: "sm" | "md" | "lg";
    variant: "primary" | "secondary";
  }
*/
0.1.3

1 year ago

0.1.2

1 year ago

0.1.1

1 year ago

0.1.0

1 year ago