react-resource-view
Introduction
One declaration, five views — list, detail, create, edit, delete — 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. Those are its five views — list, detail, create, edit and delete — and the list alone comes in seven layouts.
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 {
DatePickerInputController,
NumberInputController,
SelectInputController,
} from "react-data-form"
import { createViewResource, layout } from "react-resource-view"
const CATEGORIES = [
{ label: "Forms", value: "Forms" },
{ label: "Views", value: "Views" },
{ label: "Routing", value: "Routing" },
{ label: "JSON-LD", value: "JSON-LD" },
{ label: "Architecture", value: "Architecture" },
]
const STATUSES = [
{ label: "Draft", value: "draft" },
{ label: "In review", value: "review" },
{ label: "Published", value: "published" },
]
export const articles = createViewResource("articles", {
name: "Articles",
path: "/api/articles",
// The fields are the form *and* the table's columns.
form: {
inputs: {
title: { label: "Title", required: true },
author: { label: "Author" },
category: {
label: "Category",
controller: SelectInputController,
valueOptions: CATEGORIES,
},
status: {
label: "Status",
controller: SelectInputController,
valueOptions: STATUSES,
},
readingTime: { label: "Minutes", controller: NumberInputController },
publishedAt: { label: "Published on", controller: DatePickerInputController },
},
},
views: {
list: {
filters: {
inputs: {
title: { label: "Search a title" },
status: {
label: "Status",
controller: SelectInputController,
valueOptions: STATUSES,
},
},
},
layouts: [layout.table(), layout.cards({ columns: 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. Where those forms open is one key — a page, a dialog or a drawer — and what they ask for need not be the same when creating as when editing, which is a form per action. A layout the package does not ship is one command away — create your own layout.
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, Spring Boot, Supabase, Strapi, FastAPI and Django ship with the package, and any other REST API works without one — configured separately through
configureApi. - It is not an admin panel. The library itself is a set of components you render where you want them, with no generated dashboard. The starter command writes a back office on your API for you, and AdminLayout is an optional shell for it — neither is required.
- 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.
A form per action
One description for four screens — and a different form where creating is not editing.
Choosing a layout
Seven layouts over one collection, switched by the reader.
Create your own layout
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.