Komponen / Navigasi
TabBar
Navigasi utama BizOps versi ponsel: kapsul kaca Liquid Glass berisi 3–5 tab (ikon + label) yang melayang di atas tepi bawah layar. Tiap tab adalah tautan ke halaman utama sebuah area: Beranda, Tugas, Persetujuan, Notifikasi, Akun.
Di layar ponsel
position="absolute" menaruh TabBar 8 px di atas tepi bawah kontainer relative terdekat, di tengah. Isi bergulir di belakang kaca; beri padding bawah agar baris terakhir tidak tertutup. safeArea menambah jarak indikator beranda iPhone.
Beranda
PO-2026-0140
PT Mitra Energi Persada
PO-2026-0141
PT Mitra Energi Persada
PO-2026-0142
PT Mitra Energi Persada
PO-2026-0143
PT Mitra Energi Persada
PO-2026-0144
PT Mitra Energi Persada
PO-2026-0145
PT Mitra Energi Persada
PO-2026-0146
PT Mitra Energi Persada
PO-2026-0147
PT Mitra Energi Persada
PO-2026-0148
PT Mitra Energi Persada
PO-2026-0149
PT Mitra Energi Persada
PO-2026-0150
PT Mitra Energi Persada
PO-2026-0151
PT Mitra Energi Persada
import { useState, type MouseEvent } from 'react';
import { TabBar } from '@divistant/circca-react';
import { Bell, CheckSquare, House, Stamp, UserCircle } from '@phosphor-icons/react';
const TABS = [
{ id: 'beranda', label: 'Beranda', icon: House },
{ id: 'tugas', label: 'Tugas', icon: CheckSquare },
{ id: 'persetujuan', label: 'Persetujuan', icon: Stamp, badge: 3, badgeLabel: '3 menunggu persetujuan' },
{ id: 'notifikasi', label: 'Notifikasi', icon: Bell },
{ id: 'akun', label: 'Akun', icon: UserCircle },
];
// BizOps versi ponsel: TabBar melayang 8 px di atas tepi bawah bingkai ponsel tiruan (position="absolute").
// Isi bergulir di belakang kapsul kaca — beri padding bawah agar baris terakhir tidak tertutup.
export default function Example() {
const [aktif, setAktif] = useState('beranda');
const judul = TABS.find(t => t.id === aktif)?.label;
return (
<div className="relative mx-auto h-[700px] w-[390px] max-w-full overflow-hidden rounded-[40px] border-[0.5px] border-default bg-canvas">
<div className="h-full overflow-y-auto px-4 pt-6 pb-24">
<h2 className="type-display-page-title text-default">{judul}</h2>
<ul className="mt-4 grid gap-2">
{Array.from({ length: 12 }, (_, i) => (
<li key={i} className="rounded-xl bg-default px-4 py-3 shadow-elevation-1">
<p className="type-body-default-medium text-default">PO-2026-{String(140 + i).padStart(4, '0')}</p>
<p className="type-footnote-default text-muted">PT Mitra Energi Persada</p>
</li>
))}
</ul>
</div>
<TabBar label="Navigasi utama" position="absolute" safeArea>
{TABS.map(t => (
<TabBar.Item
key={t.id}
href="#"
icon={t.icon}
current={aktif === t.id}
badge={t.badge}
badgeLabel={t.badgeLabel}
onClick={(e: MouseEvent) => {
e.preventDefault();
setAktif(t.id);
}}
>
{t.label}
</TabBar.Item>
))}
</TabBar>
</div>
);
}Dengan Next Link
asChild memasang gaya tab ke <Link> Next.js. Empat tab (properti Figma "Tab 5" mati). Badge menandai persetujuan yang menunggu dan ikut diumumkan pembaca layar.
import Link from 'next/link';
import type { MouseEvent } from 'react';
import { TabBar } from '@divistant/circca-react';
import { CheckSquare, House, Stamp, UserCircle } from '@phosphor-icons/react';
// asChild: gaya tab dipasang ke Next <Link> — prefetch & navigasi klien tetap jalan.
// Empat tab (properti Figma "Tab 5" mati). Di contoh ini klik dicegah agar halaman dokumentasi tidak berpindah.
const cegah = (e: MouseEvent) => e.preventDefault();
export default function Example() {
return (
<div className="flex justify-center rounded-2xl bg-canvas p-6">
<TabBar label="Navigasi utama">
<TabBar.Item asChild icon={House}>
<Link href="#" onClick={cegah}>
Beranda
</Link>
</TabBar.Item>
<TabBar.Item asChild icon={CheckSquare} current>
<Link href="#" onClick={cegah}>
Tugas
</Link>
</TabBar.Item>
<TabBar.Item asChild icon={Stamp} badge={3} badgeLabel="3 menunggu persetujuan">
<Link href="#" onClick={cegah}>
Persetujuan
</Link>
</TabBar.Item>
<TabBar.Item asChild icon={UserCircle}>
<Link href="#" onClick={cegah}>
Akun
</Link>
</TabBar.Item>
</TabBar>
</div>
);
}