SplitView
sidebar | list | detail on one screen, built on Resizable.
View code
<SplitView
id="inbox"
sidebar={<FolderNav />}
rail={<FolderIcons />}
list={<ConversationList />}
detail={selected ? <Conversation id={selected} /> : null}
empty={<p>Pick a conversation to read it here.</p>}
backHref="/inbox"
layout={readSplitViewLayout(request.headers.get("Cookie"))}
labels={{ resizeSidebar: "Resize folders", resizeList: "Resize conversations", back: "Inbox" }}
/>
// each conversation link in the list
<a href="/inbox?c=42" data-split-view-item aria-current={selected === 42 ? "page" : undefined}>…</a>Demo apps
Whole pages built only from @sdxc/ui, each for an invented product with its own palette and type. They open in a new tab.
- CMSInkwellInkwell, a demo CMS built from @sdxc/ui/app: posts with count tabs and quick edit, an editor with a quiet save status and a loud Publish, media and settings./demo/apps/inkwell
- Ops dashboardPulsePulse, an invented ops dashboard: Northwind's services with live filters, a peek sheet and a bulk bar, metrics that switch one chart, incidents, deploys and settings./demo/apps/pulse
- Support inboxRelayRelay, an invented support inbox: mailboxes, conversations and the open conversation on one screen, with contacts, reports and settings./demo/apps/relay
Every demo, landings and docs sites alike, is listed in the demo gallery.
Installation
An ordinary dependency: install it, import the theme once, and import the component where it is used.
npm add @sdxc/ui remiximport "@sdxc/ui/theme.css";Usage
import { SplitView } from "@sdxc/ui/app";Renders the view. From 64rem the panes sit side by side; below it the sidebar is a sheet
opened by a SplitViewToggle; below 48rem only the active pane shows, and the
detail gains a back link. Each pane scrolls on its own and keeps its id for a frame.
Examples
<SplitView id="customers" list={<CustomerList />} detail={<Customer />} labels={labels} />Props
Read from the component's own types, so every prop, every default and every allowed value is listed.
| Prop | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The view's id; its panes take ${id}-sidebar, ${id}-list and ${id}-detail. |
sidebar | RemixNode | No | Folders, views, filters: omit it for a two-pane list + detail. |
rail | RemixNode | No | What the sidebar shows collapsed to its rail, such as its icons alone. |
list | RemixNode | Yes | The list of records, each link carrying data-split-view-item. |
detail | RemixNode | No | The selected record, or nothing while none is selected. |
empty | RemixNode | No | Shown in the detail pane while nothing is selected. |
active | Pane | No | The pane this route shows below 48rem. |
backHref | string | No | The list's URL; below 48rem the detail links back to it. |
layout | Layout | No | The remembered split, from readSplitViewLayout. |
cookie | string | No | The cookie the layout persists in; give each view on a site its own. |
keys | SplitViewKeyScope | No | Where j/k answer: "page" anywhere, "view" only while focus is inside the view. |
labels | Labels | Yes |
Also accepts everything in Omit<TagProps<"div">, "id">.