Giter Site home page Giter Site logo

storybookjs / addon-jsx Goto Github PK

View Code? Open in Web Editor NEW
236.0 46.0 32.0 2.35 MB

This Storybook addon show you the JSX / template of the story

Home Page: https://storybooks-addon-jsx.netlify.com

License: MIT License

JavaScript 37.22% TypeScript 62.78%
storybook addon story jsx

addon-jsx's Introduction


Storybook-addon-jsx

Build Status Total Download Current Version

This Storybook addon shows you the JSX of the story. This preview works for Vue components as well. The outputted JSX will reflect any changes made to the storybok by knobs or controls.

Storybook Addon JSX Demo

Getting started

Installation

First install the addon from npm:

npm i --save-dev storybook-addon-jsx
# or
yarn add --dev storybook-addon-jsx

Configuration

For the latest storybook all you need to do is add the addon to your .storybook/main.js:

module.exports = {
  addons: ['storybook-addon-jsx']
};

If you are using [email protected] or lower you will need to add the following to .storybook/addons.js:

import 'storybook-addon-jsx/register';

Usage

Import it into your stories file and then use it when you write stories:

import React from "react";
import { storiesOf } from "@storybook/react";
import { jsxDecorator } from "storybook-addon-jsx";

import { TestComponent } from './TestComponent':

export default {
  title: "Components/TestComponent",
  decorators: [jsxDecorator],
};

export const Paris = () => (
  <TestComponent fontSize={45} fontFamily="Roboto" align="center" color="#CAF200">
    Hello
  </TestComponent>
);

export const Orleans = () => <Test color="#236544">Hello</Test>;

Or to configure it globally add the jsxDecorator to your .storybook/preview.js:

const { addDecorator } = require('@storybook/react');
const { jsxDecorator } = require('storybook-addon-jsx');

addDecorator(jsxDecorator);

Vue

You can also use this addon with @storybook/vue.

.storybook/preview.js

import { configure, addDecorator } from '@storybook/vue';
import { jsxDecorator } from 'storybook-addon-jsx';

addDecorator(jsxDecorator);

If a Vue story defines its view with a template string then it will be displayed.

import { storiesOf } from '@storybook/vue';

storiesOf('Vue', module).add('template property', () => ({
  template: `<div></div>`
}));

Options

JSX

This addon support all options from react-element-to-jsx-string as well as the following options.

  • skip (default: 0) : Skip element in your component to display
export default {
  title: 'Components/TestComponent',
  parameters: {
    jsx: { skip: 1 }
  }
};
  • onBeforeRender(domString: string) => string (default: undefined) : function that receives the dom as a string before render.
export default {
  title: 'Components/TestComponent',
  parameters: {
    jsx: {
      onBeforeRender: domString => {
        if (domString.search('dangerouslySetInnerHTML') < 0) {
          return '';
        }

        try {
          domString = /(dangerouslySetInnerHTML={{)([^}}]*)/.exec(domString)[2];
          domString = /(')([^']*)/.exec(domString)[2];
        } catch (err) {}

        return domString;
      }
    }
  }
};
  • displayName (default: 0) : You can manually name the components that use useMemo or useRef.
export default {
  title: 'Components/TestComponent',
  parameters: {
    jsx: {
      displayName: () => 'CustomName'
    }
  }
};

Disable JSX Addon

If enabled globally, the JSX addon can be disabled on individual stories:

export const Simple = () => <div>Hello</div>;

Simple.story = {
  parameters: {
    jsx: {
      disable: true
    }
  }
};

Vue Options

  • enableBeautify (default: true) : Beautify the template string
  • All HTML options from js-beautify

Global Options

To configure global options for this plugin, add the following to your config.js.

import { addParameters } from '@storybook/react';

addParameters({
  jsx: {
    // your options
  }
});

Function Props

If you provide a funtion to one of your props storybook-addon-jsx will display that functions toString result. This is usaully very ugly. To override this include the following util function that will print an easiy to read string.

/**
 * Overrides the toString on a function so that it addon-jsx prints
 * the callbacks in a copy-paste-able way.
 */
export const callback = <T extends Function>(fn: T): T => {
  /** A toString to render the function in storybook */
  // eslint-disable-next-line no-param-reassign
  fn.toString = () => '() => {}';
  return fn;
};

This works well with the @storybook/addon-actions too.

export ExampleStory = () => (
  <TestComponent onClick={callback(action('onClick'))} />
)

Including DocGen Information

This addon will display prop type information while hovering over a component or prop. This is accomplished through a babel plugin in the default storybook configuration. To use the docgen information for TypeScript components you must include be using a typescript docgen loader

import { addParameters } from '@storybook/react';

addParameters({
  jsx: {
    // your options
  }
});

TypeScript Monorepo DocGen

In a TypeScript monorepo you will probably be importing components through package names. In this situation storybook will load your compiled typescript and lose information about the props.

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. We can then set storybook's webpack configuration to look for this property first, which will allow the TypeScript loader to insert docgen information.

In your component's package.json:

{
  // Can be any string you want, here we choose "source"
  "source": "src/index.tsx"
}

Then in your webpack config for storybook:

config.resolve.mainFields = ['source', 'module', 'main'];

Testing with storyshots

If you are using the addWithJSX method you will need to include storybook-addon-jsx in your test file.

import initStoryshots from '@storybook/addon-storyshots';
import { setAddon } from '@storybook/react';
import JSXAddon from 'storybook-addon-jsx';

setAddon(JSXAddon);

initStoryshots({
  /* configuration options */
});

Usage with IE11

Some of the dependencies that this package has use APIs not available in IE11. To get around this you can add the following to your webpack.config.js file (your paths might be slightly different):

config.module.rules.push({
  test: /\.js/,
  include: path.resolve(__dirname, '../node_modules/stringify-object'),
  use: [
    {
      loader: 'babel-loader',
      options: {
        presets: ['env']
      }
    }
  ]
});

Contributors ✨

Thanks goes to these wonderful people (emoji key):


William

πŸ’» 🎨 πŸ€” πŸ“–

Andrew Lisowski

πŸ’» πŸ“– πŸš‡ 🚧

Norbert de Langen

πŸ’» πŸ“–

Samuel Vaillant

πŸ’» πŸ“–

Alexandre BODIN

πŸ’»

Christophe Coevoet

πŸ’»

Leonel GalΓ‘n

πŸ’»

Lincoln Anderson

πŸ’»

Simon Mollweide

πŸ’»

lflpowell

πŸ’»

lionelbenychou

πŸ’»

Brad Adams

πŸ“–

Andrew Hansen

πŸ’»

Peter Mikitsh

πŸ“– πŸ’»

lisamartin00

πŸ’»

Semih Raif GΓΌrel

πŸ“–

Lee Powell

πŸš‡ πŸ’»

Jimmy Andrade

πŸš‡

This project follows the all-contributors specification. Contributions of any kind welcome!

addon-jsx's People

Contributors

alexandrebodin avatar alfredo-delgado avatar arahansen avatar breadadams avatar dependabot[bot] avatar github-actions[bot] avatar hipstersmoothie avatar imgbotapp avatar jimmyandrade avatar landerson352 avatar leepowelldev avatar leonelgalan avatar lflpowell avatar libetl avatar lisamartin00 avatar ndelangen avatar petermikitsh avatar samouss avatar stof avatar wcastand avatar wuweiweiwu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

addon-jsx's Issues

A working example with TypeScript?

Hey,

Can anyone provide a working TypeScript implementation with these packages?

    "storybook-addon-jsx": "7.0.1",
    "@types/storybook-addon-jsx": "5.4.2",
    "@storybook/react": "^5.0.3",

It's a game of whack-a-mole with all the errors this produces, ultimately I cannot make this work:

import React from 'react';
import { storiesOf } from '@storybook/react';
import { withKnobs, text } from '@storybook/addon-knobs';
import { jsxDecorator } from 'storybook-addon-jsx';

storiesOf('Chrome', module)
  .addDecorator(jsxDecorator) // error here
  .addDecorator(withKnobs)
  .add('Default', () => <Story />);
TS2345: Argument of type '(storyFn: RenderFunction, parameters: JSXParameters) => (ComponentClass<{}, any> & VueComponent) | (FunctionComponent<{}> & VueComponent) | (Element & VueComponent) | (Renderable[] & VueComponent)' is not assignable to parameter of type 'StoryDecorator'.
  Types of parameters 'parameters' and 'context' are incompatible.
    Type '{ kind: string; story: string; }' is missing the following properties from type 'JSXParameters': id, parameters```

I have tried using it as as addon instead, but that gives different errors.

Anyone got it working?

warning.js:33 Warning: validateDOMNesting(...): <button> cannot appear as a descendant of <button>.

warning.js:33 Warning: validateDOMNesting(...): <button> cannot appear as a descendant of <button>.
    in button (created by Title)
    in CopyToClipboard (created by Title)
    in div (created by Title)
    in Title
    in button (created by DownPanel)
    in div (created by DownPanel)
    in div (created by DownPanel)
    in DownPanel (created by Container(DownPanel))
    in Container(DownPanel) (created by Layout)
    in div (created by Layout)
    in div (created by Pane)
    in Pane (created by SplitPane)
    in div (created by SplitPane)
    in SplitPane (created by Layout)
    in div (created by Pane)
    in Pane (created by SplitPane)
    in div (created by SplitPane)
    in SplitPane (created by Layout)
    in div (created by Layout)
    in Layout (created by Container(Layout))
    in Container(Layout)
    in div

This happens because of nested <button>:

image

image

addWithJSX syntax not working with Typescript

I was able to get typescript-addon-jsx working with .addDecorator(jsxDecorator), but I'm having some trouble using the .addWithJSX syntax. I'm getting the following TS error:

ERROR in [at-loader] ./src/Button/Button.story.tsx:18:9
    TS2349: This expression is not callable.
  Not all constituents of type 'string | ClientApiReturnFn<ReactElement<unknown, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>>' are callable.
    Type 'string' has no call signatures.

I'm using [email protected] and tried installing both @types/storybook-addon-jsx as well as @types/storybook__react, but I get the same TS error.


If I navigate to the types declaration of .addWithJSX() that takes me to node_modules/.../@storybook/addons/dist/types.d.ts, which shows:

export interface StoryApi<StoryFnReturnType = unknown> {
    kind: string;
    add: (storyName: string, storyFn: StoryFn<StoryFnReturnType>, parameters?: Parameters) => StoryApi<StoryFnReturnType>;
    addDecorator: (decorator: DecoratorFunction<StoryFnReturnType>) => StoryApi<StoryFnReturnType>;
    addParameters: (parameters: Parameters) => StoryApi<StoryFnReturnType>;
    [k: string]: string | ClientApiReturnFn<StoryFnReturnType>;
}

Seems like the line [k: string]: string... is catching the .addWithJSX call, so I'm not sure the declaration merge (which I assume is what @types/storybook-addon-tsx is doing) worked as intended, but does anyone know if it's possible to use .addWithJSX() with Typescript? If not, is there a way to pass in options to the addon when using the decorator syntax?

Thanks!

Doesn't work with React.Fragment

Hello

I've tried to use addon-jsx for story that uses React.Fragment like this:

 .addWithJSX('bubble with components inside of it', () => (
    <Fragment>
      <MyComponent props />
      <MyComponent otherProps/>
    </Fragment>
  ));

and it fails with error:

Cannot convert a Symbol value to a string
    at exports.default (http://localhost:9001/static/preview.bundle.js:85619:17)
    at exports.default (http://localhost:9001/static/preview.bundle.js:81301:49)
    at exports.default (http://localhost:9001/static/preview.bundle.js:85518:39)
    at reactElementToJsxString (http://localhost:9001/static/preview.bundle.js:85494:35)
    at http://localhost:9001/static/preview.bundle.js:85400:50
    at mapSingleChildIntoContext (http://localhost:9001/static/preview.bundle.js:15121:26)
    at traverseAllChildrenImpl (http://localhost:9001/static/preview.bundle.js:14994:5)
    at traverseAllChildren (http://localhost:9001/static/preview.bundle.js:15065:10)
    at mapIntoWithKeyPrefixInternal (http://localhost:9001/static/preview.bundle.js:15141:3)
    at Object.mapChildren [as map] (http://localhost:9001/static/preview.bundle.js:15163:3)

It works perfectly once I replace <Fragment> with plain <div>

contributors.md

I'd like to suggest that a contributors.md be added to this project. In particular, I'm interested in how local development should be done.

e.g. I haven't had any luck working around multiple @storybook/addons when linking my local addon-jsx repo to my local storybook project.

Function in Props

When i put some functions on the Component, the Whole function including __WEBPACK_IMPORTED_MODULE... shows on jsx addons.

even with @storybook/addon-actions, JSX preview has shown as

<Calendar
  onSelect={function action() {
    for (var _len = arguments.length, _args = Array(_len), _key = 0; _key < _len; _key++) {
      _args[_key] = arguments[_key];
    }

    var args = _args.map(_util.prepareArguments);
    var channel = _addons2.default.getChannel();
    var id = (0, _v2.default)();
    channel.emit(_.EVENT_ID, {
      id: id,
      data: { name: name, args: args }
    });
  }}
/>

This is not what I expected... but is this intended?

Feature request: Allow to configure defaultOpts

https://github.com/storybooks/addon-jsx/blob/master/src/index.js#L45

I could help with it, if you approve the realization. Below my variant of realization.

Define let defaultOptions with current defaults in index.js
Add exported method, for example configure, to index.js.
cofigure will receive an argument and simply assign it to the defaultOptions

For future flexibility configure may accept object with keys, that define config part.
Like this configure({jsxOptions: { hereOptions }})

build-storybook error

I'm running into an issue with this addon when I run build-storybook, it's giving me

Building storybook ...
Failed to build the storybook
static/preview.89bc50f3418f0babaff2.bundle.js from UglifyJs
Invalid assignment [static/preview.89bc50f3418f0babaff2.bundle.js:44049,34]

Merely having this line import JSXAddon from 'storybook-addon-jsx' in stories/index.js causes this to happen... Any suggestions?

Error: Skip doesn't work for some cases

       .addWithJSX(
            'With Icon',
            () => (
                <ControlledWrapper defaultValue="">
                    {(value, onChange) => (
                        <div>
                            <RawTextArea
                                name="textarea"
                                value={value}
                                onChange={onChange}
                                icon="truck"
                                label="Commentaires livraison"
                            />
                            <div style={{ width: '340px' }}>
                                <RawTextArea
                                    mobile
                                    name="textarea"
                                    value={value}
                                    onChange={onChange}
                                    icon="truck"
                                    label="Commentaires livraison"
                                />
                            </div>
                        </div>
                    )}
                </ControlledWrapper>
            ),
            { skip: 1 }
        )

capture d ecran 2017-04-26 a 16 22 45

It doesn't work when the component is a function :

export default ({ title, onConfirm, onCancel, placement, children }: Props) => (
    <PopConfirm
        title={title}
        onConfirm={onConfirm}
        onCancel={onCancel}
        placement={placement}
        okText="OUI"
        cancelText="NON"
    >
        {children}
    </PopConfirm>
);

Send in the JSX panel :

<function (_ref) {
    var title = _ref.title,
        onConfirm = _ref.onConfirm,
        onCancel = _ref.onCancel,
        placement = _ref.placement,
        children = _ref.children;
    return _react2.default.createElement(
        _popconfirm2.default,
        {
            title: title,
            onConfirm: onConfirm,
            onCancel: onCancel,
            placement: placement,
            okText: 'OUI',
            cancelText: 'NON',
            __source: {
                fileName: _jsxFileName,
                lineNumber: 14
            }
        },
        children
    );
} title='Supprimer la ligne ?'
  onCancel={...}
  onConfirm={...}>
  <button>
    Confirm
  </button>
</function (_ref) {
    var title = _ref.title,
        onConfirm = _ref.onConfirm,
        onCancel = _ref.onCancel,
        placement = _ref.placement,
        children = _ref.children;
    return _react2.default.createElement(
        _popconfirm2.default,
        {
            title: title,
            onConfirm: onConfirm,
            onCancel: onCancel,
            placement: placement,
            okText: 'OUI',
            cancelText: 'NON',
            __source: {
                fileName: _jsxFileName,
                lineNumber: 14
            }
        },
        children
    );
}>

global options

hi how to setup global option eg: {showDefaultProps: false} ?

Quotes

Hi there, thank you for making this wonderful addon for storybook, it has come in handy!

With this input:

<div data={`{"bar"}`} />

I get this output in the addon:

<div data="{&quot;bar&quot;}" />

Is it possible to display this the same way as the input?

Thanks in advance!

Cannot read property 'register' of undefined

Deps:
"@storybook/addon-actions": "^4.1.11",
"@storybook/addon-info": "4.1.11",
"@storybook/addon-knobs": "4.1.11",
"@storybook/addon-options": "4.1.11",
"@storybook/cli": "4.1.11",
"@storybook/react": "4.1.11",

"storybook-addon-jsx": "^7.0.1" 

Upped from 6 version to 7 and catch error.

doesn't work with @storybook/react package

Accessing nonexistent addons channel, see https://storybook.js.org/basics/faq/#why-is-there-no-addons-channel
Error: Accessing nonexistent addons channel, see https://storybook.js.org/basics/faq/#why-is-there-no-addons-channel
    at AddonStore.getChannel (http://localhost:9001/static/preview.bundle.js:25606:15)
    at Object.addWithJSX (http://localhost:9001/static/preview.bundle.js:128442:36)
    at Object.api.(anonymous function) [as addWithJSX] (http://localhost:9001/static/preview.bundle.js:126362:17)
    at Object.<anonymous> (http://localhost:9001/static/preview.bundle.js:185918:46)
    at Object._typeof (http://localhost:9001/static/preview.bundle.js:185921:30)
    at __webpack_require__ (http://localhost:9001/static/preview.bundle.js:678:30)
    at fn (http://localhost:9001/static/preview.bundle.js:88:20)
    at webpackContext (http://localhost:9001/static/preview.bundle.js:162996:9)
    at http://localhost:9001/static/preview.bundle.js:109747:12
    at Array.forEach (<anonymous>)

Props are not all on a new line

When using a component without children and with several props, the props are not all on a new line, which is against most standards:

<Dropdown required={true}
  label='Responsable'
  value={1}
  placeholder='Choisir un responsable' />

I would expect something like:

<Dropdown
  required={true}
  label='Responsable'
  value={1}
  placeholder='Choisir un responsable'
/>

Values coming from a component using a function as a child component are first undefined

When you use an arrow function at some point of your story, it is at first called with undefined parameters, then with the correct one.

The following example works with a normal .add('Base'), or when doing {option => option && <div key={option.name}>{option.label}</div>}.

const Comp = ({ elements, children }) => (
    <div>
        {elements.map(children)}
    </div>
);
const options = [
    { name: 'register', label: 'Registered' },
    { name: 'done', label: 'Delivered' },
];
export default FelaProvider =>
    storiesOf('Test', module).addWithJSX('Base', () => (
        <Comp elements={options}>
            {option => <div key={option.name}>{option.label}</div>}
        </Comp>
    ));

I'm not 100% sure, but I think I also had this problem when using arrow function to declare onChange props, or stuff like that.

React Hooks

Only when I add addon-jsx, I have this problem.
Screenshot_2019-08-10 Storybook

button.tsx

import './button.style.css';
import * as React from 'react';

interface Props {
	/**
	 * Text for the button
	 */
	text: String;
}

export const ButtonNew = ({ text }: Props) => {
	const [value, setValue] = React.useState('...');

	console.log(value);

	return (
		<div>
			<div className="green">
				{text}
				<input type="text" value={value} onChange={({ target }) => setValue(target.value)} />
			</div>
		</div>
	);
};

ButtonNew.defaultProps = {
	text: 'ok',
};

button.stories.tsx

import * as React from 'react';
import { setAddon, storiesOf } from '@storybook/react';
import JSXAddon from 'storybook-addon-jsx';

setAddon(JSXAddon);

import { ButtonNew } from '../src/components/button/button';

storiesOf('Administrator/Button', module).addWithJSX('custom', () => <ButtonNew />);

Did you have the same issue?

[addon-jsx][enzyme][storyshots] Invariant Violation: ReactShallowRenderer render(): Shallow rendering works only with custom components, but the provided element type was `symbol`.

For anyone trying to make addon-jsx work along enzyme and Storyshots, you may run into this error when running Storyshots tests:

Invariant Violation: ReactShallowRenderer render(): Shallow rendering works only with custom components, but the provided element type was `symbol`.

The issue is that the component returned by the typical const component = story.render(context); line in a Storyshot test file is no longer just the component in question, but a fragment component with two children: the original component, and the JSX additions. When enzyme sees this, it complains with the error above. Plus, we don't want to write the JSX addons into a Jest snapshot.

So, in my Storyshort test file, I added the skip option for addon-jsx:

import initStoryshots from "@storybook/addon-storyshots";
import { shallow } from "enzyme";

initStoryshots({
  test: ({ story, context }) => {
    const component = story.render(context, { jsx: { skip: 1 } });
    const html = shallow(component).html();

    expect(html).toMatchSnapshot();
  }
});

Which made the tests pass again.

Storyshots not working with addWithJSX

I can't seem to get Storyshots to work with this addon. The error is as follows when running npm test:

FAIL  src/__tests__/storyshots.test.js
● Test suite failed to run
TypeError: (0 , _react2.storiesOf)(...).addWithJSX is not a function

  at Object.<anonymous> (src/__stories__/test.stories.js:12:40)
  at node_modules/@storybook/addon-storyshots/dist/require_context.js:39:24
      at Array.forEach (<anonymous>)
  at requireModules (node_modules/@storybook/addon-storyshots/dist/require_context.js:34:9)
  at node_modules/@storybook/addon-storyshots/dist/require_context.js:48:7
      at Array.forEach (<anonymous>)
  at requireModules (node_modules/@storybook/addon-storyshots/dist/require_context.js:34:9)
  at Function.newRequire.context (node_modules/@storybook/addon-storyshots/dist/require_context.js:90:5)
  at evalmachine.<anonymous>:23:19
  at runWithRequireContext (node_modules/@storybook/addon-storyshots/dist/require_context.js:102:3)
  at testStorySnapshots (node_modules/@storybook/addon-storyshots/dist/index.js:120:35)
  at Object.<anonymous> (src/__tests__/storyshots.test.js:24:31)

Storyshots works just fine if I use Storybook's add() instead of addWithJSX().

The only configuration I have related to addon-jsx is in .storybook/config.js:

import { setOptions } from '@storybook/addon-options';
import JSXAddon from 'storybook-addon-jsx';
setAddon(JSXAddon);
configure(loadStories, module);

And storyshots configured in storyshots.test.js as:

import initStoryshots from '@storybook/addon-storyshots';
initStoryshots();

And this is my sample story:

import * as React from 'react';
import { storiesOf } from '@storybook/react';
storiesOf('test', module).addWithJSX('test1', () => <div>hi</div>);

Support for IE11

This addon is really awesome! Unfortunately it isn't working on IE11 😞

The cause for this (there might be more) is react-element-to-jsx-string is on version 12.0.0 and not 13.0.0
(There's a long chain of dependencies here but eventually it uses version 2.0.1 of get-own-enumerable-property-symbols which now includes an ES5 compiled version of the code).

Not sure if there are any other things that might break IE11, but after disabling just this addon storybook works as expected.

As a workaround - I can take full control over the storybook webpack config and remove the exclude from the .js rule, that excludes node_modules, that way every file will go through babel, but that's highly inefficient and might cause other issues when compiling already compiled modules.

Invalid prop AddonPanel

Hi,

I'm using the latest version of your module (very useful by the way) and i have the following warning from propTypes.

Warning: Failed prop type: Invalid prop `panels.kadira/jsx/panel.title` supplied to `AddonPanel`.
    in AddonPanel (created by Container(AddonPanel))
    in Container(AddonPanel) (created by addonPanel)
    in addonPanel (created by Layout)
    in div (created by Styled(div))
    in Styled(div) (created by Layout)
    in div (created by Pane)
    in Pane (created by SplitPane)
    in div (created by SplitPane)
    in SplitPane (created by Layout)
    in div (created by Pane)
    in Pane (created by SplitPane)
    in div (created by SplitPane)
    in SplitPane (created by Layout)
    in Layout (created by Layout)
    in div (created by Styled(div))
    in Styled(div) (created by Layout)
    in div (created by Layout)
    in ThemeProvider (created by Layout)
    in Layout (created by Container(Layout))
    in Container(Layout)
    in div

This is due to storybook's AddonPanel propTypes, now checking a shape for the panels prop.

This can be solved by passing the Title functional component directly to the panel title property when registering in register.js#L18.

I'll submit a PR by the day.

The copy button is displayed weirdly

Hi,

I tried to add your nice addon, but the copy button is messing with other addons, see:
image

Maybe it would be better to put it like the action logger does, at the bottom right?

Export + Export Default + React Hooks

Hi, Thanks for the awesome plugin.

Currently I am using typescript + docgen to get a prop table for my components. To do this I have to export my component as default export + non default:

export function Component() {}
export default Component;

when I add export function Component() {} i get the following error from react 16.7.0-alpha

screen shot 2018-10-31 at 11 20 29 am

Boolean prop not displaying

When adding a prop as boolean false it does not show in the pane.

<Component propName={false} />

In output you will just see <Component />

prevent break line of array props value

Hi!
Is there any way to prevent the react-element-to-jsx-string to breaking lines on an array value props? Bellow follows an example:

Input code

<Row>
  <Cell>
    <Block>[1, 2, 3, 4, 6, 12]</Block>
  </Cell>

  <Cell size={[8, 2, 3, 4, 6, 6]}>
    <Block>[8, 2, 3, 4, 6, 6]</Block>
  </Cell>

  <Cell size={[null, null, null, null, null, 6]}>
    <Block>[1, 2, 3, 4, 6, 6]</Block>
  </Cell>

  <Cell size={[2]}>
    <Block>[2, 2, 3, 4, 6, 12]</Block>
  </Cell>
</Row>

Output formatted code

<Row>
  <Cell>
    <Block>
      [1, 2, 3, 4, 6, 12]
    </Block>
  </Cell>
  <Cell
    size={[
      8,
      2,
      3,
      4,
      6,
      6
    ]}
  >
    <Block>
      [8, 2, 3, 4, 6, 6]
    </Block>
  </Cell>
  <Cell
    size={[
      null,
      null,
      null,
      null,
      null,
      6
    ]}
  >
    <Block>
      [1, 2, 3, 4, 6, 6]
    </Block>
  </Cell>
  <Cell
    size={[
      2
    ]}
  >
    <Block>
      [2, 2, 3, 4, 6, 12]
    </Block>
  </Cell>
</Row>

Storybook-addon-jsx doesn't work with knobs

I can't get this addon to work with knobs addon.
This

storiesOf('NavKnobs', module)
  .add('without title', () =>{
    const name = text('Title', 'Page title');
    return (<Nav logo={logo}>
      <Link to="/">Home</Link>
    </Nav>)
  })
// and
storiesOf('NavKnobs', module)
  .addWithJSX('without title', () =>{
    return (<Nav logo={logo}>
      <Link to="/">Home</Link>
    </Nav>)
  })

both work.

But this doesn't

storiesOf('NavKnobs', module)
  .addWithJSX('without title', () =>{
    const name = text('Title', 'Page title');
    return (<Nav logo={logo}>
      <Link to="/">Home</Link>
    </Nav>)
  })

Knobstore is null (after page reload)

Using displayName and showFunctions: false, together causes function body to show

storybook/react v5.2.1
react v16.9.0
storybook-addon-jsx v7.1.6

When using options = { showFunctions: false, displayName: "MyComponent" }, function bodies are shown. Removing the displayName option means function bodies are hidden as intended.

Example

storiesOf("MyComponent", module)
  .addDecorator(jsxDecorator)
  .add(
    "default",
    () => <MyComponent  onSubmit={action("message")} />,
    { jsx: { showFunctions: false, displayName: "MyComponent" } }
  );

Expected

<MyComponent
  onSubmit={function noRefCheck() {}}
/>

Actual

<MyComponent
  onSubmit={function actionHandler() { /* .... some long function body ....  */ }}
/>

Doesn't work as expected with React.memo

When I try to wrap a functional component with React.memo I get <[object Object] /> instead of the component name.

The output without React.memo is:

Storybook - Google Chrome without React.memo

The output with React.memo is:

Storybook - Google Chrome with React.memo

storiesOf('My component', module)
  .addDecorator(jsxDecorator)
  .add('default', () => (
    <MyComponent>
      <span>Some text content</span>
    </MyComponent>
  ));
  • react: 16.8.6
  • storybook: 5.1.11
  • storybook-addon-jsx: 7.1.6

storybook v5 support

Any plans on updating this addon to work with v5? Tried to add, but it doesn't work.

image

How to display classes with state

We have a component that only makes sense if it is used as a class, because we need to demonstrate how it handles state.

I can't find a way of letting the JSX output of my story show the entire class. If I return the class in .addWithJsx, the component simply won't show up at all.

Any ideas?

Is it possible to make addon work with legacy createReactClass components?

We have a huge legacy codebase and this plugin suits well for us except the fact.
Now I have to call createElement method of React like this:

const stories = storiesOf('TiledHeader', module);
const Header = props => React.createElement(TiledHeader,props);
const Item = props => React.createElement(TiledHeaderItem,props);
stories.add('Simple', () =>(
    <Header>
        <Item 
            col={16}  
            positions={{alignY:'center',primary:'flex-start',secondary:'flex-start'}} 
            colors={{
                bg: color('Left Background', '#FFF', colorsGroup.left), 
                primary: color('Left Primary', 'grey', colorsGroup.left),
                secondary: color('Left Secondary', '#000', colorsGroup.left)
            }} 
            primary={'ENTITY COUNT:'}
            secondary={'4'}   
        />
    </Header>
));

Bug: the syntax highlight doesn't work in some cases

import React from 'react';
import { createComponent } from 'react-fela';
import { storiesOf } from '@kadira/storybook';

import { ResponsiveFooter } from '../src/components/footer/responsiveFooter';
import { type Theme } from '../src/components/theme';
import { AppBody } from '../src/components/layout/index';

const dummyFunction = () => {};
const Page = createComponent(
    ({ theme }: { theme: Theme }) => ({
        height: 300,
        width: '100%',
        justifyContent: 'flex-end',
        border: theme.border,
    }),
    AppBody
);

export default FelaProvider =>
    storiesOf('Responsive footer', module)
        .addDecorator(FelaProvider)
        .addWithJSX(
            'Desktop',
            () => (
                <Page>
                    <ResponsiveFooter
                        leftButtons={[{ label: 'Annuler', icon: 'close', onClick: dummyFunction }]}
                        rightButtons={[
                            {
                                label: 'Enregistrer',
                                icon: 'save',
                                onClick: dummyFunction,
                                raised: true,
                            },
                            {
                                label: 'Envoyer',
                                icon: 'send',
                                onClick: dummyFunction,
                                primary: true,
                                raised: true,
                            },
                        ]}
                    />
                </Page>
            ),
            { skip: 1 }
        )
        .addWithJSX('Mobile', () => (
            <ResponsiveFooter
                mobile
                leftButtons={[{ label: 'Annuler', icon: 'close', onClick: dummyFunction }]}
                rightButtons={[
                    {
                        label: 'Enregistrer',
                        icon: 'save',
                        onClick: dummyFunction,
                        raised: true,
                    },
                    { label: 'Envoyer', icon: 'send', onClick: dummyFunction, primary: true },
                ]}
            />
        ));

The syntax highlighting of the JSX panel doesn't seem to take effect in some cases. I still need to figure it out why :)

capture d ecran 2017-04-26 a 16 29 02

Unique "key" prop warning in v7.2.3

React v16.13.1
Storybook v5.3
storybook-addon-jsx v7.2.3

After clicking on the jsx tab i get this warning

Warning: Each child in a list should have a unique "key" prop.

image

In file: src/register.tsx on line 30

render: ({ active }) => <JSX key="addon-jsx" active={active} ob={ob} />

changing to

render: ({ active }) => <JSX key={`addon-jsx-`${+ active}} active={active} ob={ob} />

Solved the waring message. But when changing story when jsx tab is active the warning is showing again.

FYI: i have tested this changing the file in my node_module folder

Dependency on React 15 prevents clean cutover to React 16

The package.json for storybook-addon-jsx has a dependency on "react": "^15.5.4", so it installs its own version of React when the parent project is using React 16.

Is there anything in this addon that's incompatible with React 16? Could the dependency on React be changed to a peerDependency, and have its range updated to support all the newness?

Invariant Violation: Element type is invalid: expected a string

Versions

    "@storybook/react": "^5.0.11",
    "storybook-addon-jsx": "^7.1.2"

As soon as I add the addon, I get this error message. If you look at the example component that I have, it is a valid React component.

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.

Screen Shot 2019-05-14 at 10 27 42 AM

// addons.js
import 'storybook-addon-jsx/register';
// config.js
import {addDecorator, configure} from '@storybook/react';
import {jsxDecorator} from 'storybook-addon-jsx';

addDecorator(jsxDecorator);

const loadStories = () => {
    const req = require.context('../stories', true, /\.stories\.js$/);
    req.keys().forEach(filename => req(filename));
};

configure(loadStories, module);
// my-component.js
import PropTypes from 'prop-types';
import React from 'react';

export const MyComponent = (props) => (
    <div>{props.greeting}</div>
);

MyComponent.propTypes = {
    greeting: PropTypes.string
};

MyComponent.defaultProps = {
    greeting: 'Hello, world.'
};
// my-component.stories.js
import {MyComponent} from '../src/my-component';
import React from 'react';
import {storiesOf} from '@storybook/react';

storiesOf('MyComponent', module)
    .add('with default greeting', () => (
        <MyComponent/>
    ))
    .add('with custom greeting', () => (
        <MyComponent greeting={'Hello, Rodo!'}/>
    ));

JSX Panel shows compiled HTML code instead of JSX

Hi,

Not sure if anyone else has encounter this issue but in my JSX panel, I'm getting the compiled HTML code instead of JSX. I've disabled all other addons in case one of them is clashing with this addon but the issue still persist. I've included my code below but tried to remove any extra fluffβ€”however, let me know if you need more info!

Packages information

"@storybook/addons": "^5.0.3",
"@storybook/react": "^5.1.9",
"storybook-addon-jsx": "^7.1.2",

Here's what the panel shows:
image

<button
  className="and-button and-button--square"
  onClick={function actionHandler() {
    var channel = _addons.addons.getChannel();

    var id = (0, _v["default"])();
    var minDepth = 5; // anything less is really just storybook internals

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    var actionDisplayToEmit = {
      id: id,
      count: 0,
      data: {
        name: name,
        args: args
      },
      options: Object.assign({}, actionOptions, {
        depth: minDepth + (actionOptions.depth || 3)
      })
    };
    channel.emit(_constants.EVENT_ID, actionDisplayToEmit);
  }}
  type="button"
>
  Button
</button>

Here's what my story looks like:

import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { text, select } from '@storybook/addon-knobs';

import manifest from '../../manifest';
import AndButton from './dist/AndButton';
import AndButtonReadme from './README.md';

const buttonSchema = manifest.button;

storiesOf('Button', module).addWithJSX('with text', () => {
  const { colorOptions, radiusOptions } = buttonSchema.props;
  const colorKnob = select('Color', colorOptions, 'default');
  const radiusKnob = select('Border Style', radiusOptions, 'square');
  const textKnob = text('Text', 'Button');

  return (
    <AndButton radius={radiusKnob} onClick={action('clicked')} color={colorKnob}>
      {textKnob}
    </AndButton>
  );
});

And my config.js file:

import React from 'react';
import { configure, addDecorator, setAddon } from '@storybook/react';
import { withKnobs } from '@storybook/addon-knobs';
import JSXAddon from 'storybook-addon-jsx';

setAddon(JSXAddon);
const req = require.context('../components', true, /.stories.(js|jsx)$/);

addDecorator(withKnobs);

function loadStories() {
  req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);

Also, my Button component itself (minus the custom functions and imports). The button renders fine.

const AndButton = (props) => {
  const {
    color, children, className, onClick, radius,
  } = props;

  const classes = classnames(
    baseClass,
    compileClassDefinitions(color, colorOptions),
    compileClassDefinitions(radius, radiusOptions),
    className,
  );

  return (
    <button className={classes} onClick={onClick} type="button">
      {children}
    </button>
  );
};

Unique "key" prop warning in v7.1.0

Loving this addon, so thank for that! I am noticing a warning in my browser console when I have this addon installed & enabled, and it disappears if I don't have this addon registered in my Storybook addons.js:

Screen Shot 2019-04-08 at 11 26 08 AM

Looks like the warning is coming from Emotion, used by @storybook/theming. I downgraded to v6 and still saw this warning.

Use with TypeScript

Is there currently a way to use this with TypeScript? I know that there isn't a @types package, but I'm wondering if anyone has a declaration file that they're successfully using. I'm currently getting the error [ts] Property 'addWithJSX' does not exist on type 'Story'.

Props with defaultProps of `undefined` show up.

Story definition:

<Checkbox
  onChange={onChange}
  value="yes"
  label="Check the Box"
/>

Storybook's JSX:

<Checkbox
  checked={false}
  color={undefined}
  id={undefined}
  label="Check the Box"
  name={undefined}
  onChange={action('onChange')}
  value="yes"
/>

Looking for a solution I noticed a PR that just got merged in react-element-to-jsx-string, but react-element-to-jsx-string is locked to ^14.0.3.

It allows for filterProps to be a function, so one could exclude props where the value is undefined.

14.3.0 was just released. There are no breaking changes since 14.0.3, but features that might benefit the community.

iterate tree when skip options is set

storiesOf('BasicElements/Button test', module)
  .addWithJSX('default', () => (
    <div style={{ backgroundColor: '#f9f9f9' }}> {/* level 1 -- should be skipped */}
      <div style={{ padding: 15 }}>                  {/* level 2 -- should be skipped */}
        <Button tint="primary" >Button</Button>          {/* level 3 -- print JSX to TAB  */}
      </div>
      <div style={{ padding: 15 }}>                  {/* level 2 -- should be skipped */}
        <Button tint="secondary" >Button</Button>       {/* level 3 -- print JSX to TAB  */}
      </div>
    </div>
  ), { skip: 2 });

now the JSX tab in storybook is empty

expected to find in JSX tab:

<Button tint="primary" >Button</Button>    
<Button tint="secondary" >Button</Button> 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.