Komponen / Tata letak
Card
Wadah isi berjudul di halaman detail dan dashboard: judul + keterangan, aksi di kanan header, isi bebas, dan footer. Contoh: kartu Item, Termin pembayaran, dan "Perlu tindakan Anda" di detail PO.
Judul, aksi, dan footer
Flat (garis tepi tipis) adalah default untuk kartu di atas kanvas halaman. Raised memakai bayangan Elevation/1 untuk kartu yang perlu menonjol.
Termin pembayaran
Terbayar Rp 90.000.000 dari Rp 150.000.000
Terbayar
Diperbarui 25 Sep 2026 oleh Rina Kartika
Termin pembayaran
Elevation Raised
Terbayar
Diperbarui 25 Sep 2026 oleh Rina Kartika
import { Card, IconButton, ProgressBar } from '@divistant/circca-react';
import { DotsThree } from '@phosphor-icons/react';
// Flat (default) untuk kartu di atas kanvas halaman; Raised (Elevation/1) untuk kartu yang perlu menonjol.
export default function Example() {
return (
<div className="grid max-w-3xl gap-4 sm:grid-cols-2">
<Card
title="Termin pembayaran"
subtitle="Terbayar Rp 90.000.000 dari Rp 150.000.000"
action={<IconButton variant="ghost" size="sm" icon={DotsThree} label="Aksi termin pembayaran" />}
footer="Diperbarui 25 Sep 2026 oleh Rina Kartika"
>
<ProgressBar value={60} label="Terbayar" />
</Card>
<Card
elevation="raised"
title="Termin pembayaran"
subtitle="Elevation Raised"
action={<IconButton variant="ghost" size="sm" icon={DotsThree} label="Aksi termin pembayaran (raised)" />}
footer="Diperbarui 25 Sep 2026 oleh Rina Kartika"
>
<ProgressBar value={60} label="Terbayar" />
</Card>
</div>
);
}Perlu tindakan Anda
Kartu tugas di kolom kanan detail dokumen: tenggat di aksi header, penjelasan, checklist, lalu satu tombol utama.
Perlu tindakan Anda
Hari ini
Terbitkan BAST instalasi agar Termin 2 (Rp 60.000.000) bisa ditagih.
- Selesai: Instalasi & aktivasi 25 lisensi
- Selesai: Uji akses pengguna oleh customer
- Belum: Tanda tangan BAST oleh customer
import { Button, Card, formatMoney } from '@divistant/circca-react';
import { CalendarBlank, CheckCircle, Circle } from '@phosphor-icons/react';
// Kartu "Perlu tindakan Anda" di kolom kanan detail PO: tenggat di aksi header, checklist, lalu satu tombol utama.
const langkah = [
{ label: 'Instalasi & aktivasi 25 lisensi', selesai: true },
{ label: 'Uji akses pengguna oleh customer', selesai: true },
{ label: 'Tanda tangan BAST oleh customer', selesai: false },
];
export default function Example() {
return (
<Card
className="max-w-[360px]"
elevation="raised"
title="Perlu tindakan Anda"
action={
<span className="flex items-center gap-1 type-footnote-medium text-warning-fg">
<CalendarBlank size={14} aria-hidden />
Hari ini
</span>
}
>
<div className="grid gap-2">
<p className="type-callout-default text-default">
Terbitkan BAST instalasi agar Termin 2 ({formatMoney(60_000_000)}) bisa ditagih.
</p>
<ul className="grid">
{langkah.map(l => (
<li key={l.label} className="flex items-center gap-2.5 py-1.5 type-callout-default text-default">
{l.selesai ? (
<CheckCircle size={18} weight="fill" className="shrink-0 text-accent-fg" aria-hidden />
) : (
<Circle size={18} className="shrink-0 text-muted" aria-hidden />
)}
<span className="sr-only">{l.selesai ? 'Selesai: ' : 'Belum: '}</span>
{l.label}
</li>
))}
</ul>
<Button variant="primary" block>
Terbitkan BAST
</Button>
</div>
</Card>
);
}Isi menempel tepi (flush)
Dengan `flush`, isi selebar kartu dan menempel ke tepi bawah bila tanpa footer — untuk tabel item atau daftar berpemisah.
Item · 3
Lisensi & jasa · nilai sebelum PPN
| Item | Kategori | Qty | Harga satuan (Rp) | Jumlah (Rp) |
|---|---|---|---|---|
| Lisensi software kolaborasi · 25 user | Lisensi | 25 | 3.600.000 | 90.000.000 |
| Jasa instalasi & aktivasi lisensi | Jasa | 1 | 45.000.000 | 45.000.000 |
| Pelatihan admin (2 sesi) | Jasa | 1 | 15.000.000 | 15.000.000 |
| Total sebelum PPN | Rp 150.000.000 | |||
import { Card, formatMoney, formatNumber } from '@divistant/circca-react';
// `flush`: isi menempel ke tepi kartu — untuk tabel item yang barisnya selebar kartu.
const item = [
{ nama: 'Lisensi software kolaborasi · 25 user', kategori: 'Lisensi', qty: 25, harga: 3_600_000 },
{ nama: 'Jasa instalasi & aktivasi lisensi', kategori: 'Jasa', qty: 1, harga: 45_000_000 },
{ nama: 'Pelatihan admin (2 sesi)', kategori: 'Jasa', qty: 1, harga: 15_000_000 },
];
export default function Example() {
const total = item.reduce((s, i) => s + i.qty * i.harga, 0);
return (
<Card className="max-w-3xl" title={`Item · ${item.length}`} subtitle="Lisensi & jasa · nilai sebelum PPN" flush>
<div className="overflow-x-auto">
<table className="w-full min-w-[560px] border-collapse type-callout-default">
<thead>
<tr className="border-y-[0.5px] border-muted bg-subtle text-left type-footnote-medium text-muted">
<th scope="col" className="px-4 py-2 font-[inherit]">Item</th>
<th scope="col" className="px-2 py-2 font-[inherit]">Kategori</th>
<th scope="col" className="px-2 py-2 text-right font-[inherit]">Qty</th>
<th scope="col" className="px-2 py-2 text-right font-[inherit]">Harga satuan (Rp)</th>
<th scope="col" className="px-4 py-2 text-right font-[inherit]">Jumlah (Rp)</th>
</tr>
</thead>
<tbody>
{item.map(i => (
<tr key={i.nama} className="border-b-[0.5px] border-muted text-default">
<td className="px-4 py-2.5">{i.nama}</td>
<td className="px-2 py-2.5">{i.kategori}</td>
<td className="px-2 py-2.5 text-right tabular-nums">{i.qty}</td>
<td className="px-2 py-2.5 text-right tabular-nums">{formatNumber(i.harga)}</td>
<td className="px-4 py-2.5 text-right tabular-nums">{formatNumber(i.qty * i.harga)}</td>
</tr>
))}
</tbody>
<tfoot>
<tr className="bg-subtle type-body-default-semibold text-default">
<th scope="row" colSpan={4} className="px-4 py-2.5 text-left font-[inherit]">Total sebelum PPN</th>
<td className="px-4 py-2.5 text-right tabular-nums">{formatMoney(total)}</td>
</tr>
</tfoot>
</table>
</div>
</Card>
);
}