hipstersmoothie / storybook-addon-react-docgen

A storybook addon to display react docgen info.
MIT License
87 stars 14 forks source link

Not possible to exclude React Fragments, "styled.div", or other misc helper components. #97

Closed bradennapier closed 4 years ago

bradennapier commented 4 years ago

I use React Fragments to render multiple versions of a component in stories. When I do this the props tables displays a component I can not seem to remove.

This also happens with countless other scenarios - for example I try to use a styled component / div to create padding between the stories and it shows up in props tables and can not be excluded by name.

image

Or with fragment:

image

I have tried doing the following in preview.ts

import { Fragment } from 'react';

addDecorator(withPropsTable({
  propTablesExclude: [
    'styled.div',
    '',
    Fragment,
    'StoryRouter'
  ]
}))

Story:

import styled from 'styled-components';

const PaddedList = styled.div`
  > * {
    margin-top: 10px;
  }
`;

export const States = () => {
  const buttonText = text('Text', '');
  return (
    <PaddedList>
      <ButtonRouterLink to="#">
        {buttonText || 'Active Button'}
      </ButtonRouterLink>
      <ButtonRouterLink to="#" disabled>
        {buttonText || 'Disabled Button'}
      </ButtonRouterLink>
    </PaddedList>
  );
};

or

import styled from 'styled-components';

const PaddedList = styled.div`
  > * {
    margin-top: 10px;
  }
`;

export const States = () => {
  const buttonText = text('Text', '');
  return (
    <>
      <ButtonRouterLink to="#">
        {buttonText || 'Active Button'}
      </ButtonRouterLink>
      <ButtonRouterLink to="#" disabled>
        {buttonText || 'Disabled Button'}
      </ButtonRouterLink>
    </>
  );
};
bradennapier commented 4 years ago

Perhaps an option to only look at the component included in the component and subcomponent properties that addon-docs uses?

joshjeong commented 4 years ago

I'm also having issues with this.

export default {
  title: 'Atoms/LoadingButton',
  component: LoadingButton,
  props: {
    propTablesExclude: ['StoryContainer'],
  },
};
hipstersmoothie commented 4 years ago

@bradennapier I like that idea. Something like propTableIncludes that only displays the tables for those components. I'll gladly accept a PR for this, shouldn't be too hard.

I think we can probably fix the exclusion too, it'll only be 1 or 2 lines of code change.

bradennapier commented 4 years ago

My team hasn’t adopted storybook yet although I’ve been putting together examples on why we should. Happy to look at pr if/when I run into this again as that was one of the bigger pain points to having something convincing.

In reality it should probably detect a chunk of components to exclude by default such as html elements and fragments on top of the inclusion methods.

Either way, I def hope to be adopting for our org soon

hipstersmoothie commented 4 years ago

I'm actually gonna pick this up today cause I want it now! Thanks for the great idea

hipstersmoothie commented 4 years ago

One thing to note: Don't use a string, use the actual component.

@joshjeong So instead of

export default {
  title: 'Atoms/LoadingButton',
  component: LoadingButton,
  props: {
    propTablesExclude: ['StoryContainer'],
  },
};

do this

export default {
  title: 'Atoms/LoadingButton',
  component: LoadingButton,
  props: {
    propTablesExclude: [StoryContainer],
  },
};
hipstersmoothie commented 4 years ago

@bradennapier It seems like you can exclude fragments like

export default {
  title: 'Atoms/LoadingButton',
  component: LoadingButton,
  props: {
    propTablesExclude: [React.Fragment],
  },
};
bradennapier commented 4 years ago

I show me trying that. I import fragment then put it in the array and it still showed.

Does it work when using <></> syntax?

hipstersmoothie commented 4 years ago

In my example I was using <></> syntax

This is my story

import React from "react";
import { FlexibleTextArea } from "@cgds/storybook-utils";

export default {
  title: "Components/Button",
  parameters: {
    props: {
      propTablesExclude: [React.Fragment],
    },
  },
};

export const VisualGuide = () => (
  <>
    <FlexibleTextArea />
  </>
);
hipstersmoothie commented 4 years ago

One thing it might be is that the type for the fragment is a Symbol. If you had multiple version of react in your project the fragment you are excluding might not be the fragment that gets excluded from the story (this is a theory though)

bradennapier commented 4 years ago

Would be good to understand why

import React, { Fragment } Doesn’t work or if import * as React would work when then using React.Fragment

I felt like I tried everything but I def never use module interop that way due to using typescript.

bradennapier commented 4 years ago

Interesting, I doubt I had multiple versions but it’s possible ofc a dependency of my storybook env was causing it.

I’ll have to play with it again now that you put that PR together and see

hipstersmoothie commented 4 years ago

It also works if I do import * as React from "react"; and import React, {Fragment} from "react"; in my own repo

hipstersmoothie commented 4 years ago

as for styled components you include the component and not the styled.div

import styled from "styled-components";

const PaddedList = styled.div`
  > * {
    margin-top: 10px;
  }
`;

export default {
  title: "Components/Button",
  parameters: {
    props: {
      propTablesExclude: [PaddedList],
    },
  },
};
petermikitsh commented 4 years ago

Fragments now excluded: https://github.com/hipstersmoothie/storybook-addon-react-docgen/pull/106 (v1.2.38)