81 lines
2.6 KiB
TypeScript
81 lines
2.6 KiB
TypeScript
"use client";
|
|
import { useRouter, useSearchParams } from "next/navigation";
|
|
import { useTransition } from "react";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
const LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
|
|
const NON_LATIN = "#";
|
|
|
|
export function LetterBar({
|
|
active,
|
|
counts,
|
|
}: {
|
|
active: string | null;
|
|
counts: Record<string, number>;
|
|
}) {
|
|
const router = useRouter();
|
|
const params = useSearchParams();
|
|
const [, start] = useTransition();
|
|
const total = counts[""] ?? 0;
|
|
const hasSearch = !!(params.get("q") ?? "").trim();
|
|
|
|
function go(letter: string | null) {
|
|
const next = new URLSearchParams(params.toString());
|
|
if (letter == null) next.delete("letter");
|
|
else next.set("letter", letter);
|
|
start(() => router.push(`?${next.toString()}`, { scroll: false }));
|
|
}
|
|
|
|
return (
|
|
<div className="flex items-stretch gap-1 w-full">
|
|
<button
|
|
type="button"
|
|
onClick={() => go(null)}
|
|
className={cn(
|
|
"flex-1 flex flex-col items-center justify-center font-mono py-2 rounded-lg border transition-colors",
|
|
active === null
|
|
? "bg-[var(--color-cyan)] text-black border-transparent"
|
|
: "glass glass-hover",
|
|
)}
|
|
>
|
|
<span className="text-base font-semibold leading-none">ALL</span>
|
|
<span className={cn(
|
|
"text-[10px] font-semibold tabular-nums mt-0.5",
|
|
active === null ? "text-black/70" : "text-[var(--color-fg-muted)]",
|
|
)}>
|
|
{total}
|
|
</span>
|
|
</button>
|
|
{[...LETTERS, NON_LATIN].map((L) => {
|
|
const n = counts[L] ?? 0;
|
|
const enabled = n > 0 && !hasSearch;
|
|
const isActive = active === L;
|
|
return (
|
|
<button
|
|
key={L}
|
|
type="button"
|
|
disabled={!enabled}
|
|
onClick={() => go(isActive ? null : L)}
|
|
className={cn(
|
|
"flex-1 flex flex-col items-center justify-center font-mono py-2 rounded-lg border transition-colors",
|
|
isActive
|
|
? "bg-[var(--color-cyan)] text-black border-transparent"
|
|
: enabled
|
|
? "glass glass-hover"
|
|
: "border-transparent text-[var(--color-fg-muted)]/40 cursor-not-allowed",
|
|
)}
|
|
>
|
|
<span className="text-base font-semibold leading-none">{L}</span>
|
|
<span className={cn(
|
|
"text-[10px] font-semibold tabular-nums mt-0.5",
|
|
isActive ? "text-black/70" : enabled ? "text-[var(--color-fg-muted)]" : "text-transparent",
|
|
)}>
|
|
{enabled ? n : 0}
|
|
</span>
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
}
|