Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with webpack configuration - Material-UI decorator #463

Closed
PolGuixe opened this issue Sep 19, 2016 · 9 comments
Closed

Problems with webpack configuration - Material-UI decorator #463

PolGuixe opened this issue Sep 19, 2016 · 9 comments

Comments

@PolGuixe
Copy link

PolGuixe commented Sep 19, 2016

I am trying to use different npm modules (Material-ui, etc) , but they don't seem load properly.

The error message I get is:

Cannot read property 'prepareStyles' of undefined
TypeError: Cannot read property 'prepareStyles' of undefined
    at RaisedButton.render (webpack:///~/material-ui/RaisedButton/RaisedButton.js:273:48)
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (webpack:///~/react/lib/ReactCompositeComponent.js:808:34)
    at ReactCompositeComponentWrapper._renderValidatedComponent (webpack:///~/react/lib/ReactCompositeComponent.js:835:34)
    at ReactCompositeComponentWrapper.performInitialMount (webpack:///~/react/lib/ReactCompositeComponent.js:372:30)
    at ReactCompositeComponentWrapper.mountComponent (webpack:///~/react/lib/ReactCompositeComponent.js:260:21)
    at Object.mountComponent (webpack:///~/react/lib/ReactReconciler.js:47:35)
    at ReactDOMComponent.mountChildren (webpack:///~/react/lib/ReactMultiChild.js:240:44)
    at ReactDOMComponent._createInitialChildren (webpack:///~/react/lib/ReactDOMComponent.js:698:32)
    at ReactDOMComponent.mountComponent (webpack:///~/react/lib/ReactDOMComponent.js:523:12)
    at Object.mountComponent (webpack:///~/react/lib/ReactReconciler.js:47:35)

I am using Meteor, hence the only Webpack configuration I have is the one for Storybook:

//Webpack configuration
const path = require('path');
module.exports = {
    module: {
        loaders: [
            {
                test: /\.css?$/,
                loaders: [
                    'style', 'raw'
                ],
                include: path.resolve(__dirname, '../')
            }
        ]
    },
    resolve: {
        extensions: [
            '', '.js', '.jsx'
        ]
    }
};

Here is the story:

import React from 'react';
import {storiesOf, action} from '@kadira/storybook';
import {setComposerStub} from 'react-komposer';
import FileUploader from '../file_uploader.jsx';

storiesOf('core.FileUploader', module).add('default view', () => {
    return (<FileUploader/>);
})

Here is the component:

import React from 'react';
import DropZone from 'dropzone';
import {RaisedButton, FontIcon} from 'material-ui';

class FileUploader extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        const {imageFiles} = this.props;

        return (
            <div>
                <DropZone className="drop-zone">
                    <RaisedButton label="Upload Pictures" icon={<FontIcon className="fa fa-upload"/>}/>
                    <p>
                        <small>Drop here the product pictures in
                            <code>jpeg</code>
                            or
                            <code>png</code>
                            format, with size less or equal to 2MB</small>
                    </p>
                </DropZone>
                <div className="image-preview">
                    {imageFiles && imageFiles[0]
                        ? imageFiles.map((image) => {
                            return (
                                <div className="image-wrapper"><img src={image.preview
                                    ? image.preview
                                    : image.link()}/></div>
                            );
                        })
                        : <div>
                            <i className="fa fa-camera"></i>{' Preview Images'}</div>}
                </div>
            </div>
        );
    }
}

export default FileUploader;

What I am missing?

@tinybug
Copy link

tinybug commented Sep 20, 2016

you should add MuiThemeProvider before you use material-ui components, you can find the answer here: http://www.material-ui.com/#/get-started/usage, but I have not tried to use the material-ui in storybook.

@PolGuixe
Copy link
Author

@tinybug ok I see the problem.
In my normal app as the MuiThemeProvider is added as to the main_layout. Hence, there are no issues.

In React Storybook I'll have to add the MuiThemeProvider to all the component. Is the a way to add it to all the component, without doing it explicitly? May be using a decorator?

@tinybug
Copy link

tinybug commented Sep 20, 2016

@PolGuixe I try to add decorator before add story like this, but it doesn't work...😵:

import {storiesOf, action, addDecorator} from '@kadira/storybook';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
function muiThemeDecorator(component) {
  return class muiTheme extends React.Component {
    constructor(props) {
      super(props);
    }

    render() {
      return (
        <MuiThemeProvider>
          <component {...this.props}/>
        </MuiThemeProvider>
      );
    }
  };
}

addDecorator(muiThemeDecorator);

@arunoda
Copy link
Member

arunoda commented Sep 21, 2016

@tinybug could you look at out docs on how to write a decorator properly: https://getstorybook.io/docs/addons/

@tinybug
Copy link

tinybug commented Sep 21, 2016

@arunoda nice!

import {storiesOf, action, addDecorator} from '@kadira/storybook';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';

const muiThemeDecorator = (story) => (
  <MuiThemeProvider>
    {story()}
  </MuiThemeProvider>
);

addDecorator(muiThemeDecorator);

@PolGuixe you can work like this.

@arunoda
Copy link
Member

arunoda commented Sep 21, 2016

Thanks @tinybug
I'm closing this as we already have a fix for this.

Anyway, feel free to re-open this if needed.

@arunoda arunoda closed this as completed Sep 21, 2016
@PolGuixe
Copy link
Author

I can confirm that now it works.

cheers @tinybug and @arunoda

@PolGuixe PolGuixe changed the title Problems with webpack configuration Problems with webpack configuration - Material-UI decorator Sep 23, 2016
@PolGuixe
Copy link
Author

I would also recomend to add this bit of code:

// -----------------------------------------------------------
// TODO: remove when not necessary - dependency for Material-ui
import injectTapEventPlugin from 'react-tap-event-plugin';

// Needed for onTouchTap http://stackoverflow.com/a/34015469/988941
injectTapEventPlugin();
// -----------------------------------------------------------

It is a dependency for Material-UI, otherwise it will throw an error

@Fer0x
Copy link

Fer0x commented Feb 23, 2017

That's because of calling injectTapEventPlugin(); on each re-render. Just wrap it with try/catch.

try {
  injectTapEventPlugin();
} catch (e) {}

addDecorator(story => (
  <MuiThemeProvider>
    {story()}
  </MuiThemeProvider>
));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants