Komponen / Tata letak
Drawer
Panel inspector di kanan yang menyatu dengan layar: ringkasan record terpilih, filter lanjutan, atau form singkat. Mode inline untuk slot inspector SplitView, mode overlay untuk layar sempit atau aksi sementara.
Inline (menyatu)
Gaya HIG: panel menyatu di kanan dengan garis kiri 0,5 px, tanpa bayangan. Tombol tutup menghilangkan panel; tampilkan lagi lewat aksi di layar.
PO-2026-0142
Microsoft 365 Business Premium × 120 · Jasa migrasi email
import { useState } from 'react';
import { Button, DescriptionList, Drawer, StateLabel, formatMoney } from '@divistant/circca-react';
// Mode inline: panel menyatu di kanan layar Detail (garis kiri 0,5 px, tanpa bayangan). Tutup = panel hilang.
export default function Example() {
const [open, setOpen] = useState(true);
return (
<div className="flex h-[420px] overflow-hidden rounded-2xl border-[0.5px] border-default bg-canvas">
<div className="flex min-w-[240px] flex-1 flex-col gap-3 p-4">
<h2 className="type-headline-default text-default">PO-2026-0142</h2>
<p className="type-callout-default text-muted">Microsoft 365 Business Premium × 120 · Jasa migrasi email</p>
{!open && (
<Button className="self-start" onClick={() => setOpen(true)}>
Tampilkan info
</Button>
)}
</div>
<Drawer
title="Info PO"
subtitle="Diperbarui 2 Okt 2026"
open={open}
onOpenChange={setOpen}
footer={
<>
<Drawer.Close>
<Button>Batal</Button>
</Drawer.Close>
<Button variant="primary">Simpan</Button>
</>
}
>
<div className="grid gap-3 pt-1 pb-4">
<StateLabel tone="info" size="sm" className="justify-self-start">
Diproses
</StateLabel>
<DescriptionList
variant="plain"
items={[
{ label: 'Customer', value: 'PT Mitra Energi Persada' },
{ label: 'Nilai', value: formatMoney(186_000_000), numeric: true },
{ label: 'Penagihan', value: 'Termin 60 / 40' },
]}
/>
</div>
</Drawer>
</div>
);
}Overlay
Panel modal di tepi kanan (Size Large 400 px) untuk filter lanjutan. Fokus terkunci, Esc menutup, fokus kembali ke tombol pemicu.
import { useState } from 'react';
import { Button, Checkbox, Drawer } from '@divistant/circca-react';
import { FunnelSimple } from '@phosphor-icons/react';
const STATUS = ['Draft', 'Diproses', 'Menunggu BAST', 'Selesai'];
// Mode overlay: panel modal di tepi kanan untuk aksi sementara (filter lanjutan) atau layar sempit.
// Fokus terkunci di panel, Esc menutup, fokus kembali ke tombol pemicu.
export default function Example() {
const [open, setOpen] = useState(false);
const [status, setStatus] = useState<string[]>(['Diproses']);
return (
<Drawer
mode="overlay"
size="lg"
title="Filter lanjutan"
subtitle="PO Customer"
open={open}
onOpenChange={setOpen}
trigger={<Button leadingVisual={FunnelSimple}>Filter</Button>}
footer={
<>
<Drawer.Close>
<Button>Batal</Button>
</Drawer.Close>
<Button variant="primary" onClick={() => setOpen(false)}>
Terapkan
</Button>
</>
}
>
<fieldset className="grid gap-2 pt-1 pb-4">
<legend className="mb-2 type-footnote-medium text-muted">Status</legend>
{STATUS.map(s => (
<Checkbox
key={s}
checked={status.includes(s)}
onCheckedChange={c => setStatus(prev => (c ? [...prev, s] : prev.filter(x => x !== s)))}
>
{s}
</Checkbox>
))}
</fieldset>
</Drawer>
);
}