mirror of
https://github.com/johndoe6345789/postgres.git
synced 2026-04-24 13:55:00 +00:00
Add dynamic Storybook stories loading from features.json
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
43
src/components/admin/ConfirmDialog.dynamic.stories.tsx
Normal file
43
src/components/admin/ConfirmDialog.dynamic.stories.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import featuresConfig from '@/config/features.json';
|
||||
import ConfirmDialog from './ConfirmDialog';
|
||||
|
||||
const meta = {
|
||||
title: 'Admin/ConfirmDialog (From JSON)',
|
||||
component: ConfirmDialog,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
docs: {
|
||||
description: {
|
||||
component: 'ConfirmDialog component with stories dynamically loaded from features.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof ConfirmDialog>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
// Dynamically generate stories from features.json
|
||||
const confirmDialogStories = featuresConfig.storybookStories.ConfirmDialog;
|
||||
|
||||
// Default Story
|
||||
export const Default: Story = {
|
||||
name: confirmDialogStories.default.name,
|
||||
args: {
|
||||
...confirmDialogStories.default.args,
|
||||
onConfirm: () => console.log('Confirmed'),
|
||||
onCancel: () => console.log('Cancelled'),
|
||||
},
|
||||
};
|
||||
|
||||
// Delete Warning Story
|
||||
export const DeleteWarning: Story = {
|
||||
name: confirmDialogStories.deleteWarning.name,
|
||||
args: {
|
||||
...confirmDialogStories.deleteWarning.args,
|
||||
onConfirm: () => console.log('Confirmed delete'),
|
||||
onCancel: () => console.log('Cancelled delete'),
|
||||
},
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { fn } from '@storybook/test';
|
||||
import ConfirmDialog from './ConfirmDialog';
|
||||
|
||||
const meta = {
|
||||
@@ -9,10 +8,6 @@ const meta = {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
onConfirm: { action: 'confirm' },
|
||||
onCancel: { action: 'cancel' },
|
||||
},
|
||||
} satisfies Meta<typeof ConfirmDialog>;
|
||||
|
||||
export default meta;
|
||||
@@ -27,8 +22,8 @@ export const Default: Story = {
|
||||
message: 'Are you sure you want to proceed?',
|
||||
confirmLabel: 'Confirm',
|
||||
cancelLabel: 'Cancel',
|
||||
onConfirm: fn(),
|
||||
onCancel: fn(),
|
||||
onConfirm: () => console.log('Confirmed'),
|
||||
onCancel: () => console.log('Cancelled'),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -40,7 +35,7 @@ export const DeleteWarning: Story = {
|
||||
message: 'This action cannot be undone. Are you sure you want to delete this item?',
|
||||
confirmLabel: 'Delete',
|
||||
cancelLabel: 'Cancel',
|
||||
onConfirm: fn(),
|
||||
onCancel: fn(),
|
||||
onConfirm: () => console.log('Confirmed delete'),
|
||||
onCancel: () => console.log('Cancelled delete'),
|
||||
},
|
||||
};
|
||||
|
||||
45
src/components/admin/DataGrid.dynamic.stories.tsx
Normal file
45
src/components/admin/DataGrid.dynamic.stories.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import featuresConfig from '@/config/features.json';
|
||||
import DataGrid from './DataGrid';
|
||||
|
||||
const meta = {
|
||||
title: 'Admin/DataGrid (From JSON)',
|
||||
component: DataGrid,
|
||||
parameters: {
|
||||
layout: 'padded',
|
||||
docs: {
|
||||
description: {
|
||||
component: 'DataGrid component with stories dynamically loaded from features.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof DataGrid>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
// Dynamically generate stories from features.json
|
||||
const dataGridStories = featuresConfig.storybookStories.DataGrid;
|
||||
|
||||
// Default Story
|
||||
export const Default: Story = {
|
||||
name: dataGridStories.default.name,
|
||||
args: dataGridStories.default.args,
|
||||
};
|
||||
|
||||
// With Actions Story
|
||||
export const WithActions: Story = {
|
||||
name: dataGridStories.withActions.name,
|
||||
args: {
|
||||
...dataGridStories.withActions.args,
|
||||
onEdit: () => console.log('Edit clicked'),
|
||||
onDelete: () => console.log('Delete clicked'),
|
||||
},
|
||||
};
|
||||
|
||||
// Empty State
|
||||
export const Empty: Story = {
|
||||
name: dataGridStories.empty.name,
|
||||
args: dataGridStories.empty.args,
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { fn } from '@storybook/test';
|
||||
import DataGrid from './DataGrid';
|
||||
|
||||
const meta = {
|
||||
@@ -9,10 +8,6 @@ const meta = {
|
||||
layout: 'padded',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
onEdit: { action: 'edit' },
|
||||
onDelete: { action: 'delete' },
|
||||
},
|
||||
} satisfies Meta<typeof DataGrid>;
|
||||
|
||||
export default meta;
|
||||
@@ -48,8 +43,8 @@ export const WithActions: Story = {
|
||||
{ id: 1, name: 'Active User', status: 'active' },
|
||||
{ id: 2, name: 'Pending User', status: 'pending' },
|
||||
],
|
||||
onEdit: fn(),
|
||||
onDelete: fn(),
|
||||
onEdit: () => console.log('Edit clicked'),
|
||||
onDelete: () => console.log('Delete clicked'),
|
||||
primaryKey: 'id',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import {
|
||||
IconButton as MuiIconButton,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
|
||||
47
src/components/atoms/Button.dynamic.stories.tsx
Normal file
47
src/components/atoms/Button.dynamic.stories.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import featuresConfig from '@/config/features.json';
|
||||
import Button, { type ButtonProps } from './Button';
|
||||
|
||||
const meta = {
|
||||
title: 'Atoms/Button (From JSON)',
|
||||
component: Button,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
docs: {
|
||||
description: {
|
||||
component: 'Button component with stories dynamically loaded from features.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof Button>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
// Dynamically generate stories from features.json
|
||||
const buttonStories = featuresConfig.storybookStories.Button;
|
||||
|
||||
// Primary Button
|
||||
export const Primary: Story = {
|
||||
name: buttonStories.primary.name,
|
||||
args: buttonStories.primary.args as Partial<ButtonProps>,
|
||||
};
|
||||
|
||||
// Secondary Button
|
||||
export const Secondary: Story = {
|
||||
name: buttonStories.secondary.name,
|
||||
args: buttonStories.secondary.args as Partial<ButtonProps>,
|
||||
};
|
||||
|
||||
// Button with Icon
|
||||
export const WithIcon: Story = {
|
||||
name: buttonStories.withIcon.name,
|
||||
args: buttonStories.withIcon.args as Partial<ButtonProps>,
|
||||
};
|
||||
|
||||
// Loading State
|
||||
export const Loading: Story = {
|
||||
name: buttonStories.loading.name,
|
||||
args: buttonStories.loading.args as Partial<ButtonProps>,
|
||||
};
|
||||
83
src/components/atoms/DynamicStories.tsx
Normal file
83
src/components/atoms/DynamicStories.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import featuresConfig from '@/config/features.json';
|
||||
import Button from './Button';
|
||||
import TextField from './TextField';
|
||||
import Typography from './Typography';
|
||||
import IconButton from './IconButton';
|
||||
import Icon from './Icon';
|
||||
|
||||
// Component mapping
|
||||
const componentMap = {
|
||||
Button,
|
||||
TextField,
|
||||
Typography,
|
||||
IconButton,
|
||||
Icon,
|
||||
};
|
||||
|
||||
// Dynamically generate stories from features.json
|
||||
export function generateStoriesFromConfig() {
|
||||
const stories: Record<string, any> = {};
|
||||
const storybookStories = featuresConfig.storybookStories;
|
||||
|
||||
Object.entries(storybookStories).forEach(([componentName, componentStories]) => {
|
||||
if (componentMap[componentName as keyof typeof componentMap]) {
|
||||
const Component = componentMap[componentName as keyof typeof componentMap];
|
||||
|
||||
const meta: Meta<typeof Component> = {
|
||||
title: `Atoms/${componentName}`,
|
||||
component: Component,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
};
|
||||
|
||||
stories[componentName] = {
|
||||
meta,
|
||||
stories: Object.entries(componentStories).map(([storyName, storyConfig]: [string, any]) => ({
|
||||
name: storyConfig.name || storyName,
|
||||
args: storyConfig.args,
|
||||
})),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return stories;
|
||||
}
|
||||
|
||||
// Generate stories for Button component from features.json
|
||||
const buttonStories = featuresConfig.storybookStories.Button;
|
||||
|
||||
const meta = {
|
||||
title: 'Atoms/Button (Dynamic)',
|
||||
component: Button,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
} satisfies Meta<typeof Button>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
// Generate stories dynamically from features.json
|
||||
export const Primary: Story = {
|
||||
name: buttonStories.primary.name,
|
||||
args: buttonStories.primary.args,
|
||||
};
|
||||
|
||||
export const Secondary: Story = {
|
||||
name: buttonStories.secondary.name,
|
||||
args: buttonStories.secondary.args,
|
||||
};
|
||||
|
||||
export const WithIcon: Story = {
|
||||
name: buttonStories.withIcon.name,
|
||||
args: buttonStories.withIcon.args,
|
||||
};
|
||||
|
||||
export const Loading: Story = {
|
||||
name: buttonStories.loading.name,
|
||||
args: buttonStories.loading.args,
|
||||
};
|
||||
Reference in New Issue
Block a user