react-resource-view
Introduction
One declaration, five views, and a URL that carries the state.
react-resource-view renders the CRUD surface of a resource: the list and its layouts, the detail page, the create and edit forms, the delete confirmation, the filter bar and the pagination. You describe the resource; it writes the screens.
It is built on react-data-form for everything with fields in it, which is why the two are documented side by side.
One declaration#
import { createViewResource, tableViewOptionFactory } from "react-resource-view"
export const articles = createViewResource("articles", {
name: "Articles",
path: "/api/articles",
view: {
// The fields are the form *and* the table's columns.
form: {
inputs: {
title: { label: "Title", required: true },
author: { label: "Author" },
status: { label: "Status", controller: SelectInputController, valueOptions: STATUSES },
},
},
formFilter: { inputs: { title: { label: "Search a title" } } },
viewVariants: [tableViewOptionFactory(), cardViewOptionFactory({ grid: 3 })],
},
})Rendering it is one component:
import { ViewResourceContextProvider } from "react-resource-view"
import { ActionList } from "react-data-form"
<ViewResourceContextProvider
resource={articles}
resourceAction={ActionList.list}
/>What that gives you#
Everything below comes from a declaration of that shape — no screen was written by hand. Switch the layout, filter the list, open a row, edit it, delete it. A layout the package does not ship is one command away — create your own view variant.
A resource, running
No server behind this page
A resource declared without a path falls back to a localStorage-backed repository. Every demo on this site runs against a real repository with no API behind it — your edits survive a reload.
The URL is the state#
Which view, which item, which filters, which page, which layout: all of it lives in the address bar rather than in component state.
- A link reopens exactly what the sender was looking at.
- The back button does what the reader expects.
- A reload does not lose the filters — which is the difference between a list people use and a list people fight.
Two routing modes carry it: in the path, or entirely in the query string for statically hosted or embedded views.
What it does not do#
- It has no router. Four primitives are asked for; an adapter for TanStack Router ships with the package.
- It knows no API in particular. Which backend answers, and how it spells a page or a filter, is a dialect — API Platform, Strapi and Supabase ship with the package — configured separately through
configureApi. - It is not an admin panel. There is no generated dashboard and no scaffolding step: it is a set of components you render where you want them.
- It does not own your layout. A view is a component, not a page.
Where to go next#
Installation
Install, style, and point the client at your API.
Declaring a resource
createViewResource, its five views, and the repository behind them.
Choosing a layout
Seven variants over one collection, switched by the reader.
Create your own view variant
One command writes the eighth layout: a single file, yours to draw.
Routing
The four primitives, and the two ways to carry a context.
Other projects#
- React Data Form — the form library this package renders its fields with, documented on this same site and published separately as
react-data-form. - cardona.digital — the portfolio of Salvador Cardona, who writes and maintains both packages.