spb/datacenterindex
Public
HTML 53.9%
TypeScript 44.5%
JavaScript 0.6%
SQL 0.5%
1"use client";23import { ChevronDown } from "lucide-react";4import { useState, type ReactNode } from "react";5import { fmtInt } from "@/lib/format";6import { cn } from "./cn";78/** Rows kept visible while collapsed (matches `.dci-collapse` nth-child rule in globals.css). */9export const COLLAPSE_ROWS = 10;1011/**12 * Mobile-only "Show all N" for long server-rendered lists (tables, <ol>/<ul>): under 640 px only the13 * first COLLAPSE_ROWS rows are shown until the user expands. Purely CSS-driven (data attribute), so the14 * children stay server components and nothing but serialisable props crosses the boundary.15 * On ≥ 640 px every row is visible and the toggle is hidden.16 */17export function CollapsibleRows({ total, label = "rows", children, className }: { total: number; label?: string; children: ReactNode; className?: string }) {18 const [open, setOpen] = useState(false);19 const collapsible = total > COLLAPSE_ROWS + 2;20 const collapsed = collapsible && !open;21 return (22 <div className={cn("dci-collapse", className)} data-collapsed={collapsed ? "" : undefined}>23 {children}24 {collapsible && (25 <button26 type="button"27 onClick={() => setOpen((o) => !o)}28 aria-expanded={!collapsed}29 className="mt-1 flex h-11 w-full items-center justify-center gap-1.5 rounded-sm border border-hair bg-surface text-[12.5px] font-medium text-ink-2 hover:text-ink sm:hidden"30 >31 {collapsed ? `Show all ${fmtInt(total)} ${label}` : "Show fewer"}32 <ChevronDown className={cn("size-3.5 transition-transform", !collapsed && "rotate-180")} strokeWidth={1.75} aria-hidden />33 </button>34 )}35 </div>36 );37}38