SearchCtrlK

  • ↑↓navigate
  • ↵open
  • escclose

Can’t find it? Contact us

SplitView

sidebar | list | detail on one screen, built on Resizable.

Open in a new tab
View code
tsx
<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.

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.

Terminal
npm add @sdxc/ui remix
typescript
import "@sdxc/ui/theme.css";

Usage

typescript
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

tsx
<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.

PropTypeRequiredDescription
idstringYesThe view's id; its panes take ${id}-sidebar, ${id}-list and ${id}-detail.
sidebarRemixNodeNoFolders, views, filters: omit it for a two-pane list + detail.
railRemixNodeNoWhat the sidebar shows collapsed to its rail, such as its icons alone.
listRemixNodeYesThe list of records, each link carrying data-split-view-item.
detailRemixNodeNoThe selected record, or nothing while none is selected.
emptyRemixNodeNoShown in the detail pane while nothing is selected.
activePaneNoThe pane this route shows below 48rem.
backHrefstringNoThe list's URL; below 48rem the detail links back to it.
layoutLayoutNoThe remembered split, from readSplitViewLayout.
cookiestringNoThe cookie the layout persists in; give each view on a site its own.
keysSplitViewKeyScopeNoWhere j/k answer: "page" anywhere, "view" only while focus is inside the view.
labelsLabelsYes

Also accepts everything in Omit<TagProps<"div">, "id">.

@sdxc/ui

Can’t find it? Contact us