1. What we can build on design-system components today
The hard rule on this build was real components first, bespoke only where the library has no equivalent. It held: an independent review confirmed every element below uses a real @wordpress/* component, and every hand-rolled piece has a genuine gap behind it. The panel is component-honest, not a re-skin pretending to be one.
| Piece | Built with |
|---|---|
| Notifications list | real DataViews list layout, fields, infinite scroll, empty + loading states |
| Per-row overflow ⋮ | native DataViews actions prop, no hand-rolled row menu |
| Filter tabs | Tabs from @wordpress/components (private API, see limits) |
| Panel, header, cards | Card / CardHeader / Heading |
| Buttons, header menu | Button, DropdownMenu / MenuGroup / MenuItem |
| Reply input + send | InputControl (experimental export) |
| Layout, text, links, icons | HStack / VStack / Text / ExternalLink / Icon / Spinner |
| Slide-out detail (both modes) | composed from the primitives above, one component with a mode prop, no bespoke UI kit |
Three native wins we should just take: the row ⋮ via the actions prop; the built-in empty and isLoading states; and dropping groupBy entirely (i1 is a flat list with time in the row metadata), which deletes the three worst structural CSS hacks in the shipped panel.
2. What DataViews can’t carry (the laundry list)
These are real, verified against the installed @wordpress/dataviews@16 source, not guesses. Each one is either work we own or an upstream gap to log. None of it is a blocker for the relaunch; it is the honest maintenance picture.
| What it can’t do | What that forces on us |
|---|---|
| No detail / preview / master-detail concept. Six layouts, none of them a pane. | Both slide-out modes are 100% app-composed. DataViews gives the click bridge (onChangeSelection on the list layout), not the pane. |
| No read / unread or row-state concept. | Style .is-unread with :has() against the library’s private DOM. A refactor upstream silently breaks it. |
| Its selected-row styling out-shouts any unread cue. | Bypass the selection model entirely (empty selection + our own active marker). |
| No responsive or container-aware layout switching. | The 464 to 927 flip, the width animation, and keeping the row highlighted while a sibling pane shows all live in our code. |
Malformed list grid ARIA (role=grid with article rows). | Library-side, unfixable by us. Logged as an accessibility gap to push upstream. |
No Avatar; no drawer / slide-over primitive; Tabs is private-API only; InputControl is an experimental export. | Hand-roll the avatar + status badge, and lean on unstable APIs the shipped panel already depends on. |
| The library’s WPDS design-token stylesheet isn’t loaded in this app. | Its native row backgrounds compute to transparent, so the visual skin is mostly our CSS. “Real library” is true for structure, behavior, and a11y roles, not the paint. |
3. The one change that would move most of this into the library
DataViews v16 ships an activity layout: a purpose-built feed (media icon, title, description, a per-row actions menu, grouped or flat, role="feed"). It is the closest thing in Gutenberg to a notifications list, and the natural convergence point. We stayed on list for exactly one reason: activity makes only the title clickable, and a notification row needs the whole row as the target.
Make the whole row a click target on the activity layout, and add a detail render slot with open-vs-selected semantics. Then activity, not list, is the right base for notifications, and roughly half of the overrides above disappear. That is the single highest-leverage thing this evaluation surfaced.
4. Open calls before I write the post
A few things I want a read on, none of them blocking the prototype:
- Time-group headers. i1 is a flat list with time in the row metadata (“Today · Mention”), so I dropped grouping, which is what deletes those CSS hacks. That is a change from today’s grouped panel. Worth confirming we want the flat list.
- Detail on the left or the right. The Figma has it both ways in different frames. The prototype went detail-left, list-right, per the read/unread flow. One-line check with @cbusquets1989.
- Accessibility to finish. In the narrow slide-over the list behind the detail isn’t inert yet, so a keyboard or screen-reader user can tab back into it. On the fix list alongside the unread-in-the-a11y-tree work.
- Fidelity nits the build knows about: the Trash button renders Gutenberg blue rather than neutral,
ExternalLinkshows its arrow glyph, avatars are colored initials standing in for gravatars, and the mixed-weight titles read subtly at 13px.
Tell me your laundry list on top of these and I’ll fold it into the next build pass, then the P2 goes out with the prototype linked.