UI Kit
- Tailwind Variants (opens in a new tab)
- Tailwind CSS Color Generator (opens in a new tab)
- tailwind-merge (opens in a new tab)
- Storybook (opens in a new tab)
src/components/ui/button.tsx
"use client";
import { twMerge } from "tailwind-merge";
import { tv, type VariantProps } from "tailwind-variants";
const buttonStyle = tv({
base: "tracking-tight font-medium bg-zinc-300 text-zinc-600 rounded-lg transition duration-200 ease-in-out",
variants: {
variant: {
primary: "bg-primary-600 text-primary-50 hover:bg-primary-700 active:bg-primary-800 ",
secondary: "bg-secondary-100 text-secondary-700 hover:bg-secondary-200 active:bg-secondary-300",
},
size: {
sm: "py-1 px-2 text-sm",
md: "py-2 px-4 text-base",
lg: "py-3 px-6 text-lg",
},
},
defaultVariants: {
variant: "primary",
size: "md",
},
});
type ButtonProps = VariantProps<typeof buttonStyle>;
type ButtonNativeProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
interface ButtonCombinedProps extends ButtonProps, ButtonNativeProps {}
export const Button: React.FC<ButtonCombinedProps> = ({ className, ...props }) => {
return (
<button className={twMerge(buttonStyle(props), className)} {...props}>
{props.children}
</button>
);
};
tailwind.config.ts
import type { Config } from "tailwindcss";
const config: Config = {
darkMode: "class",
content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
theme: {
colors: {
primary: {
"50": "#f3f3ff",
"100": "#e9e9fe",
"200": "#d6d6fe",
"300": "#b8b5fd",
"400": "#948bfa",
"500": "#715df5",
"600": "#532deb",
"700": "#4f29d8",
"800": "#4222b5",
"900": "#381d95",
"950": "#201065",
},
secondary: {
"50": "#f6f7f8",
"100": "#ebebee",
"200": "#e3e4e8",
"300": "#c3c6cd",
"400": "#a5a8b5",
"500": "#8f91a2",
"600": "#7e7f92",
"700": "#717184",
"800": "#5f5f6e",
"900": "#4f4f59",
"950": "#323239",
},
},
extend: {
borderWidth: {
1: "1px",
1.5: "1.5px",
},
},
},
plugins: [],
};
export default config;
src/components/ui/button.stories.tsx
import { Meta } from "@storybook/react";
import { Button } from ".";
const meta: Meta = {
component: Button,
title: "Components/Button",
};
export default meta;
export const Primary = () => <Button variant="primary">Primary</Button>;
export const Secondary = () => <Button variant="secondary">Secondary</Button>;