1 | <p align="center">
|
2 | <img width=100 src="storybook-jsx.png">
|
3 | <br>
|
4 | <h1 style="text-align:center;">Storybook-addon-jsx</h1>
|
5 | </p>
|
6 |
|
7 | [![Build Status](https://travis-ci.org/Kilix/storybook-addon-jsx.svg?branch=master)](https://travis-ci.org/Kilix/storybook-addon-jsx)
|
8 | [![Total Download](https://img.shields.io/npm/dt/storybook-addon-jsx.svg)](https://www.npmjs.com/package/storybook-addon-jsx)
|
9 | [![Current Version](https://img.shields.io/npm/v/storybook-addon-jsx.svg)](https://www.npmjs.com/package/storybook-addon-jsx)
|
10 |
|
11 | This Storybook addon shows you the JSX of the story.
|
12 | This preview works for Vue components as well.
|
13 | The outputted JSX will reflect any changes made to the storybok by knobs or controls.
|
14 |
|
15 | ![Storybook Addon JSX Demo](screenshot.png)
|
16 |
|
17 | ## Getting started
|
18 |
|
19 | ### Installation
|
20 |
|
21 | First install the addon from `npm`:
|
22 |
|
23 | ```sh
|
24 | npm i --save-dev storybook-addon-jsx
|
25 | # or
|
26 | yarn add --dev storybook-addon-jsx
|
27 | ```
|
28 |
|
29 | ### Configuration
|
30 |
|
31 | For the latest storybook all you need to do is add the addon to your `.storybook/main.js`:
|
32 |
|
33 | ```js
|
34 | module.exports = {
|
35 | addons: ['storybook-addon-jsx']
|
36 | };
|
37 | ```
|
38 |
|
39 | If you are using storybook@5.x or lower you will need to add the following to `.storybook/addons.js`:
|
40 |
|
41 | ```js
|
42 | import 'storybook-addon-jsx/register';
|
43 | ```
|
44 |
|
45 | ### Usage
|
46 |
|
47 | Import it into your stories file and then use it when you write stories:
|
48 |
|
49 | ```js
|
50 | import React from "react";
|
51 | import { storiesOf } from "@storybook/react";
|
52 | import { jsxDecorator } from "storybook-addon-jsx";
|
53 |
|
54 | import { TestComponent } from './TestComponent':
|
55 |
|
56 | export default {
|
57 | title: "Components/TestComponent",
|
58 | decorators: [jsxDecorator],
|
59 | };
|
60 |
|
61 | export const Paris = () => (
|
62 | <TestComponent fontSize={45} fontFamily="Roboto" align="center" color="#CAF200">
|
63 | Hello
|
64 | </TestComponent>
|
65 | );
|
66 |
|
67 | export const Orleans = () => <Test color="#236544">Hello</Test>;
|
68 | ```
|
69 |
|
70 | Or to configure it globally add the `jsxDecorator` to your `.storybook/preview.js`:
|
71 |
|
72 | ```js
|
73 | const { addDecorator } = require('@storybook/react');
|
74 | const { jsxDecorator } = require('storybook-addon-jsx');
|
75 |
|
76 | addDecorator(jsxDecorator);
|
77 | ```
|
78 |
|
79 | #### Vue
|
80 |
|
81 | You can also use this addon with `@storybook/vue`.
|
82 |
|
83 | **`.storybook/preview.js`**
|
84 |
|
85 | ```js
|
86 | import { configure, addDecorator } from '@storybook/vue';
|
87 | import { jsxDecorator } from 'storybook-addon-jsx';
|
88 |
|
89 | addDecorator(jsxDecorator);
|
90 | ```
|
91 |
|
92 | If a Vue story defines its view with a template string then it will be displayed.
|
93 |
|
94 | ```js
|
95 | import { storiesOf } from '@storybook/vue';
|
96 |
|
97 | storiesOf('Vue', module).add('template property', () => ({
|
98 | template: `<div></div>`
|
99 | }));
|
100 | ```
|
101 |
|
102 | ## Options
|
103 |
|
104 | ### JSX
|
105 |
|
106 | This addon support all options from [react-element-to-jsx-string](https://github.com/algolia/react-element-to-jsx-string) as well as the following options.
|
107 |
|
108 | - `skip` (default: 0) : Skip element in your component to display
|
109 |
|
110 | ```javascript
|
111 | export default {
|
112 | title: 'Components/TestComponent',
|
113 | parameters: {
|
114 | jsx: { skip: 1 }
|
115 | }
|
116 | };
|
117 | ```
|
118 |
|
119 | - `onBeforeRender(domString: string) => string` (default: undefined) : function that receives the dom as a string before render.
|
120 |
|
121 | ```js
|
122 | export default {
|
123 | title: 'Components/TestComponent',
|
124 | parameters: {
|
125 | jsx: {
|
126 | onBeforeRender: domString => {
|
127 | if (domString.search('dangerouslySetInnerHTML') < 0) {
|
128 | return '';
|
129 | }
|
130 |
|
131 | try {
|
132 | domString = /(dangerouslySetInnerHTML={{)([^}}]*)/.exec(domString)[2];
|
133 | domString = /(')([^']*)/.exec(domString)[2];
|
134 | } catch (err) {}
|
135 |
|
136 | return domString;
|
137 | }
|
138 | }
|
139 | }
|
140 | };
|
141 | ```
|
142 |
|
143 | - `displayName` (default: 0) : You can manually name the components that use useMemo or useRef.
|
144 |
|
145 | ```javascript
|
146 | export default {
|
147 | title: 'Components/TestComponent',
|
148 | parameters: {
|
149 | jsx: {
|
150 | displayName: () => 'CustomName'
|
151 | }
|
152 | }
|
153 | };
|
154 | ```
|
155 |
|
156 | ### Disable JSX Addon
|
157 |
|
158 | If enabled globally, the JSX addon can be disabled on individual stories:
|
159 |
|
160 | ```jsx
|
161 | export const Simple = () => <div>Hello</div>;
|
162 |
|
163 | Simple.story = {
|
164 | parameters: {
|
165 | jsx: {
|
166 | disable: true
|
167 | }
|
168 | }
|
169 | };
|
170 | ```
|
171 |
|
172 | ### Vue Options
|
173 |
|
174 | - `enableBeautify` (default: true) : Beautify the template string
|
175 | - All HTML options from [js-beautify](https://github.com/beautify-web/js-beautify#css--html)
|
176 |
|
177 | ## Global Options
|
178 |
|
179 | To configure global options for this plugin, add the following to your `config.js`.
|
180 |
|
181 | ```js
|
182 | import { addParameters } from '@storybook/react';
|
183 |
|
184 | addParameters({
|
185 | jsx: {
|
186 | // your options
|
187 | }
|
188 | });
|
189 | ```
|
190 |
|
191 | ## Function Props
|
192 |
|
193 | If you provide a funtion to one of your props `storybook-addon-jsx` will display that functions `toString` result.
|
194 | This is usaully very ugly.
|
195 | To override this include the following util function that will print an easiy to read string.
|
196 |
|
197 | ```tsx
|
198 | /**
|
199 | * Overrides the toString on a function so that it addon-jsx prints
|
200 | * the callbacks in a copy-paste-able way.
|
201 | */
|
202 | export const callback = <T extends Function>(fn: T): T => {
|
203 | /** A toString to render the function in storybook */
|
204 | // eslint-disable-next-line no-param-reassign
|
205 | fn.toString = () => '() => {}';
|
206 | return fn;
|
207 | };
|
208 | ```
|
209 |
|
210 | This works well with the `@storybook/addon-actions` too.
|
211 |
|
212 | ```tsx
|
213 | export ExampleStory = () => (
|
214 | <TestComponent onClick={callback(action('onClick'))} />
|
215 | )
|
216 | ```
|
217 |
|
218 | ## Including DocGen Information
|
219 |
|
220 | This addon will display prop type information while hovering over a component or prop.
|
221 | This is accomplished through [a babel plugin](https://github.com/storybookjs/babel-plugin-react-docgen) in the default storybook configuration.
|
222 | To use the docgen information for TypeScript components you must include be using [a typescript docgen loader](https://github.com/strothj/react-docgen-typescript-loader)
|
223 |
|
224 | ```js
|
225 | import { addParameters } from '@storybook/react';
|
226 |
|
227 | addParameters({
|
228 | jsx: {
|
229 | // your options
|
230 | }
|
231 | });
|
232 | ```
|
233 |
|
234 | ### TypeScript Monorepo DocGen
|
235 |
|
236 | In a TypeScript monorepo you will probably be importing components through package names.
|
237 | In this situation storybook will load your compiled typescript and lose information about the props.
|
238 |
|
239 | One solution to get around this is to add a unique property to your component's `package.json` that points directly at the TypeScript source.
|
240 | We can then set storybook's webpack configuration to look for this property first, which will allow the TypeScript loader to insert docgen information.
|
241 |
|
242 | In your component's `package.json`:
|
243 |
|
244 | ```jsonc
|
245 | {
|
246 | // Can be any string you want, here we choose "source"
|
247 | "source": "src/index.tsx"
|
248 | }
|
249 | ```
|
250 |
|
251 | Then in your webpack config for storybook:
|
252 |
|
253 | ```js
|
254 | config.resolve.mainFields = ['source', 'module', 'main'];
|
255 | ```
|
256 |
|
257 | ## Testing with storyshots
|
258 |
|
259 | If you are using the `addWithJSX` method you will need to include `storybook-addon-jsx` in your test file.
|
260 |
|
261 | ```js
|
262 | import initStoryshots from '@storybook/addon-storyshots';
|
263 | import { setAddon } from '@storybook/react';
|
264 | import JSXAddon from 'storybook-addon-jsx';
|
265 |
|
266 | setAddon(JSXAddon);
|
267 |
|
268 | initStoryshots({
|
269 | /* configuration options */
|
270 | });
|
271 | ```
|
272 |
|
273 | ## Usage with IE11
|
274 |
|
275 | Some of the dependencies that this package has use APIs not available in IE11.
|
276 | To get around this you can add the following to your `webpack.config.js` file
|
277 | (your paths might be slightly different):
|
278 |
|
279 | ```js
|
280 | config.module.rules.push({
|
281 | test: /\.js/,
|
282 | include: path.resolve(__dirname, '../node_modules/stringify-object'),
|
283 | use: [
|
284 | {
|
285 | loader: 'babel-loader',
|
286 | options: {
|
287 | presets: ['env']
|
288 | }
|
289 | }
|
290 | ]
|
291 | });
|
292 | ```
|
293 |
|
294 | ## Contributors β¨
|
295 |
|
296 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
297 |
|
298 |
|
299 |
|
300 |
|
301 | <table>
|
302 | <tr>
|
303 | <td align="center"><a href="https://wcastand.tech/"><img src="https://avatars3.githubusercontent.com/u/2178244?v=4" width="100px;" alt=""/><br /><sub><b>William</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=wcastand" title="Code">π»</a> <a href="#design-wcastand" title="Design">π¨</a> <a href="#ideas-wcastand" title="Ideas, Planning, & Feedback">π€</a> <a href="https://github.com/storybookjs/addon-jsx/commits?author=wcastand" title="Documentation">π</a></td>
|
304 | <td align="center"><a href="http://hipstersmoothie.com"><img src="https://avatars3.githubusercontent.com/u/1192452?v=4" width="100px;" alt=""/><br /><sub><b>Andrew Lisowski</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=hipstersmoothie" title="Code">π»</a> <a href="https://github.com/storybookjs/addon-jsx/commits?author=hipstersmoothie" title="Documentation">π</a> <a href="#infra-hipstersmoothie" title="Infrastructure (Hosting, Build-Tools, etc)">π</a> <a href="#maintenance-hipstersmoothie" title="Maintenance">π§</a></td>
|
305 | <td align="center"><a href="https://github.com/ndelangen"><img src="https://avatars2.githubusercontent.com/u/3070389?v=4" width="100px;" alt=""/><br /><sub><b>Norbert de Langen</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=ndelangen" title="Code">π»</a> <a href="https://github.com/storybookjs/addon-jsx/commits?author=ndelangen" title="Documentation">π</a></td>
|
306 | <td align="center"><a href="https://github.com/samouss"><img src="https://avatars2.githubusercontent.com/u/6513513?v=4" width="100px;" alt=""/><br /><sub><b>Samuel Vaillant</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=samouss" title="Code">π»</a> <a href="https://github.com/storybookjs/addon-jsx/commits?author=samouss" title="Documentation">π</a></td>
|
307 | <td align="center"><a href="https://twitter.com/_alexandrebodin"><img src="https://avatars2.githubusercontent.com/u/6065744?v=4" width="100px;" alt=""/><br /><sub><b>Alexandre BODIN</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=alexandrebodin" title="Code">π»</a></td>
|
308 | <td align="center"><a href="https://github.com/stof"><img src="https://avatars0.githubusercontent.com/u/439401?v=4" width="100px;" alt=""/><br /><sub><b>Christophe Coevoet</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=stof" title="Code">π»</a></td>
|
309 | <td align="center"><a href="http://www.leonelgalan.com"><img src="https://avatars3.githubusercontent.com/u/727774?v=4" width="100px;" alt=""/><br /><sub><b>Leonel GalΓ‘n</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=leonelgalan" title="Code">π»</a></td>
|
310 | </tr>
|
311 | <tr>
|
312 | <td align="center"><a href="http://threefivetwo.com"><img src="https://avatars3.githubusercontent.com/u/5214462?v=4" width="100px;" alt=""/><br /><sub><b>Lincoln Anderson</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=Landerson352" title="Code">π»</a></td>
|
313 | <td align="center"><a href="https://github.com/smollweide"><img src="https://avatars2.githubusercontent.com/u/2912007?v=4" width="100px;" alt=""/><br /><sub><b>Simon Mollweide</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=smollweide" title="Code">π»</a></td>
|
314 | <td align="center"><a href="https://github.com/lflpowell"><img src="https://avatars0.githubusercontent.com/u/37211236?v=4" width="100px;" alt=""/><br /><sub><b>lflpowell</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=lflpowell" title="Code">π»</a></td>
|
315 | <td align="center"><a href="https://github.com/expe-lbenychou"><img src="https://avatars1.githubusercontent.com/u/31204794?v=4" width="100px;" alt=""/><br /><sub><b>lionelbenychou</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=expe-lbenychou" title="Code">π»</a></td>
|
316 | <td align="center"><a href="http://breadadams.com"><img src="https://avatars1.githubusercontent.com/u/5795227?v=4" width="100px;" alt=""/><br /><sub><b>Brad Adams</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=breadadams" title="Documentation">π</a></td>
|
317 | <td align="center"><a href="http://twitter.com/arahansen"><img src="https://avatars0.githubusercontent.com/u/8746094?v=4" width="100px;" alt=""/><br /><sub><b>Andrew Hansen</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=arahansen" title="Code">π»</a></td>
|
318 | <td align="center"><a href="http://peter.mikit.sh"><img src="https://avatars3.githubusercontent.com/u/1571918?v=4" width="100px;" alt=""/><br /><sub><b>Peter Mikitsh</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=petermikitsh" title="Documentation">π</a> <a href="https://github.com/storybookjs/addon-jsx/commits?author=petermikitsh" title="Code">π»</a></td>
|
319 | </tr>
|
320 | <tr>
|
321 | <td align="center"><a href="https://github.com/lisamartin00"><img src="https://avatars0.githubusercontent.com/u/6465955?v=4" width="100px;" alt=""/><br /><sub><b>lisamartin00</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=lisamartin00" title="Code">π»</a></td>
|
322 | <td align="center"><a href="https://github.com/semihraifgurel"><img src="https://avatars.githubusercontent.com/u/29544960?v=4" width="100px;" alt=""/><br /><sub><b>Semih Raif GΓΌrel</b></sub></a><br /><a href="https://github.com/storybookjs/addon-jsx/commits?author=semihraifgurel" title="Documentation">π</a></td>
|
323 | <td align="center"><a href="https://leepowell.dev"><img src="https://avatars.githubusercontent.com/u/602052?v=4" width="100px;" alt=""/><br /><sub><b>Lee Powell</b></sub></a><br /><a href="#infra-leepowelldev" title="Infrastructure (Hosting, Build-Tools, etc)">π</a> <a href="https://github.com/storybookjs/addon-jsx/commits?author=leepowelldev" title="Code">π»</a></td>
|
324 | <td align="center"><a href="http://jimmyandrade.com"><img src="https://avatars.githubusercontent.com/u/2307245?v=4" width="100px;" alt=""/><br /><sub><b>Jimmy Andrade</b></sub></a><br /><a href="#infra-jimmyandrade" title="Infrastructure (Hosting, Build-Tools, etc)">π</a></td>
|
325 | </tr>
|
326 | </table>
|
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|