Skip to content

Commit

Permalink
Merge branch 'next' into 5818-cleanup-backgrounds
Browse files Browse the repository at this point in the history
  • Loading branch information
shilman committed Mar 4, 2019
2 parents 81b9656 + 112b9f4 commit 1ccc201
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 342 deletions.
46 changes: 35 additions & 11 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,36 @@ storiesOf('Stories', module)
.addDecorator(withBackgrounds(options));
```

You can replace it with:
You should replace it with:

```js
storiesOf('Stories', module).addParameters({ backgrounds: options });
```

You can pass `backgrounds` parameters at the global level (via `addParameters` imported from `@storybook/react` et al.), and the story level (via the third argument to `.add()`).

## Addon viewport uses parameters

Similarly, `@storybook/addon-viewport` uses parameters to pass viewport options. If you previously had:

```js
import { configureViewport } from `@storybook/addon-viewport`;

configureViewport(options);
```

You should replace it with:

```js
import { addParameters } from '@storybook/react'; // or others

addParameters({ viewport: options });
```

The `withViewport` decorator is also no longer supported and should be replaced with a parameter based API as above. Also the `onViewportChange` callback is no longer supported.

See the [README](https://github.com/storybooks/storybook/blob/master/addons/viewport/README.md) for the viewport addon for more information.

## From version 4.0.x to 4.1.x

There are are a few migrations you should be aware of in 4.1, including one unintentionally breaking change for advanced addon usage.
Expand Down Expand Up @@ -211,17 +233,19 @@ However, if you're developing React components, this means you need to upgrade t
Also, here's the error you'll get if you're running an older version of React:

```
core.browser.esm.js:15 Uncaught TypeError: Object(...) is not a function
at Module../node_modules/@emotion/core/dist/core.browser.esm.js (core.browser.esm.js:15)
at **webpack_require** (bootstrap:724)
at fn (bootstrap:101)
at Module../node_modules/@emotion/styled-base/dist/styled-base.browser.esm.js (styled-base.browser.esm.js:1)
at **webpack_require** (bootstrap:724)
at fn (bootstrap:101)
at Module../node_modules/@emotion/styled/dist/styled.esm.js (styled.esm.js:1)
at **webpack_require** (bootstrap:724)
at fn (bootstrap:101)
at Object../node_modules/@storybook/components/dist/navigation/MenuLink.js (MenuLink.js:12)
at Module../node_modules/@emotion/core/dist/core.browser.esm.js (core.browser.esm.js:15)
at **webpack_require** (bootstrap:724)
at fn (bootstrap:101)
at Module../node_modules/@emotion/styled-base/dist/styled-base.browser.esm.js (styled-base.browser.esm.js:1)
at **webpack_require** (bootstrap:724)
at fn (bootstrap:101)
at Module../node_modules/@emotion/styled/dist/styled.esm.js (styled.esm.js:1)
at **webpack_require** (bootstrap:724)
at fn (bootstrap:101)
at Object../node_modules/@storybook/components/dist/navigation/MenuLink.js (MenuLink.js:12)
```

### Generic addons
Expand Down
152 changes: 44 additions & 108 deletions addons/viewport/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Storybook Viewport Addon

Storybook Viewport Addon allows your stories to be displayed in different sizes and layouts in [Storybook](https://storybook.js.org). This helps build responsive components inside of Storybook.
Storybook Viewport Addon allows your stories to be displayed in different sizes and layouts in [Storybook](https://storybook.js.org). This helps build responsive components inside of Storybook.

[Framework Support](https://github.com/storybooks/storybook/blob/master/ADDONS_SUPPORT.md)

Expand Down Expand Up @@ -28,21 +28,30 @@ import '@storybook/addon-viewport/register';

## Configuration

Import and use the `configureViewport` function in your `config.js` file.
The viewport addon is configured by story parameters with the `viewport` key. To configure globally, import `addParameters` from your app layer in your `config.js` file.

```js
import { configureViewport } from '@storybook/addon-viewport';
import { addParameters } from '@storybook/react';

addParameters({ viewport: options });
```

Options can take a object with the following keys:

### defaultViewport : String
----

---

Setting this property to, let say `iphone6`, will make `iPhone 6` the default device/viewport for all stories. Default is `'responsive'` which fills 100% of the preview area.

### viewports : Object
----

---

A key-value pair of viewport's key and properties (see `Viewport` definition below) for all viewports to be displayed. Default is [`INITIAL_VIEWPORTS`](src/shared/index.js)

#### Viewport Model

```js
{
/**
Expand Down Expand Up @@ -70,154 +79,81 @@ A key-value pair of viewport's key and properties (see `Viewport` definition bel
}
```

## Decorators
## Configuring per component or story

Sometimes you want to show collection of mobile stories, and you know those stories look horible on desktop (`responsive`), so you think you need to change the default viewport only for those?
Parameters can be configured for a whole set of stories or a single story via the standard parameter API:

Here is the answer, with `withViewport` decorator, you can change the default viewport of single, multiple, or all stories.

`withViewport` accepts either
* A `String`, which represents the default viewport, or
* An `Object`, which looks like
```js
{
name: 'iphone6', // default viewport
onViewportChange({ viewport }) { // called whenever different viewport is selected from the dropdown
import addStories from '@storybook/react';

}
}
addStories('Stories', module)
// To set a default viewport for all the stories for this component
.addParameters({ viewport: { defaultViewport: 'iphone6' }})
.add('story', () => </>, { viewport: 'iphonex' });
```

## Examples

### Basic Usage

Simply import the Storybook Viewport Addon in the `addons.js` file in your `.storybook` directory.

```js
import '@storybook/addon-viewport/register'
```

This will register the Viewport Addon to Storybook and will show up in the action area.


### Use Custom Set of Devices

This will replace all previous devices with `Kindle Fire 2` and `Kindle Fire HD` by simply calling `configureViewport` with the two devices as `viewports` in `config.js` file in your `.storybook` directory.
This will replace all previous devices with `Kindle Fire 2` and `Kindle Fire HD` by simply calling `addParameters` with the two devices as `viewports` in `config.js` file in your `.storybook` directory.

```js
import { configureViewport } from '@storybook/addon-viewport';
import { addParameters } from '@storybook/react';

const newViewports = {
kindleFire2: {
name: 'Kindle Fire 2',
styles: {
width: '600px',
height: '963px'
}
height: '963px',
},
},
kindleFireHD: {
name: 'Kindle Fire HD',
styles: {
width: '533px',
height: '801px'
}
}
height: '801px',
},
},
};

configureViewport({
viewports: newViewports
addParameters({
viewport: { viewports: newViewports },
});
```


### Add New Device

This will add both `Kindle Fire 2` and `Kindle Fire HD` to the list of devices. This is acheived by making use of the exported [`INITIAL_VIEWPORTS`](src/shared/index.js) property, by merging it with the new viewports and pass the result as `viewports` to `configureViewport` function

```js
import { configureViewport, INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
import { addParameters } from '@storybook/react';
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';

const newViewports = {
kindleFire2: {
name: 'Kindle Fire 2',
styles: {
width: '600px',
height: '963px'
}
height: '963px',
},
},
kindleFireHD: {
name: 'Kindle Fire HD',
styles: {
width: '533px',
height: '801px'
}
}
height: '801px',
},
},
};

configureViewport({
viewports: {
...INITIAL_VIEWPORTS,
...newViewports
}
});
```


### Change The Default Viewport

This will make `iPhone 6` the default viewport for all stories.

```js
import { configureViewport } from '@storybook/addon-viewport';

configureViewport({
defaultViewport: 'iphone6'
addParameters({
viewport: {
viewports: {
...INITIAL_VIEWPORTS,
...newViewports,
},
},
});
```

## withViewport Decorator

Change the default viewport for single/multiple/global stories, or listen to viewport selection changes

```js
import React from 'react';
import { storiesOf, addDecorator } from '@storybook/react';
import { withViewport } from '@storybook/addon-viewport';

// Globablly
addDecorator(withViewport('iphone5'));

// Collection
storiesOf('Decorator with string', module)
.addDecorator(withViewport('iphone6'))
.add('iPhone 6', () => (
<h1>
Do I look good on <b>iPhone 6</b>?
</h1>
));

// Single
storiesOf('Parameterized story', module)
.addDecorator(withViewport())
.add(
'iPad',
() => (
<h1>
Do I look good on <b>iPad</b>?
</h1>
),
{ viewport: 'ipad' }
);

storiesOf('Decorator with object', module)
.addDecorator(
withViewport({
onViewportChange({ viewport }) {
console.log(`Viewport changed: ${viewport.name} (${viewport.type})`); // e.g. Viewport changed: iphone6 (mobile)
},
})
)
.add('onViewportChange', () => <MobileFirstComponent />);

```
1 change: 0 additions & 1 deletion addons/viewport/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ exports.configureViewport = preview.configureViewport;
exports.DEFAULT_VIEWPORT = preview.DEFAULT_VIEWPORT;
exports.INITIAL_VIEWPORTS = preview.INITIAL_VIEWPORTS;
exports.withViewport = preview.withViewport;
exports.Viewport = preview.Viewport;
27 changes: 25 additions & 2 deletions addons/viewport/src/Tool.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import memoize from 'memoizerific';
import deprecate from 'util-deprecate';

import { Global } from '@storybook/theming';

import { Icons, IconButton, WithTooltip, TooltipLinkList } from '@storybook/components';
import { SET_STORIES } from '@storybook/core-events';

import { PARAM_KEY } from './constants';
import { INITIAL_VIEWPORTS, DEFAULT_VIEWPORT } from './defaults';

const toList = memoize(50)(items =>
items ? Object.entries(items).map(([id, value]) => ({ ...value, id })) : []
Expand All @@ -26,14 +28,35 @@ const createItem = memoize(1000)((id, name, value, change) => ({

const flip = ({ width, height }) => ({ height: width, width: height });

const deprecatedViewportString = deprecate(
() => 0,
'The viewport parameter must be an object with keys `viewports` and `defaultViewport`'
);
const deprecateOnViewportChange = deprecate(
() => 0,
'The viewport parameter `onViewportChange` is no longer supported'
);

const getState = memoize(10)((props, state, change) => {
const data = props.api.getCurrentStoryData();
const list = toList(data && data.parameters && data.parameters[PARAM_KEY]);
const parameters = data && data.parameters && data.parameters[PARAM_KEY];

if (parameters && typeof parameters !== 'object') {
deprecatedViewportString();
}

const { disable, viewports, defaultViewport, onViewportChange } = parameters || {};

if (onViewportChange) {
deprecateOnViewportChange();
}

const list = disable ? [] : toList(viewports || INITIAL_VIEWPORTS);

const selected =
state.selected === 'responsive' || list.find(i => i.id === state.selected)
? state.selected
: list.find(i => i.default) || 'responsive';
: list.find(i => i.default) || defaultViewport || DEFAULT_VIEWPORT;

const resets =
selected !== 'responsive'
Expand Down
2 changes: 1 addition & 1 deletion addons/viewport/src/constants.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const ADDON_ID = 'storybook/viewport';
export const PARAM_KEY = 'viewports';
export const PARAM_KEY = 'viewport';

export default {
UPDATE: `${ADDON_ID}/update`,
Expand Down
4 changes: 2 additions & 2 deletions addons/viewport/src/legacy_preview/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import deprecate from 'util-deprecate';

export { INITIAL_VIEWPORTS, DEFAULT_VIEWPORT } from '../defaults';
export { default as withViewport, Viewport } from './withViewport';
export { default as withViewport } from './withViewport';

export const configureViewport = deprecate(() => {},
'usage is deprecated, use .addParameters({ viewport }) instead');
'configureViewport is no longer supported, use .addParameters({ viewport }) instead');
10 changes: 2 additions & 8 deletions addons/viewport/src/legacy_preview/withViewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@ import deprecate from 'util-deprecate';

const withViewport = makeDecorator({
name: 'withViewport',
parameterName: 'viewports',
allowDeprecatedUsage: true,
parameterName: 'viewport',
wrapper: deprecate(
(getStory, context) => getStory(context),
'usage is deprecated, use .addParameters({ viewport }) instead'
'withViewport is no longer supported, use .addParameters({ viewport }) instead'
),
});

export default withViewport;

export const Viewport = deprecate(
({ children }) => children,
`<Viewport> usage is deprecated, use .addParameters({ viewport }) instead`
);
Loading

0 comments on commit 1ccc201

Please sign in to comment.