Search

Ctrl + K

Switch

This document outlines the steps to create Switch component styled withTailwind CSS and using some npm dependency libraries.

Prerequisites

  • Node.js and npm installed on your machine.
  • Tailwind CSS installed in your project.
  • CVA(class-variance-authority) is a utility for managing CSS class names based on various conditions.
  • clsx is a tiny utility for constructing className strings conditionally.
Step 1: Create variant styles
1// switch.helpers.ts
2import { cva } from "class-variance-authority";
3
4export const switchVariants = cva(
5  "rounded-full cursor-pointer transition-all duration-150 bg-neutral-400 data-[disabled=true]:bg-neutral-300",
6  {
7    variants: {
8      size: {
9        small: "w-7 h-4 p-0.5",
10        medium: "w-10 h-6 p-1",
11        large: "w-12 h-7 p-1",
12      },
13      color: {
14        primary:
15          "data-[checked=true]:bg-blue-500 data-[checked=true]:data-[disabled=true]:bg-blue-300",
16        secondary:
17          "data-[checked=true]:bg-gray-500 data-[checked=true]:data-[disabled=true]:bg-gray-300",
18        success:
19          "data-[checked=true]:bg-green-500 data-[checked=true]:data-[disabled=true]:bg-green-300",
20        danger:
21          "data-[checked=true]:bg-red-500 data-[checked=true]:data-[disabled=true]:bg-red-300",
22        warning:
23          "data-[checked=true]:bg-yellow-500 data-[checked=true]:data-[disabled=true]:bg-yellow-300",
24        info: "data-[checked=true]:bg-cyan-500 data-[checked=true]:data-[disabled=true]:bg-cyan-300",
25        light:
26          "data-[checked=true]:bg-gray-300 data-[checked=true]:data-[disabled=true]:bg-gray-200",
27        dark: "data-[checked=true]:bg-black data-[checked=true]:data-[disabled=true]:bg-gray-400",
28      },
29    },
30    defaultVariants: {
31      size: "medium",
32      color: "primary",
33    },
34  },
35);
36
37export const switchIconVariants = cva(
38  "rounded-full bg-white transform transition-all duration-150 translate-x-0",
39  {
40    variants: {
41      size: {
42        small: "w-3 h-3 data-[checked=true]:translate-x-3",
43        medium: "w-4 h-4 data-[checked=true]:translate-x-4",
44        large: "w-5 h-5 data-[checked=true]:translate-x-5",
45      },
46    },
47    defaultVariants: {
48      size: "medium",
49    },
50  },
51);
52
Step 2: Create Switch component
1// switch.component.tsx
2import clsx from "clsx";
3import type { VariantProps } from "class-variance-authority";
4import { switchIconVariants, switchVariants } from "./switch.helpers";
5
6export interface SwitchProps extends VariantProps<typeof switchVariants> {
7  checked: boolean;
8  disabled?: boolean;
9  className?: string;
10  onChange: (checked: boolean) => void;
11}
12
13const Switch: React.FC<SwitchProps> = ({
14  checked,
15  size,
16  color,
17  disabled,
18  className,
19  onChange,
20}) => {
21  const handleClick = () => {
22    if (disabled) return;
23    onChange(!checked);
24  };
25
26  return (
27    <div
28      data-disabled={Boolean(disabled).toString()}
29      data-checked={Boolean(checked).toString()}
30      className={clsx(switchVariants({ size, color }), className)}
31      onClick={handleClick}
32    >
33      <div
34        data-checked={Boolean(checked).toString()}
35        className={switchIconVariants({ size })}
36      />
37    </div>
38  );
39};
40
41export default Switch;
42