Initial commit
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
"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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user