← Back to Crumbs
InterfacesReactTypeScriptTailwind
Rattan Button
A button woven to look like rattan cane, with the press handling to match.
Live preview
Code
rattan-button.tsx
"use client";
import * as React from "react";
export interface RattanButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
children: React.ReactNode;
}
export const RattanButton = React.forwardRef<HTMLButtonElement, RattanButtonProps>(
({ children, className = "", ...props }, ref) => {
return (
<button
ref={ref}
{...props}
className={[
"relative inline-flex items-center justify-center gap-2 overflow-hidden",
"rounded-full border-2 border-[#5c3a21] px-7 py-3",
"font-bold text-[15px] text-[#381d09] dark:text-[#fbe8cf]",
"bg-[#ecb47c] bg-[length:16px_16px]",
"bg-[image:repeating-linear-gradient(45deg,rgba(92,58,33,0.28)_0_2px,transparent_2px_8px),repeating-linear-gradient(-45deg,rgba(92,58,33,0.28)_0_2px,transparent_2px_8px)]",
"shadow-[inset_0_1px_0_rgba(255,236,205,0.6),inset_0_-3px_4px_rgba(92,58,33,0.35),0_4px_0_#5c3a21,0_8px_14px_rgba(92,58,33,0.35)]",
"transition-transform duration-150 ease-out",
"focus-visible:outline-none",
"hover:brightness-105",
"active:translate-y-[3px] active:shadow-[inset_0_1px_0_rgba(255,236,205,0.6),inset_0_-3px_4px_rgba(92,58,33,0.35),0_1px_0_#5c3a21,0_2px_6px_rgba(92,58,33,0.3)]",
"focus-visible:ring-2 focus-visible:ring-[#8a5a2b] focus-visible:ring-offset-2 focus-visible:ring-offset-[#fff8ef] dark:focus-visible:ring-offset-[#1c1410]",
"disabled:cursor-not-allowed disabled:opacity-50 disabled:saturate-50",
"dark:border-[#3a2413] dark:bg-[#8a5a2b] dark:bg-[image:repeating-linear-gradient(45deg,rgba(58,36,19,0.5)_0_2px,transparent_2px_8px),repeating-linear-gradient(-45deg,rgba(58,36,19,0.5)_0_2px,transparent_2px_8px)]",
className,
]
.filter(Boolean)
.join(" ")}
>
<span className="pointer-events-none absolute inset-x-0 top-0 h-1/2 rounded-t-full bg-gradient-to-b from-white/25 to-transparent" />
<span className="relative">{children}</span>
</button>
);
},
);
RattanButton.displayName = "RattanButton";
Usage
usage.tsx
import { RattanButton } from "@/components/rattan-button";
export function AddToBasket() {
return <RattanButton onClick={() => {}}>Add to basket</RattanButton>;
}Dependencies
None - just React and Tailwind.
Responsive
Sizes to its content with padding, like a native button - drop it anywhere from a compact toolbar to a full-width mobile CTA.
Dark mode
Switches to a darker walnut weave with lighter grout lines via Tailwind's dark: variant - no extra props needed.