Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/iamchanii/storybook-addon-relay
A Storybook add-on to write stories for Relay components.
https://github.com/iamchanii/storybook-addon-relay
react-relay relay relay-morden storybook storybook-addon storybook-addons
Last synced: 3 months ago
JSON representation
A Storybook add-on to write stories for Relay components.
- Host: GitHub
- URL: https://github.com/iamchanii/storybook-addon-relay
- Owner: iamchanii
- Created: 2023-03-02T03:56:54.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-07-21T08:20:19.000Z (6 months ago)
- Last Synced: 2024-10-13T19:47:26.373Z (3 months ago)
- Topics: react-relay, relay, relay-morden, storybook, storybook-addon, storybook-addons
- Language: JavaScript
- Homepage:
- Size: 95.7 MB
- Stars: 9
- Watchers: 1
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# storybook-addon-relay
[![npm version](https://badge.fury.io/js/@imchhh%2Fstorybook-addon-relay.svg)](https://badge.fury.io/js/@imchhh%2Fstorybook-addon-relay)
A Storybook add-on to write stories for Relay components.
[github_demo.webm](https://user-images.githubusercontent.com/26643843/222612688-ca0cc4b5-9173-4215-a5cb-b8a46f20219e.webm)
## Installation
Install the `@imchhh/storybook-addon-relay` package using the package manager of your choice:
```
yarn add -D @imchhh/storybook-addon-relay
```Add `@imchhh/storybook-addon-relay` to the `addons` list in your `.storybook/main.c?(j|t)s` file:
```ts
const config: StorybookConfig = {
addons: [
// ...
'@imchhh/storybook-addon-relay',
],
};
```## Usage
Add a `relay` field to your story's `parameters`.
```ts
export const Default = {
parameters: {
relay: {
query: graphql`...`,
getReferenceEntry: (data) => ['data', data.node],
variables: {},
mockResolvers: {},
},
},
};
```- `query`: A `GraphQLTaggedNode` returned by the Relay's `graphql` template literal. You should pass the query operation that uses the `@relay_test_operation` directive.
- `getReferenceEntry`: A function that returns an entry to be added to the story's args. It takes the result of the `useLazyLoadQuery` hook with the query passed as a parameter and returns an entry to be added to the story's args.
- `variables`: Optional. Variables to pass to the query.
- `mockResolvers`: Optional. A mock resolver object passed to the `relay-test-utils`' `MockPayloadGenerator.generate` function.
- `generateFunction`: Optional. A function to execute instead of the default `MockPayloadGenerator.generate` function.Here is a minimal example:
```tsx
// UserAvatar.tsx
export const UserAvatar = (props) => {
const data = useFragment(
graphql`
fragment UserAvatar on User {
profileImageUrl
}
`,
props.user,
);return ;
};// UserAvatar.stories.tsx
import { StoryObj } from '@storybook/react';
import { graphql } from 'react-relay';
import { UserAvatar } from './UserAvatar';export default {
component: UserAvatar,
};export const Default: StoryObj = {
parameters: {
relay: {
query: graphql`
query UserAvatarStoryQuery @relay_test_operation {
node(id: "test-id") {
... on User {
...UserAvatar
}
}
}
`,
getReferenceEntry: queryResult => ['user', queryResult.node],
mockResolvers: {
User: () => ({
profileImageUrl: 'https://source.unsplash.com/random/400x400',
}),
},
},
},
};
```### TypeScript (Optional)
If you are using TypeScript 4.9 or later, you can use the `WithRelayParameters` interface and the `satisfies` keyword to get type-safe:
```ts
// UserAvatar.stories.tsx
import { WithRelayParameters } from '@imchhh/storybook-addon-relay';
import { StoryObj } from '@storybook/react';
import { graphql } from 'react-relay';
import { UserAvatarStoryQuery } from '~/path/of/relay/artifacts';
import { UserAvatar } from './UserAvatar';export default {
component: UserAvatar,
};export const Default: StoryObj = {
parameters: {
relay: {
query: graphql`
query UserAvatarStoryQuery @relay_test_operation {
node(id: "test-id") {
... on User {
...UserAvatar
}
}
}
`,
// Now `queryResult` is typed!
getReferenceEntry: queryResult => ['user', queryResult.node],
mockResolvers: {
User: () => ({
profileImageUrl: 'https://source.unsplash.com/random/400x400',
}),
},
} satisfies WithRelayParameters,
},
};
```And you can pass the `Resolvers` type, which generated via [GraphQL Code Generator](https://the-guild.dev/graphql/codegen), as the second type parameter to `WithRelayParameters`.
```ts
// UserAvatar.stories.tsx
import { WithRelayParameters } from '@imchhh/storybook-addon-relay';
import { StoryObj } from '@storybook/react';
import { graphql } from 'react-relay';
import { Resolvers } from '~/path/of/codegen/generated';
import { UserAvatarStoryQuery } from '~/path/of/relay/artifacts';
import { UserAvatar } from './UserAvatar';export default {
component: UserAvatar,
};export const Default: StoryObj = {
parameters: {
relay: {
query: graphql`
query UserAvatarStoryQuery @relay_test_operation {
node(id: "test-id") {
... on User {
...UserAvatar
}
}
}
`,
getReferenceEntry: queryResult => ['user', queryResult.node],
// Now `mockResolvers` is typed!
mockResolvers: {
User: () => ({
profileImageUrl: 'https://source.unsplash.com/random/400x400',
}),
},
} satisfies WithRelayParameters,
},
};
```These are totally optional, so feel free to skip them
## Contribute
I don't have any plans to write or set up a contribution guide. If this library doesn't solve your problem or isn't sufficient, please create an issue and describe your situation or suggestion. I would appreciate it very much.
## License
MIT