Commit d46c8350 by Ari Rizzitano

webpack config handles exports better

parent 3caa975e
...@@ -7,5 +7,14 @@ ...@@ -7,5 +7,14 @@
}], }],
"babel-preset-react" "babel-preset-react"
], ],
"plugins": ["transform-object-rest-spread"] "plugins": [
"transform-object-rest-spread",
["babel-plugin-react-css-modules", {
"webpackHotModuleReloading": true,
"filetypes": {
".scss": "postcss-scss"
},
"generateScopedName": '[name]__[local]___[hash:base64:5]'
}]
]
} }
// you can use this file to add your custom webpack plugins, loaders and anything you like.
// This is just the basic way to add addional webpack configurations.
// For more information refer the docs: https://getstorybook.io/docs/configurations/custom-webpack-config
// IMPORTANT
// When you add this file, we won't add the default configurations which is similar
// to "React Create App". This only has babel loader to load JavaScript.
const path = require('path'); const path = require('path');
module.exports = { module.exports = {
module: { module: {
rules: [{ rules: [
test: /\.scss$/, {
use: [ test: /\.scss$/,
{loader: 'style-loader'}, use: [
{loader: 'css-loader'}, {
{ loader: 'style-loader',
loader: 'sass-loader', },
options: { {
data: '@import "variables"; @import "mixins";', loader: 'css-loader',
includePaths: [ options: {
path.join(__dirname, '../'), modules: true,
], localIdentName: '[name]__[local]___[hash:base64:5]',
},
},
{
loader: 'sass-loader',
options: {
data: '@import "variables"; @import "mixins";',
includePaths: [
path.join(__dirname, '../node_modules/bootstrap/scss'),
],
},
}, },
}, ],
], },
}], ],
}, },
}; };
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "paragon", "name": "paragon",
"version": "0.0.1", "version": "0.0.1",
"description": "Accessible, responsive UI component library based on Bootstrap.", "description": "Accessible, responsive UI component library based on Bootstrap.",
"main": "dist/paragon.min.js", "main": "src/index.js",
"author": "arizzitano", "author": "arizzitano",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
"babel-cli": "^6.24.1", "babel-cli": "^6.24.1",
"babel-jest": "^20.0.3", "babel-jest": "^20.0.3",
"babel-loader": "^7.0.0", "babel-loader": "^7.0.0",
"babel-plugin-react-css-modules": "^2.7.1",
"babel-plugin-transform-object-rest-spread": "^6.23.0", "babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-preset-babili": "^0.0.12", "babel-preset-babili": "^0.0.12",
"babel-preset-env": "^1.4.0", "babel-preset-env": "^1.4.0",
...@@ -39,6 +40,7 @@ ...@@ -39,6 +40,7 @@
"babel-preset-react": "^6.24.1", "babel-preset-react": "^6.24.1",
"coveralls": "^2.13.1", "coveralls": "^2.13.1",
"enzyme": "^2.8.2", "enzyme": "^2.8.2",
"babili-webpack-plugin": "^0.1.1",
"css-loader": "^0.28.4", "css-loader": "^0.28.4",
"eslint": "^3.19.0", "eslint": "^3.19.0",
"eslint-config-airbnb": "^14.1.0", "eslint-config-airbnb": "^14.1.0",
...@@ -49,6 +51,7 @@ ...@@ -49,6 +51,7 @@
"husky": "^0.13.4", "husky": "^0.13.4",
"jest": "^20.0.4", "jest": "^20.0.4",
"node-sass": "^4.5.3", "node-sass": "^4.5.3",
"postcss-scss": "^1.0.1",
"react-router-dom": "^4.1.1", "react-router-dom": "^4.1.1",
"react-test-renderer": "^15.6.1", "react-test-renderer": "^15.6.1",
"sass-loader": "^6.0.5", "sass-loader": "^6.0.5",
......
/* eslint-disable no-unused-vars */
import React from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import borders from 'bootstrap/scss/utilities/_borders.scss';
import buttons from 'bootstrap/scss/_buttons.scss';
function Button(props) {
const styles = [
...props.classNames,
'buttons.btn',
];
if (props.buttonType) {
styles.push(`buttons.btn-${props.buttonType}`);
}
return (
<button
onBlur={props.onBlur}
onClick={props.onClick}
onKeyDown={props.onKeyDown}
styleName={classNames(styles)}
type={props.type}
>
{props.display}
</button>
);
}
Button.propTypes = {
buttonType: PropTypes.string,
classNames: PropTypes.arrayOf(PropTypes.string),
display: PropTypes.string.isRequired,
onBlur: PropTypes.function,
onClick: PropTypes.function,
onKeyDown: PropTypes.function,
type: PropTypes.string,
};
Button.defaultProps = {
buttonType: undefined,
classNames: [],
onBlur: () => {},
onClick: () => {},
onKeyDown: () => {},
type: 'button',
};
export default Button;
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import 'bootstrap/scss/_dropdown.scss'; import 'bootstrap/scss/_dropdown.scss';
import Button from './Button';
const triggerKeys = { const triggerKeys = {
OPEN_MENU: ['ArrowDown', 'Space'], OPEN_MENU: ['ArrowDown', 'Space'],
CLOSE_MENU: ['Escape'], CLOSE_MENU: ['Escape'],
...@@ -96,7 +97,7 @@ class Dropdown extends React.Component { ...@@ -96,7 +97,7 @@ class Dropdown extends React.Component {
generateMenuItems(menuItems) { generateMenuItems(menuItems) {
return menuItems.map((menuItem, i) => ( return menuItems.map((menuItem, i) => (
<li className={this.props.classes.menuItem} key={i}> <li styleName='dropdown-item' key={i}>
<a <a
role="menuitem" role="menuitem"
href={menuItem.href} href={menuItem.href}
...@@ -114,34 +115,29 @@ class Dropdown extends React.Component { ...@@ -114,34 +115,29 @@ class Dropdown extends React.Component {
render() { render() {
const menuItems = this.generateMenuItems(this.props.menuItems); const menuItems = this.generateMenuItems(this.props.menuItems);
const classes = this.props.classes;
return ( return (
<div <div
className={classNames([ styleName={classNames([
classes.dropdown, 'dropdown',
{ [classes.show]: this.state.open }, { show: this.state.open },
])} ])}
ref={(container) => { this.container = container; }} ref={(container) => { this.container = container; }}
> >
<button <Button
aria-expanded={this.state.open} aria-expanded={this.state.open}
aria-haspopup="true" aria-haspopup="true"
className={classNames([ display={this.props.title}
classes.toggle, className="dropdown-toggle"
{ [classes.active]: this.state.open },
])}
onClick={this.toggle} onClick={this.toggle}
onKeyDown={this.handleToggleKeyDown} onKeyDown={this.handleToggleKeyDown}
type="button" type="button"
ref={(toggleElem) => { this.toggleElem = toggleElem; }} ref={(toggleElem) => { this.toggleElem = toggleElem; }}
> />
{this.props.title}
</button>
<ul <ul
aria-label={this.props.title} aria-label={this.props.title}
aria-hidden={!this.state.open} aria-hidden={!this.state.open}
className={classes.menu} styleName='dropdown-menu'
role="menu" role="menu"
> >
{menuItems} {menuItems}
...@@ -157,21 +153,6 @@ Dropdown.propTypes = { ...@@ -157,21 +153,6 @@ Dropdown.propTypes = {
label: PropTypes.string, label: PropTypes.string,
href: PropTypes.string, href: PropTypes.string,
})).isRequired, })).isRequired,
classes: PropTypes.shape,
};
Dropdown.defaultProps = {
classes: {
dropdown: 'dropdown',
active: 'active',
toggle: 'btn btn-secondary dropdown-toggle',
screenreader: 'sr-only',
show: 'show',
menu: 'dropdown-menu',
menuActive: null,
menuItem: 'dropdown-item',
menuWrapper: null,
},
}; };
export default Dropdown; export default Dropdown;
...@@ -113,7 +113,7 @@ storiesOf('Dropdown', module) ...@@ -113,7 +113,7 @@ storiesOf('Dropdown', module)
classes={{ classes={{
dropdown: 'dropdown', dropdown: 'dropdown',
active: 'active', active: 'active',
toggle: 'btn btn-secondary border-0 dropdown-toggle', toggle: 'dropdown-toggle',
screenreader: 'sr-only', screenreader: 'sr-only',
show: 'show', show: 'show',
menu: 'dropdown-menu', menu: 'dropdown-menu',
......
const path = require('path'); const path = require('path');
const BabiliPlugin = require('babili-webpack-plugin');
const env = process.env.NODE_ENV || 'dev'; const env = process.env.NODE_ENV || 'dev';
...@@ -15,6 +16,9 @@ const base = { ...@@ -15,6 +16,9 @@ const base = {
resolve: { resolve: {
extensions: ['.js', '.jsx'], extensions: ['.js', '.jsx'],
}, },
plugins: [
new BabiliPlugin(),
],
module: { module: {
rules: [ rules: [
{ {
...@@ -30,41 +34,43 @@ const base = { ...@@ -30,41 +34,43 @@ const base = {
{ loader: 'source-map-loader' }, { loader: 'source-map-loader' },
], ],
}, },
{
test: /\.scss$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]',
},
},
{
loader: 'sass-loader',
options: {
data: '@import "variables"; @import "mixins";',
includePaths: [
path.join(__dirname, './node_modules/bootstrap/scss'),
],
},
},
],
},
], ],
}, },
}; };
const additionalConfig = { const additionalConfig = {
// dev runs the doc site locally.
dev: {
devServer: {
contentBase: path.resolve('./docs'),
historyApiFallback: true,
stats: {
chunks: false,
},
},
node: {
fs: 'empty',
},
module: {
loaders: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loaders: [
'babel-loader?cacheDirectory',
],
},
],
},
},
// production builds the library for external consumption // production builds the library for external consumption
production: { production: {
entry: path.resolve('./src/index.js'), entry: {
Dropdown: path.resolve('./src/Dropdown.jsx'),
},
output: { output: {
path: path.resolve('./dist'), path: path.resolve('./dist'),
filename: 'paragon.min.js', filename: '[name].js',
library: 'paragon', library: 'paragon',
libraryTarget: 'umd', libraryTarget: 'umd',
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment