Buttons

A collection of buttons examples, showcasing different color combinations and effects.

Border Shining Button

Preview
Source Code
Source Code
tsx
"use client";
import { cn } from "@/lib/utils";
import { motion } from "motion/react";

const BorderShiningButton = () => {
  return (
    <div className={cn("flex items-center justify-center")}>
      <div
        className={cn(
          "absolute flex items-center justify-center overflow-hidden rounded-md p-px",
          "bg-white dark:bg-black",
        )}
      >
        <motion.div
          className={cn("absolute inset-[-50%] rounded-md")}
          style={{
            background:
              "conic-gradient(from 0deg,transparent 235deg,#1FB74D 235deg,transparent 360deg)",
          }}
          animate={{ rotate: 360 }}
          transition={{
            duration: 4,
            repeat: Infinity,
            ease: "linear",
          }}
        ></motion.div>
        <button
          className={cn(
            "relative flex items-center justify-center rounded-md border px-4 py-2",
            "border-zinc-200 dark:border-zinc-800",
            "bg-white dark:bg-black",
          )}
        >
          Borders are cool
        </button>
      </div>
    </div>
  );
};

export default BorderShiningButton;

Shimer Button

Preview
Source Code
Source Code
tsx
import { cn } from "@/lib/utils";
import React from "react";

const ShimerButton = () => {
  return (
    <div className={cn("flex items-center justify-center")}>
      <button
        className={cn(
          "h-[50px] w-[200px] cursor-pointer rounded-md px-4 py-2",
          "bg-neutral-200 text-black dark:bg-zinc-900 dark:text-white",
          "after:transition-all after:duration-900",
          "after:content[''] relative overflow-hidden after:absolute after:-top-10 after:-left-50 after:h-[200px] after:w-1/2 after:rotate-10 after:bg-neutral-400 hover:after:translate-x-[500%] dark:after:bg-white/10",
        )}
      >
        Hover me
      </button>
    </div>
  );
};

export default ShimerButton;

Stitched Button

Preview
Source Code
Source Code
tsx
"use client";
import { cn } from "@/lib/utils";
import { motion } from "motion/react";

const StitchedButton = () => {
  return (
    <div className={cn("flex items-center justify-center")}>
      <div
        className={cn(
          "relative flex items-center justify-center overflow-hidden rounded-md p-[2px]",
          "rounded-md bg-neutral-200 dark:bg-neutral-800",
        )}
      >
        <motion.button
          className={cn(
            "relative flex items-center justify-center rounded-md px-4 py-2",
            "cursor-pointer border-2 border-dashed bg-white dark:bg-black",
            "border-neutral-500 dark:border-neutral-500",
          )}
          transition={{
            duration: 0.1,
            ease: "easeOut",
          }}
          whileTap={{ scale: 0.95 }}
        >
          Stitched Button
        </motion.button>
      </div>
    </div>
  );
};

export default StitchedButton;

Wooden Button

Preview
Source Code
Source Code
tsx
"use client";
import { cn } from "@/lib/utils";
import { motion } from "motion/react";
import { useState } from "react";

const WoodGrain = () => (
  <svg
    className={cn(
      "pointer-events-none absolute inset-0 h-full w-full opacity-40",
    )}
    xmlns="http://www.w3.org/2000/svg"
    preserveAspectRatio="none"
  >
    <defs>
      <filter id="wood-noise">
        <feTurbulence
          type="fractalNoise"
          baseFrequency="10.5"
          numOctaves="3"
          stitchTiles="stitch"
        />
        <feColorMatrix type="saturate" values="0" />
      </filter>
    </defs>

    {/* Base noise texture */}
    <rect width="100%" height="100%" filter="url(#wood-noise)" opacity="0.4" />

    {/* Grain lines - Elliptical patterns */}
    <g stroke="#3E2723" strokeWidth="1" fill="none" opacity="0.6">
      {/* Bottom rings */}
      <ellipse cx="50%" cy="120%" rx="120%" ry="80%" />
      <ellipse cx="50%" cy="120%" rx="100%" ry="65%" />
      <ellipse cx="50%" cy="120%" rx="80%" ry="50%" />
      <ellipse cx="50%" cy="120%" rx="60%" ry="35%" />
      <ellipse cx="50%" cy="120%" rx="40%" ry="25%" />

      {/* Top rings interaction */}
      <ellipse cx="50%" cy="-20%" rx="110%" ry="70%" />
      <ellipse cx="50%" cy="-20%" rx="90%" ry="55%" />
      <ellipse cx="50%" cy="-20%" rx="70%" ry="40%" />

      {/* Random grain details */}
      <path d="M0 20 Q 50 25 100 20" strokeOpacity="0.5" />
      <path d="M0 80 Q 50 75 100 80" strokeOpacity="0.5" />
    </g>
  </svg>
);

const WoodenButton = () => {
  const [activeTab, setActiveTab] = useState<"left" | "right">("left");

  return (
    <div className={cn("flex items-center justify-center")}>
      <div
        className={cn(
          "relative flex items-center justify-center overflow-hidden rounded-lg p-px",
          "bg-white dark:bg-black",
        )}
      >
        <div
          className={cn(
            "relative flex items-center justify-center rounded-lg border",
            "border-zinc-200 dark:border-zinc-800",
            "bg-white dark:bg-black",
          )}
        >
          <button
            onClick={() => setActiveTab("left")}
            className={cn(
              "relative z-10 cursor-pointer px-6 py-2 text-sm font-medium transition-colors duration-200",
              activeTab === "left"
                ? "text-white"
                : "text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200",
            )}
          >
            Left
            {activeTab === "left" && (
              <motion.div
                layoutId="active-tab-bg"
                className={cn(
                  "absolute inset-0 -z-10 overflow-hidden rounded-l-lg",
                )}
                style={{
                  backgroundColor: "#6d4c41",
                  boxShadow:
                    "inset 0 2px 4px rgba(255,255,255,0.2), inset 0 -2px 4px rgba(0,0,0,0.3)",
                }}
                transition={{ type: "spring", bounce: 0.3, duration: 0.5 }}
              >
                <WoodGrain />
              </motion.div>
            )}
          </button>
          <button
            onClick={() => setActiveTab("right")}
            className={cn(
              "relative z-10 cursor-pointer px-6 py-2 text-sm font-medium transition-colors duration-200",
              activeTab === "right"
                ? "text-white"
                : "text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200",
            )}
          >
            Right
            {activeTab === "right" && (
              <motion.div
                layoutId="active-tab-bg"
                className={cn(
                  "absolute inset-0 -z-10 overflow-hidden rounded-r-lg",
                )}
                style={{
                  backgroundColor: "#6d4c41",
                  boxShadow:
                    "inset 0 2px 4px rgba(255,255,255,0.2), inset 0 -2px 4px rgba(0,0,0,0.3)",
                }}
                transition={{ type: "spring", bounce: 0.3, duration: 0.5 }}
              >
                <WoodGrain />
              </motion.div>
            )}
          </button>
        </div>
      </div>
    </div>
  );
};

export default WoodenButton;
Share this post