diff --git a/addons/queryparams/README.md b/addons/queryparams/README.md new file mode 100644 index 00000000000..8f340200437 --- /dev/null +++ b/addons/queryparams/README.md @@ -0,0 +1,32 @@ +# storybook-addon-queryparams + +This storybook addon can be helpful if your components need special query parameters to work the way you want them. + +## Getting started + +First, install the addon. + +```sh +$ yarn add @storybook/addon-queryparams --dev +``` + +import the `withQuery` decorator so the url will be changed before rendering stories. + +```js +import React from 'react'; +import { storiesOf, addDecorator } from '@storybook/react'; +import { withQuery } from '@storybook/addon-queryparams'; + +storiesOf('button', module) + .addDecorator(withQuery) + .addParameters({ + query: { + mock: true, + } + }) + .add('Prints the document.search', () => ( +
+ This is the current document.search: {document.search}, it includes `mock`! +
+ )); +``` diff --git a/addons/queryparams/package.json b/addons/queryparams/package.json new file mode 100644 index 00000000000..1434411e868 --- /dev/null +++ b/addons/queryparams/package.json @@ -0,0 +1,44 @@ +{ + "name": "@storybook/addon-queryparams", + "version": "5.1.1", + "description": "parameter addon for storybook", + "keywords": [ + "addon", + "storybook", + "query" + ], + "homepage": "https://github.com/storybooks/storybook#readme", + "bugs": { + "url": "https://github.com/storybooks/storybook/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/storybooks/storybook.git", + "directory": "addons/addon-queryparams" + }, + "license": "MIT", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "prepare": "node ../../scripts/prepare.js" + }, + "dependencies": { + "@storybook/addons": "5.1.1", + "@storybook/api": "5.1.1", + "@storybook/client-logger": "5.1.1", + "@storybook/components": "5.1.1", + "@storybook/core-events": "5.1.1", + "@storybook/theming": "5.1.1", + "common-tags": "^1.8.0", + "core-js": "^2.6.5", + "global": "^4.3.2", + "qs": "^6.6.0", + "react": "^16.8.3" + }, + "devDependencies": { + "@types/common-tags": "^1.8.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/addons/queryparams/src/constants.ts b/addons/queryparams/src/constants.ts new file mode 100755 index 00000000000..d8fc643d74b --- /dev/null +++ b/addons/queryparams/src/constants.ts @@ -0,0 +1,3 @@ +export const ADDON_ID = 'storybook/queryparams'; +export const PANEL_ID = `${ADDON_ID}/panel`; +export const PARAM_KEY = `query`; diff --git a/addons/queryparams/src/index.ts b/addons/queryparams/src/index.ts new file mode 100644 index 00000000000..bdcc8854569 --- /dev/null +++ b/addons/queryparams/src/index.ts @@ -0,0 +1,30 @@ +import { document, history } from 'global'; +import qs from 'qs'; + +import { makeDecorator, StoryContext, StoryGetter } from '@storybook/addons'; + +import { PARAM_KEY } from './constants'; + +export const withQuery = makeDecorator({ + name: 'withQuery', + parameterName: PARAM_KEY, + wrapper: (getStory: StoryGetter, context: StoryContext, { parameters }) => { + const { location } = document; + const currentQuery = qs.parse(location.search, { ignoreQueryPrefix: true }); + const additionalQuery = + typeof parameters === 'string' + ? qs.parse(parameters, { ignoreQueryPrefix: true }) + : parameters; + + const newQuery = qs.stringify(Object.assign({}, currentQuery, additionalQuery)); + const newLocation = location.href.replace(location.search, `?${newQuery}`); + + history.replaceState({}, document.title, newLocation); + + return getStory(context); + }, +}); + +if (module && module.hot && module.hot.decline) { + module.hot.decline(); +} diff --git a/addons/queryparams/src/typings.d.ts b/addons/queryparams/src/typings.d.ts new file mode 100644 index 00000000000..e2d982c525c --- /dev/null +++ b/addons/queryparams/src/typings.d.ts @@ -0,0 +1,2 @@ +declare module 'global'; +declare module 'react-sizeme'; diff --git a/addons/queryparams/tsconfig.json b/addons/queryparams/tsconfig.json new file mode 100644 index 00000000000..8876bb6737a --- /dev/null +++ b/addons/queryparams/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "types": ["webpack-env"] + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "src/__tests__/**/*" + ] +} diff --git a/examples/official-storybook/package.json b/examples/official-storybook/package.json index 4a507728e34..62e8a708a09 100644 --- a/examples/official-storybook/package.json +++ b/examples/official-storybook/package.json @@ -28,6 +28,7 @@ "@storybook/addon-links": "5.1.1", "@storybook/addon-notes": "5.1.1", "@storybook/addon-options": "5.1.1", + "@storybook/addon-queryparams": "5.1.1", "@storybook/addon-storyshots": "5.1.1", "@storybook/addon-storyshots-puppeteer": "5.1.1", "@storybook/addon-storysource": "5.1.1", diff --git a/examples/official-storybook/stories/__snapshots__/addon-queryparams.stories.storyshot b/examples/official-storybook/stories/__snapshots__/addon-queryparams.stories.storyshot new file mode 100644 index 00000000000..95433107590 --- /dev/null +++ b/examples/official-storybook/stories/__snapshots__/addon-queryparams.stories.storyshot @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Addons|QueryParams mock is 4 1`] = ` +
+ This story should have an extra url query param: ?mock=4 +
+`; + +exports[`Storyshots Addons|QueryParams mock is true 1`] = ` +
+ This story should have an extra url query param: ?mock=truehttp://localhost/ +
+`; diff --git a/examples/official-storybook/stories/addon-queryparams.stories.js b/examples/official-storybook/stories/addon-queryparams.stories.js new file mode 100644 index 00000000000..7c32fca677e --- /dev/null +++ b/examples/official-storybook/stories/addon-queryparams.stories.js @@ -0,0 +1,22 @@ +import { document } from 'global'; +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { withQuery } from '@storybook/addon-queryparams'; + +// debugger; + +storiesOf('Addons|QueryParams', module) + .addDecorator(withQuery) + .addParameters({ + query: { + mock: true, + }, + }) + .add('mock is true', () => ( +
This story should have an extra url query param: {document.location.search}
+ )) + .add( + 'mock is 4', + () =>
This story should have an extra url query param: {document.location.search}
, + { query: { mock: 4 } } + );