SPB Git

spb/rareindex

Public
2.0 KB · 50 lines tsx
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-1">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 items-center gap-1.5 whitespace-nowrap border-b-2 px-3 py-2 text-[13px] font-medium', isActive ? 'border-fg text-fg' : 'border-transparent text-muted hover:text-fg')}27            >28              {t.label}29              {t.count !== undefined && t.count !== null ? <span className="num rounded-sm bg-inset px-1 text-[10px] 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('rounded-[4px] px-2 py-1', 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
Files · 93afc664ddb333d55c451ac27e1a79bfd8e89448
Menu

Theme