├── .gitignore ├── LICENSE ├── README.md ├── fab-dev ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json ├── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── FAB │ │ ├── FloatingActionButton.jsx │ │ ├── css │ │ │ └── FAB.css │ │ └── js │ │ │ └── MaterialColors.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ └── serviceWorker.js └── yarn.lock ├── img └── FAB-Demo.gif └── lib ├── .babelrc ├── package-lock.json ├── package.json ├── publish ├── FAB-Demo.gif ├── README.md ├── build │ └── index.js └── package.json ├── src ├── css │ └── FAB.css ├── index.js └── js │ └── MaterialColors.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React-Floating-Action-Button 2 | A dead simple React component that works similar to Android's Action Button 3 | 4 | 5 | ![FAB Demo GIF](https://github.com/Gustavo-Kuze/React-Floating-Action-Button/blob/master/img/FAB-Demo.gif "FAB Demo") 6 | 7 | ___ 8 | 9 | ### Getting Started 10 | 1. First, You need to install It, just like You would do with any NPM package: 11 | ``` 12 | npm i --save react-floating-action-button 13 | ``` 14 | 15 | 2. Then, You need to import the library components within your own component 16 | ``` javascript 17 | import React from 'react' 18 | import { Container, Button, Link } from 'react-floating-action-button' 19 | ``` 20 | 21 | 3. You can now start using the FAB components! 22 | ``` javascript 23 | export default const YourAwesomeComponent = () => { 24 | return ( 25 | 26 | 29 | 32 | className="fab-item btn btn-link btn-lg text-white" 33 | 35 | 36 | 37 | 38 | ); 39 | } 40 | } 41 | 42 | export default App; 43 | -------------------------------------------------------------------------------- /fab-dev/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /fab-dev/src/FAB/FloatingActionButton.jsx: -------------------------------------------------------------------------------- 1 | import './css/FAB.css' 2 | import React from 'react' 3 | import {darkColors, lightColors} from './js/MaterialColors' 4 | 5 | const Container = props => { 6 | return ( 7 | 10 | ) 11 | } 12 | 13 | const Button = props => { 14 | return ( 15 | 21 | ) 22 | } 23 | 24 | const Link = props => { 25 | return ( 26 | 29 | 30 | {props.children} 31 | 32 | ) 33 | } 34 | 35 | const defaultItemStyles = { 36 | backgroundColor: darkColors.lighterRed, 37 | color: darkColors.white, 38 | textDecoration: "none", 39 | border: "none" 40 | } 41 | 42 | export { Container, Link, Button, darkColors, lightColors } 43 | -------------------------------------------------------------------------------- /fab-dev/src/FAB/css/FAB.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Roboto:100,200,300,400,500); 2 | 3 | :root { 4 | --tooltip-backcolor: #424242; 5 | --tooltip-forecolor: #FAFAFA; 6 | } 7 | 8 | .fab-container { 9 | bottom: 10vh; 10 | position: fixed; 11 | margin: 1em; 12 | right: 8vw; 13 | } 14 | 15 | .fab-item { 16 | box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); 17 | border-radius: 50%; 18 | border-style: none; 19 | display: flex; 20 | justify-content: center; 21 | align-items: center; 22 | width: 56px; 23 | height: 56px; 24 | margin: 20px auto 0; 25 | position: relative; 26 | -webkit-transition: transform .1s ease-out, height 100ms ease, opacity 100ms ease; 27 | transition: transform .1s ease-out, height 100ms ease, opacity 100ms ease; 28 | text-decoration: none; 29 | } 30 | 31 | .fab-item:active, 32 | .fab-item:focus, 33 | .fab-item:hover { 34 | box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); 35 | transition: box-shadow .2s ease; 36 | outline: none; 37 | } 38 | 39 | .fab-item:not(:last-child) { 40 | width: 40px; 41 | height: 0px; 42 | margin: 0px auto 0; 43 | opacity: 0; 44 | -webkit-transform: translateY(50px); 45 | -ms-transform: translateY(50px); 46 | transform: translateY(50px); 47 | } 48 | 49 | .fab-container:hover 50 | .fab-item:not(:last-child) { 51 | height: 40px; 52 | opacity: 1; 53 | -webkit-transform: none; 54 | -ms-transform: none; 55 | transform: none; 56 | margin: 15px auto 0; 57 | } 58 | 59 | .fab-item:not(:last-child) i{ 60 | opacity: 0; 61 | } 62 | 63 | .fab-container:hover 64 | .fab-item:not(:last-child) i { 65 | opacity: 1; 66 | } 67 | 68 | .fab-item:nth-last-child(1) { 69 | -webkit-transition-delay: 25ms; 70 | transition-delay: 25ms; 71 | background-size: contain; 72 | } 73 | 74 | .fab-item:not(:last-child):nth-last-child(2) { 75 | -webkit-transition-delay: 50ms; 76 | transition-delay: 20ms; 77 | background-size: contain; 78 | } 79 | 80 | .fab-item:not(:last-child):nth-last-child(3) { 81 | -webkit-transition-delay: 75ms; 82 | transition-delay: 40ms; 83 | background-size: contain; 84 | } 85 | 86 | .fab-item:not(:last-child):nth-last-child(4) { 87 | -webkit-transition-delay: 100ms; 88 | transition-delay: 60ms; 89 | background-size: contain; 90 | } 91 | 92 | [tooltip]:before { 93 | bottom: 25%; 94 | font-family: arial; 95 | font-weight: 600; 96 | border-radius: 2px; 97 | background: var(--tooltip-backcolor); 98 | color: var(--tooltip-forecolor); 99 | content: attr(tooltip); 100 | font-size: 12px; 101 | visibility: hidden; 102 | opacity: 0; 103 | padding: 5px 7px; 104 | margin-right: 12px; 105 | position: absolute; 106 | right: 100%; 107 | white-space: nowrap; 108 | } 109 | 110 | [tooltip]:hover:before, 111 | [tooltip]:hover:after { 112 | visibility: visible; 113 | opacity: 1; 114 | transition: opacity .1s ease-in-out; 115 | } 116 | 117 | .fab-item:nth-last-child(1)[tooltip]:hover:before, 118 | .fab-item:nth-last-child(1)[tooltip]:hover:after { 119 | transition: opacity .1s step-end; 120 | } 121 | 122 | .fab-item.fab-rotate:active, 123 | .fab-item.fab-rotate:focus, 124 | .fab-item.fab-rotate:hover 125 | { 126 | transform: rotate(45deg); 127 | box-shadow: 5px 5px 20px rgba(0,0,0,0.19), 3px 3px 6px rgba(0,0,0,0.23); 128 | transition: box-shadow .2s ease, transform .1s ease; 129 | outline: none; 130 | } 131 | 132 | .fab-item.fab-rotate:nth-last-child(1)[tooltip]:hover:before, 133 | .fab-item.fab-rotate:nth-last-child(1)[tooltip]:hover:after 134 | { 135 | transform: rotate(-45deg); 136 | bottom: -60%; 137 | right: 60%; 138 | } 139 | -------------------------------------------------------------------------------- /fab-dev/src/FAB/js/MaterialColors.js: -------------------------------------------------------------------------------- 1 | const lightColors = { 2 | red: "#ffcdd2", 3 | pink: "#f8bbd0", 4 | purple: "#e1bee7", 5 | lightBlue: "#81d4fa", 6 | cyan: "#80deea", 7 | teal: "#80cbc4", 8 | blue: "#bbdefb", 9 | green: "#dcedc8", 10 | yellow: "#fff9c4", 11 | orange: "#ffe0b2", 12 | brown: "#d7ccc8", 13 | grey:"#e0e0e0", 14 | darkerGrey: "#bdbdbd", 15 | black: "#212121", 16 | white: "#f5f5f5" 17 | } 18 | 19 | const darkColors = { 20 | lighterRed: "#f44336", 21 | red: "#c62828", 22 | pink: "#ad1457", 23 | purple: "#6a1b9a", 24 | lightBlue: "#01579b", 25 | cyan: "#00838f", 26 | teal: "#00695c", 27 | blue: "#0d47a1", 28 | green: "#1b5e20", 29 | yellow: "#f9a825", 30 | orange: "#e65100", 31 | brown: "#4e342e", 32 | grey:"#424242", 33 | black: "#212121", 34 | white: "#fafafa" 35 | } 36 | 37 | export {darkColors, lightColors} -------------------------------------------------------------------------------- /fab-dev/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /fab-dev/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: http://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /fab-dev/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fab-dev/src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read http://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit http://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See http://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /img/FAB-Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gustavo-Kuze/React-Floating-Action-Button/62ebe55c954fa23d74fca6a20986a2c92f3e3d6e/img/FAB-Demo.gif -------------------------------------------------------------------------------- /lib/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ], 6 | "plugins": [ 7 | "transform-object-rest-spread", 8 | "transform-react-jsx" 9 | ] 10 | } -------------------------------------------------------------------------------- /lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-floating-action-button", 3 | "version": "1.0.1", 4 | "description": "A simple Android like FAB Component for React", 5 | "main": "build/index.js", 6 | "scripts": { 7 | "start": "webpack --watch", 8 | "build": "webpack" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/Gustavo-Kuze/React-Floating-Action-Button" 13 | }, 14 | "peerDependencies": { 15 | "react": "^16.4.0" 16 | }, 17 | "keywords": [], 18 | "author": "Gustavo Kuze da Silva", 19 | "license": "MIT", 20 | "dependencies": { 21 | "react": "^16.8.3" 22 | }, 23 | "devDependencies": { 24 | "webpack": "^4.29.6", 25 | "@babel/core": "^7.3.4", 26 | "@babel/preset-env": "^7.3.4", 27 | "@babel/preset-react": "^7.0.0", 28 | "babel-cli": "^6.26.0", 29 | "babel-core": "^6.26.3", 30 | "babel-loader": "^8.0.5", 31 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 32 | "babel-plugin-transform-react-jsx": "^6.24.1", 33 | "babel-preset-env": "^1.7.0", 34 | "babel-preset-es2015": "^6.24.1", 35 | "css-loader": "^2.1.0", 36 | "style-loader": "^0.23.1", 37 | "webpack-cli": "^3.2.3" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/publish/FAB-Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gustavo-Kuze/React-Floating-Action-Button/62ebe55c954fa23d74fca6a20986a2c92f3e3d6e/lib/publish/FAB-Demo.gif -------------------------------------------------------------------------------- /lib/publish/README.md: -------------------------------------------------------------------------------- 1 | # React-Floating-Action-Button 2 | A dead simple React component that works similar to Android's Action Button 3 | 4 | 5 | ![FAB Demo GIF](https://media.giphy.com/media/1yMfOTxGP7fvhqccXp/giphy.gif "FAB Demo") 6 | 7 | ___ 8 | 9 | ### Getting Started 10 | 1. First, You need to install It, just like You would do with most any NPM packages: 11 | ``` 12 | npm i --save react-floating-action-button 13 | ``` 14 | 15 | 2. Then, You need to import the library component within your own component 16 | ``` javascript 17 | import React from 'react' 18 | import { Container, Button, Link } from 'react-floating-action-button' 19 | ``` 20 | 21 | 3. You can now start using the FAB components! 22 | ``` javascript 23 | export default const YourAwesomeComponent = () => { 24 | return ( 25 | 26 | 29 | 32 | className="fab-item btn btn-link btn-lg text-white" 33 | 21 | ) 22 | } 23 | 24 | const Link = props => { 25 | return ( 26 | 29 | 30 | {props.children} 31 | 32 | ) 33 | } 34 | 35 | const defaultItemStyles = { 36 | backgroundColor: darkColors.lighterRed, 37 | color: darkColors.white, 38 | textDecoration: "none", 39 | border: "none" 40 | } 41 | 42 | export { Container, Link, Button, darkColors, lightColors } 43 | -------------------------------------------------------------------------------- /lib/src/js/MaterialColors.js: -------------------------------------------------------------------------------- 1 | const lightColors = { 2 | red: "#ffcdd2", 3 | pink: "#f8bbd0", 4 | purple: "#e1bee7", 5 | lightBlue: "#81d4fa", 6 | cyan: "#80deea", 7 | teal: "#80cbc4", 8 | blue: "#bbdefb", 9 | green: "#dcedc8", 10 | yellow: "#fff9c4", 11 | orange: "#ffe0b2", 12 | brown: "#d7ccc8", 13 | grey:"#e0e0e0", 14 | darkerGrey: "#bdbdbd", 15 | black: "#212121", 16 | white: "#f5f5f5" 17 | } 18 | 19 | const darkColors = { 20 | lighterRed: "#f44336", 21 | red: "#c62828", 22 | pink: "#ad1457", 23 | purple: "#6a1b9a", 24 | lightBlue: "#01579b", 25 | cyan: "#00838f", 26 | teal: "#00695c", 27 | blue: "#0d47a1", 28 | green: "#1b5e20", 29 | yellow: "#f9a825", 30 | orange: "#e65100", 31 | brown: "#4e342e", 32 | grey:"#424242", 33 | black: "#212121", 34 | white: "#fafafa" 35 | } 36 | 37 | export {darkColors, lightColors} -------------------------------------------------------------------------------- /lib/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | module.exports = { 3 | entry: './src/index.js', 4 | output: { 5 | path: path.resolve(__dirname, 'build'), 6 | filename: 'index.js', 7 | libraryTarget: 'commonjs2' 8 | }, 9 | module: { 10 | rules: [ 11 | { 12 | test: /\.jsx?$/, 13 | include: path.resolve(__dirname, 'src'), 14 | exclude: /(node_modules|bower_components|build)/, 15 | use: { 16 | loader: 'babel-loader', 17 | options: { 18 | "presets": [ 19 | [ 20 | "@babel/preset-react", 21 | { 22 | "pragma": "dom", // default pragma is React.createElement 23 | "pragmaFrag": "DomFrag", // default is React.Fragment 24 | "throwIfNamespace": false // defaults to true 25 | } 26 | ] 27 | ] 28 | } 29 | } 30 | }, 31 | { 32 | test: /\.css$/, 33 | use: ['style-loader', 'css-loader'], 34 | } 35 | ] 36 | }, 37 | externals: { 38 | 'react': 'commonjs react' 39 | } 40 | }; --------------------------------------------------------------------------------