ZeroToShip

Docs/Componenti

// componente

Tabs

Selettore a tab con header a griglia e un solo pannello visibile alla volta. Client component: tiene l'id della tab attiva in useState. Nel boilerplate arriva con tre tab di esempio (Mobile / Tablet / Desktop) da sostituire con il tuo contenuto.

File

components/Tabs.tsx

Uso base

app/page.tsx
tsx
import Tabs from "@/components/Tabs";

<Tabs />

Nessuna prop: il contenuto vive nell'array tabs in cima al file, tipizzato così:

components/Tabs.tsx
ts
interface Tab {
  id: string;          // chiave univoca, usata anche come stato attivo
  title: string;       // etichetta nell'header
  icon?: JSX.Element;  // opzionale, di solito un <svg className="size-5">
  content: JSX.Element; // mostrato solo quando la tab è attiva
}

La tab iniziale è sempre tabs[0].id. L'header usa gridTemplateColumns: repeat(tabs.length, 1fr), quindi le colonne si adattano da sole a quante tab metti. Il contenitore del contenuto ha key={activeTab}: cambiando tab React rimonta il nodo e l'animazione animate-opacity riparte.

Personalizzare

  • Le tue tab: riscrivi l'array tabs. content è JSX, quindi puoi metterci qualsiasi cosa — tabelle, immagini, altri componenti.
  • Renderlo riutilizzabile: se ti servono più gruppi di tab nella stessa app, sposta l'array in una prop:
components/Tabs.tsx
tsx
const Tabs = ({ tabs }: { tabs: Tab[] }) => {
  const [activeTab, setActiveTab] = useState<string>(tabs[0].id);
  // ...resto identico
};

// e poi
<Tabs tabs={mieTabs} />
  • Stile: l'header usa le classi DaisyUI bg-base-200 / bg-base-100. Per allinearlo al tema neobrutalista sostituiscile con card-brutal-flat e i token var(--cream-2) / var(--cream).
  • Accessibilità: le tab sono <a role="tab"> senza href. Se ti interessa la navigazione da tastiera, passa a <button> con aria-selected, oppure usa il componente Tab di Headless UI (è già una dipendenza del progetto).

Nota: la sezione docs ha un suo componente separato, app/docs/_components/DocsTabs.tsx. Questo Tabs.tsx non è usato da nessuna pagina: è materiale di libreria.