├── .babelrc ├── .bumpedrc ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── .nvmrc ├── .travis.yml ├── README.md ├── doc ├── .babelrc ├── app │ ├── components │ │ ├── _colors.scss │ │ ├── _globals.scss │ │ ├── _mixins.scss │ │ ├── box │ │ │ ├── index.jsx │ │ │ └── style.scss │ │ ├── button │ │ │ ├── index.jsx │ │ │ └── style.scss │ │ ├── hero │ │ │ ├── index.jsx │ │ │ └── style.scss │ │ ├── home │ │ │ ├── align-bottom.md │ │ │ ├── align-center.md │ │ │ ├── align-end.md │ │ │ ├── align-middle.md │ │ │ ├── align-start.md │ │ │ ├── align-top.md │ │ │ ├── auto-width.md │ │ │ ├── dist-around.md │ │ │ ├── dist-between.md │ │ │ ├── fluid.md │ │ │ ├── index.jsx │ │ │ ├── offset.md │ │ │ ├── responsive.md │ │ │ └── style.scss │ │ ├── markdown │ │ │ ├── index.jsx │ │ │ └── style.scss │ │ └── section │ │ │ ├── index.jsx │ │ │ └── style.scss │ └── index.jsx ├── package.json ├── server.js ├── webpack.config.development.js ├── webpack.config.production.js └── www │ ├── images │ └── logo.png │ ├── index.html │ └── other │ └── CNAME ├── karma.conf.js ├── package.json ├── react-flexbox-grid.d.ts ├── server.js ├── spec ├── index.html ├── index.js ├── root.js └── stylesheets │ ├── base.scss │ ├── modules │ └── box.scss │ └── utilities │ ├── font.scss │ └── reset.scss ├── src ├── classNames.js ├── components │ ├── Col.js │ ├── Grid.js │ └── Row.js ├── createProps.js ├── index.js └── types.js ├── test ├── .eslintrc ├── classNames.spec.js ├── components │ ├── Col.spec.js │ ├── Grid.spec.js │ └── Row.spec.js ├── index.spec.js ├── react-flexbox-grid-test.tsx ├── reactErrors.js └── setup.js ├── tests.webpack.js ├── webpack.config.development.js ├── webpack.config.js ├── webpack.config.production.js ├── webpack.config.test.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "env", 4 | "stage-1", 5 | "react" 6 | ] 7 | } -------------------------------------------------------------------------------- /.bumpedrc: -------------------------------------------------------------------------------- 1 | files: [ 2 | 'package.json' 3 | ] 4 | 5 | plugins: 6 | 7 | prerelease: 8 | 9 | 'Linting config files': 10 | plugin: 'bumped-finepack' 11 | 12 | 'Lint-ing project files': 13 | plugin: 'bumped-terminal' 14 | command: 'npm run lint' 15 | 16 | 'Preparing build': 17 | plugin: 'bumped-terminal' 18 | command: 'npm run prepublish' 19 | 20 | postrelease: 21 | 22 | 'Committing new version': 23 | plugin: 'bumped-terminal' 24 | command: 'git add package.json && git commit package.json -m "v$newVersion release" && git push origin master' 25 | 26 | 'Publishing tag at Github': 27 | plugin: 'bumped-terminal' 28 | command: 'git tag v$newVersion && git push origin v$newVersion' 29 | 30 | 'Publishing at NPM': 31 | plugin: 'bumped-terminal' 32 | command: 'npm publish' 33 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [Makefile] 13 | indent_style = tab 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | lib 2 | dist 3 | node_modules 4 | coverage 5 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb", 3 | "env": { 4 | "browser": true, 5 | "node": true, 6 | "es6": true 7 | }, 8 | "ecmaFeatures": { 9 | "jsx": true, 10 | "templateStrings": true, 11 | "superInFunctions": false, 12 | "classes": true, 13 | "modules": true 14 | }, 15 | "rules": { 16 | "comma-dangle": 0, 17 | "react/jsx-uses-react": 2, 18 | "react/jsx-uses-vars": 2, 19 | "react/react-in-jsx-scope": 2 20 | }, 21 | "parser": "babel-eslint", 22 | "plugins": [ 23 | "react" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | lib 3 | dist 4 | node_modules 5 | npm-debug.log 6 | .idea 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | doc 2 | spec 3 | test 4 | 5 | node_modules 6 | .idea 7 | .travis.yml 8 | .gitignore 9 | .circle.yml 10 | .wercker.yml 11 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | stable -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "stable" 4 | script: 5 | - npm run lint 6 | - npm test 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-flexbox-grid 2 | [![npm version](https://badge.fury.io/js/react-flexbox-grid.svg)](https://badge.fury.io/js/react-flexbox-grid) 3 | [![Build Status](https://travis-ci.org/roylee0704/react-flexbox-grid.svg)](https://travis-ci.org/roylee0704/react-flexbox-grid) 4 | [![NPM Status](http://img.shields.io/npm/dm/react-flexbox-grid.svg?style=flat)](https://www.npmjs.org/package/react-flexbox-grid) 5 | 6 | 7 | `react-flexbox-grid` is a set of React components that implement [flexboxgrid.css](https://goo.gl/imrHBZ). It even has an optional support for [CSS Modules](https://github.com/webpack-contrib/css-loader#css-modules) with some extra configuration. 8 | 9 | 10 | **http://roylee0704.github.io/react-flexbox-grid/** 11 | 12 | 13 | Setup 14 | ----- 15 | 16 | ### Installation 17 | 18 | `react-flexbox-grid` can be installed as an [npm package](https://www.npmjs.com/package/react-flexbox-grid): 19 | 20 | ``` 21 | npm install --save react-flexbox-grid 22 | ``` 23 | 24 | ### Minimal configuration 25 | 26 | The recommended way to use `react-flexbox-grid` is with a tool like [webpack](https://webpack.js.org/) or [Meteor](https://www.meteor.com/), make sure you set it up to support requiring CSS files. For example, the minimum required loader configuration for webpack would look like this: 27 | 28 | ```js 29 | { 30 | test: /\.css$/, 31 | loader: 'style-loader!css-loader', 32 | include: /flexboxgrid/ 33 | } 34 | ``` 35 | 36 | `react-flexbox-grid` imports the styles from `flexboxgrid`, that's why we're configuring the loader for it. 37 | 38 | ### CSS Modules 39 | 40 | If you want to use CSS Modules (this is _mandatory_ for versions earlier than v1), webpack's [`css-loader`](https://github.com/webpack-contrib/css-loader) supports this by passing `modules` param in the loader configuration. 41 | 42 | First, install `style-loader` and `css-loader` as development dependencies: 43 | 44 | ``` 45 | npm install --save-dev style-loader css-loader 46 | ``` 47 | 48 | Next, add a loader for `flexboxgrid` with CSS Modules enabled: 49 | 50 | ```js 51 | { 52 | test: /\.css$/, 53 | loader: 'style-loader!css-loader?modules', 54 | include: /flexboxgrid/ 55 | } 56 | ``` 57 | 58 | Make sure you don't have another CSS loader which also affects `flexboxgrid`. In case you do, exclude `flexboxgrid`, for example: 59 | 60 | ```js 61 | { 62 | test: /\.css$/, 63 | loader: 'style-loader!css-loader!postcss-loader', 64 | include: path.join(__dirname, 'node_modules'), // oops, this also includes flexboxgrid 65 | exclude: /flexboxgrid/ // so we have to exclude it 66 | } 67 | ``` 68 | 69 | Otherwise you would end up with an [obscure error](https://github.com/roylee0704/react-flexbox-grid/issues/94#issuecomment-282825720) because webpack stacks loaders together, it doesn't override them. 70 | 71 | ### Isomorphic support 72 | 73 | Try: [this comment](https://github.com/roylee0704/react-flexbox-grid/issues/28#issuecomment-198758253). 74 | 75 | If this doesn't work for you, use the build located in the dist directory. This build removes all `.css` imports and extracts the relevant css into `react-flexbox-grid/dist/react-flexbox-grid.css`. 76 | 77 | ### Not using a bundler? 78 | 79 | Use the pre-bundled build located in the dist directory. It contains a single umd js distributable and built css file. 80 | 81 | Usage 82 | ----- 83 | 84 | Now you can import and use the components: 85 | 86 | ```jsx 87 | import React from 'react'; 88 | import { Grid, Row, Col } from 'react-flexbox-grid'; 89 | 90 | class App extends React.Component { 91 | render() { 92 | return ( 93 | 94 | 95 | 96 | Hello, world! 97 | 98 | 99 | 100 | ); 101 | } 102 | } 103 | ``` 104 | 105 | ### Gotcha 106 | 107 | For the time being always use `fluid` for `` to prevent [horizontal overflow issues](https://github.com/kristoferjoseph/flexboxgrid/issues/144). 108 | 109 | 110 | Example 111 | ------- 112 | Looking for a complete example? Head over to [react-flexbox-grid-example](https://github.com/roylee0704/react-flexbox-grid-example). 113 | 114 | 115 | Advanced composition 116 | ------- 117 | 118 | We also export functions for generating Row and Column class names for use in other components. 119 | 120 | For example, suppose you're using a third party component that accepts `className` and you would like it to be rendered as `Col`. You could do so by extracting the column sizing props that `MyComponent` uses and then pass the generated className on to `SomeComponent` 121 | 122 | 123 | ```jsx 124 | import React from 'react'; 125 | import { Row, Col, getRowProps, getColumnProps } from 'react-flexbox-grid'; 126 | // a component that accepts a className 127 | import SomeComponent from 'some-package'; 128 | 129 | export default function MyComponent(props) { 130 | const colProps = getColumnProps(props); 131 | const rowProps = getRowProps(props); 132 | 133 | return ( 134 |
135 | 136 | 137 | 138 | ); 139 | } 140 | 141 | MyComponent.propTypes = Object.assign({ 142 | onChange: React.PropTypes.func.isRequired, 143 | value: React.PropTypes.string.isRequired, 144 | }, Col.propTypes, Row.propTypes); // Re-use existing Row and Col propType validations 145 | 146 | // Can now be rendered as: 147 | ``` 148 | 149 | Contributors 150 | ----------- 151 | [![Roy Lee](https://avatars0.githubusercontent.com/u/3850661?v=3&s=144)](https://github.com/roylee0704/) | [![Helder Santana](https://avatars1.githubusercontent.com/u/134727?v=3&s=144)](https://github.com/heldr/) | [![Matija Marohnić](https://avatars2.githubusercontent.com/u/471278?v=3&s=144)](https://github.com/silvenon) 152 | ---|---|--- 153 | [Roy Lee](https://github.com/roylee0704) | [Helder Santana](https://github.com/heldr/) | [Matija Marohnić](https://github.com/silvenon) 154 | 155 | License 156 | ------- 157 | MIT 158 | -------------------------------------------------------------------------------- /doc/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015-loose", "stage-0", "react"], 3 | "env": { 4 | "development": { 5 | "presets": ["react-hmre"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /doc/app/components/_colors.scss: -------------------------------------------------------------------------------- 1 | //-- Color definitions taken from Material Design Lite 2 | 3 | // Red 4 | $palette-red-50: rgb(255,235,238); 5 | $palette-red-100: rgb(255,205,210); 6 | $palette-red-200: rgb(239,154,154); 7 | $palette-red-300: rgb(229,115,115); 8 | $palette-red-400: rgb(239,83,80); 9 | $palette-red-500: rgb(244,67,54); 10 | $palette-red-600: rgb(229,57,53); 11 | $palette-red-700: rgb(211,47,47); 12 | $palette-red-800: rgb(198,40,40); 13 | $palette-red-900: rgb(183,28,28); 14 | $palette-red-a100: rgb(255,138,128); 15 | $palette-red-a200: rgb(255,82,82); 16 | $palette-red-a400: rgb(255,23,68); 17 | $palette-red-a700: rgb(213,0,0); 18 | 19 | // Pink 20 | $palette-pink-50: rgb(252,228,236); 21 | $palette-pink-100: rgb(248,187,208); 22 | $palette-pink-200: rgb(244,143,177); 23 | $palette-pink-300: rgb(240,98,146); 24 | $palette-pink-400: rgb(236,64,122); 25 | $palette-pink-500: rgb(233,30,99); 26 | $palette-pink-600: rgb(216,27,96); 27 | $palette-pink-700: rgb(194,24,91); 28 | $palette-pink-800: rgb(173,20,87); 29 | $palette-pink-900: rgb(136,14,79); 30 | $palette-pink-a100: rgb(255,128,171); 31 | $palette-pink-a200: rgb(255,64,129); 32 | $palette-pink-a400: rgb(245,0,87); 33 | $palette-pink-a700: rgb(197,17,98); 34 | 35 | // Purple 36 | $palette-purple-50: rgb(243,229,245); 37 | $palette-purple-100: rgb(225,190,231); 38 | $palette-purple-200: rgb(206,147,216); 39 | $palette-purple-300: rgb(186,104,200); 40 | $palette-purple-400: rgb(171,71,188); 41 | $palette-purple-500: rgb(156,39,176); 42 | $palette-purple-600: rgb(142,36,170); 43 | $palette-purple-700: rgb(123,31,162); 44 | $palette-purple-800: rgb(106,27,154); 45 | $palette-purple-900: rgb(74,20,140); 46 | $palette-purple-a100: rgb(234,128,252); 47 | $palette-purple-a200: rgb(224,64,251); 48 | $palette-purple-a400: rgb(213,0,249); 49 | $palette-purple-a700: rgb(170,0,255); 50 | 51 | //Deep Purple 52 | $palette-deep-purple-50: rgb(237,231,246); 53 | $palette-deep-purple-100: rgb(209,196,233); 54 | $palette-deep-purple-200: rgb(179,157,219); 55 | $palette-deep-purple-300: rgb(149,117,205); 56 | $palette-deep-purple-400: rgb(126,87,194); 57 | $palette-deep-purple-500: rgb(103,58,183); 58 | $palette-deep-purple-600: rgb(94,53,177); 59 | $palette-deep-purple-700: rgb(81,45,168); 60 | $palette-deep-purple-800: rgb(69,39,160); 61 | $palette-deep-purple-900: rgb(49,27,146); 62 | $palette-deep-purple-a100: rgb(179,136,255); 63 | $palette-deep-purple-a200: rgb(124,77,255); 64 | $palette-deep-purple-a400: rgb(101,31,255); 65 | $palette-deep-purple-a700: rgb(98,0,234); 66 | 67 | // Indigo 68 | $palette-indigo-50: rgb(232,234,246); 69 | $palette-indigo-100: rgb(197,202,233); 70 | $palette-indigo-200: rgb(159,168,218); 71 | $palette-indigo-300: rgb(121,134,203); 72 | $palette-indigo-400: rgb(92,107,192); 73 | $palette-indigo-500: rgb(63,81,181); 74 | $palette-indigo-600: rgb(57,73,171); 75 | $palette-indigo-700: rgb(48,63,159); 76 | $palette-indigo-800: rgb(40,53,147); 77 | $palette-indigo-900: rgb(26,35,126); 78 | $palette-indigo-a100: rgb(140,158,255); 79 | $palette-indigo-a200: rgb(83,109,254); 80 | $palette-indigo-a400: rgb(61,90,254); 81 | $palette-indigo-a700: rgb(48,79,254); 82 | 83 | // Blue 84 | $palette-blue-50: rgb(227,242,253); 85 | $palette-blue-100: rgb(187,222,251); 86 | $palette-blue-200: rgb(144,202,249); 87 | $palette-blue-300: rgb(100,181,246); 88 | $palette-blue-400: rgb(66,165,245); 89 | $palette-blue-500: rgb(33,150,243); 90 | $palette-blue-600: rgb(30,136,229); 91 | $palette-blue-700: rgb(25,118,210); 92 | $palette-blue-800: rgb(21,101,192); 93 | $palette-blue-900: rgb(13,71,161); 94 | $palette-blue-a100: rgb(130,177,255); 95 | $palette-blue-a200: rgb(68,138,255); 96 | $palette-blue-a400: rgb(41,121,255); 97 | $palette-blue-a700: rgb(41,98,255); 98 | 99 | // Light Blue 100 | $palette-light-blue-50: rgb(225,245,254); 101 | $palette-light-blue-100: rgb(179,229,252); 102 | $palette-light-blue-200: rgb(129,212,250); 103 | $palette-light-blue-300: rgb(79,195,247); 104 | $palette-light-blue-400: rgb(41,182,246); 105 | $palette-light-blue-500: rgb(3,169,244); 106 | $palette-light-blue-600: rgb(3,155,229); 107 | $palette-light-blue-700: rgb(2,136,209); 108 | $palette-light-blue-800: rgb(2,119,189); 109 | $palette-light-blue-900: rgb(1,87,155); 110 | $palette-light-blue-a100: rgb(128,216,255); 111 | $palette-light-blue-a200: rgb(64,196,255); 112 | $palette-light-blue-a400: rgb(0,176,255); 113 | $palette-light-blue-a700: rgb(0,145,234); 114 | 115 | // Cyan 116 | $palette-cyan-50: rgb(224,247,250); 117 | $palette-cyan-100: rgb(178,235,242); 118 | $palette-cyan-200: rgb(128,222,234); 119 | $palette-cyan-300: rgb(77,208,225); 120 | $palette-cyan-400: rgb(38,198,218); 121 | $palette-cyan-500: rgb(0,188,212); 122 | $palette-cyan-600: rgb(0,172,193); 123 | $palette-cyan-700: rgb(0,151,167); 124 | $palette-cyan-800: rgb(0,131,143); 125 | $palette-cyan-900: rgb(0,96,100); 126 | $palette-cyan-a100: rgb(132,255,255); 127 | $palette-cyan-a200: rgb(24,255,255); 128 | $palette-cyan-a400: rgb(0,229,255); 129 | $palette-cyan-a700: rgb(0,184,212); 130 | 131 | // Teal 132 | $palette-teal-50: rgb(224,242,241); 133 | $palette-teal-100: rgb(178,223,219); 134 | $palette-teal-200: rgb(128,203,196); 135 | $palette-teal-300: rgb(77,182,172); 136 | $palette-teal-400: rgb(38,166,154); 137 | $palette-teal-500: rgb(0,150,136); 138 | $palette-teal-600: rgb(0,137,123); 139 | $palette-teal-700: rgb(0,121,107); 140 | $palette-teal-800: rgb(0,105,92); 141 | $palette-teal-900: rgb(0,77,64); 142 | $palette-teal-a100: rgb(167,255,235); 143 | $palette-teal-a200: rgb(100,255,218); 144 | $palette-teal-a400: rgb(29,233,182); 145 | $palette-teal-a700: rgb(0,191,165); 146 | 147 | // Green 148 | $palette-green-50: rgb(232,245,233); 149 | $palette-green-100: rgb(200,230,201); 150 | $palette-green-200: rgb(165,214,167); 151 | $palette-green-300: rgb(129,199,132); 152 | $palette-green-400: rgb(102,187,106); 153 | $palette-green-500: rgb(76,175,80); 154 | $palette-green-600: rgb(67,160,71); 155 | $palette-green-700: rgb(56,142,60); 156 | $palette-green-800: rgb(46,125,50); 157 | $palette-green-900: rgb(27,94,32); 158 | $palette-green-a100: rgb(185,246,202); 159 | $palette-green-a200: rgb(105,240,174); 160 | $palette-green-a400: rgb(0,230,118); 161 | $palette-green-a700: rgb(0,200,83); 162 | 163 | // Green 164 | $palette-light-green-50: rgb(241,248,233); 165 | $palette-light-green-100: rgb(220,237,200); 166 | $palette-light-green-200: rgb(197,225,165); 167 | $palette-light-green-300: rgb(174,213,129); 168 | $palette-light-green-400: rgb(156,204,101); 169 | $palette-light-green-500: rgb(139,195,74); 170 | $palette-light-green-600: rgb(124,179,66); 171 | $palette-light-green-700: rgb(104,159,56); 172 | $palette-light-green-800: rgb(85,139,47); 173 | $palette-light-green-900: rgb(51,105,30); 174 | $palette-light-green-a100: rgb(204,255,144); 175 | $palette-light-green-a200: rgb(178,255,89); 176 | $palette-light-green-a400: rgb(118,255,3); 177 | $palette-light-green-a700: rgb(100,221,23); 178 | 179 | // Lime 180 | $palette-lime-50: rgb(249,251,231); 181 | $palette-lime-100: rgb(240,244,195); 182 | $palette-lime-200: rgb(230,238,156); 183 | $palette-lime-300: rgb(220,231,117); 184 | $palette-lime-400: rgb(212,225,87); 185 | $palette-lime-500: rgb(205,220,57); 186 | $palette-lime-600: rgb(192,202,51); 187 | $palette-lime-700: rgb(175,180,43); 188 | $palette-lime-800: rgb(158,157,36); 189 | $palette-lime-900: rgb(130,119,23); 190 | $palette-lime-a100: rgb(244,255,129); 191 | $palette-lime-a200: rgb(238,255,65); 192 | $palette-lime-a400: rgb(198,255,0); 193 | $palette-lime-a700: rgb(174,234,0); 194 | 195 | // Yellow 196 | $palette-yellow-50: rgb(255,253,231); 197 | $palette-yellow-100: rgb(255,249,196); 198 | $palette-yellow-200: rgb(255,245,157); 199 | $palette-yellow-300: rgb(255,241,118); 200 | $palette-yellow-400: rgb(255,238,88); 201 | $palette-yellow-500: rgb(255,235,59); 202 | $palette-yellow-600: rgb(253,216,53); 203 | $palette-yellow-700: rgb(251,192,45); 204 | $palette-yellow-800: rgb(249,168,37); 205 | $palette-yellow-900: rgb(245,127,23); 206 | $palette-yellow-a100: rgb(255,255,141); 207 | $palette-yellow-a200: rgb(255,255,0); 208 | $palette-yellow-a400: rgb(255,234,0); 209 | $palette-yellow-a700: rgb(255,214,0); 210 | 211 | // Amber 212 | $palette-amber-50: rgb(255,248,225); 213 | $palette-amber-100: rgb(255,236,179); 214 | $palette-amber-200: rgb(255,224,130); 215 | $palette-amber-300: rgb(255,213,79); 216 | $palette-amber-400: rgb(255,202,40); 217 | $palette-amber-500: rgb(255,193,7); 218 | $palette-amber-600: rgb(255,179,0); 219 | $palette-amber-700: rgb(255,160,0); 220 | $palette-amber-800: rgb(255,143,0); 221 | $palette-amber-900: rgb(255,111,0); 222 | $palette-amber-a100: rgb(255,229,127); 223 | $palette-amber-a200: rgb(255,215,64); 224 | $palette-amber-a400: rgb(255,196,0); 225 | $palette-amber-a700: rgb(255,171,0); 226 | 227 | // Orange 228 | $palette-orange-50: rgb(255,243,224); 229 | $palette-orange-100: rgb(255,224,178); 230 | $palette-orange-200: rgb(255,204,128); 231 | $palette-orange-300: rgb(255,183,77); 232 | $palette-orange-400: rgb(255,167,38); 233 | $palette-orange-500: rgb(255,152,0); 234 | $palette-orange-600: rgb(251,140,0); 235 | $palette-orange-700: rgb(245,124,0); 236 | $palette-orange-800: rgb(239,108,0); 237 | $palette-orange-900: rgb(230,81,0); 238 | $palette-orange-a100: rgb(255,209,128); 239 | $palette-orange-a200: rgb(255,171,64); 240 | $palette-orange-a400: rgb(255,145,0); 241 | $palette-orange-a700: rgb(255,109,0); 242 | 243 | // Deep Orange 244 | $palette-deep-orange-50: rgb(251,233,231); 245 | $palette-deep-orange-100: rgb(255,204,188); 246 | $palette-deep-orange-200: rgb(255,171,145); 247 | $palette-deep-orange-300: rgb(255,138,101); 248 | $palette-deep-orange-400: rgb(255,112,67); 249 | $palette-deep-orange-500: rgb(255,87,34); 250 | $palette-deep-orange-600: rgb(244,81,30); 251 | $palette-deep-orange-700: rgb(230,74,25); 252 | $palette-deep-orange-800: rgb(216,67,21); 253 | $palette-deep-orange-900: rgb(191,54,12); 254 | $palette-deep-orange-a100: rgb(255,158,128); 255 | $palette-deep-orange-a200: rgb(255,110,64); 256 | $palette-deep-orange-a400: rgb(255,61,0); 257 | $palette-deep-orange-a700: rgb(221,44,0); 258 | 259 | // Brown 260 | $palette-brown-50: rgb(239,235,233); 261 | $palette-brown-100: rgb(215,204,200); 262 | $palette-brown-200: rgb(188,170,164); 263 | $palette-brown-300: rgb(161,136,127); 264 | $palette-brown-400: rgb(141,110,99); 265 | $palette-brown-500: rgb(121,85,72); 266 | $palette-brown-600: rgb(109,76,65); 267 | $palette-brown-700: rgb(93,64,55); 268 | $palette-brown-800: rgb(78,52,46); 269 | $palette-brown-900: rgb(62,39,35); 270 | 271 | // Grey 272 | $palette-grey-50: rgb(250,250,250); 273 | $palette-grey-100: rgb(245,245,245); 274 | $palette-grey-200: rgb(238,238,238); 275 | $palette-grey-300: rgb(224,224,224); 276 | $palette-grey-400: rgb(189,189,189); 277 | $palette-grey-500: rgb(158,158,158); 278 | $palette-grey-600: rgb(117,117,117); 279 | $palette-grey-700: rgb(97,97,97); 280 | $palette-grey-800: rgb(66,66,66); 281 | $palette-grey-900: rgb(33,33,33); 282 | 283 | // Blue Grey 284 | $palette-blue-grey-50: rgb(236,239,241); 285 | $palette-blue-grey-100: rgb(207,216,220); 286 | $palette-blue-grey-200: rgb(176,190,197); 287 | $palette-blue-grey-300: rgb(144,164,174); 288 | $palette-blue-grey-400: rgb(120,144,156); 289 | $palette-blue-grey-500: rgb(96,125,139); 290 | $palette-blue-grey-600: rgb(84,110,122); 291 | $palette-blue-grey-700: rgb(69,90,100); 292 | $palette-blue-grey-800: rgb(55,71,79); 293 | $palette-blue-grey-900: rgb(38,50,56); 294 | 295 | $color-black: rgb(0,0,0); 296 | $color-white: rgb(255,255,255); 297 | 298 | //-- The two possible colors for overlayed text. 299 | $styleguide-generate-template: false !default; 300 | $color-dark-contrast: $color-white !default; 301 | $color-light-contrast: $color-black !default; 302 | -------------------------------------------------------------------------------- /doc/app/components/_globals.scss: -------------------------------------------------------------------------------- 1 | body { 2 | box-sizing: border-box; 3 | padding: 0; 4 | margin: 0; 5 | font-size: 18px; 6 | font-weight: 400; 7 | background: #EEE; 8 | line-height: 1.4rem; 9 | } 10 | 11 | h1 { 12 | font-size: 5em; 13 | margin: 0.67em 0; 14 | } 15 | 16 | h1, h2, h3, h4, h5, h6 { 17 | font-family: Gibson,HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif; 18 | color: #001A33; 19 | } 20 | 21 | @import "./colors"; 22 | 23 | //-- Color configuration 24 | $color-divider: $palette-grey-200 !default; 25 | $color-background: $color-white !default; 26 | $color-text: $palette-grey-900 !default; 27 | $color-text-secondary: $palette-grey-600 !default; 28 | 29 | $color-primary: $palette-indigo-500 !default; 30 | $color-primary-dark: $palette-indigo-700 !default; 31 | $color-accent: $palette-pink-a200 !default; 32 | $color-accent-dark: $palette-pink-700 !default; 33 | $color-primary-contrast: $color-dark-contrast !default; 34 | $color-accent-contrast: $color-dark-contrast !default; 35 | 36 | 37 | //-- Sizing 38 | $unit: 1rem !default; //can be overriden by child. 39 | 40 | // -- Fonts 41 | $preferred-font: "Roboto", "Helvetica", "Arial", sans-serif !default; 42 | $font-size: 1.6 * $unit !default; 43 | $font-size-tiny: 1.2 * $unit !default; 44 | $font-size-small: 1.4 * $unit !default; 45 | $font-size-normal: $font-size !default; 46 | $font-size-big: 1.8 * $unit !default; 47 | $font-weight-thin: 300 !default; 48 | $font-weight-normal: 400 !default; 49 | $font-weight-semi-bold: 500 !default; 50 | $font-weight-bold: 700 !default; 51 | -------------------------------------------------------------------------------- /doc/app/components/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin code-typography { 2 | font-family: 'source-code-pro', Menlo, Consolas, Monaco, 'Andale Mono', 'Courier New', monospace; 3 | font-size: 13px; 4 | line-height: 1.4; 5 | } 6 | -------------------------------------------------------------------------------- /doc/app/components/box/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Col } from 'react-flexbox-grid'; 4 | import box from './style'; 5 | 6 | const Box = (props) => { 7 | return ( 8 | 9 |
10 | {props.children} 11 |
12 | 13 | ); 14 | }; 15 | 16 | Box.propTypes = { 17 | type: PropTypes.oneOf(['row', 'container', 'nested', 'large']).isRequired, 18 | children: PropTypes.node 19 | }; 20 | 21 | export default Box; 22 | -------------------------------------------------------------------------------- /doc/app/components/box/style.scss: -------------------------------------------------------------------------------- 1 | .box { 2 | position: relative; 3 | box-sizing: border-box; 4 | min-height: 1rem; 5 | margin-bottom: 0; 6 | background: #007FFF; 7 | border: 1px solid #FFF; 8 | border-radius: 2px; 9 | overflow: hidden; 10 | text-align: center; 11 | color: #fff; 12 | } 13 | 14 | .row { 15 | composes: box; 16 | margin-bottom: 1rem; 17 | } 18 | 19 | .container { 20 | composes: box; 21 | box-sizing: border-box; 22 | padding: .5em; 23 | } 24 | 25 | .nested { 26 | composes: box; 27 | background: #036; 28 | border-color: #007FFF; 29 | } 30 | 31 | .large { 32 | composes: box; 33 | height: 8rem; 34 | } 35 | 36 | @media only screen and (min-width: 48rem) { 37 | 38 | .box { 39 | padding: 1rem; 40 | } 41 | 42 | .row { 43 | padding: 1rem; 44 | } 45 | .container { 46 | padding: 1rem; 47 | } 48 | .nested { 49 | padding: 1rem; 50 | } 51 | .large { 52 | padding: 1rem; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /doc/app/components/button/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import style from './style'; 4 | 5 | const Button = (props) => { 6 | return ( 7 | {props.children} 8 | ); 9 | }; 10 | 11 | Button.propTypes = { 12 | url: PropTypes.string, 13 | children: PropTypes.string 14 | }; 15 | 16 | export default Button; 17 | -------------------------------------------------------------------------------- /doc/app/components/button/style.scss: -------------------------------------------------------------------------------- 1 | .button { 2 | border: 1px solid #007FFF; 3 | box-sizing: border-box; 4 | padding: 0rem 4rem; 5 | line-height: 3rem; 6 | height: 3rem; 7 | font-size: 1.25rem; 8 | font-weight: bold; 9 | color: #007FFF; 10 | text-decoration: none; 11 | transition: background-color, .15s; 12 | border-radius: 2px; 13 | margin: 1rem; 14 | 15 | &:hover { 16 | background: #39F; 17 | border-color: #39F; 18 | color: #FFF; 19 | text-shadow: 0 1px #007FFF; 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /doc/app/components/hero/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Row} from 'react-flexbox-grid'; 3 | import style from './style'; 4 | 5 | import Button from '../button'; 6 | 7 | const Hero = () => { 8 | return ( 9 |
10 | 11 |

React-FlexBox-Grid

12 |
13 | 14 | React(CSS-Modules(flexboxgrid2.css)); 15 | 16 | 17 | 18 | 19 |
20 | ); 21 | }; 22 | 23 | export default Hero; 24 | -------------------------------------------------------------------------------- /doc/app/components/hero/style.scss: -------------------------------------------------------------------------------- 1 | .hero { 2 | background: white; 3 | box-sizing: border-box; 4 | padding: 2rem; 5 | border: 1px solid white; 6 | border-radius: 2px; 7 | } 8 | 9 | .headline { 10 | font-size: 2.5rem; 11 | white-space: nowrap; 12 | } 13 | 14 | .description { 15 | font-size: .95rem; 16 | margin-bottom: 2rem; 17 | } 18 | 19 | @media only screen and (min-width: 48rem) { 20 | .headline { 21 | font-size: 4rem; 22 | margin-bottom: 2rem; 23 | } 24 | .description { 25 | font-size: 1.35rem; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /doc/app/components/home/align-bottom.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | ``` 7 | -------------------------------------------------------------------------------- /doc/app/components/home/align-center.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ``` 10 | -------------------------------------------------------------------------------- /doc/app/components/home/align-end.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ``` 10 | -------------------------------------------------------------------------------- /doc/app/components/home/align-middle.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | ``` 7 | -------------------------------------------------------------------------------- /doc/app/components/home/align-start.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ``` 10 | -------------------------------------------------------------------------------- /doc/app/components/home/align-top.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | ``` 7 | -------------------------------------------------------------------------------- /doc/app/components/home/auto-width.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ``` 12 | -------------------------------------------------------------------------------- /doc/app/components/home/dist-around.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | 7 | ``` 8 | -------------------------------------------------------------------------------- /doc/app/components/home/dist-between.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | 7 | ``` 8 | -------------------------------------------------------------------------------- /doc/app/components/home/fluid.md: -------------------------------------------------------------------------------- 1 | ```css 2 | .col-xs-6 { 3 | flex-basis: 50%; 4 | } 5 | ``` 6 | -------------------------------------------------------------------------------- /doc/app/components/home/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Grid, Row} from 'react-flexbox-grid'; 3 | import home from './style'; 4 | 5 | import Markdown from '../markdown'; 6 | import Hero from '../hero'; 7 | import Section from '../section'; 8 | import Box from '../box'; 9 | 10 | import responsiveMD from './responsive'; 11 | import fluidMD from './fluid'; 12 | import offsetMD from './offset'; 13 | import autoWidthMD from './auto-width'; 14 | import alignStartMD from './align-start'; 15 | import alignCenterMD from './align-center'; 16 | import alignEndMD from './align-end'; 17 | import alignTopMD from './align-top'; 18 | import alignMiddleMD from './align-middle'; 19 | import alignBottomMD from './align-bottom'; 20 | import distAroundMD from './dist-around'; 21 | import distBetweenMD from './dist-between'; 22 | 23 | const Home = () => ( 24 |
25 | 26 | 27 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |
83 |
84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 |
97 |
98 |

.start-

99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 |

.center-

110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 |

.end-

121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 |

.top-

132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 |

.middle-

140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 |

.bottom-

148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 |
156 |
157 |

.around-

158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 |

.between-

171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 |
184 |
185 |
186 | ); 187 | 188 | export default Home; 189 | -------------------------------------------------------------------------------- /doc/app/components/home/offset.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | ``` 16 | -------------------------------------------------------------------------------- /doc/app/components/home/responsive.md: -------------------------------------------------------------------------------- 1 | ```jsx 2 | 3 | 4 | 5 | 6 | 7 | ``` 8 | -------------------------------------------------------------------------------- /doc/app/components/home/style.scss: -------------------------------------------------------------------------------- 1 | @import '../_globals'; 2 | 3 | .wrap { 4 | box-sizing: border-box; 5 | max-width: 1200px; 6 | margin: 0 auto; 7 | } 8 | -------------------------------------------------------------------------------- /doc/app/components/markdown/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import style from './style'; 3 | 4 | 5 | const Markdown = (props) => { 6 | const className = style.markdown; 7 | const html = { 8 | __html: props.html 9 | }; 10 | 11 | return ( 12 |
13 | ); 14 | }; 15 | 16 | Markdown.propTypes = { 17 | html: React.PropTypes.string 18 | }; 19 | 20 | export default Markdown; 21 | -------------------------------------------------------------------------------- /doc/app/components/markdown/style.scss: -------------------------------------------------------------------------------- 1 | @import "../globals"; 2 | @import "../mixins"; 3 | 4 | $documentation-h1-size: 3.4 * $unit; 5 | $documentation-h2-size: 2.4 * $unit; 6 | $documentation-h-offset: 4 * $unit; 7 | $documentation-v-offset: ($documentation-h-offset / 2); 8 | $documentation-code-background: rgb(255, 255, 255); 9 | $documentation-playground-button-height: 3 * $unit; 10 | $documentation-playground-button-font-size: 1.2 * $unit; 11 | $documentation-table-font-size: 1.4 * $unit; 12 | 13 | :global { 14 | @import "~highlight.js/styles/github-gist"; 15 | } 16 | 17 | .markdown { 18 | display: block; 19 | max-height: 100%; 20 | flex-grow: 1; 21 | padding-bottom: 1 * $unit; 22 | overflow-y: scroll; 23 | font-size: $font-size-normal; 24 | color: $color-text; 25 | > *:not(pre) { 26 | margin: $documentation-v-offset $documentation-h-offset; 27 | } 28 | h1 { 29 | font-size: $documentation-h1-size; 30 | } 31 | h2 { 32 | font-size: $documentation-h2-size; 33 | } 34 | h3, h4, h5, h6 { 35 | font-size: inherit; 36 | font-weight: $font-weight-bold; 37 | } 38 | h1, h2 { 39 | padding-top: $documentation-v-offset; 40 | color: $color-primary-dark; 41 | } 42 | p { 43 | font-size: inherit; 44 | line-height: 1.5; 45 | a { 46 | color: $color-text; 47 | text-decoration: underline; 48 | } 49 | } 50 | code { 51 | @include code-typography; 52 | padding: .3 * $unit .5 * $unit; 53 | background-color: $documentation-code-background; 54 | border-radius: 2px; 55 | } 56 | pre { 57 | @include code-typography; 58 | padding: $documentation-v-offset $documentation-h-offset; 59 | background-color: $documentation-code-background; 60 | } 61 | > :global(.playground-button) { 62 | display: block; 63 | text-align: left; 64 | > button { 65 | height: $documentation-playground-button-height; 66 | > span { 67 | font-size: $documentation-playground-button-font-size; 68 | line-height: $documentation-playground-button-height; 69 | } 70 | } 71 | } 72 | ul { 73 | margin-left: 7 * $unit; 74 | 75 | -webkit-font-smoothing: antialiased; 76 | font-smoothing: antialiased; 77 | > li { 78 | margin-bottom: $unit; 79 | } 80 | } 81 | table { 82 | width: auto; 83 | font-size: $documentation-table-font-size; 84 | thead th { 85 | -webkit-font-smoothing: antialiased; 86 | font-smoothing: antialiased; 87 | } 88 | th, td { 89 | padding: $unit; 90 | 91 | -webkit-font-smoothing: antialiased; 92 | font-smoothing: antialiased; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /doc/app/components/section/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import style from './style'; 4 | 5 | const Section = (props) => { 6 | return ( 7 |
8 |

{props.title}

9 |

{props.description}

10 | {props.children} 11 |
12 | ); 13 | }; 14 | 15 | Section.propTypes = { 16 | title: PropTypes.string, 17 | description: PropTypes.string, 18 | children: PropTypes.node 19 | }; 20 | 21 | export default Section; 22 | -------------------------------------------------------------------------------- /doc/app/components/section/style.scss: -------------------------------------------------------------------------------- 1 | .section { 2 | padding-top: 3rem; 3 | } 4 | -------------------------------------------------------------------------------- /doc/app/index.jsx: -------------------------------------------------------------------------------- 1 | import 'babel-polyfill'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import Home from './components/home'; 5 | 6 | ReactDOM.render(, document.getElementById('app')); 7 | -------------------------------------------------------------------------------- /doc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-flexbox-grid-docs", 3 | "version": "0.0.1", 4 | "description": "Documentation for React Flexbox Grid", 5 | "scripts": { 6 | "start": "cross-env NODE_ENV=development UV_THREADPOOL_SIZE=100 node ./server", 7 | "build": "cross-env NODE_ENV=production UV_THREADPOOL_SIZE=100 webpack --config ./webpack.config.production --colors --profile --progress", 8 | "predeploy": "npm run build", 9 | "deploy": "gh-pages -d build" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/roylee0704/react-flexbox-grid.git" 14 | }, 15 | "author": "roylee0704 (https://twitter.com/roylee0704)", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/roylee0704/react-flexbox-grid/issues" 19 | }, 20 | "dependencies": { 21 | "codemirror": "^5.8.0", 22 | "history": "~1.13.1", 23 | "react": "^0.14.0", 24 | "react-dom": "^0.14.0", 25 | "react-router": "^1.0.0-rc3" 26 | }, 27 | "devDependencies": { 28 | "autoprefixer": "^6.0.3", 29 | "babel-cli": "^6.4.0", 30 | "babel-core": "^6.4.0", 31 | "babel-eslint": "^5.0.0-beta6", 32 | "babel-loader": "^6.2.1", 33 | "babel-plugin-react-transform": "^2.0.0", 34 | "babel-polyfill": "^6.3.14", 35 | "babel-preset-es2015-loose": "^6.1.4", 36 | "babel-preset-react": "^6.3.13", 37 | "babel-preset-react-hmre": "^1.0.1", 38 | "babel-preset-stage-0": "^6.3.13", 39 | "cross-env": "^1.0.4", 40 | "css-loader": "^0.21.0", 41 | "eslint-config-airbnb": "^1.0.0", 42 | "eslint-plugin-react": "^3.10.0", 43 | "express": "^4.13.3", 44 | "extract-text-webpack-plugin": "^0.8.2", 45 | "gh-pages": "^0.5.0", 46 | "highlight-loader": "git://github.com/javivelasco/highlight-loader.git#master", 47 | "highlight.js": "^8.9.1", 48 | "html-loader": "^0.3.0", 49 | "html-webpack-plugin": "^1.6.2", 50 | "markdown-loader": "^0.1.7", 51 | "node-sass": "^3.3.3", 52 | "postcss-loader": "^0.7.0", 53 | "raw-loader": "^0.5.1", 54 | "redbox-react": "^1.1.1", 55 | "sass-loader": "^3.0.0", 56 | "style-loader": "^0.13.0", 57 | "transfer-webpack-plugin": "^0.1.4", 58 | "webpack": "^1.12.0", 59 | "webpack-dev-middleware": "^1.2.0", 60 | "webpack-hot-middleware": "^2.4.1" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /doc/server.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const express = require('express'); 3 | const webpack = require('webpack'); 4 | const config = require('./webpack.config'); 5 | 6 | const app = express(); 7 | const compiler = webpack(config); 8 | 9 | app.use(require('webpack-dev-middleware')(compiler, { 10 | publicPath: config.output.publicPath, 11 | stats: { 12 | colors: true 13 | } 14 | })); 15 | 16 | app.use(require('webpack-hot-middleware')(compiler)); 17 | 18 | app.get('*', (req, res) => { 19 | res.sendFile(path.join(__dirname, './www/index.html')); 20 | }); 21 | 22 | app.listen(8081, '0.0.0.0', (err) => { 23 | if (err) { 24 | console.log(err); 25 | return; 26 | } 27 | 28 | console.log('Listening at http://0.0.0.0:8081'); 29 | }); 30 | -------------------------------------------------------------------------------- /doc/webpack.config.development.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const autoprefixer = require('autoprefixer'); 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 5 | const TransferWebpackPlugin = require('transfer-webpack-plugin'); 6 | 7 | module.exports = { 8 | context: __dirname, 9 | devtool: 'inline-source-map', 10 | entry: [ 11 | 'webpack-hot-middleware/client', 12 | './app/index.jsx' 13 | ], 14 | output: { 15 | path: path.join(__dirname, 'build'), 16 | filename: 'docs.js', 17 | publicPath: '/' 18 | }, 19 | resolve: { 20 | extensions: ['', '.jsx', '.scss', '.js', '.json', '.md'], 21 | alias: { 22 | 'react-flexbox-grid': path.resolve(__dirname + './../src') 23 | }, 24 | modulesDirectories: [ 25 | 'node_modules', 26 | path.resolve(__dirname, './node_modules'), 27 | path.resolve(__dirname, './../node_modules'), 28 | path.resolve(__dirname, './../src') 29 | ] 30 | }, 31 | module: { 32 | loaders: [ 33 | { 34 | test: /(\.js|\.jsx)$/, 35 | exclude: /(node_modules)/, 36 | loader: 'babel' 37 | }, { 38 | test: /(\.scss|\.css)$/, 39 | loader: ExtractTextPlugin.extract('style', 'css?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss!sass?sourceMap') 40 | }, { 41 | test: /(\.md)$/, 42 | loader: 'html!highlight!markdown' 43 | } 44 | ] 45 | }, 46 | postcss: [autoprefixer], 47 | plugins: [ 48 | new ExtractTextPlugin('docs.css', { allChunks: true }), 49 | new TransferWebpackPlugin([{ 50 | from: 'www/images', 51 | to: 'images' 52 | }], path.resolve(__dirname, './')), 53 | new webpack.HotModuleReplacementPlugin(), 54 | new webpack.NoErrorsPlugin(), 55 | new webpack.DefinePlugin({ 56 | 'process.env.NODE_ENV': JSON.stringify('development') 57 | }) 58 | ] 59 | }; 60 | -------------------------------------------------------------------------------- /doc/webpack.config.production.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const autoprefixer = require('autoprefixer'); 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 5 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 6 | const TransferWebpackPlugin = require('transfer-webpack-plugin'); 7 | 8 | module.exports = { 9 | context: __dirname, 10 | entry: ['./app/index.jsx'], 11 | output: { 12 | path: path.join(__dirname, 'build'), 13 | filename: 'docs.js' 14 | }, 15 | resolve: { 16 | extensions: ['', '.jsx', '.scss', '.js', '.json', '.md'], 17 | alias: { 18 | 'react-flexbox-grid': path.resolve(__dirname + './../src') 19 | }, 20 | modulesDirectories: [ 21 | 'node_modules', 22 | path.resolve(__dirname, './node_modules'), 23 | path.resolve(__dirname, './../node_modules'), 24 | path.resolve(__dirname, './../src') 25 | ] 26 | }, 27 | module: { 28 | loaders: [ 29 | { 30 | test: /(\.js|\.jsx)$/, 31 | exclude: /(node_modules)/, 32 | loader: 'babel' 33 | }, { 34 | test: /(\.scss|\.css)$/, 35 | loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss!sass') 36 | }, { 37 | test: /(\.md)$/, 38 | loader: 'html?removeComments=false!highlight!markdown' 39 | } 40 | ] 41 | }, 42 | postcss: [autoprefixer], 43 | plugins: [ 44 | new ExtractTextPlugin('docs.css', { allChunks: true }), 45 | new webpack.optimize.UglifyJsPlugin({ 46 | compress: { warnings: false } 47 | }), 48 | new HtmlWebpackPlugin({ 49 | inject: false, 50 | template: path.resolve(__dirname, './www/index.html') 51 | }), 52 | new TransferWebpackPlugin([{ 53 | from: 'www/images', 54 | to: 'images' 55 | }, { 56 | from: 'www/other' 57 | }], path.resolve(__dirname, './')), 58 | new webpack.optimize.OccurenceOrderPlugin(), 59 | new webpack.DefinePlugin({ 60 | 'process.env.NODE_ENV': JSON.stringify('production') 61 | }) 62 | ] 63 | }; 64 | -------------------------------------------------------------------------------- /doc/www/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roylee0704/react-flexbox-grid/743137e11644caa5c6cbb7cb5cac57faf17af9a3/doc/www/images/logo.png -------------------------------------------------------------------------------- /doc/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React Flexbox Grid 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
36 | 45 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /doc/www/other/CNAME: -------------------------------------------------------------------------------- 1 | roylee0704.com/react-flexboxgrid.com 2 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | const webpackConfig = require('./webpack.config'); 2 | 3 | module.exports = function karmaConfig(config) { 4 | config.set({ 5 | browsers: ['PhantomJS'], 6 | singleRun: true, 7 | frameworks: ['mocha'], 8 | files: [ 9 | './node_modules/babel-polyfill/browser.js', 10 | 'tests.webpack.js', 11 | 'test/reactErrors.js' 12 | ], 13 | reporters: ['dots'], 14 | preprocessors: {'tests.webpack.js': ['webpack']}, 15 | webpack: webpackConfig, 16 | webpackServer: { 17 | noInfo: true 18 | }, 19 | plugins: [ 20 | 'karma-webpack', 21 | 'karma-phantomjs-launcher', 22 | 'karma-mocha' 23 | ] 24 | }); 25 | }; 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-flexbox-grid", 3 | "description": "A set of React components implementing flexboxgrid with the power of CSS Modules", 4 | "homepage": "https://github.com/roylee0704/react-flexbox-grid", 5 | "version": "2.1.2", 6 | "main": "lib/index.js", 7 | "author": { 8 | "email": "roylee0704@gmail.com", 9 | "name": "Roy Lee" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/roylee0704/react-flexbox-grid.git" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/roylee0704/react-flexbox-grid/issues" 17 | }, 18 | "keywords": [ 19 | "css modules", 20 | "flexbox", 21 | "grid", 22 | "react", 23 | "react-component" 24 | ], 25 | "dependencies": { 26 | "flexboxgrid2": "^7.2.0", 27 | "prop-types": "^15.5.8" 28 | }, 29 | "devDependencies": { 30 | "@types/react": "*", 31 | "autoprefixer": "^6.0.3", 32 | "babel-cli": "^6.4.1", 33 | "babel-core": "^6.24.1", 34 | "babel-eslint": "^7.2.1", 35 | "babel-loader": "^6.4.1", 36 | "babel-plugin-react-transform": "^2.0.0", 37 | "babel-polyfill": "^6.23.0", 38 | "babel-preset-env": "^1.6.4", 39 | "babel-preset-react": "^6.24.1", 40 | "babel-preset-stage-1": "^6.24.1", 41 | "cpx": "^1.2.1", 42 | "cross-env": "^1.0.4", 43 | "css-loader": "^0.21.0", 44 | "eslint": "^1.10.1", 45 | "eslint-config-airbnb": "^1.0.0", 46 | "eslint-plugin-react": "^3.10.0", 47 | "expect": "^1.13.0", 48 | "express": "^4.13.3", 49 | "extract-text-webpack-plugin": "^0.8.2", 50 | "isparta": "^4.0.0", 51 | "jsdom": "^7.0.2", 52 | "karma": "^1.6.0", 53 | "karma-mocha": "^1.3.0", 54 | "karma-phantomjs-launcher": "^1.0.4", 55 | "karma-webpack": "^2.0.3", 56 | "mocha": "^3.1.2", 57 | "node-sass": "^3.4.2", 58 | "phantomjs-prebuilt": "^2.1.14", 59 | "postcss-loader": "^0.7.0", 60 | "react": "^15.5.4", 61 | "react-addons-test-utils": "^15.5.1", 62 | "react-dom": "^15.5.4", 63 | "react-hot-loader": "^1.3.0", 64 | "redbox-react": "^1.1.1", 65 | "rimraf": "^2.4.4", 66 | "sass-loader": "^3.1.2", 67 | "style-loader": "^0.12.3", 68 | "webpack": "^1.12.9", 69 | "webpack-dev-middleware": "^1.4.0", 70 | "webpack-hot-middleware": "^2.4.1", 71 | "webpack-merge": "^4.1.0" 72 | }, 73 | "scripts": { 74 | "build": "cross-env NODE_ENV=production npm run compile", 75 | "clean": "rimraf ./lib", 76 | "compile": "npm run compile:lib && npm run compile:dist", 77 | "compile:dist": "rm -rf dist && cross-env ./node_modules/.bin/webpack", 78 | "compile:lib": "rm -rf lib && ./node_modules/.bin/babel -d ./lib ./src", 79 | "lint": "eslint src test", 80 | "patch": "bumped release patch", 81 | "prebuild": "npm run clean", 82 | "prepublish": "npm run build", 83 | "release": "bumped release", 84 | "start": "cross-env NODE_ENV=development UV_THREADPOOL_SIZE=100 node ./server", 85 | "test": "cross-env NODE_ENV=test karma start", 86 | "test:watch": "cross-env NODE_ENV=test karma start --no-single-run" 87 | }, 88 | "license": "MIT", 89 | "peerDependencies": { 90 | "react": "^0.14.3 || ^15.5.4 || ^16.0.0 || ^17.0.0" 91 | }, 92 | "types": "react-flexbox-grid.d.ts" 93 | } 94 | -------------------------------------------------------------------------------- /react-flexbox-grid.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for react-flexbox-grid v0.10.2 2 | // Project: https://github.com/roylee0704/react-flexbox-grid 3 | // Definitions by: Ruslan Ibragimov 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | 6 | import {Component, HTMLAttributes} from 'react'; 7 | 8 | declare namespace __ReactFlexboxGrid { 9 | type ViewportSizeType = 'xs' | 'sm' | 'md' | 'lg' | 'xl'; 10 | type ColumnSizeType = number | boolean; 11 | 12 | export interface GridProps extends HTMLAttributes { 13 | readonly fluid?: boolean, 14 | readonly className?: string, 15 | readonly tagName?: string, 16 | } 17 | 18 | export interface RowProps extends HTMLAttributes { 19 | readonly reverse?: boolean, 20 | readonly start?: ViewportSizeType, 21 | readonly center?: ViewportSizeType, 22 | readonly end?: ViewportSizeType, 23 | readonly top?: ViewportSizeType, 24 | readonly middle?: ViewportSizeType, 25 | readonly bottom?: ViewportSizeType, 26 | readonly around?: ViewportSizeType, 27 | readonly between?: ViewportSizeType, 28 | readonly className?: string, 29 | readonly tagName?: string, 30 | } 31 | 32 | export interface ColProps extends HTMLAttributes { 33 | readonly xs?: ColumnSizeType, 34 | readonly sm?: ColumnSizeType, 35 | readonly md?: ColumnSizeType, 36 | readonly lg?: ColumnSizeType, 37 | readonly xl?: ColumnSizeType, 38 | readonly xsOffset?: number, 39 | readonly smOffset?: number, 40 | readonly mdOffset?: number, 41 | readonly lgOffset?: number, 42 | readonly xlOffset?: number, 43 | readonly first?: ViewportSizeType, 44 | readonly last?: ViewportSizeType, 45 | readonly className?: string, 46 | readonly tagName?: string, 47 | } 48 | 49 | export class Grid extends Component { 50 | 51 | } 52 | 53 | export class Row extends Component { 54 | 55 | } 56 | 57 | export class Col extends Component { 58 | 59 | } 60 | } 61 | 62 | export = __ReactFlexboxGrid; 63 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const express = require('express'); 3 | const webpack = require('webpack'); 4 | const config = require('./webpack.config'); 5 | const port = 8080; 6 | 7 | const app = express(); 8 | const compiler = webpack(config); 9 | 10 | 11 | app.use(require('webpack-dev-middleware')(compiler, { 12 | publicPath: config.output.publicPath, 13 | stats: { 14 | colors: true 15 | } 16 | })); 17 | 18 | app.use(require('webpack-hot-middleware')(compiler)); 19 | 20 | app.get('*', (req, resp) => { 21 | resp.sendFile(path.join(__dirname, './spec/index.html')); 22 | }); 23 | 24 | app.listen(port, '0.0.0.0', (err) => { 25 | if (err) { 26 | console.log(err); 27 | return; 28 | } 29 | 30 | console.log(path.join(__dirname, './spec/index.html')); 31 | 32 | console.log('Listening at http://0.0.0.0:' + port); 33 | }); 34 | -------------------------------------------------------------------------------- /spec/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /spec/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Root from './root'; 4 | 5 | ReactDOM.render(, document.getElementById('flexboxgrid-test')); 6 | -------------------------------------------------------------------------------- /spec/root.js: -------------------------------------------------------------------------------- 1 | /* global VERSION */ 2 | require('./stylesheets/base'); 3 | import box from './stylesheets/modules/box'; 4 | 5 | import React from 'react'; 6 | import {Grid, Row, Col} from '../src/index'; 7 | 8 | const Root = () => ( 9 |
10 |

React Flexbox Grid Spec {VERSION}

11 | 12 | 13 | 14 |
15 | 16 | 17 |
18 | 19 | 20 |
21 | 22 | 23 | 24 |
25 | ); 26 | 27 | 28 | export default Root; 29 | -------------------------------------------------------------------------------- /spec/stylesheets/base.scss: -------------------------------------------------------------------------------- 1 | @import "./utilities/reset"; 2 | @import "./utilities/font"; 3 | -------------------------------------------------------------------------------- /spec/stylesheets/modules/box.scss: -------------------------------------------------------------------------------- 1 | .box { 2 | position: relative; 3 | box-sizing: border-box; 4 | min-height: 1rem; 5 | margin-bottom: 0; 6 | background: #007FFF; 7 | border: 1px solid #FFF; 8 | border-radius: 2px; 9 | overflow: hidden; 10 | text-align: center; 11 | color: #fff; 12 | } 13 | 14 | .row { 15 | composes: box; 16 | } 17 | -------------------------------------------------------------------------------- /spec/stylesheets/utilities/font.scss: -------------------------------------------------------------------------------- 1 | html { 2 | font-family: 'Roboto', sans-serif; 3 | font-weight: 400; 4 | line-height: 1.4rem; 5 | } 6 | -------------------------------------------------------------------------------- /spec/stylesheets/utilities/reset.scss: -------------------------------------------------------------------------------- 1 | body, h1, h2, h3, h4, h5, h6 { 2 | margin: 0 3 | } 4 | -------------------------------------------------------------------------------- /src/classNames.js: -------------------------------------------------------------------------------- 1 | import styles from 'flexboxgrid2/flexboxgrid2.css'; 2 | 3 | export default function getClass(className) { 4 | return (styles && styles[className]) ? styles[className] : className; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/Col.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import createProps from '../createProps'; 4 | import getClass from '../classNames'; 5 | import { ColumnSizeType, ViewportSizeType } from '../types'; 6 | 7 | const propTypes = { 8 | xs: ColumnSizeType, 9 | sm: ColumnSizeType, 10 | md: ColumnSizeType, 11 | lg: ColumnSizeType, 12 | xl: ColumnSizeType, 13 | xsOffset: PropTypes.number, 14 | smOffset: PropTypes.number, 15 | mdOffset: PropTypes.number, 16 | lgOffset: PropTypes.number, 17 | xlOffset: PropTypes.number, 18 | first: ViewportSizeType, 19 | last: ViewportSizeType, 20 | className: PropTypes.string, 21 | tagName: PropTypes.string, 22 | children: PropTypes.node 23 | }; 24 | 25 | const classMap = { 26 | xs: 'col-xs', 27 | sm: 'col-sm', 28 | md: 'col-md', 29 | lg: 'col-lg', 30 | xl: 'col-xl', 31 | xsOffset: 'col-xs-offset', 32 | smOffset: 'col-sm-offset', 33 | mdOffset: 'col-md-offset', 34 | lgOffset: 'col-lg-offset', 35 | xlOffset: 'col-xl-offset' 36 | }; 37 | 38 | function isInteger(value) { 39 | return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; 40 | } 41 | 42 | function getColClassNames(props) { 43 | const extraClasses = []; 44 | 45 | if (props.className) { 46 | extraClasses.push(props.className); 47 | } 48 | 49 | if (props.first) { 50 | extraClasses.push(getClass('first-' + props.first)); 51 | } 52 | 53 | if (props.last) { 54 | extraClasses.push(getClass('last-' + props.last)); 55 | } 56 | 57 | return Object.keys(props) 58 | .filter(key => classMap[key]) 59 | .map(key => getClass(isInteger(props[key]) ? (classMap[key] + '-' + props[key]) : classMap[key])) 60 | .concat(extraClasses); 61 | } 62 | 63 | export function getColumnProps(props) { 64 | return createProps(propTypes, props, getColClassNames(props)); 65 | } 66 | 67 | export default function Col(props) { 68 | const { tagName, ...columnProps } = props; 69 | return React.createElement(tagName || 'div', getColumnProps(columnProps)); 70 | } 71 | 72 | Col.propTypes = propTypes; 73 | -------------------------------------------------------------------------------- /src/components/Grid.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import createProps from '../createProps'; 4 | import getClass from '../classNames'; 5 | 6 | const propTypes = { 7 | fluid: PropTypes.bool, 8 | className: PropTypes.string, 9 | tagName: PropTypes.string, 10 | children: PropTypes.node 11 | }; 12 | 13 | export default function Grid(props) { 14 | const containerClass = getClass(props.fluid ? 'container-fluid' : 'container'); 15 | const classNames = [props.className, containerClass]; 16 | 17 | return React.createElement(props.tagName || 'div', createProps(propTypes, props, classNames)); 18 | } 19 | 20 | Grid.propTypes = propTypes; 21 | -------------------------------------------------------------------------------- /src/components/Row.js: -------------------------------------------------------------------------------- 1 | import getClass from '../classNames'; 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import createProps from '../createProps'; 5 | import { ViewportSizeType } from '../types'; 6 | 7 | const rowKeys = ['start', 'center', 'end', 'top', 'middle', 'bottom', 'around', 'between']; 8 | 9 | const propTypes = { 10 | reverse: PropTypes.bool, 11 | start: ViewportSizeType, 12 | center: ViewportSizeType, 13 | end: ViewportSizeType, 14 | top: ViewportSizeType, 15 | middle: ViewportSizeType, 16 | bottom: ViewportSizeType, 17 | around: ViewportSizeType, 18 | between: ViewportSizeType, 19 | className: PropTypes.string, 20 | tagName: PropTypes.string, 21 | children: PropTypes.node 22 | }; 23 | 24 | function getRowClassNames(props) { 25 | const modificators = [props.className, getClass('row')]; 26 | 27 | for (let i = 0; i < rowKeys.length; ++i) { 28 | const key = rowKeys[i]; 29 | const value = props[key]; 30 | if (value) { 31 | modificators.push(getClass(`${key}-${value}`)); 32 | } 33 | } 34 | 35 | if (props.reverse) { 36 | modificators.push(getClass('reverse')); 37 | } 38 | 39 | return modificators; 40 | } 41 | 42 | export function getRowProps(props) { 43 | return createProps(propTypes, props, getRowClassNames(props)); 44 | } 45 | 46 | export default function Row(props) { 47 | return React.createElement(props.tagName || 'div', getRowProps(props)); 48 | } 49 | 50 | Row.propTypes = propTypes; 51 | -------------------------------------------------------------------------------- /src/createProps.js: -------------------------------------------------------------------------------- 1 | export default function createProps(propTypes, props, classNames) { 2 | const newProps = {}; 3 | 4 | Object.keys(props) 5 | .filter(key => (key === 'children' || !propTypes[key])) 6 | .forEach(key => (newProps[key] = props[key])); 7 | 8 | const className = classNames.filter(cn => cn).join(' '); 9 | return Object.assign({}, newProps, { className }); 10 | } 11 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export Grid from './components/Grid'; 2 | export Row, { getRowProps } from './components/Row'; 3 | export Col, { getColumnProps } from './components/Col'; 4 | -------------------------------------------------------------------------------- /src/types.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | export const ColumnSizeType = PropTypes.oneOfType([PropTypes.number, PropTypes.bool]); 4 | export const ViewportSizeType = PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']); 5 | -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/classNames.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'expect'; 2 | import style from 'flexboxgrid2'; 3 | import getClass from '../src/classNames'; 4 | 5 | describe('classNames lookups', () => { 6 | it('translates known styles', () => { 7 | expect(getClass('col-xs')).toEqual(style['col-xs']); 8 | }); 9 | it('falls back to returning unknown classnames', () => { 10 | expect(getClass('blah-blah-blah')).toEqual('blah-blah-blah'); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /test/components/Col.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'expect'; 2 | import React from 'react'; 3 | import TestUtils from 'react-addons-test-utils'; 4 | import Col, { getColumnProps } from '../../src/components/Col'; 5 | import style from 'flexboxgrid2'; 6 | 7 | const renderer = TestUtils.createRenderer(); 8 | 9 | describe('Col', () => { 10 | it('Should add classes equals to props', () => { 11 | renderer.render(); 12 | const { type, props: { className } } = renderer.getRenderOutput(); 13 | expect(type).toBe('div'); 14 | expect(className).toContain(style['col-xs-12']); 15 | expect(className).toContain(style['col-sm-8']); 16 | expect(className).toContain(style['col-md-6']); 17 | expect(className).toContain(style['col-lg-4']); 18 | expect(className).toContain(style['col-xl-2']); 19 | }); 20 | 21 | it('Computes the column properties', () => { 22 | expect(getColumnProps({ className: 'test', xs: 12, unknown: 'foo' })).toEqual({ 23 | unknown: 'foo', className: `${style['col-xs-12']} test` 24 | }); 25 | }); 26 | 27 | it('Should add "first-*" class if "first" property is set', () => { 28 | renderer.render(); 29 | expect(renderer.getRenderOutput().props.className).toContain(style['first-md']); 30 | }); 31 | 32 | it('Should not replace class', () => { 33 | renderer.render(); 34 | 35 | const { className } = renderer.getRenderOutput().props; 36 | 37 | expect(className).toContain('foo'); 38 | expect(className).toContain(style['col-md-3']); 39 | }); 40 | 41 | it('Should support auto-width', () => { 42 | renderer.render(); 43 | const { className } = renderer.getRenderOutput().props; 44 | expect(className).toContain(style['col-xs']); 45 | expect(className).toContain(style['col-sm']); 46 | expect(className).toContain(style['col-md']); 47 | expect(className).toContain(style['col-lg']); 48 | expect(className).toContain(style['col-xl']); 49 | }); 50 | 51 | it('Should support custom tag name', () => { 52 | renderer.render(); 53 | 54 | expect(renderer.getRenderOutput().type).toBe('li'); 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /test/components/Grid.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'expect'; 2 | import React from 'react'; 3 | import TestUtils from 'react-addons-test-utils'; 4 | import Grid from '../../src/components/Grid'; 5 | import style from 'flexboxgrid2'; 6 | 7 | const renderer = TestUtils.createRenderer(); 8 | 9 | describe('Grid', () => { 10 | it('Should add "container" class', () => { 11 | renderer.render(); 12 | expect(renderer.getRenderOutput().props.className).toEqual(style.container); 13 | }); 14 | 15 | it('Should not replace class', () => { 16 | renderer.render(); 17 | const { className } = renderer.getRenderOutput().props; 18 | 19 | expect(className).toContain('foo'); 20 | expect(className).toContain(style.container); 21 | }); 22 | 23 | it('Should add "container-fluid" class if "fluid" property is true', () => { 24 | renderer.render(); 25 | expect(renderer.getRenderOutput().props.className).toEqual(style['container-fluid']); 26 | }); 27 | 28 | it('Should support custom tag name', () => { 29 | renderer.render(); 30 | expect(renderer.getRenderOutput().type).toBe('section'); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /test/components/Row.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'expect'; 2 | import React from 'react'; 3 | import TestUtils from 'react-addons-test-utils'; 4 | import Row, { getRowProps } from '../../src/components/Row'; 5 | import style from 'flexboxgrid2'; 6 | 7 | const renderer = TestUtils.createRenderer(); 8 | 9 | describe('Row', () => { 10 | it('Should add "row" class', () => { 11 | renderer.render(); 12 | expect(renderer.getRenderOutput().props.className).toEqual(style.row); 13 | }); 14 | 15 | it('Computes the row properties', () => { 16 | expect(getRowProps({ className: 'test', reverse: true, unknown: 'bar' })).toEqual({ 17 | unknown: 'bar', className: `test ${style.row} ${style.reverse}` 18 | }); 19 | }); 20 | 21 | it('Should add "reverse" class if "reverse" property is true', () => { 22 | renderer.render(); 23 | expect(renderer.getRenderOutput().props.className).toContain(style.reverse); 24 | }); 25 | 26 | it('Should not replace class', () => { 27 | renderer.render(); 28 | const { className } = renderer.getRenderOutput().props; 29 | expect(className).toContain('foo'); 30 | expect(className).toContain(style.row); 31 | }); 32 | 33 | it('Should add modificators', () => { 34 | renderer.render( 35 | 45 | ); 46 | const { className } = renderer.getRenderOutput().props; 47 | 48 | expect(className).toContain(style.row); 49 | expect(className).toContain(style['start-xs']); 50 | expect(className).toContain(style['center-sm']); 51 | expect(className).toContain(style['end-md']); 52 | expect(className).toContain(style['top-lg']); 53 | expect(className).toContain(style['middle-xs']); 54 | expect(className).toContain(style['bottom-sm']); 55 | expect(className).toContain(style['around-md']); 56 | expect(className).toContain(style['between-lg']); 57 | }); 58 | 59 | it('Should support custom tag name', () => { 60 | renderer.render(); 61 | expect(renderer.getRenderOutput().type).toBe('ul'); 62 | }); 63 | }); 64 | -------------------------------------------------------------------------------- /test/index.spec.js: -------------------------------------------------------------------------------- 1 | import expect from 'expect'; 2 | import * as Exports from '../src/index'; 3 | 4 | describe('react-flexbox-grid exports', () => { 5 | it('exports all the symbols it should', () => { 6 | ['Grid', 'Row', 'Col', 'getColumnProps', 'getRowProps'].forEach((prop) => { 7 | expect(Exports.hasOwnProperty(prop)).toBe(true); 8 | }); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/react-flexbox-grid-test.tsx: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import {Grid, Row, Col} from "react-flexbox-grid"; 4 | import * as React from "react"; 5 | 6 | const ex1: JSX.Element = ( 7 | 8 | 9 | Hello, world! 10 | 11 | 12 | ); 13 | 14 | const ex2: JSX.Element = ( 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ); 29 | 30 | const ex3: JSX.Element = ( 31 | 32 | 33 | 34 | 35 | 36 | ); 37 | 38 | const ex4: JSX.Element = ( 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ); 51 | 52 | 53 | const ex5: JSX.Element = ( 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | ); 62 | 63 | const ex6: JSX.Element = ( 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | ); 72 | -------------------------------------------------------------------------------- /test/reactErrors.js: -------------------------------------------------------------------------------- 1 | /* 2 | Convert react error logging to a raised error. 3 | */ 4 | 5 | /* eslint-disable no-console */ 6 | function treatReactWarningsAsErrors() { 7 | const error = console.error; 8 | 9 | console.error = function reactError(warning) { 10 | if (/(Invalid prop|Failed propType|Unknown prop)/.test(warning)) { 11 | throw new Error(warning); 12 | } 13 | error.apply(console, arguments); 14 | }; 15 | } 16 | /* eslint-enable no-console */ 17 | 18 | treatReactWarningsAsErrors(); 19 | -------------------------------------------------------------------------------- /test/setup.js: -------------------------------------------------------------------------------- 1 | import { jsdom } from 'jsdom'; 2 | 3 | global.document = jsdom(''); 4 | global.window = document.defaultView; 5 | global.navigator = global.window.navigator; 6 | -------------------------------------------------------------------------------- /tests.webpack.js: -------------------------------------------------------------------------------- 1 | 'use strict'; // eslint-disable-line 2 | 3 | const context = require.context('./test', true, /.spec\.js$/); 4 | context.keys().forEach(context); 5 | -------------------------------------------------------------------------------- /webpack.config.development.js: -------------------------------------------------------------------------------- 1 | const pkg = require('./package'); 2 | const webpack = require('webpack'); 3 | const path = require('path'); 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 5 | 6 | module.exports = { 7 | context: __dirname, 8 | devtool: 'inline-source-map', 9 | entry: [ 10 | 'webpack-hot-middleware/client', 11 | './spec/index.js' 12 | ], 13 | output: { 14 | path: path.join(__dirname, 'build'), 15 | publicPath: '/build/', 16 | filename: 'spec.js' 17 | }, 18 | module: { 19 | loaders: [{ 20 | test: /(\.scss|\.css)$/, 21 | loader: ExtractTextPlugin.extract('style-loader', 'css?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss!sass?sourceMap') 22 | }] 23 | }, 24 | plugins: [ 25 | new ExtractTextPlugin('spec.css', {allChunks: true}), 26 | new webpack.HotModuleReplacementPlugin(), 27 | new webpack.NoErrorsPlugin(), 28 | new webpack.DefinePlugin({ 29 | 'process.env.NODE_ENV': JSON.stringify('development'), 30 | VERSION: JSON.stringify(pkg.version) 31 | }) 32 | ] 33 | }; 34 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge'); 2 | const testConfig = require('./webpack.config.test'); 3 | const developmentConfig = require('./webpack.config.development'); 4 | const productionConfig = require('./webpack.config.production'); 5 | const autoprefixer = require('autoprefixer'); 6 | 7 | const configForEnv = (env) => { 8 | switch (env) { 9 | case 'test': 10 | return testConfig; 11 | case 'development': 12 | return developmentConfig; 13 | case 'production': 14 | return productionConfig; 15 | default: 16 | throw new TypeError(`Invalid environment given ${env}!`); 17 | } 18 | }; 19 | 20 | const baseConfig = { 21 | module: { 22 | loaders: [ 23 | { 24 | test: /\.js$/, 25 | loader: 'babel', 26 | exclude: /node_modules/, 27 | } 28 | ] 29 | }, 30 | resolve: { 31 | extensions: ['', '.css', '.scss', '.js', '.json'] 32 | }, 33 | postcss: [autoprefixer] 34 | }; 35 | 36 | module.exports = merge(baseConfig, configForEnv(process.env.NODE_ENV)); 37 | -------------------------------------------------------------------------------- /webpack.config.production.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pkg = require('./package.json'); 3 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 4 | const webpack = require('webpack'); 5 | 6 | const LIB_NAME = pkg.name; 7 | 8 | module.exports = { 9 | entry: { 10 | [LIB_NAME]: path.resolve(__dirname, 'src') 11 | }, 12 | output: { 13 | libraryTarget: 'umd', 14 | path: path.resolve(__dirname, 'dist'), 15 | library: 'ReactFlexboxGrid', 16 | filename: '[name].js', 17 | }, 18 | module: { 19 | loaders: [ 20 | { 21 | test: /\.css$/, 22 | loader: ExtractTextPlugin.extract('style-loader', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss') 23 | } 24 | ], 25 | }, 26 | externals: ['react'], 27 | plugins: [ 28 | new webpack.DefinePlugin({ 29 | 'process.env.NODE_ENV': JSON.stringify('production') 30 | }), 31 | new ExtractTextPlugin('[name].css') 32 | ] 33 | }; 34 | -------------------------------------------------------------------------------- /webpack.config.test.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | 3 | module.exports = { 4 | module: { 5 | loaders: [{ 6 | test: /\.css$/, 7 | loader: 'style!css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss' 8 | }] 9 | }, 10 | watch: true, 11 | plugins: [ 12 | new webpack.DefinePlugin({ 13 | 'process.env.NODE_ENV': JSON.stringify('test') 14 | }) 15 | ] 16 | }; 17 | --------------------------------------------------------------------------------