Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Reintroduce the backgrounds addon #229

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 6 additions & 33 deletions addons/ondevice-backgrounds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

Storybook Backgrounds Addon for react-native can be used to change background colors of your stories right from the device.

<img src="https://raw.githubusercontent.com/storybookjs/storybook/master/addons/ondevice-backgrounds/docs/demo.gif" alt="Storybook Backgrounds Addon Demo" width="400" />

## Installation

```sh
Expand All @@ -12,41 +10,16 @@ yarn add -D @storybook/addon-ondevice-backgrounds

## Configuration

Create a file called `rn-addons.js` in your storybook config.

Add following content to it:

```js
import '@storybook/addon-ondevice-backgrounds/register';
```

Then import `rn-addons.js` next to your `getStorybookUI` call.
Then, add following content to `.storybook/main.js`:

```js
import './rn-addons';
module.exports = {
dannyhw marked this conversation as resolved.
Show resolved Hide resolved
addons: ['@storybook/addon-ondevice-backgrounds'],
};
```

## Usage

react-native users will have to import `storiesOf` from `@storybook/react-native` and are required to add the `withBackgrounds` decorator.

Then write your stories like this:

```js
import React from 'react';
import { storiesOf } from '@storybook/react-native';
import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';

addDecorator(withBackgrounds);

storiesOf('Button', module)
.addParameters({
backgrounds: [
{ name: 'dark', value: '#222222' },
{ name: 'light', value: '#eeeeee', default: true },
],
})
.add('with text', () => <Text>Click me</Text>);
```
See the [example of using the Backgrounds addon with Component Story Format](../../examples/native/components/BackgroundExample/BackgroundCsf.stories.tsx). You can also run the [react-native app](../../examples/native) to see it in action.

See [web backgrounds addon](../backgrounds#usage) for detailed usage and the [crna-kitchen-sink app](../../examples/crna-kitchen-sink) for more examples.
The [web backgrounds addon documentation](https://storybook.js.org/docs/react/essentials/backgrounds) may also be useful, but the examples there have not been tested with React-Native Storybook.
62 changes: 34 additions & 28 deletions addons/ondevice-backgrounds/src/BackgroundPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import Events from '@storybook/core-events';
import { AddonStore } from '@storybook/addons';
import { API } from '@storybook/api';
import { StoryStore } from '@storybook/client-api';
Expand All @@ -10,33 +9,51 @@ import BackgroundEvents, { PARAM_KEY } from './constants';
import { Background } from './index';

const codeSample = `
import { storiesOf } from '@storybook/react-native';
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react-native';
import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';
import { Text, StyleSheet } from 'react-native';

addDecorator(withBackgrounds);
const Background = () => (
<Text style={styles.text}>Change background color via Addons -&gt; Background</Text>
);

const styles = StyleSheet.create({
text: { color: 'black' },
});

storiesOf('First Component', module)
.addParameters({
const BackgroundMeta: ComponentMeta<typeof Background> = {
title: 'Background CSF',
component: Background,
decorators: [withBackgrounds],
parameters: {
backgrounds: [
{ name: 'warm', value: 'hotpink', default: true },
{ name: 'cool', value: 'deepskyblue' },
],
})
.add("First Button", () => <Button>Click me</Button>);
},
};

export default BackgroundMeta;

type BackgroundStory = ComponentStory<typeof Background>;

export const Basic: BackgroundStory = () => <Background />;
`.trim();

const Instructions = () => (
<View>
<Text style={styles.title}>Setup Instructions</Text>
<Text>
<Text style={[styles.paragraph, styles.title]}>Setup Instructions</Text>
<Text style={styles.paragraph}>
Please add the background decorator definition to your story. The background decorate accepts
an array of items, which should include a name for your color (preferably the css class name)
and the corresponding color / image value.
</Text>
<Text>
Below is an example of how to add the background decorator to your story definition.
<Text style={styles.paragraph}>
Below is an example of how to add the background decorator to your story definition. Long
press the example to copy it.
</Text>
<Text>{codeSample}</Text>
<Text selectable>{codeSample}</Text>
</View>
);

Expand All @@ -53,32 +70,20 @@ interface BackgroundPanelState {
}

export default class BackgroundPanel extends Component<BackgroundPanelProps, BackgroundPanelState> {
componentDidMount() {
this.props.channel.on(Events.SELECT_STORY, this.onStorySelected);
}

componentWillUnmount() {
this.props.channel.removeListener(Events.SELECT_STORY, this.onStorySelected);
}

setBackgroundFromSwatch = (background: string) => {
this.props.channel.emit(BackgroundEvents.UPDATE_BACKGROUND, background);
};

onStorySelected = (selection: Selection) => {
this.setState({ selection });
};

render() {
const { active, api } = this.props;

if (!active || !this.state) {
if (!active) {
return null;
}

const story = api
.store()
.getStoryAndParameters(this.state.selection.kind, this.state.selection.name);
const store = api.store();
const storyId = store.getSelection().storyId;
const story = store.fromId(storyId);
const backgrounds: Background[] = story.parameters[PARAM_KEY];

return (
Expand All @@ -99,4 +104,5 @@ export default class BackgroundPanel extends Component<BackgroundPanelProps, Bac

const styles = StyleSheet.create({
title: { fontSize: 16 },
paragraph: { marginBottom: 8 },
});
6 changes: 5 additions & 1 deletion examples/native/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@ module.exports = {
'./components/**/*.stories.?(ts|tsx|js|jsx)',
'./other_components/AnotherButton/AnotherButton.stories.tsx',
],
addons: ['@storybook/addon-ondevice-notes', '@storybook/addon-ondevice-controls'],
addons: [
'@storybook/addon-ondevice-notes',
'@storybook/addon-ondevice-controls',
'@storybook/addon-ondevice-backgrounds',
dannyhw marked this conversation as resolved.
Show resolved Hide resolved
],
};
14 changes: 11 additions & 3 deletions examples/native/.storybook/preview.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import React from 'react';
import { View, StyleSheet } from 'react-native';
// import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';
import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';

export const decorators = [
(StoryFn) => (
<View style={styles.container}>
<StoryFn />
</View>
),
withBackgrounds,
];
export const parameters = { my_param: 'anything' };
export const parameters = {
my_param: 'anything',
backgrounds: [
{ name: 'plain', value: 'white', default: true },
{ name: 'warm', value: 'hotpink' },
{ name: 'cool', value: 'deepskyblue' },
],
};

const styles = StyleSheet.create({
container: { padding: 8 },
container: { padding: 8, flex: 1 },
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { addDecorator, storiesOf } from '@storybook/react-native';
import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';
import { Text } from 'react-native';

// Remember to also include '@storybook/addon-ondevice-backgrounds' in your addons config: see /examples/native/.storybook/main.js
addDecorator(withBackgrounds);

storiesOf('Background StoriesOf', module)
.addParameters({
backgrounds: [
{ name: 'warm', value: 'hotpink', default: true },
{ name: 'cool', value: 'deepskyblue' },
],
})
.add('Basic', () => <Text>Change background color via Addons -&gt; Background</Text>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react-native';
import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';
import { Text, StyleSheet } from 'react-native';

const Background = () => (
<Text style={styles.text}>Change background color via Addons -&gt; Background</Text>
);

const styles = StyleSheet.create({
text: { color: 'black' },
});

const BackgroundMeta: ComponentMeta<typeof Background> = {
title: 'Background CSF',
component: Background,
decorators: [withBackgrounds],
parameters: {
backgrounds: [
{ name: 'warm', value: 'hotpink', default: true },
{ name: 'cool', value: 'deepskyblue' },
],
},
};

export default BackgroundMeta;

type BackgroundStory = ComponentStory<typeof Background>;

export const Basic: BackgroundStory = () => <Background />;
1 change: 1 addition & 0 deletions examples/native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@react-native-community/slider": "^3.0.3",
"@storybook/addon-actions": "^6.3.1",
"@storybook/addon-links": "^6.3.1",
"@storybook/addon-ondevice-backgrounds": "^6.0.0-alpha.0",
"@storybook/addon-ondevice-controls": "^6.0.0-alpha.0",
"@storybook/addons": "^6.3.1",
"@storybook/react-native": "^6.0.0-alpha.0",
Expand Down