Improve Redux Storybook (#37227)

pull/35996/head
Echo 4 weeks ago committed by GitHub
parent 7230c2059f
commit 8c2845906c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -55,12 +55,31 @@ const preview: Preview = {
locale: 'en',
},
decorators: [
(Story, { parameters, globals, args }) => {
(Story, { parameters, globals, args, argTypes }) => {
// Get the locale from the global toolbar
// and merge it with any parameters or args state.
const { locale } = globals as { locale: string };
const { state = {} } = parameters;
const { state: argsState = {} } = args;
const argsState: Record<string, unknown> = {};
for (const [key, value] of Object.entries(args)) {
const argType = argTypes[key];
if (argType?.reduxPath) {
const reduxPath = Array.isArray(argType.reduxPath)
? argType.reduxPath.map((p) => p.toString())
: argType.reduxPath.split('.');
reduxPath.reduce((acc, key, i) => {
if (acc[key] === undefined) {
acc[key] = {};
}
if (i === reduxPath.length - 1) {
acc[key] = value;
}
return acc[key] as Record<string, unknown>;
}, argsState);
}
}
const reducer = reducerWithInitialState(
{
@ -69,7 +88,7 @@ const preview: Preview = {
},
},
state as Record<string, unknown>,
argsState as Record<string, unknown>,
argsState,
);
const store = configureStore({

@ -1,7 +1,20 @@
// The addon package.json incorrectly exports types, so we need to override them here.
import type { RootState } from '@/mastodon/store';
// See: https://github.com/storybookjs/storybook/blob/v9.0.4/code/addons/vitest/package.json#L70-L76
declare module '@storybook/addon-vitest/vitest-plugin' {
export * from '@storybook/addon-vitest/dist/vitest-plugin/index';
}
type RootPathKeys = keyof RootState;
declare module 'storybook/internal/csf' {
export interface InputType {
reduxPath?:
| `${RootPathKeys}.${string}`
| [RootPathKeys, ...(string | number)[]];
}
}
export {};

@ -1,16 +1,28 @@
import type { ComponentProps } from 'react';
import type { Meta, StoryObj } from '@storybook/react-vite';
import { accountFactoryState, relationshipsFactory } from '@/testing/factories';
import { Account } from './index';
type Props = Omit<ComponentProps<typeof Account>, 'id'> & {
name: string;
username: string;
};
const meta = {
title: 'Components/Account',
component: Account,
argTypes: {
id: {
name: {
type: 'string',
description: 'The display name of the account',
reduxPath: 'accounts.1.display_name_html',
},
username: {
type: 'string',
description: 'ID of the account to display',
description: 'The username of the account',
reduxPath: 'accounts.1.acct',
},
size: {
type: 'number',
@ -40,7 +52,8 @@ const meta = {
},
},
args: {
id: '1',
name: 'Test User',
username: 'testuser',
size: 46,
hidden: false,
minimal: false,
@ -55,17 +68,16 @@ const meta = {
},
},
},
} satisfies Meta<typeof Account>;
render(args) {
return <Account id='1' {...args} />;
},
} satisfies Meta<Props>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
args: {
id: '1',
},
};
export const Primary: Story = {};
export const Hidden: Story = {
args: {

@ -4,20 +4,22 @@ import type { Meta, StoryObj } from '@storybook/react-vite';
import { Emoji } from './index';
type EmojiProps = ComponentProps<typeof Emoji> & { state: string };
type EmojiProps = ComponentProps<typeof Emoji> & {
style: 'auto' | 'native' | 'twemoji';
};
const meta = {
title: 'Components/Emoji',
component: Emoji,
args: {
code: '🖤',
state: 'auto',
style: 'auto',
},
argTypes: {
code: {
name: 'Emoji',
},
state: {
style: {
control: {
type: 'select',
labels: {
@ -28,11 +30,7 @@ const meta = {
},
options: ['auto', 'native', 'twemoji'],
name: 'Emoji Style',
mapping: {
auto: { meta: { emoji_style: 'auto' } },
native: { meta: { emoji_style: 'native' } },
twemoji: { meta: { emoji_style: 'twemoji' } },
},
reduxPath: 'meta.emoji_style',
},
},
render(args) {

Loading…
Cancel
Save