Inbox Split View
A mail inbox with a list plus a reading pane, a sliding selection highlight, and unread badges.
This is a WebberUI Pro component
Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.
The classic mail inbox split view: on the left, a message list with sender initial avatars, unread dots, and star indicators, where the selection highlight bar glides smoothly between items using layoutId; on the right, a reading pane that switches message content with AnimatePresence, with a toolbar that supports starring and archiving (archiving selects the adjacent message automatically).
npx shadcn@latest add "https://webberui.com/r/inbox-split-view.json?t=<install token>"Playground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<InboxSplitView />
Installation
npx shadcn@latest add "https://webberui.com/r/inbox-split-view.json?t=<install token>"Or, once registries are configured in components.json, install it as @webberui/inbox-split-view.
Usage
import { InboxSplitView, type InboxEmail } from "@/components/ui/inbox-split-view";
const emails: InboxEmail[] = [
{
id: "1",
sender: "Grace Lin",
subject: "Draft of the Q3 product roadmap for review",
preview: "Hi, attaching the first draft of this quarter's roadmap…",
time: "9:24 AM",
unread: true,
body: ["Hi, attaching the first draft of this quarter's product roadmap — please give it a read."],
},
];
<InboxSplitView
emails={emails}
onArchive={(email) => console.log("archived", email.id)}
onToggleStar={(email, starred) => console.log(email.id, starred)}
/>Props
InboxSplitView
| Prop | Type | Default | Description |
|---|---|---|---|
emails | InboxEmail[] | — | Initial message data; the component manages read / starred / archived state internally |
defaultSelectedId | string | the first message's id | The id of the message selected by default |
title | string | "收件匣" | Inbox title text |
height | number | 420 | Panel height (px); the list and the message body scroll independently |
onArchive | (email: InboxEmail) => void | — | Fires when a message is archived |
onToggleStar | (email: InboxEmail, starred: boolean) => void | — | Fires when the star is toggled; starred is the state after the toggle |
className | string | — | Forwarded to the outer container |
InboxEmail
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | — | Unique identifier |
sender | string | — | Sender name; the avatar takes its first character |
subject | string | — | Message subject |
preview | string | — | Preview snippet in the list (truncated to one line) |
time | string | — | Display time string, for example "9:24 AM" |
body | string[] | — | Body paragraphs for the reading pane |
unread | boolean | false | Whether it is unread (marked read automatically once selected) |
starred | boolean | false | Whether it is starred |
Accessibility
- The message list uses
role="listbox"withrole="option", marks the selected itemaria-selected, and supports up / down arrow keys to switch messages - The star button expresses its toggle state with
aria-pressed, and both the star and archive buttons have Chinesearia-labels - The unread dot carries
aria-label="未讀", and unread messages are also distinguished by bold weight, not by color alone - When the user has "reduce motion" enabled at the system level, the highlight bar's slide, the list reflow, and the pane switch animations all become instant changes
- Sender initial avatars are decorative and hidden from assistive technology with
aria-hidden
Ornament Toolbar
A visionOS-style ornament toolbar floating just outside the edge of a content panel: it shrinks to a pill while scrolling and expands to full controls when you stop, with Z-axis lift and a follow-along parallax.
File Manager Grid
A file/folder grid with marquee multi-select, a right-click menu, and view switching.