SPB Git forge

spb/rareindex

Public
54commits 1branches 0releases
7.1 MBsize
maindefault branch
10 days agolast push
TypeScript 61.9% HTML 37.2% SQL 0.7%
2.1 KB · 50 lines tsx
Raw Blame History
1import Link from 'next/link';2import type { ReactNode } from 'react';3import { cn } from '@/lib/format';45export interface TabDef {6  id: string;7  label: ReactNode;8  count?: number | null;9  href: string;10}1112/** Server-rendered, URL-driven tabs (no client state; deep-linkable; works without JS). */13export function Tabs({ tabs, active, className }: { tabs: TabDef[]; active: string; className?: string }) {14  return (15    <div className={cn('scrollbar-none -mx-4 overflow-x-auto border-b border-border px-4 sm:mx-0 sm:px-0', className)} role="tablist">16      <div className="flex min-w-max gap-0.5">17        {tabs.map((t) => {18          const isActive = t.id === active;19          return (20            <Link21              key={t.id}22              href={t.href}23              role="tab"24              aria-selected={isActive}25              scroll={false}26              className={cn('-mb-px inline-flex min-h-[44px] items-center gap-1.5 whitespace-nowrap border-b-2 px-3 text-[13px] font-medium md:min-h-[38px]', isActive ? 'border-fg text-fg' : 'border-transparent text-muted hover:border-border-strong hover:text-fg')}27            >28              {t.label}29              {t.count !== undefined && t.count !== null ? <span className={cn('num rounded-sm px-1 text-[10px]', isActive ? 'bg-accent text-accent-fg' : 'bg-inset text-muted')}>{t.count.toLocaleString('en-US')}</span> : null}30            </Link>31          );32        })}33      </div>34    </div>35  );36}3738/** Pill group for period selectors etc. */39export function Segmented({ options, active, className }: { options: Array<{ id: string; label: string; href: string }>; active: string; className?: string }) {40  return (41    <div className={cn('inline-flex rounded-md border border-border bg-sunken p-0.5 text-[11px] font-medium', className)}>42      {options.map((o) => (43        <Link key={o.id} href={o.href} scroll={false} className={cn('inline-flex min-h-[28px] items-center rounded-[4px] px-2.5', o.id === active ? 'bg-elevated text-fg shadow-card' : 'text-muted hover:text-fg')} aria-current={o.id === active ? 'true' : undefined}>44          {o.label}45        </Link>46      ))}47    </div>48  );49}50