Split view
betaThe one two-pane layout: aside next to the main content (rail | detail, list | reader, work | discussion); bar above, not resizable.
React lives in the app (SplitView.tsx); stories render its markup 1:1. Beta 4 Oct 2026: stories + usage + a11y done; canon after AD approval. Open: settings (OpravneniRole, SadyOpravneniTab) use SplitView with fill={false} although DS-SPLITVIEW lists Settings as not-SplitView, and pass gap without divider="gap" (no effect).
Used in 32 files · 28 areas · 33× — components/GlobalSearch, components/agent-desk, components/company, pages/AccountingInvoiceDetailPage, pages/AccountingInvoiceEditPage, pages/AsistentPlochaPage …
Default
Defaults: aside left, clamp(356px, 31%, 452px), vertical line, fill (each pane scrolls on its own)
export const Default = () => (
<div style={stack}>
<Labeled text="Defaults: aside left, clamp(356px, 31%, 452px), vertical line, fill (each pane scrolls on its own)">
<Frame>
<SV aside={<Rail />} main={<Detail />} />
</Frame>
</Labeled>
</div>
);Variants
asidePosition="right" — work | discussion (main first in the DOM, line on the left of the aside)
divider="gap" gap="var(--sp-5)" — a gap instead of the line (Projekt)
fill={false} — inside a region that already scrolls: panes hug their content and scroll together
Novák Consulting s.r.o.
VlastníkJana DvořákováFázeJednáníMěstoBrno
Aktivity
Hovor s jednatelem
Nabídka odeslána
Schůzka v kanceláři
export const Variants = () => (
<div style={stack}>
<Labeled text='asidePosition="right" — work | discussion (main first in the DOM, line on the left of the aside)'>
<Frame>
<SV
asidePosition="right"
asideWidth="clamp(300px, 24%, 360px)"
aside={<Detail title="Diskuse" />}
main={<Detail title="Úkoly projektu" />}
/>
</Frame>
</Labeled>
<Labeled text='divider="gap" gap="var(--sp-5)" — a gap instead of the line (Projekt)'>
<Frame>
<SV divider="gap" gap="var(--sp-5)" aside={<Rail />} main={<Detail />} />
</Frame>
</Labeled>
<Labeled text="fill={false} — inside a region that already scrolls: panes hug their content and scroll together">
<div
style={{
border: '1px solid var(--border)',
borderRadius: 'var(--radius-md)',
background: 'var(--surface-100)',
}}
>
<SV fill={false} asideWidth={240} aside={<Rail rows={3} />} main={<Detail />} />
</div>
</Labeled>
</div>
);Sizes
default — clamp(356px, 31%, 452px): record rail | detail, config | preview
Schůzka — rail | transcript
Aktivity, DPH — list | reader (asideWidth={372})
Deník, Účtový rozvrh — narrow filter list (asideWidth={280})
export const Sizes = () => (
<div style={stack}>
{(
[
[undefined, 'default — clamp(356px, 31%, 452px): record rail | detail, config | preview'],
['clamp(320px, 27%, 396px)', 'Schůzka — rail | transcript'],
[372, 'Aktivity, DPH — list | reader (asideWidth={372})'],
[280, 'Deník, Účtový rozvrh — narrow filter list (asideWidth={280})'],
] as const
).map(([w, t]) => (
<Labeled key={t} text={t}>
<Frame h={200}>
<SV asideWidth={w} aside={<Rail rows={3} />} main={<Detail />} />
</Frame>
</Labeled>
))}
</div>
);States
Loading — the split stands, panes show skeletons (no layout jump when data arrives)
Empty main — nothing selected in the list yet; the aside keeps its place
Long aside — fill: the aside scrolls on its own, the detail stays put
export const States = () => (
<div style={stack}>
<Labeled text="Loading — the split stands, panes show skeletons (no layout jump when data arrives)">
<Frame h={240}>
<SV
aside={
<div className="sv-pad">
<SkeletonList rows={5} />
</div>
}
main={
<div className="sv-pad">
<SkeletonList rows={4} />
</div>
}
/>
</Frame>
</Labeled>
<Labeled text="Empty main — nothing selected in the list yet; the aside keeps its place">
<Frame h={200}>
<SV
asideWidth={372}
aside={<Rail rows={4} />}
main={
<div
className="sv-pad"
style={{
alignItems: 'center',
justifyContent: 'center',
flex: 1,
color: 'var(--fg-muted)',
font: 'var(--p)',
}}
>
Vyberte záznam vlevo
</div>
}
/>
</Frame>
</Labeled>
<Labeled text="Long aside — fill: the aside scrolls on its own, the detail stays put">
<Frame h={200}>
<SV aside={<Rail rows={10} />} main={<Detail />} />
</Frame>
</Labeled>
</div>
);Composition
Bar above the split across the full width; the split is the body under it
export const Composition = () => (
<div style={stack}>
<Labeled text="Bar above the split across the full width; the split is the body under it">
<Frame h={360}>
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
gap: 'var(--sp-3)',
padding: 'var(--sp-3) var(--sp-5)',
borderBottom: '1px solid var(--border)',
}}
>
<div style={{ font: 'var(--h3)', color: 'var(--fg)' }}>Novák Consulting s.r.o.</div>
<Button variant="primary">
<Icon name="plus" />
Nový obchod
</Button>
</div>
<SV aside={<Rail rows={6} />} main={<Detail />} />
</Frame>
</Labeled>
</div>
);