├── src ├── version.json ├── demo │ ├── logo.png │ ├── index.js │ ├── App.css │ ├── registerServiceWorker.js │ └── App.js └── lib │ ├── components │ ├── View │ │ ├── index.js │ │ └── View.jsx │ └── Layout │ │ ├── VerticalLayout.jsx │ │ ├── HorizontalLayout.jsx │ │ ├── index.js │ │ ├── Spacer.jsx │ │ ├── Separator.jsx │ │ ├── Panel.jsx │ │ └── Layout.jsx │ └── index.js ├── public ├── logo.png ├── favicon.ico ├── manifest.json ├── index.html └── logo.svg ├── .gitignore ├── config ├── jest │ ├── fileTransform.js │ └── cssTransform.js ├── polyfills.js ├── paths.js ├── env.js ├── webpackDevServer.config.js ├── webpack.config.prod.js ├── webpack.config.dev.js └── webpack.config.demo.js ├── scripts ├── test.js ├── start.js ├── build.js └── demo.js ├── LICENSE ├── package.json └── README.md /src/version.json: -------------------------------------------------------------------------------- 1 | { 2 | "number": "0.9.0" 3 | } 4 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekros/nice-react-layout/HEAD/public/logo.png -------------------------------------------------------------------------------- /src/demo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekros/nice-react-layout/HEAD/src/demo/logo.png -------------------------------------------------------------------------------- /src/lib/components/View/index.js: -------------------------------------------------------------------------------- 1 | import View from "./View.jsx"; 2 | 3 | export { View }; 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekros/nice-react-layout/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/lib/components/Layout/VerticalLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Layout from "./Layout.jsx"; 3 | 4 | const VerticalLayout = ({ ...props }) => { 5 | return ; 6 | }; 7 | 8 | export default VerticalLayout; 9 | -------------------------------------------------------------------------------- /src/demo/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | import registerServiceWorker from './registerServiceWorker'; 5 | 6 | ReactDOM.render(, document.getElementById('root')); 7 | registerServiceWorker(); 8 | -------------------------------------------------------------------------------- /src/lib/components/Layout/HorizontalLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Layout from "./Layout.jsx"; 3 | 4 | const HorizontalLayout = ({ ...props }) => { 5 | return ; 6 | }; 7 | 8 | export default HorizontalLayout; 9 | -------------------------------------------------------------------------------- /src/demo/App.css: -------------------------------------------------------------------------------- 1 | body { 2 | display: flex; 3 | justify-content: center; 4 | margin: 0; 5 | } 6 | 7 | li > a { 8 | color: gray; 9 | text-decoration: none; 10 | } 11 | 12 | li > a.is-active { 13 | color: black; 14 | font-weight: bold; 15 | } 16 | 17 | li > a:hover { 18 | color: #222222; 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # production 7 | /demo 8 | 9 | # testing 10 | /coverage 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /config/jest/fileTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | // This is a custom Jest transformer turning file imports into filenames. 6 | // http://facebook.github.io/jest/docs/tutorial-webpack.html 7 | 8 | module.exports = { 9 | process(src, filename) { 10 | return `module.exports = ${JSON.stringify(path.basename(filename))};`; 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This is a custom Jest transformer turning style imports into empty objects. 4 | // http://facebook.github.io/jest/docs/tutorial-webpack.html 5 | 6 | module.exports = { 7 | process() { 8 | return 'module.exports = {};'; 9 | }, 10 | getCacheKey() { 11 | // The output is always the same. 12 | return 'cssTransform'; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /src/lib/components/Layout/index.js: -------------------------------------------------------------------------------- 1 | import Layout from "./Layout.jsx"; 2 | import HorizontalLayout from "./HorizontalLayout.jsx"; 3 | import VerticalLayout from "./VerticalLayout.jsx"; 4 | import Panel from "./Panel.jsx"; 5 | import Separator from "./Separator.jsx"; 6 | import Spacer from "./Spacer.jsx"; 7 | 8 | export { 9 | Layout, 10 | HorizontalLayout, 11 | VerticalLayout, 12 | Panel, 13 | Separator, 14 | Spacer, 15 | }; 16 | -------------------------------------------------------------------------------- /src/lib/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | Layout, 3 | HorizontalLayout, 4 | VerticalLayout, 5 | Panel, 6 | Separator, 7 | Spacer, 8 | FormLayout, 9 | TableLayout 10 | } from "./components/Layout"; 11 | import { View } from "./components/View"; 12 | 13 | export { 14 | Layout, 15 | HorizontalLayout, 16 | VerticalLayout, 17 | Panel, 18 | Separator, 19 | Spacer, 20 | FormLayout, 21 | TableLayout, 22 | View, 23 | }; 24 | -------------------------------------------------------------------------------- /src/lib/components/View/View.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const View = ({ children, width, height }) => { 5 | const styles = { 6 | view: { 7 | width, 8 | height, 9 | } 10 | }; 11 | return ( 12 |
{children}
13 | ); 14 | }; 15 | 16 | View.propTypes = { 17 | children: PropTypes.node, 18 | width: PropTypes.string, 19 | height: PropTypes.string, 20 | }; 21 | 22 | View.defaultProps = { 23 | width: "100vw", 24 | height: "100vh", 25 | }; 26 | 27 | export default View; 28 | -------------------------------------------------------------------------------- /src/lib/components/Layout/Spacer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Panel from './Panel.jsx'; 4 | 5 | const Spacer = ({ orientation, size }) => { 6 | return ( 7 | 13 | ); 14 | }; 15 | 16 | Spacer.propTypes = { 17 | name: PropTypes.string, 18 | orientation: PropTypes.string, 19 | size: PropTypes.number, 20 | }; 21 | 22 | Spacer.defaultProps = { 23 | name: "spacer", 24 | }; 25 | 26 | export default Spacer; 27 | -------------------------------------------------------------------------------- /scripts/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Do this as the first thing so that any code reading it knows the right env. 4 | process.env.BABEL_ENV = 'test'; 5 | process.env.NODE_ENV = 'test'; 6 | process.env.PUBLIC_URL = ''; 7 | 8 | // Makes the script crash on unhandled rejections instead of silently 9 | // ignoring them. In the future, promise rejections that are not handled will 10 | // terminate the Node.js process with a non-zero exit code. 11 | process.on('unhandledRejection', err => { 12 | throw err; 13 | }); 14 | 15 | // Ensure environment variables are read. 16 | require('../config/env'); 17 | 18 | const jest = require('jest'); 19 | const argv = process.argv.slice(2); 20 | 21 | // Watch unless on CI or in coverage mode 22 | if (!process.env.CI && argv.indexOf('--coverage') < 0) { 23 | argv.push('--watch'); 24 | } 25 | 26 | 27 | jest.run(argv); 28 | -------------------------------------------------------------------------------- /config/polyfills.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (typeof Promise === 'undefined') { 4 | // Rejection tracking prevents a common issue where React gets into an 5 | // inconsistent state due to an error, but it gets swallowed by a Promise, 6 | // and the user has no idea what causes React's erratic future behavior. 7 | require('promise/lib/rejection-tracking').enable(); 8 | window.Promise = require('promise/lib/es6-extensions.js'); 9 | } 10 | 11 | // fetch() polyfill for making API calls. 12 | require('whatwg-fetch'); 13 | 14 | // Object.assign() is commonly used with React. 15 | // It will use the native implementation if it's present and isn't buggy. 16 | Object.assign = require('object-assign'); 17 | 18 | // In tests, polyfill requestAnimationFrame since jsdom doesn't provide it yet. 19 | // We don't polyfill it in the browser--this is user's responsibility. 20 | if (process.env.NODE_ENV === 'test') { 21 | require('raf').polyfill(global); 22 | } 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Eric Ros 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 | -------------------------------------------------------------------------------- /src/lib/components/Layout/Separator.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | 4 | const Separator = ({ 5 | defaultDblClickPos, 6 | disabled, 7 | layoutIndex, 8 | onSeparatorDoubleClick, 9 | onSeparatorMouseDown, 10 | orientation, 11 | customCss, 12 | }) => { 13 | const styles = { 14 | horizontalSeparator: { 15 | display: "inline-block", 16 | width: "100%", 17 | height: "3px", 18 | background: "hsl(0, 0%, 80%)", 19 | cursor: disabled ? "not-allowed" : "row-resize", 20 | }, 21 | verticalSeparator: { 22 | display: "inline-block", 23 | width: "3px", 24 | height: "100%", 25 | background: "hsl(0, 0%, 80%)", 26 | cursor: disabled ? "not-allowed" : "col-resize", 27 | }, 28 | }; 29 | return ( 30 |
onSeparatorMouseDown(layoutIndex)} 39 | onDoubleClick={ 40 | disabled 41 | ? null 42 | : () => onSeparatorDoubleClick(layoutIndex, defaultDblClickPos) 43 | } 44 | /> 45 | ); 46 | }; 47 | 48 | Separator.propTypes = { 49 | id: PropTypes.string, // internal use only 50 | defaultDblClickPos: PropTypes.number, 51 | disabled: PropTypes.bool, 52 | layoutIndex: PropTypes.number, 53 | onSeparatorDoubleClick: PropTypes.func, 54 | onSeparatorMouseDown: PropTypes.func, 55 | orientation: PropTypes.string, 56 | customCss: PropTypes.object, 57 | }; 58 | 59 | Separator.defaultProps = { 60 | id: "separator" 61 | }; 62 | 63 | export default Separator; 64 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 21 | Nice React Layout Demo 22 | 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /config/paths.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | const url = require('url'); 6 | 7 | // Make sure any symlinks in the project folder are resolved: 8 | // https://github.com/facebookincubator/create-react-app/issues/637 9 | const appDirectory = fs.realpathSync(process.cwd()); 10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath); 11 | 12 | const envPublicUrl = process.env.PUBLIC_URL; 13 | 14 | function ensureSlash(path, needsSlash) { 15 | const hasSlash = path.endsWith('/'); 16 | if (hasSlash && !needsSlash) { 17 | return path.substr(path, path.length - 1); 18 | } else if (!hasSlash && needsSlash) { 19 | return `${path}/`; 20 | } else { 21 | return path; 22 | } 23 | } 24 | 25 | const getPublicUrl = appPackageJson => 26 | envPublicUrl || require(appPackageJson).homepage; 27 | 28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer 29 | // "public path" at which the app is served. 30 | // Webpack needs to know it to put the right