From fbf098f0c4ad46d44099a114172b0103e2cf06b3 Mon Sep 17 00:00:00 2001 From: Marie-Laure Sin Date: Thu, 2 Nov 2017 11:00:53 +0100 Subject: [PATCH] docs(storybook): add widgets usage * docs(storybook): add jsx addon * docs(storybook): add method to display correct component names * docs(storybook): add jsx usage to the stories * docs(storybook): update yarn.lock * docs(storybook): modify webpack config to fix build-storybook fail See https://github.com/storybooks/storybook/issues/1774 * docs(storybook): filter out unnecessary props * docs(storybook): updates after reviews on PR --- package.json | 1 + stories/Breadcrumb.stories.js | 76 +++++--- stories/ClearAll.stories.js | 86 +++++---- stories/CurrentRefinements.stories.js | 118 ++++++++----- stories/HierarchicalMenu.stories.js | 162 ++++++++++------- stories/Hits.stories.js | 18 +- stories/HitsPerPage.stories.js | 118 ++++++++----- stories/InfiniteHits.stories.js | 18 +- stories/Menu.stories.js | 214 ++++++++++++++--------- stories/MenuSelect.stories.js | 147 ++++++++++------ stories/MultiRange.stories.js | 151 ++++++++++------ stories/Pagination.stories.js | 143 +++++++++------ stories/PoweredBy.stories.js | 24 ++- stories/RangeInput.stories.js | 242 ++++++++++++++++++-------- stories/RangeSlider.stories.js | 92 +++++++--- stories/RefinementList.stories.js | 205 ++++++++++++++-------- stories/ScrollTo.stories.js | 18 +- stories/SearchBox.stories.js | 138 +++++++++------ stories/SortBy.stories.js | 72 +++++--- stories/StarRating.stories.js | 146 ++++++++++------ stories/Stats.stories.js | 19 +- stories/Toggle.stories.js | 62 ++++--- stories/util.js | 57 +++++- storybook/addons.js | 2 + storybook/webpack.config.js | 5 + yarn.lock | 66 ++++++- 26 files changed, 1586 insertions(+), 814 deletions(-) diff --git a/package.json b/package.json index f2021a7e07..ef54f818d6 100644 --- a/package.json +++ b/package.json @@ -113,6 +113,7 @@ "rheostat": "2.1.1", "sass-loader": "6.0.6", "stat-mode": "0.2.2", + "storybook-addon-jsx": "5.0.0", "string": "3.3.3", "style-loader": "0.19.0", "uglify-js": "3.0.25", diff --git a/stories/Breadcrumb.stories.js b/stories/Breadcrumb.stories.js index fd54573885..f1afdab573 100644 --- a/stories/Breadcrumb.stories.js +++ b/stories/Breadcrumb.stories.js @@ -1,5 +1,5 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { Breadcrumb, Panel, @@ -7,45 +7,63 @@ import { } from '../packages/react-instantsearch/dom'; import { connectHierarchicalMenu } from '../packages/react-instantsearch/connectors'; import { withKnobs, object, text } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; + +setAddon(JSXAddon); const stories = storiesOf('Breadcrumb', module); const VirtualHierarchicalMenu = connectHierarchicalMenu(() => null); -stories.addDecorator(withKnobs); - stories - .add('default', () => ( -
+ .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( +
+ + +
+ +
+
+ ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel', + () => ( - + + +
-
- )) - .add('with panel', () => ( - - - - -
- -
- )) + ), + { + displayName, + filterProps, + } + ); + +stories .add('with custom component', () => ( ( - -
- -
- + .addDecorator(withKnobs) + .addWithJSX( + 'with refinements to clear', + () => ( + +
+ +
+ +
-
- - )) - .add('nothing to clear', () => ( - - - - )) - .add('clear all refinements and the query', () => ( - - - - - )); + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'nothing to clear', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'clear all refinements and the query', + () => ( + + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/CurrentRefinements.stories.js b/stories/CurrentRefinements.stories.js index d8b4387275..2dcfa463d4 100644 --- a/stories/CurrentRefinements.stories.js +++ b/stories/CurrentRefinements.stories.js @@ -1,5 +1,5 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { CurrentRefinements, RefinementList, @@ -7,55 +7,85 @@ import { Panel, } from '../packages/react-instantsearch/dom'; import { withKnobs } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; +setAddon(JSXAddon); const stories = storiesOf('CurrentRefinements', module); stories.addDecorator(withKnobs); stories - .add('default', () => ( - -
- -
- + .addWithJSX( + 'default', + () => ( + +
+ +
+ +
-
- - )) - .add('with toggle', () => ( - -
- - -
-
- )) - .add('with panel', () => ( - - - -
- + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with toggle', + () => ( + +
+ +
- -
- )) - .add('with panel but no refinement', () => ( - - - - - - )); + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel', + () => ( + + + +
+ +
+
+
+ ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel but no refinement', + () => ( + + + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/HierarchicalMenu.stories.js b/stories/HierarchicalMenu.stories.js index 9ffa2409a4..f067ce9e87 100644 --- a/stories/HierarchicalMenu.stories.js +++ b/stories/HierarchicalMenu.stories.js @@ -1,76 +1,120 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { HierarchicalMenu, Panel, SearchBox, } from '../packages/react-instantsearch/dom'; import { withKnobs, text, boolean, number } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('HierarchicalMenu', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('HierarchicalMenu', module); stories - .add('default', () => ( - - - - )) - .add('with default selected item', () => ( - - - - )) - .add('with show more', () => ( - - - - )) - .add('with panel', () => ( - - + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with default selected item', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with show more', + () => ( + - - - )) - .add('with panel but no refinement', () => ( - - + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel', + () => ( + + + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel but no refinement', + () => ( + + + +
+ +
+
+
+ ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'playground', + () => ( + -
- -
- -
- )) - .add('playground', () => ( - - - - )); + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/Hits.stories.js b/stories/Hits.stories.js index f0e9a3bcc0..68b8807616 100644 --- a/stories/Hits.stories.js +++ b/stories/Hits.stories.js @@ -1,19 +1,25 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { Hits, Highlight, Snippet } from '../packages/react-instantsearch/dom'; import { withKnobs } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('Hits', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('Hits', module); -stories.add('default', () => ( +stories.addDecorator(withKnobs).addWithJSX('default', +() => ( -)); +), +{ + displayName, + filterProps, +}); stories.add('with custom rendering', () => ( diff --git a/stories/HitsPerPage.stories.js b/stories/HitsPerPage.stories.js index b7ecaa7850..7b9b20fdc1 100644 --- a/stories/HitsPerPage.stories.js +++ b/stories/HitsPerPage.stories.js @@ -1,38 +1,77 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { HitsPerPage, Panel } from '../packages/react-instantsearch/dom'; import { withKnobs, number } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('HitsPerPage', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('HitsPerPage', module); stories - .add('default', () => ( - - - - )) - .add('without label', () => ( - - - - )) - .add('inside a panel', () => ( - - + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'without label', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'inside a panel', + () => ( + + + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'playground', + () => ( + - - - )) - .add('playground', () => ( - - - - )); + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/InfiniteHits.stories.js b/stories/InfiniteHits.stories.js index e47919eac6..6d09a136f6 100644 --- a/stories/InfiniteHits.stories.js +++ b/stories/InfiniteHits.stories.js @@ -1,15 +1,21 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { InfiniteHits } from '../packages/react-instantsearch/dom'; import { withKnobs } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('InfiniteHits', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('InfiniteHits', module); -stories.add('default', () => ( +stories.addDecorator(withKnobs).addWithJSX('default', +() => ( -)); +), +{ + displayName, + filterProps, +}); diff --git a/stories/Menu.stories.js b/stories/Menu.stories.js index 76134a55cc..1d1f5ebba4 100644 --- a/stories/Menu.stories.js +++ b/stories/Menu.stories.js @@ -1,87 +1,145 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { Menu, Panel, SearchBox } from '../packages/react-instantsearch/dom'; import { withKnobs, text, boolean, number } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; import { orderBy } from 'lodash'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('Menu', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('Menu', module); stories - .add('default', () => ( - - - - )) - .add('with default selected item', () => ( - - - - )) - .add('with show more', () => ( - - - - )) - .add('with search inside items', () => ( - - - orderBy( - items, - ['isRefined', 'count', 'label'], - ['desc', 'desc', 'asc'] - )} - /> - - )) - .add('with the sort strategy changed', () => ( - - - orderBy(items, ['label', 'count'], ['asc', 'desc'])} - /> - - )) - .add('with panel', () => ( - - - - - - )) - .add('with panel but no available refinement', () => ( - - + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + -
- -
- - - )) - .add('playground', () => ( - - - - )); + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with default selected item', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with show more', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with search inside items', + () => ( + + + orderBy( + items, + ['isRefined', 'count', 'label'], + ['desc', 'desc', 'asc'] + )} + /> + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with the sort strategy changed', + () => ( + + + orderBy(items, ['label', 'count'], ['asc', 'desc'])} + /> + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel', + () => ( + + + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel but no available refinement', + () => ( + + + +
+ +
+ + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'playground', + () => ( + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/MenuSelect.stories.js b/stories/MenuSelect.stories.js index 4ccc3d1207..67d148aa14 100644 --- a/stories/MenuSelect.stories.js +++ b/stories/MenuSelect.stories.js @@ -1,65 +1,108 @@ import React from 'react'; import { orderBy } from 'lodash'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { withKnobs, text } from '@storybook/addon-knobs'; - -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; import { MenuSelect, Panel, SearchBox, } from '../packages/react-instantsearch/dom'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('MenuSelect', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('MenuSelect', module); stories - .add('default', () => ( - - - - )) - .add('with default selected item', () => ( - - - - )) - .add('with the sort strategy changed', () => ( - - - orderBy(items, ['label', 'count'], ['asc', 'desc'])} - /> - - )) - .add('with panel', () => ( - - - - - - )) - .add('with panel but no available refinement', () => ( - - + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + -
- -
-
-
- )) - .add('playground', () => ( - - - - )); + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with default selected item', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with the sort strategy changed', + () => ( + + + orderBy(items, ['label', 'count'], ['asc', 'desc'])} + /> + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel', + () => ( + + + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel but no available refinement', + () => ( + + + +
+ +
+
+
+ ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'playground', + () => ( + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/MultiRange.stories.js b/stories/MultiRange.stories.js index 8cd24ecde9..de30410e4d 100644 --- a/stories/MultiRange.stories.js +++ b/stories/MultiRange.stories.js @@ -1,61 +1,24 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { MultiRange, Panel, Configure, } from '../packages/react-instantsearch/dom'; import { withKnobs } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('MultiRange', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('MultiRange', module); stories - .add('default', () => ( - - $500' }, - ]} - /> - - )) - .add('with a default range selected', () => ( - - $500' }, - ]} - defaultRefinement=":10" - /> - - )) - .add('with some non selectable ranges', () => ( - - $90000' }, - ]} - /> - - )) - .add('with panel', () => ( - - + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + $500' }, ]} /> - - - )) - .add('with panel but no available refinements', () => ( - - - + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with a default range selected', + () => ( + $500' }, ]} + defaultRefinement=":10" + /> + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with some non selectable ranges', + () => ( + + $90000' }, + ]} /> - - - )); + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel', + () => ( + + + $500' }, + ]} + /> + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel but no available refinements', + () => ( + + + + $500' }, + ]} + /> + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/Pagination.stories.js b/stories/Pagination.stories.js index a140316de9..7ef0a08441 100644 --- a/stories/Pagination.stories.js +++ b/stories/Pagination.stories.js @@ -1,65 +1,102 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { Pagination, Panel, SearchBox, } from '../packages/react-instantsearch/dom'; import { withKnobs, boolean, number } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('Pagination', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('Pagination', module); stories - .add('default', () => ( - - - - )) - .add('with all props', () => ( - - - - )) - .add('with panel', () => ( - - - - - - )) - .add('with panel but no refinement', () => ( - - + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + -
- -
-
-
- )) - .add('playground', () => ( - - - - )); + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with all props', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel', + () => ( + + + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel but no refinement', + () => ( + + + +
+ +
+
+
+ ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'playground', + () => ( + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/PoweredBy.stories.js b/stories/PoweredBy.stories.js index 78fd029b6d..50c8180d43 100644 --- a/stories/PoweredBy.stories.js +++ b/stories/PoweredBy.stories.js @@ -1,12 +1,22 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { PoweredBy } from '../packages/react-instantsearch/dom'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; + +setAddon(JSXAddon); const stories = storiesOf('PoweredBy', module); -stories.add('default', () => ( - - - -)); +stories.addWithJSX( + 'default', + () => ( + + + + ), + { + displayName, + filterProps, + } +); diff --git a/stories/RangeInput.stories.js b/stories/RangeInput.stories.js index dbb2cc6e99..e8095c3062 100644 --- a/stories/RangeInput.stories.js +++ b/stories/RangeInput.stories.js @@ -1,88 +1,178 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { RangeInput, Panel, SearchBox, } from '../packages/react-instantsearch/dom'; import { withKnobs, object, number } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; -const stories = storiesOf('RangeInput', module); +import JSXAddon from 'storybook-addon-jsx'; + +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('RangeInput', module); stories - .add('default', () => ( - - - - )) - .add('with panel', () => ( - - + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel', + () => ( + + + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with no refinement', + () => ( + - - - )) - .add('with no refinement', () => ( - - -
- -
-
- )) - .add('with precision of 0', () => ( - - - - )) - .add('with default value', () => ( - - - - )) - .add('with min boundaries', () => ( - - - - )) - .add('with max boundaries', () => ( - - - - )) - .add('with min / max boundaries', () => ( - - - - )) - .add('with boundaries and default value', () => ( - - - - )) - .add('playground', () => ( - - - - )); +
+ +
+ + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with precision of 0', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with default value', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with min boundaries', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with max boundaries', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with min / max boundaries', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with boundaries and default value', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel but no refinement', + () => ( + + + +
+ +
+
+
+ ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'playground', + () => ( + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/RangeSlider.stories.js b/stories/RangeSlider.stories.js index 70dcf031b8..544a3477a6 100644 --- a/stories/RangeSlider.stories.js +++ b/stories/RangeSlider.stories.js @@ -1,35 +1,69 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { withKnobs, object, number } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; import Range from './3rdPartyIntegrations.stories'; -const stories = storiesOf('RangeSlider', module); +import JSXAddon from 'storybook-addon-jsx'; + +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('RangeSlider', module); stories - .add('default', () => ( - - - - )) - .add('providing default value', () => ( - - - - )) - .add('custom min/max bounds', () => ( - - - - )) - .add('playground', () => ( - - - - )); + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'providing default value', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'custom min/max bounds', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'playground', + () => ( + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/RefinementList.stories.js b/stories/RefinementList.stories.js index 88d870b5da..492c223113 100644 --- a/stories/RefinementList.stories.js +++ b/stories/RefinementList.stories.js @@ -1,85 +1,146 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { RefinementList, Panel, SearchBox, } from '../packages/react-instantsearch/dom'; import { withKnobs, boolean, number, array } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; import { orderBy } from 'lodash'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('RefinementList', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('RefinementList', module); stories - .add('default', () => ( - - - - )) - .add('with selected item', () => ( - - - - )) - .add('with show more', () => ( - - - - )) - .add('with search inside items', () => ( - - - - )) - .add('with the sort strategy changed', () => ( - - - orderBy(items, ['label', 'count'], ['asc', 'desc'])} - /> - - )) - .add('with panel', () => ( - - - - - - )) - .add('with panel but no refinement', () => ( - - + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + -
- -
-
-
- )) - .add('playground', () => ( - - - - )); + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with selected item', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with show more', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with search inside items', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with the sort strategy changed', + () => ( + + + orderBy(items, ['label', 'count'], ['asc', 'desc'])} + /> + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel', + () => ( + + + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel but no refinement', + () => ( + + + +
+ +
+
+
+ ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'playground', + () => ( + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/ScrollTo.stories.js b/stories/ScrollTo.stories.js index 0dd5f8f524..fe90f6e09a 100644 --- a/stories/ScrollTo.stories.js +++ b/stories/ScrollTo.stories.js @@ -1,18 +1,24 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { ScrollTo, Hits, Configure } from '../packages/react-instantsearch/dom'; import { withKnobs } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('ScrollTo', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('ScrollTo', module); -stories.add('default', () => ( +stories.addDecorator(withKnobs).addWithJSX('default', +() => ( -)); +), +{ + displayName, + filterProps, +}); diff --git a/stories/SearchBox.stories.js b/stories/SearchBox.stories.js index 17dbaccff1..797a79f695 100644 --- a/stories/SearchBox.stories.js +++ b/stories/SearchBox.stories.js @@ -1,65 +1,95 @@ import React, { Component } from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { SearchBox } from '../packages/react-instantsearch/dom'; import { withKnobs, object } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; import { action } from '@storybook/addon-actions'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('SearchBox', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('SearchBox', module); stories - .add('default', () => ( - - - - )) - .add('with a default query', () => ( - - - - )) - .add('with submit and reset components', () => ( - - 🔍} - resetComponent={ - - - - } - /> - - )) - .add('playground', () => ( - - - - )); + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with a default query', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with submit and reset components', + () => ( + + 🔍} + resetComponent={ + + + + } + /> + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'playground', + () => ( + + + + ), + { + displayName, + filterProps, + } + ); // with event listeners // -------------------- diff --git a/stories/SortBy.stories.js b/stories/SortBy.stories.js index 3f9a2defcc..afcb3f9957 100644 --- a/stories/SortBy.stories.js +++ b/stories/SortBy.stories.js @@ -1,35 +1,51 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { SortBy } from '../packages/react-instantsearch/dom'; import { withKnobs } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('SortBy', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('SortBy', module); stories - .add('default', () => ( - - - - )) - .add('without label', () => ( - - - - )); + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'without label', + () => ( + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/StarRating.stories.js b/stories/StarRating.stories.js index b793f11a20..37fd2541a9 100644 --- a/stories/StarRating.stories.js +++ b/stories/StarRating.stories.js @@ -1,5 +1,5 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { StarRating, Panel, @@ -7,59 +7,103 @@ import { Configure, } from '../packages/react-instantsearch/dom'; import { withKnobs, object, number } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('StarRating', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('StarRating', module); stories - .add('default', () => ( - - - - )) - .add('with panel', () => ( - - - - - - )) - .add('with some unavailable refinements', () => ( - - - + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + - - - )) - .add('with panel but no refinement', () => ( - - + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel', + () => ( + + + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with some unavailable refinements', + () => ( + + + + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with panel but no refinement', + () => ( + + + +
+ +
+
+
+ ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'with filter on rating', + () => ( + + -
- -
- -
- )) - .add('with filter on rating', () => ( - - - - - )) - .add('playground', () => ( - - - - )); + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'playground', + () => ( + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/Stats.stories.js b/stories/Stats.stories.js index 4253194d27..89fb5aa7c6 100644 --- a/stories/Stats.stories.js +++ b/stories/Stats.stories.js @@ -1,17 +1,24 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { Stats } from '../packages/react-instantsearch/dom'; import { withKnobs } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; -const stories = storiesOf('Stats', module); +import JSXAddon from 'storybook-addon-jsx'; + +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('Stats', module); -stories.add('default', () => ( +stories.addDecorator(withKnobs).addWithJSX('default', +() => (
-)); +), +{ + displayName, + filterProps, +}); diff --git a/stories/Toggle.stories.js b/stories/Toggle.stories.js index 375954aa73..952491395e 100644 --- a/stories/Toggle.stories.js +++ b/stories/Toggle.stories.js @@ -1,30 +1,46 @@ import React from 'react'; -import { storiesOf } from '@storybook/react'; +import { setAddon, storiesOf } from '@storybook/react'; import { Toggle } from '../packages/react-instantsearch/dom'; import { withKnobs } from '@storybook/addon-knobs'; -import { WrapWithHits } from './util'; +import { displayName, filterProps, WrapWithHits } from './util'; +import JSXAddon from 'storybook-addon-jsx'; -const stories = storiesOf('Toggle', module); +setAddon(JSXAddon); -stories.addDecorator(withKnobs); +const stories = storiesOf('Toggle', module); stories - .add('default', () => ( - - - - )) - .add('checked by default', () => ( - - - - )); + .addDecorator(withKnobs) + .addWithJSX( + 'default', + () => ( + + + + ), + { + displayName, + filterProps, + } + ) + .addWithJSX( + 'checked by default', + () => ( + + + + ), + { + displayName, + filterProps, + } + ); diff --git a/stories/util.js b/stories/util.js index 29a4f500d3..fb9926c8ce 100644 --- a/stories/util.js +++ b/stories/util.js @@ -125,6 +125,9 @@ const CustomHits = connectHits(({ hits }) => ( )); WrapWithHits.propTypes = { + appId: PropTypes.string, + apiKey: PropTypes.string, + indexName: PropTypes.string, children: PropTypes.node, searchBox: PropTypes.bool, linkedStoryGroup: PropTypes.string, @@ -133,4 +136,56 @@ WrapWithHits.propTypes = { searchParameters: PropTypes.object, }; -export { Wrap, WrapWithHits }; +// defaultProps added so that they're displayed in the JSX addon +WrapWithHits.defaultProps = { + appId: 'latency', + apiKey: '6be0576ff61c053d5f9a3225e2a90f76', + indexName: 'ikea', +}; + +// retrieves the displayName of the React Component +const getReactElementDisplayName = element => + element.type.displayName || + element.type.name || + (typeof element.type === 'function' // function without a name, provide one + ? 'No Display Name' + : element.type); + +// displays the right name for the JSX addon in Storybook +const displayName = element => { + // display 'InstantSearch' instead of 'WrapWithHits' + if (getReactElementDisplayName(element) === 'WrapWithHits') { + const instantSearch = 'InstantSearch'; + return instantSearch; + } + // wrapped component: AlgoliaWidgetName(Translatable..)" => "WidgetName" + if ( + React.Component.isPrototypeOf(element.type) && + getReactElementDisplayName(element).startsWith('Algolia') + ) { + const innerComponentRegex = /\(([^()]+)\)/; + const match = innerComponentRegex.exec(element.type.displayName); + const innerComponentName = match[1]; + const rawName = element.type.displayName; + const widgetName = rawName.split('(')[0].replace('Algolia', ''); + if (match) { + // when a VirtualWidget is used, Algolia returns 'UnknownComponent' as the displayName + if (innerComponentName === 'UnknownComponent') { + return widgetName; + } + // when a Configure widget is used, Algolia returns '_default' as the displayName + if (innerComponentName === '_default') { + return widgetName; + } + // when a RangeInput widget is used, Algolia returns 'RawRangeInput' as the displayName + if (innerComponentName === 'RawRangeInput') { + return 'RangeInput'; + } + return innerComponentName; + } + } + return getReactElementDisplayName(element); +}; + +const filterProps = ['linkedStoryGroup', 'hasPlayground']; +export { displayName, filterProps, Wrap, WrapWithHits }; diff --git a/storybook/addons.js b/storybook/addons.js index 894847cfa5..0e2cfdf3be 100644 --- a/storybook/addons.js +++ b/storybook/addons.js @@ -1,3 +1,5 @@ import '@storybook/addon-knobs/register'; import '@storybook/addon-actions/register'; import '@storybook/addon-options/register'; +import '@storybook/addons'; +import 'storybook-addon-jsx/register'; diff --git a/storybook/webpack.config.js b/storybook/webpack.config.js index a0c1784d8b..6f249f4af6 100644 --- a/storybook/webpack.config.js +++ b/storybook/webpack.config.js @@ -2,6 +2,11 @@ module.exports = { module: { rules: [ + { + test: /\.js$/, + loader: 'babel-loader', + include: /node_modules\/(stringify-object|get-own-enumerable-property-symbols)/, + }, { test: /\.scss$/, use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'], diff --git a/yarn.lock b/yarn.lock index a604fe5323..a1239eb134 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2595,7 +2595,7 @@ coffee-script@^1.12.4: version "1.12.7" resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53" -collapse-white-space@^1.0.0: +collapse-white-space@1.0.3, collapse-white-space@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.3.tgz#4b906f670e5a963a87b76b0e1689643341b6023c" @@ -3081,6 +3081,12 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" +copy-to-clipboard@^3: + version "3.0.8" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.0.8.tgz#f4e82f4a8830dce4666b7eb8ded0c9bcc313aba9" + dependencies: + toggle-selection "^1.0.3" + core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" @@ -3709,6 +3715,10 @@ ecc-jsbn@~0.1.1: dependencies: jsbn "~0.1.0" +editions@^1.1.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.3.tgz#0907101bdda20fac3cbe334c27cbd0688dc99a5b" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4763,6 +4773,10 @@ get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" +get-own-enumerable-property-symbols@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b" + get-pkg-repo@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" @@ -5917,7 +5931,7 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-obj@^1.0.0: +is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -5941,7 +5955,7 @@ is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" -is-plain-object@^2.0.1, is-plain-object@^2.0.4: +is-plain-object@2.0.4, is-plain-object@^2.0.1, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" dependencies: @@ -5973,6 +5987,10 @@ is-regex@^1.0.3, is-regex@^1.0.4: dependencies: has "^1.0.1" +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + is-relative@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" @@ -9049,6 +9067,13 @@ react-color@^2.11.4: reactcss "^1.2.0" tinycolor2 "^1.4.1" +react-copy-to-clipboard@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.1.tgz#8eae107bb400be73132ed3b6a7b4fb156090208e" + dependencies: + copy-to-clipboard "^3" + prop-types "^15.5.8" + react-datetime@^2.10.3: version "2.10.3" resolved "https://registry.yarnpkg.com/react-datetime/-/react-datetime-2.10.3.tgz#9807a7d9be1dd4ee01b3466b0416614e3543378e" @@ -9091,6 +9116,16 @@ react-dom@16.0.0: object-assign "^4.1.1" prop-types "^15.6.0" +react-element-to-jsx-string@13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-13.0.0.tgz#5c6c90883ac172acd69ed3d664ba17ea648db0df" + dependencies: + collapse-white-space "1.0.3" + is-plain-object "2.0.4" + lodash "4.17.4" + sortobject "1.1.1" + stringify-object "3.2.1" + react-event-listener@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.5.1.tgz#ba36076e47bc37c5a67ff5ccd4a9ff0f15621040" @@ -10289,6 +10324,12 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" +sortobject@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/sortobject/-/sortobject-1.1.1.tgz#4f695d4d44ed0a4c06482c34c2582a2dcdc2ab34" + dependencies: + editions "^1.1.1" + source-list-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" @@ -10422,6 +10463,13 @@ stdout-stream@^1.4.0: dependencies: readable-stream "^2.0.1" +storybook-addon-jsx@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/storybook-addon-jsx/-/storybook-addon-jsx-5.0.0.tgz#412574c20a45eec5d70460cc7d25e23f614f9865" + dependencies: + react-copy-to-clipboard "5.0.1" + react-element-to-jsx-string "13.0.0" + stream-browserify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" @@ -10539,6 +10587,14 @@ stringify-entities@^1.0.1: is-alphanumerical "^1.0.0" is-hexadecimal "^1.0.0" +stringify-object@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.1.tgz#2720c2eff940854c819f6ee252aaeb581f30624d" + dependencies: + get-own-enumerable-property-symbols "^2.0.1" + is-obj "^1.0.1" + is-regexp "^1.0.0" + stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -10903,6 +10959,10 @@ to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" +toggle-selection@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + token-stream@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a"