import type { Meta, StoryObj } from '@storybook/react'
import { Users, Package, FileText, Settings, Key } from 'lucide-react'
import { Resource } from '../components/resource'
import { ResourcesProvider, useResources, useResource } from '../context/resource-context'
// =============================================================================
// Mock View Components
// =============================================================================
const UsersList = () => (
Users List View
Displays all users in a table
)
const UserShow = ({ id }: { id: string | number }) => (
User Detail View
Showing user: {id}
)
const UserCreate = () => (
Create User Form
Form to create a new user
)
const UserEdit = ({ id }: { id: string | number }) => (
Edit User Form
Editing user: {id}
)
const ProductsList = () => (
Products List View
Displays all products in a grid
)
// =============================================================================
// Helper Components for Stories
// =============================================================================
/**
* Display registered resources for debugging
*/
const ResourcesDebugger = () => {
const { resources } = useResources()
return (
Registered Resources ({resources.length})
{resources.length === 0 ? (
No resources registered yet
) : (
{resources.map((r) => (
-
{r.icon && }
{r.labelPlural ?? r.label ?? r.name}
({r.name})
[{r.list ? 'list' : ''}{r.show ? ' show' : ''}{r.create ? ' create' : ''}{r.edit ? ' edit' : ''}]
))}
)}
)
}
/**
* Display current resource context
*/
const ResourceContextDisplay = () => {
const context = useResource()
return (
Resource Context
- Resource:
- {context.resource}
- Has List:
- {context.hasList ? 'Yes' : 'No'}
- Has Create:
- {context.hasCreate ? 'Yes' : 'No'}
- Has Edit:
- {context.hasEdit ? 'Yes' : 'No'}
- Has Show:
- {context.hasShow ? 'Yes' : 'No'}
{context.id && (
<>
- Current ID:
- {context.id}
>
)}
)
}
// =============================================================================
// Story Meta
// =============================================================================
const meta: Meta = {
title: 'App/Resource',
component: Resource,
tags: ['autodocs'],
parameters: {
layout: 'padded',
},
decorators: [
(Story) => (
),
],
}
export default meta
type Story = StoryObj
// =============================================================================
// Stories
// =============================================================================
/**
* Basic resource registration with all CRUD operations.
*/
export const Default: Story = {
args: {
name: 'users',
label: 'User',
labelPlural: 'Users',
icon: Users,
list: UsersList,
show: UserShow,
create: UserCreate,
edit: UserEdit,
},
render: (args) => (
Resource Registration
The Resource component registers itself with ResourcesProvider on mount.
),
}
/**
* Resource with only list view - common for read-only resources.
*/
export const ListOnly: Story = {
args: {
name: 'products',
label: 'Product',
labelPlural: 'Products',
icon: Package,
list: ProductsList,
},
render: (args) => (
List-Only Resource
Some resources only need a list view (e.g., logs, analytics).
),
}
/**
* Multiple resources registered together.
*/
export const MultipleResources: Story = {
render: () => (
Multiple Resources
Multiple Resource components can be registered in the same provider.
Documents List
}
create={() => Create Document
}
/>
),
}
/**
* Resource with children - wraps content in ResourceProvider context.
*/
export const WithChildren: Story = {
render: () => (
Resource with Children
When children are provided, they receive resource context.
API Keys List
}
create={() => Create API Key
}
>
Child Content
),
}
/**
* Resource with custom options.
*/
export const WithOptions: Story = {
args: {
name: 'settings',
label: 'Setting',
labelPlural: 'Settings',
icon: Settings,
list: () => Settings List
,
options: {
allowBulkDelete: false,
defaultSort: { field: 'name', order: 'ASC' },
permissions: ['admin', 'editor'],
},
},
render: (args) => (
Resource with Custom Options
Resources can include custom options for app-specific configuration.
Custom Options
{JSON.stringify(args.options, null, 2)}
),
}