import clsx from "clsx"; import { useTranslation } from "react-i18next"; import { Layers } from "lucide-react"; import { formatNumber } from "../../lib/format"; // At a million and above we stop printing the exact figure — six digits is the readable ceiling, so // the pill shows "1M+" and the tooltip carries the precise number. const OVERFLOW_AT = 1_000_000; // A compact, FIXED-WIDTH count pill for a toolbar: the filtered item count at the toolbar's 28, flat // and tonal like a `Badge` (the same opaque `bg-tint`: the toolbar is glass over scrolling thumbnails) // — no edge, because it does nothing (edged = pressable, flat = just // says; it used to wear the filter dropdowns' glass pill and read as one more). The fixed width is the point — a // changing number must never shove the controls beside it, so the box is sized to the widest value // ("999,999 items") and the content is centred within it. A count of a million or more collapses to // "1M+", with the exact figure in the title tooltip. Deliberately generic ("item(s)", dynamic plural) // so any surface can reuse it for whatever it counts. `stale`: the count is the previous filter's, // kept while the new one loads (keepPreviousData) — dimmed, and "updating" for a screen reader (which // does not voice aria-busy on plain text), so a broad search's slow count ("a": ~3 s) never reads as // the new result. `failed`: the count could not be read — a dash that says so, not the icon-only box // of a first load. export default function ItemCount({ count, stale = false, failed = false, }: { count?: number; stale?: boolean; failed?: boolean; }) { const { t, i18n } = useTranslation(); const lang = i18n.language; // `count` undefined and not `failed`: a first, un-cached load — keep the fixed box (nothing shifts), // just show the icon until the number arrives. const label = failed ? "—" : count == null ? "" : t("common.itemCount", { count, formattedCount: count >= OVERFLOW_AT ? "1M+" : formatNumber(count, lang), }); return ( ); }