Componentticket-stub
Pool Table
Pool ball grid organizer with striped/solid ball rendering.
Preview
Live Preview
Bilardo topu düzenleyici
123456789101112
Installation
Tokens guide →Add to your project via CLI (zero dependencies, code you own):
npx bigbullui add pool-tableOr install the full npm package:
npm install bigbulluiUsage
import { PoolTable } from "@/components/ui/pool-table";
<PoolTable />Source code
pool-table.tsxZero dependencies (only React + utils). Copy and paste directly into your project:
"use client";
import * as React from "react";
import { cn } from "./lib/utils";
export interface PoolBall {
number: number;
color: string;
striped?: boolean;
}
export interface PoolTableProps extends React.HTMLAttributes<HTMLDivElement> {
balls?: PoolBall[];
}
const DEFAULT_BALLS: PoolBall[] = [
{ number: 1, color: "bg-amber-400" },
{ number: 2, color: "bg-sky-500" },
{ number: 3, color: "bg-red-500" },
{ number: 4, color: "bg-violet-600" },
{ number: 5, color: "bg-orange-500" },
{ number: 6, color: "bg-emerald-600" },
{ number: 7, color: "bg-red-800" },
{ number: 8, color: "bg-black" },
{ number: 9, color: "bg-amber-400", striped: true },
{ number: 10, color: "bg-sky-500", striped: true },
{ number: 11, color: "bg-red-500", striped: true },
{ number: 12, color: "bg-violet-600", striped: true },
];
/** Bilardo topu düzenleyici: renkli top grid'i. */
export function PoolTable({ balls = DEFAULT_BALLS, className, ...props }: PoolTableProps) {
return (
<div className={cn("w-48 rounded-lg border-2 border-amber-900/60 bg-emerald-900/40 p-3", className)} {...props}>
<style>{`@keyframes ptIn { from { transform: scale(0.5); opacity: 0; } to { transform: scale(1); opacity: 1; } }`}</style>
<p className="mb-2 text-center font-mono text-[9px] uppercase tracking-widest text-emerald-200/60">Bilardo topu düzenleyici</p>
<div className="grid grid-cols-4 place-items-center gap-2">
{balls.map((ball, idx) => (
<span
key={ball.number}
className={cn(
"relative flex size-8 items-center justify-center rounded-full border border-black/30 shadow-sm",
ball.striped ? "bg-white" : ball.color
)}
style={{ animation: `ptIn 0.3s cubic-bezier(0.34,1.56,0.64,1) both`, animationDelay: `${idx * 45}ms` }}
aria-label={`${ball.number} numaralı top`}
>
{ball.striped && <span className={cn("absolute inset-x-0 top-1/2 h-1/2 -translate-y-0", ball.color)} aria-hidden="true" />}
<span className="relative z-10 flex size-3.5 items-center justify-center rounded-full bg-white font-mono text-[8px] font-bold text-black">
{ball.number}
</span>
</span>
))}
</div>
</div>
);
}
Props
| Prop | Type | Description |
|---|---|---|
| balls | PoolBall[] |