Skip to content

FRD: CRUD Resource Page Recipe

FieldValue
IDFRD-042
OwnerDavid Holmes
StatusDraft
PriorityP1 — Recipes
SizeM (Recipe)
Target Releasev2.0.0
Last Updated2026-05-26
RelatedADR-027 (Default Tech Stack)

Document Summary

Create an MDX recipe in Storybook that teaches developers how to compose a complete CRUD (Create, Read, Update, Delete) resource page using design system components. The recipe combines DataGrid, Dialog, SearchInput, Pagination, FilterBar, EmptyState, and Toast into a cohesive page pattern with copy-pasteable code, realistic data, and guidance for pagination, search, bulk actions, and error states.


Introduction

Overview

A CRUD resource page (e.g., “Users”, “Products”, “Orders”) is the most common page pattern in B2B SaaS applications. Developers building these pages need to wire together 7-10 design system components with query state, form validation, toast notifications, and loading/error/empty states. Today, there is no canonical recipe showing how to do this correctly. Developers assemble these pages ad-hoc, resulting in inconsistent patterns, missing states, and duplicated logic.

Goals

  • Provide a single MDX recipe page in Storybook that shows the complete CRUD page composition pattern.
  • Include copy-pasteable code blocks for each section: list view with DataGrid, create/edit Dialog with form, delete confirmation, search/filter bar, pagination, bulk actions, and empty/error/loading states.
  • Use realistic sample data (e.g., a “Team Members” resource) so developers can see the pattern in context.
  • Link to each component’s Storybook docs page and relevant ADRs.
  • Document when to use this recipe and when to use an alternative pattern.

Non-Goals

  • Building new components (all components must already exist in the design system).
  • Implementing backend API logic — the recipe shows frontend composition only.
  • Providing a full working example application (that belongs in examples/).
  • Covering every possible CRUD variation (e.g., inline editing, tree-structured resources).

Scope

In Scope

ItemDescription
MDX recipe pagesrc/docs/recipes/crud-resource-page.mdx with Storybook sidebar entry
List view compositionDataGrid + SortableColumnHeader + Pagination + SearchInput + FilterBar
Create/Edit flowDialog with form fields, validation, submit/cancel, toast feedback
Delete flowAlertDialog confirmation, toast feedback, optimistic update pattern
Bulk actionsCheckbox selection in DataGrid, bulk action toolbar, confirmation dialog
State managementLoading skeletons, empty state, error state, no-results state
Realistic sample dataTypeScript interface + mock data for a “Team Members” resource
Overview page updateAdd CRUD recipe entry to src/docs/recipes/00-overview.mdx

Out of Scope

ItemReason
Server-side pagination implementationBackend-specific; recipe covers the client-side wiring
TanStack Query integration detailsQuery library specifics vary by project; recipe shows the component composition
Inline editing patternDifferent enough to warrant a separate recipe
Mobile-responsive layoutRecipe focuses on desktop layout; responsive behavior is a component concern

Users and Pain Points

UserPain Point
Application developerNo reference for how to wire DataGrid + Dialog + Toast together for a standard CRUD page
Application developerUnclear which empty state component to use (EmptyState vs. NoResultsState) and when
Application developerMissing bulk action patterns — selection state, toolbar visibility, confirmation flow
Application developerPagination and search not integrated — unclear how filter state and page state interact
New team memberNo canonical “this is how we build a resource page” guide

Definitions

TermDefinition
CRUDCreate, Read, Update, Delete — the four basic operations on a persistent resource
Resource pageA full-page view showing a list of resources with actions to create, edit, and delete them
Bulk actionAn operation performed on multiple selected resources simultaneously
Optimistic updateUpdating the UI immediately before the server confirms the operation

Current State

  • The src/docs/recipes/00-overview.mdx page lists “CRUD Resource Page” as a planned recipe with status “Planned”.
  • All required components exist: data-grid.tsx, dialog.tsx, alert-dialog.tsx, search-input.tsx, pagination.tsx, empty-state.tsx, no-results-state.tsx, toast.tsx, filter-bar.tsx, sortable-column-header.tsx, list-toolbar.tsx.
  • No recipe MDX file exists yet.
  • No code examples exist for the full CRUD page composition pattern.

Proposed Solution

Create src/docs/recipes/crud-resource-page.mdx with the following structure:

  1. Introduction — What this recipe builds, when to use it, when not to use it.
  2. Component inventory — Table listing every component used with links to its docs.
  3. Data model — TypeScript interface for the sample resource and mock data.
  4. List view — DataGrid configuration, column definitions, sorting, pagination.
  5. Search and filter — SearchInput + FilterBar wired to the data query.
  6. Create/Edit dialog — Dialog with form fields, validation, submit handler, toast.
  7. Delete confirmation — AlertDialog with confirmation text, delete handler, toast.
  8. Bulk actions — Selection state, bulk action toolbar, confirmation flow.
  9. Loading, empty, and error states — Skeleton loading, EmptyState for zero resources, NoResultsState for zero search results, error alert.
  10. Full composition — Complete code block bringing all sections together.

Each section includes a copy-pasteable code block and a brief explanation of the pattern.


Requirements

IDRequirementPriority
REQ-01Recipe is a single MDX file in src/docs/recipes/Must
REQ-02Recipe appears in the Storybook sidebar under “Docs/Best Practices/Recipes”Must
REQ-03All code blocks are copy-pasteable and self-containedMust
REQ-04Recipe uses realistic sample data with a TypeScript interfaceMust
REQ-05Recipe covers all CRUD operations (create, read, update, delete)Must
REQ-06Recipe documents pagination, search, and filter integrationMust
REQ-07Recipe documents bulk action patternMust
REQ-08Recipe shows loading, empty, error, and no-results statesMust
REQ-09Recipe links to each component’s Storybook docs pageShould
REQ-10Recipe references relevant ADRsShould

Functional Requirements

IDDescriptionAcceptance
FR-01MDX file renders in Storybook without errorspnpm build-storybook succeeds
FR-02All code blocks compile when extracted to a standalone TSX fileManual verification
FR-03Recipe overview page lists CRUD recipe as “Available”Status column updated in overview.mdx
FR-04Each section has a “When to use” / “When not to use” calloutVisual verification

Non-Functional Requirements

IDDescriptionTarget
NFR-01Recipe page load time in StorybookUnder 2 seconds
NFR-02Code block line count per sectionUnder 80 lines per block; full composition under 200 lines
NFR-03ReadabilityA developer unfamiliar with the design system can follow the recipe without external documentation

API/Interface Requirements

InterfaceRequirement
MDX fileMust use “ for sidebar placement
Code blocksMust use fenced code blocks with tsx language identifier
Component importsMust use the public package import path

Accessibility Requirements

IDRequirement
A11Y-01Code examples must include proper aria-label props on DataGrid, Dialog, and action buttons
A11Y-02Delete confirmation must show the resource name in the dialog for screen reader context
A11Y-03Bulk action toolbar must announce selection count to screen readers
A11Y-04Empty and error states must use appropriate ARIA roles (status, alert)

Content and Documentation Requirements

IDRequirement
DOC-01Update src/docs/recipes/00-overview.mdx to change CRUD recipe status from “Planned” to “Available”
DOC-02Each recipe section must have a 1-2 sentence explanation before the code block
DOC-03Include a “Component inventory” table linking to each used component’s docs

Dependencies

DependencyTypeRisk
DataGrid componentInternalMust support selection, sorting, and column configuration
Dialog componentInternalMust support form content and controlled open state
Toast componentInternalMust support success and error variants
Pagination componentInternalMust support controlled page state
FilterBar componentInternalMust exist and be functional

Risks and Tradeoffs

RiskImpactMitigation
Code examples may not compile with future component API changesStale recipeInclude recipe code in CI typecheck or add a compile test
Recipe may be too long for a single MDX pagePoor readabilityUse collapsible sections; keep individual blocks under 80 lines
Sample data may not resemble real-world schemasReduced usefulnessUse a realistic “Team Members” resource with common fields (name, email, role, status, created date)

Open Questions

#QuestionStatus
1Should the recipe include TanStack Query hooks or stay framework-agnostic with plain fetch?Open
2Should the full composition block be a live Storybook story or just a static code block?Open
3Should inline editing be a separate recipe or a subsection of this one?Open — leaning separate

Acceptance Criteria

  • src/docs/recipes/crud-resource-page.mdx exists and renders in Storybook.
  • Recipe appears in the sidebar under “Docs/Best Practices/Recipes/CRUD Resource Page”.
  • All code blocks are self-contained with imports and compile when extracted.
  • Recipe covers create, read, update, and delete operations.
  • Recipe shows pagination, search, filter, and bulk action patterns.
  • Recipe shows loading skeleton, empty state, error state, and no-results state.
  • src/docs/recipes/00-overview.mdx lists CRUD recipe as available.
  • pnpm build-storybook succeeds with the new MDX file.

LLM Handoff Instructions

When an LLM agent picks up this FRD:

  1. Read src/docs/recipes/00-overview.mdx for the recipe structure and conventions.
  2. Read the component source files for each component used: data-grid.tsx, dialog.tsx, alert-dialog.tsx, search-input.tsx, pagination.tsx, empty-state.tsx, no-results-state.tsx, toast.tsx, filter-bar.tsx, sortable-column-header.tsx, list-toolbar.tsx.
  3. Read each component’s .stories.tsx file to understand the established usage patterns.
  4. Create src/docs/recipes/crud-resource-page.mdx with the section structure described in the Proposed Solution.
  5. Use a “Team Members” resource as sample data with fields: id, name, email, role (Admin/Member/Viewer), status (Active/Invited/Deactivated), createdAt.
  6. All code blocks must use the public package import path (not relative imports).
  7. After creating the file, run pnpm build-storybook to verify it renders correctly.
  8. Update src/docs/recipes/00-overview.mdx to mark the CRUD recipe as available.

Decision Log

DateDecisionRationale
2026-05-26Use “Team Members” as the sample resourceUniversally relatable B2B pattern; exercises all CRUD operations plus role-based access
2026-05-26Static code blocks rather than live storiesRecipes should teach the pattern, not demo a running implementation; live examples go in examples/

Document History

DateVersionAuthorChanges
2026-05-260.1David HolmesInitial draft