3
votes

I’m using Storybook 5.2.6 for React 16.9.0 with Typescript 3.5.3 and using Material UI themed components. Having added, and configured, @storybook/addon-docs the Storybook Docs page displays: “Cannot read property 'classes' of undefined” in the PropsTable when a component is wrapped withStyles from @material-ui.

Component:

import React, {FunctionComponent} from 'react';
import { Typography } from '@material-ui/core';
import {
  withStyles,
  WithStyles,
} from '@material-ui/core/styles';
import styles from './index.styles';

export interface IProps extends WithStyles<typeof styles> {
  message?: string;
  testId?: string;
}

const Bar: FunctionComponent<IProps> = (props) => {
  const {
    classes,
    message,
    testId = ‘test-bar',
  } = props;

  if (!message) { return null; }
  return (
    <Typography className={classes.message} data-testid={testId}>
      {message}
    </Typography>
  );
};

export default withStyles(styles)(Bar);

Story

import React from 'react';
import { storiesOf } from '@storybook/react';
import { MuiThemeProvider } from '@material-ui/core/styles';

import Bar from './index';

import theme from '../../../others/global/material-ui-theme';

storiesOf('Bar', module)
  .addDecorator(story => <MuiThemeProvider theme={theme}>{story()}</MuiThemeProvider>)
  .addParameters({ component: Bar, componentSubtitle: 'Displays the Bar with message’ })
  .add('Warning', () => <Bar message="warning" />);

In React devtools and debugging in Chrome devtools I can see the classes do get injected as props so I’m kinda stumped at the moment how to resolve this?

1

1 Answers

0
votes

So a work around exists, you export the "unwrapped" component and use that as the component in docs:

As mentioned here: https://github.com/storybookjs/storybook/issues/8361

and commented here: https://github.com/storybookjs/storybook/issues/8435#issuecomment-547075209

Example:

export const PureBar: FunctionComponent<IProps> = (props) => {
    // ...
};

export default withStyles(styles)(PureBar);

Then in the story, update the component parameters to target the "Pure" component:

// import both the pure and wrapped components:
import Bar, { PureBar } from './Bar'

// Add to the story:
storiesOf('Bar', module)
.addParameters({ component: PureBar, componentSubtitle: 'Displays the Bar with message’ })
.add(/* ... */);