├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── dist ├── components │ ├── Dom.js │ └── index.js ├── css │ ├── BeforeAfter.js │ ├── Hover.js │ ├── Match.js │ ├── MediaQuery.js │ ├── Pseudo.js │ └── index.js ├── grid │ ├── Col.js │ ├── Container.js │ ├── GridCss.js │ ├── GridStyle.js │ ├── Row.js │ ├── W100.js │ └── index.js ├── index.js └── media │ ├── Empty.js │ ├── MatchMedia.js │ ├── MediaQueryAtom.js │ ├── Query.js │ ├── Range.js │ └── index.js ├── example ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json ├── src │ ├── App.js │ ├── App.test.js │ ├── bootstrap │ │ ├── Icon.js │ │ ├── Nav.js │ │ ├── Section.js │ │ └── index.js │ ├── components │ │ ├── grid │ │ │ ├── EqualWidth.js │ │ │ ├── Fluid.js │ │ │ ├── GridWrapper.js │ │ │ ├── HorizontalAlignment.js │ │ │ ├── MultiRow.js │ │ │ ├── Nest.js │ │ │ ├── OneWidth.js │ │ │ ├── SelfAlignment.js │ │ │ ├── VariableWidth.js │ │ │ ├── VerticalAlignment.js │ │ │ ├── ZeroWidth.js │ │ │ └── index.js │ │ ├── match │ │ │ ├── Listener.js │ │ │ ├── MatchEl.js │ │ │ └── index.js │ │ ├── mediaquery │ │ │ ├── ResponsiveStyle.js │ │ │ └── index.js │ │ └── pseudo │ │ │ ├── Before.js │ │ │ └── index.js │ ├── containers │ │ ├── GridSection.js │ │ ├── MatchSection.js │ │ ├── MediaQuerySection.js │ │ ├── PseudoSection.js │ │ ├── Sidebar.js │ │ └── index.js │ ├── index.css │ ├── index.js │ ├── registerServiceWorker.js │ └── theme │ │ ├── AppStyle.js │ │ ├── Bootstrap.js │ │ └── index.js └── yarn.lock ├── media └── fluid_react.png ├── package-lock.json ├── package.json └── src ├── components ├── Dom.js └── index.js ├── css ├── BeforeAfter.js ├── Hover.js ├── Match.js ├── MediaQuery.js └── index.js ├── grid ├── Col.js ├── Container.js ├── GridCss.js ├── GridStyle.js ├── Row.js ├── W100.js └── index.js ├── index.js └── media ├── Empty.js ├── MatchMedia.js ├── MediaQueryAtom.js ├── Query.js ├── Range.js └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | **node_modules** 2 | example/build/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | **node_modules** 2 | example/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Richard Zhang 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 | # fluid-react 2 | 3 | React inline-style solution for frontend development. CSS free. 4 | 5 | Why Javascript styling instead of CSS? Check out this [video](https://youtu.be/ERB1TJBn32c) 6 | 7 | * [Install](#install) 8 | * [Example](#example) 9 | * [Documentation](#documentation) 10 | * [CSS](#css) 11 | - [MediaQuery](#mediaquery) 12 | - [Match](#match) 13 | - [Pseudo Element](#pseudo-element) 14 | * [Grid](#grid) 15 | 16 | 17 | 18 | ## Install 19 | 20 | No CSS file needed. 21 | 22 | ``` 23 | npm install --save fluid-react 24 | ``` 25 | 26 | ## Example 27 | 28 | Of course I am biased, to me this is the simplest to use library in this category. 29 | 30 | **Mobile vs Desktop** 31 | 32 | ``` 33 | > npm install --save fluid-react 34 | ``` 35 | 36 | then 37 | ``` 38 | import React, { Component } from 'react'; 39 | import { Container, Row, Col } from 'fluid-react'; 40 | 41 | export default class App extends Component { 42 | render() { 43 | return ( 44 | 45 | 46 | Sidebar 47 | Main Section 48 | 49 | 50 | ) 51 | } 52 | } 53 | ``` 54 | 55 | ## Documentation 56 | 57 | Documentation is on [Live Demo](https://richardzcode.github.io/fluid-react/index.html) 58 | 59 | To run documentation/demo in local: 60 | ``` 61 | git clone https://github.com/richardzcode/fluid-react.git 62 | cd fluid-react/example 63 | npm install 64 | npm start 65 | ``` 66 | 67 | ## CSS 68 | 69 | ### MediaQuery 70 | 71 | ``` 72 | const style = { 73 | margin: 'auto 1rem', 74 | padding: '2rem', 75 | color: '#fff', 76 | backgroundColor: '#0275d8', 77 | borderColor: '#0275d8', 78 | '@media (min-width: 576px) and (max-width: 767px)': { 79 | backgroundColor: '#5cb85c', 80 | borderColor: '#5cb85c' 81 | }, 82 | '@media (min-width: 768px) and (max-width: 991px)': { 83 | backgroundColor: '#5bc0de', 84 | borderColor: '#5bc0de' 85 | }, 86 | '@media (min-width: 992px) and (max-width: 1199px)': { 87 | backgroundColor: '#f0ad4e', 88 | borderColor: '#f0ad4e' 89 | }, 90 | '@media (min-width: 1200px)': { 91 | backgroundColor: '#d9534f', 92 | borderColor: '#d9534f' 93 | } 94 | } 95 | ``` 96 | 97 | ### Match 98 | ``` 99 | export const MatchBlocks = (props) => ( 100 |
101 | xs, sm 102 | md,lg 103 | xl 104 |
105 | ) 106 | ``` 107 | 108 | ### Pseudo Element 109 | ``` 110 | const brandStyle = { 111 | fontSize: '24px', 112 | verticalAlign: 'top', 113 | padding: '4px', 114 | '::before': { 115 | content: '', 116 | display: 'inline-block', 117 | width: '64px', 118 | height: '32px', 119 | backgroundImage: 'url(https://reactjs.org/logo-og.png)', 120 | backgroundSize: '64px 32px' 121 | } 122 | } 123 | ``` 124 | 125 | ## Grid 126 | 127 | Base on [Bootstrap 12 column grid system](https://v4-alpha.getbootstrap.com/layout/grid/). A mobile-first grid system for React. 128 | 129 | ``` 130 | 131 | 132 | 1 133 | 2 134 | 3 135 | 4 136 | 5 137 | 6 138 | 7 139 | 8 140 | 9 141 | 10 142 | 11 143 | 12 144 | 145 | 146 | ``` 147 | -------------------------------------------------------------------------------- /dist/components/Dom.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.Hr = exports.H6 = exports.H5 = exports.H4 = exports.H3 = exports.H2 = exports.H1 = exports.A = exports.Video = exports.Audio = exports.Canvas = exports.Img = exports.Aside = exports.Article = exports.Code = exports.Pre = exports.Button = exports.Option = exports.Select = exports.Textarea = exports.Input = exports.Form = exports.Footer = exports.Header = exports.Section = exports.Li = exports.Ul = exports.Label = exports.Span = exports.P = exports.Div = undefined; 7 | 8 | var _react = require('react'); 9 | 10 | var _react2 = _interopRequireDefault(_react); 11 | 12 | var _css = require('../css'); 13 | 14 | var _fsts = require('fsts'); 15 | 16 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 17 | 18 | var _Div = function _Div(props) { 19 | return _react2.default.createElement( 20 | 'div', 21 | props, 22 | props.children 23 | ); 24 | }; 25 | var Div = (0, _css.withMediaQuery)(_Div); 26 | 27 | var _P = function _P(props) { 28 | return _react2.default.createElement( 29 | 'p', 30 | props, 31 | props.children 32 | ); 33 | }; 34 | var P = (0, _css.withMediaQuery)(_P); 35 | 36 | var _Span = function _Span(props) { 37 | return _react2.default.createElement( 38 | 'span', 39 | props, 40 | props.children 41 | ); 42 | }; 43 | var Span = (0, _css.withMediaQuery)(_Span); 44 | 45 | var _Label = function _Label(props) { 46 | return _react2.default.createElement( 47 | 'label', 48 | props, 49 | props.children 50 | ); 51 | }; 52 | var Label = (0, _css.withMediaQuery)(_Label); 53 | 54 | var _Ul = function _Ul(props) { 55 | return _react2.default.createElement( 56 | 'ul', 57 | props, 58 | props.children 59 | ); 60 | }; 61 | var Ul = (0, _css.withMediaQuery)(_Ul); 62 | 63 | var _Li = function _Li(props) { 64 | return _react2.default.createElement( 65 | 'li', 66 | props, 67 | props.children 68 | ); 69 | }; 70 | var Li = (0, _css.withMediaQuery)(_Li); 71 | 72 | var _Section = function _Section(props) { 73 | return _react2.default.createElement( 74 | 'section', 75 | props, 76 | props.children 77 | ); 78 | }; 79 | var Section = (0, _css.withMediaQuery)(_Section); 80 | 81 | var _Header = function _Header(props) { 82 | return _react2.default.createElement( 83 | 'header', 84 | props, 85 | props.children 86 | ); 87 | }; 88 | var Header = (0, _css.withMediaQuery)(_Header); 89 | 90 | var _Footer = function _Footer(props) { 91 | return _react2.default.createElement( 92 | 'footer', 93 | props, 94 | props.children 95 | ); 96 | }; 97 | var Footer = (0, _css.withMediaQuery)(_Footer); 98 | 99 | var _Form = function _Form(props) { 100 | return _react2.default.createElement( 101 | 'form', 102 | props, 103 | props.children 104 | ); 105 | }; 106 | var Form = (0, _css.withMediaQuery)(_Form); 107 | 108 | var _Input = function _Input(props) { 109 | return _react2.default.createElement( 110 | 'input', 111 | props, 112 | props.children 113 | ); 114 | }; 115 | var Input = (0, _css.withMediaQuery)(_Input); 116 | 117 | var _Textarea = function _Textarea(props) { 118 | return _react2.default.createElement( 119 | 'textarea', 120 | props, 121 | props.children 122 | ); 123 | }; 124 | var Textarea = (0, _css.withMediaQuery)(_Textarea); 125 | 126 | var _Select = function _Select(props) { 127 | return _react2.default.createElement( 128 | 'select', 129 | props, 130 | props.children 131 | ); 132 | }; 133 | var Select = (0, _css.withMediaQuery)(_Select); 134 | 135 | var _Option = function _Option(props) { 136 | return _react2.default.createElement( 137 | 'option', 138 | props, 139 | props.children 140 | ); 141 | }; 142 | var Option = (0, _css.withMediaQuery)(_Option); 143 | 144 | var _Button = function _Button(props) { 145 | return _react2.default.createElement( 146 | 'button', 147 | props, 148 | props.children 149 | ); 150 | }; 151 | var Button = (0, _css.withMediaQuery)(_Button); 152 | 153 | var _Pre = function _Pre(props) { 154 | return _react2.default.createElement( 155 | 'pre', 156 | props, 157 | props.children 158 | ); 159 | }; 160 | var Pre = (0, _css.withMediaQuery)(_Pre); 161 | 162 | var _Code = function _Code(props) { 163 | return _react2.default.createElement( 164 | 'code', 165 | props, 166 | props.children 167 | ); 168 | }; 169 | var Code = (0, _css.withMediaQuery)(_Code); 170 | 171 | var _Article = function _Article(props) { 172 | return _react2.default.createElement( 173 | 'article', 174 | props, 175 | props.children 176 | ); 177 | }; 178 | var Article = (0, _css.withMediaQuery)(_Article); 179 | 180 | var _Aside = function _Aside(props) { 181 | return _react2.default.createElement( 182 | 'aside', 183 | props, 184 | props.children 185 | ); 186 | }; 187 | var Aside = (0, _css.withMediaQuery)(_Aside); 188 | 189 | var _Img = function _Img(props) { 190 | return _react2.default.createElement( 191 | 'img', 192 | props, 193 | props.children 194 | ); 195 | }; 196 | var Img = (0, _css.withMediaQuery)(_Img); 197 | 198 | var _Canvas = function _Canvas(props) { 199 | return _react2.default.createElement( 200 | 'canvas', 201 | props, 202 | props.children 203 | ); 204 | }; 205 | var Canvas = (0, _css.withMediaQuery)(_Canvas); 206 | 207 | var _Audio = function _Audio(props) { 208 | return _react2.default.createElement( 209 | 'audio', 210 | props, 211 | props.children 212 | ); 213 | }; 214 | var Audio = (0, _css.withMediaQuery)(_Audio); 215 | 216 | var _Video = function _Video(props) { 217 | return _react2.default.createElement( 218 | 'video', 219 | props, 220 | props.children 221 | ); 222 | }; 223 | var Video = (0, _css.withMediaQuery)(_Video); 224 | 225 | var _A = function _A(props) { 226 | return _react2.default.createElement( 227 | 'a', 228 | props, 229 | props.children 230 | ); 231 | }; 232 | var A = (0, _css.withMediaQuery)(_A); 233 | 234 | var _H1 = function _H1(props) { 235 | return _react2.default.createElement( 236 | 'h1', 237 | props, 238 | props.children 239 | ); 240 | }; 241 | var H1 = (0, _css.withMediaQuery)(_H1); 242 | 243 | var _H2 = function _H2(props) { 244 | return _react2.default.createElement( 245 | 'h2', 246 | props, 247 | props.children 248 | ); 249 | }; 250 | var H2 = (0, _css.withMediaQuery)(_H2); 251 | 252 | var _H3 = function _H3(props) { 253 | return _react2.default.createElement( 254 | 'h3', 255 | props, 256 | props.children 257 | ); 258 | }; 259 | var H3 = (0, _css.withMediaQuery)(_H3); 260 | 261 | var _H4 = function _H4(props) { 262 | return _react2.default.createElement( 263 | 'h4', 264 | props, 265 | props.children 266 | ); 267 | }; 268 | var H4 = (0, _css.withMediaQuery)(_H4); 269 | 270 | var _H5 = function _H5(props) { 271 | return _react2.default.createElement( 272 | 'h5', 273 | props, 274 | props.children 275 | ); 276 | }; 277 | var H5 = (0, _css.withMediaQuery)(_H5); 278 | 279 | var _H6 = function _H6(props) { 280 | return _react2.default.createElement( 281 | 'h6', 282 | props, 283 | props.children 284 | ); 285 | }; 286 | var H6 = (0, _css.withMediaQuery)(_H6); 287 | 288 | var _Hr = function _Hr(props) { 289 | return _react2.default.createElement( 290 | 'hr', 291 | props, 292 | props.children 293 | ); 294 | }; 295 | var Hr = (0, _css.withMediaQuery)(_Hr); 296 | 297 | exports.Div = Div; 298 | exports.P = P; 299 | exports.Span = Span; 300 | exports.Label = Label; 301 | exports.Ul = Ul; 302 | exports.Li = Li; 303 | exports.Section = Section; 304 | exports.Header = Header; 305 | exports.Footer = Footer; 306 | exports.Form = Form; 307 | exports.Input = Input; 308 | exports.Textarea = Textarea; 309 | exports.Select = Select; 310 | exports.Option = Option; 311 | exports.Button = Button; 312 | exports.Pre = Pre; 313 | exports.Code = Code; 314 | exports.Article = Article; 315 | exports.Aside = Aside; 316 | exports.Img = Img; 317 | exports.Canvas = Canvas; 318 | exports.Audio = Audio; 319 | exports.Video = Video; 320 | exports.A = A; 321 | exports.H1 = H1; 322 | exports.H2 = H2; 323 | exports.H3 = H3; 324 | exports.H4 = H4; 325 | exports.H5 = H5; 326 | exports.H6 = H6; 327 | exports.Hr = Hr; -------------------------------------------------------------------------------- /dist/components/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _Dom = require('./Dom'); 8 | 9 | Object.keys(_Dom).forEach(function (key) { 10 | if (key === "default" || key === "__esModule") return; 11 | Object.defineProperty(exports, key, { 12 | enumerable: true, 13 | get: function get() { 14 | return _Dom[key]; 15 | } 16 | }); 17 | }); -------------------------------------------------------------------------------- /dist/css/BeforeAfter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | exports.withBeforeAfter = withBeforeAfter; 12 | 13 | var _react = require('react'); 14 | 15 | var _react2 = _interopRequireDefault(_react); 16 | 17 | var _fsts = require('fsts'); 18 | 19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 20 | 21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 22 | 23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 24 | 25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 26 | 27 | function withBeforeAfter(Comp) { 28 | return function (_Component) { 29 | _inherits(_class, _Component); 30 | 31 | function _class() { 32 | _classCallCheck(this, _class); 33 | 34 | return _possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments)); 35 | } 36 | 37 | _createClass(_class, [{ 38 | key: 'render', 39 | value: function render() { 40 | var style = this.props.style || {}; 41 | var p = _fsts.JS.lessProps(this.props, 'style'); 42 | var styl = _fsts.JS.lessProps(style, '@media.*'); 43 | return beforeAfter(_react2.default.createElement(Comp, _extends({}, p, { style: styl }))); 44 | } 45 | }]); 46 | 47 | return _class; 48 | }(_react.Component); 49 | } 50 | 51 | var beforeAfter = function beforeAfter(el) { 52 | var style = el.props.style || {}; 53 | var before = style['::before']; 54 | var after = style['::after']; 55 | if (!before && !after) { 56 | return el; 57 | } 58 | 59 | var beforeEl = null; 60 | if (before) { 61 | var content = before.content; 62 | var styl = _fsts.JS.lessProps(before, 'content'); 63 | beforeEl = _react2.default.createElement( 64 | 'span', 65 | { style: styl }, 66 | content 67 | ); 68 | } 69 | 70 | var afterEl = null; 71 | if (after) { 72 | var _content = after.content; 73 | var _styl = _fsts.JS.lessProps(after, 'content'); 74 | afterEl = _react2.default.createElement( 75 | 'span', 76 | { style: _styl }, 77 | _content 78 | ); 79 | } 80 | 81 | return _react2.default.createElement( 82 | 'span', 83 | { className: 'fluid-react-before-after-wrapper', style: { position: 'relative' } }, 84 | beforeEl, 85 | el, 86 | afterEl 87 | ); 88 | }; -------------------------------------------------------------------------------- /dist/css/Hover.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | exports.withHover = withHover; 12 | 13 | var _react = require('react'); 14 | 15 | var _react2 = _interopRequireDefault(_react); 16 | 17 | var _fsts = require('fsts'); 18 | 19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 20 | 21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 22 | 23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 24 | 25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 26 | 27 | function withHover(Comp) { 28 | return function (_Component) { 29 | _inherits(_class, _Component); 30 | 31 | function _class(props) { 32 | _classCallCheck(this, _class); 33 | 34 | var _this = _possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).call(this, props)); 35 | 36 | _this.mouseEnterHandler = _this.mouseEnterHandler.bind(_this); 37 | _this.mouseLeaveHandler = _this.mouseLeaveHandler.bind(_this); 38 | 39 | _this.state = { hover: false }; 40 | return _this; 41 | } 42 | 43 | _createClass(_class, [{ 44 | key: 'mouseEnterHandler', 45 | value: function mouseEnterHandler() { 46 | this.setState({ hover: true }); 47 | } 48 | }, { 49 | key: 'mouseLeaveHandler', 50 | value: function mouseLeaveHandler() { 51 | this.setState({ hover: false }); 52 | } 53 | }, { 54 | key: 'render', 55 | value: function render() { 56 | var style = this.props.style; 57 | if (!style || !style[':hover']) { 58 | return _react2.default.createElement( 59 | Comp, 60 | this.props, 61 | this.props.children 62 | ); 63 | } 64 | 65 | var hover = this.state.hover; 66 | 67 | var p = _fsts.JS.lessProps(this.props, 'style'); 68 | if (hover) { 69 | style = style[':hover']; 70 | } else { 71 | style = _fsts.JS.lessProps(style, ':hover'); 72 | } 73 | return _react2.default.createElement( 74 | Comp, 75 | _extends({}, p, { 76 | style: style, 77 | onMouseEnter: this.mouseEnterHandler, 78 | onMouseLeave: this.mouseLeaveHandler 79 | }), 80 | this.props.children 81 | ); 82 | } 83 | }]); 84 | 85 | return _class; 86 | }(_react.Component); 87 | } -------------------------------------------------------------------------------- /dist/css/Match.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | var _react = require('react'); 12 | 13 | var _react2 = _interopRequireDefault(_react); 14 | 15 | var _media = require('../media'); 16 | 17 | var _media2 = _interopRequireDefault(_media); 18 | 19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 20 | 21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 22 | 23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 24 | 25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 26 | 27 | var Match = function (_Component) { 28 | _inherits(Match, _Component); 29 | 30 | function Match(props) { 31 | _classCallCheck(this, Match); 32 | 33 | var _this = _possibleConstructorReturn(this, (Match.__proto__ || Object.getPrototypeOf(Match)).call(this, props)); 34 | 35 | _this.onBreakpoint = _this.onBreakpoint.bind(_this); 36 | 37 | _this.state = { mq: '' }; 38 | return _this; 39 | } 40 | 41 | _createClass(Match, [{ 42 | key: 'componentDidMount', 43 | value: function componentDidMount() { 44 | _media2.default.listenBreakpoint(this.onBreakpoint); 45 | } 46 | }, { 47 | key: 'componentWillUnmount', 48 | value: function componentWillUnmount() { 49 | _media2.default.unlistenBreakpoint(this.onBreakpoint); 50 | } 51 | }, { 52 | key: 'onBreakpoint', 53 | value: function onBreakpoint(query_name) { 54 | this.setState({ 55 | mq: query_name 56 | }); 57 | } 58 | }, { 59 | key: 'render', 60 | value: function render() { 61 | var show = this.props.show; 62 | var mq = this.state.mq; 63 | 64 | 65 | if (show && show.split(',').filter(function (name) { 66 | return name.trim() === mq; 67 | }).length == 0) { 68 | return null; 69 | } 70 | 71 | return _react2.default.createElement( 72 | 'div', 73 | _extends({ className: 'fluid-react-breakpoint' }, this.props), 74 | this.props.children 75 | ); 76 | } 77 | }]); 78 | 79 | return Match; 80 | }(_react.Component); 81 | 82 | exports.default = Match; -------------------------------------------------------------------------------- /dist/css/MediaQuery.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | exports.withMediaQuery = withMediaQuery; 12 | 13 | var _react = require('react'); 14 | 15 | var _react2 = _interopRequireDefault(_react); 16 | 17 | var _fsts = require('fsts'); 18 | 19 | var _media = require('../media'); 20 | 21 | var _media2 = _interopRequireDefault(_media); 22 | 23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 24 | 25 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 26 | 27 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 28 | 29 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 30 | 31 | function withMediaQuery(Comp) { 32 | return function (_Component) { 33 | _inherits(_class, _Component); 34 | 35 | function _class(props) { 36 | _classCallCheck(this, _class); 37 | 38 | var _this = _possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).call(this, props)); 39 | 40 | _this.state = { style: props.style || {} }; 41 | return _this; 42 | } 43 | 44 | _createClass(_class, [{ 45 | key: 'componentDidUpdate', 46 | value: function componentDidUpdate(prevProps, prevState) { 47 | if (this.props.style !== prevProps.style) { 48 | this.attachStyle(); 49 | } 50 | } 51 | }, { 52 | key: 'componentDidMount', 53 | value: function componentDidMount() { 54 | this.attachStyle(); 55 | } 56 | }, { 57 | key: 'componentWillUnmount', 58 | value: function componentWillUnmount() { 59 | _media2.default.detach(this._style); 60 | } 61 | }, { 62 | key: 'attachStyle', 63 | value: function attachStyle() { 64 | var _this2 = this; 65 | 66 | var hasWindow = _fsts.Device.hasWindow(); 67 | 68 | if (this._style) { 69 | _media2.default.detach(this._style); 70 | } 71 | 72 | this._style = Object.assign({}, this.props.style); 73 | if (hasWindow) { 74 | this.setState({ style: this._style }); 75 | return _media2.default.attach(this._style, function (new_style) { 76 | _this2.setState({ style: new_style }); 77 | }); 78 | } 79 | 80 | var queries = {}; 81 | Object.keys(this._style).filter(function (key) { 82 | return key.startsWith('@media'); 83 | }).forEach(function (key) { 84 | return queries[key] = _this2._style[key]; 85 | }); 86 | if (Object.keys(queries).length > 0) { 87 | this._style['__fr_class__'] = '__fr_mq_' + _fsts.JS.cheapId() + '__'; 88 | this._style['__fr_queries__'] = queries; 89 | } 90 | return _fsts.JS.lessProps(this._style, '@media.*'); 91 | } 92 | }, { 93 | key: 'render', 94 | value: function render() { 95 | if (_fsts.Device.hasWindow()) { 96 | var _style = this.state; 97 | var _styl = _fsts.JS.lessProps(_style, '@media.*'); 98 | var _p = _fsts.JS.lessProps(this.props, 'style'); 99 | return _react2.default.createElement(Comp, _extends({}, _p, { style: _styl })); 100 | } 101 | 102 | var style = this.attachStyle(); 103 | if (!style['__fr_class__']) { 104 | var _p2 = _fsts.JS.lessProps(this.props, 'style'); 105 | return _react2.default.createElement(Comp, _extends({}, _p2, { style: style })); 106 | } 107 | 108 | var cls = style['__fr_class__']; 109 | var queries = style['__fr_queries__']; 110 | var styl = _fsts.JS.lessProps(style, '__fr.*'); 111 | var css = '.' + cls + _fsts.JS.styleToCss(styl); 112 | Object.keys(queries).forEach(function (key) { 113 | css += key + '{' + '.' + cls + _fsts.JS.styleToCss(queries[key]) + '}'; 114 | }); 115 | 116 | var p = _fsts.JS.lessProps(this.props, 'style'); 117 | return _react2.default.createElement( 118 | _react.Fragment, 119 | null, 120 | _react2.default.createElement(Comp, _extends({}, p, { className: cls })), 121 | _react2.default.createElement('style', { dangerouslySetInnerHTML: { __html: css } }) 122 | ); 123 | } 124 | }]); 125 | 126 | return _class; 127 | }(_react.Component); 128 | } -------------------------------------------------------------------------------- /dist/css/Pseudo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | exports.withPseudo = withPseudo; 12 | 13 | var _react = require('react'); 14 | 15 | var _react2 = _interopRequireDefault(_react); 16 | 17 | var _fsts = require('fsts'); 18 | 19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 20 | 21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 22 | 23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 24 | 25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 26 | 27 | function withPseudo(Comp) { 28 | return function (_Component) { 29 | _inherits(_class, _Component); 30 | 31 | function _class() { 32 | _classCallCheck(this, _class); 33 | 34 | return _possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments)); 35 | } 36 | 37 | _createClass(_class, [{ 38 | key: 'render', 39 | value: function render() { 40 | var style = this.props.style || {}; 41 | var p = _fsts.JS.lessProps(this.props, 'style'); 42 | var styl = _fsts.JS.lessProps(style, '@media.*'); 43 | return beforeAfter(_react2.default.createElement(Comp, _extends({}, p, { style: styl }))); 44 | } 45 | }]); 46 | 47 | return _class; 48 | }(_react.Component); 49 | } 50 | 51 | var beforeAfter = function beforeAfter(el) { 52 | var style = el.props.style || {}; 53 | var before = style['::before']; 54 | var after = style['::after']; 55 | if (!before && !after) { 56 | return el; 57 | } 58 | 59 | var beforeEl = null; 60 | if (before) { 61 | var content = before.content; 62 | var styl = _fsts.JS.lessProps(before, 'content'); 63 | beforeEl = _react2.default.createElement( 64 | 'span', 65 | { style: styl }, 66 | content 67 | ); 68 | } 69 | 70 | var afterEl = null; 71 | if (after) { 72 | var _content = after.content; 73 | var _styl = _fsts.JS.lessProps(after, 'content'); 74 | afterEl = _react2.default.createElement( 75 | 'span', 76 | { style: _styl }, 77 | _content 78 | ); 79 | } 80 | 81 | return _react2.default.createElement( 82 | 'span', 83 | { className: 'fluid-react-before-after-wrapper', style: { position: 'relative' } }, 84 | beforeEl, 85 | el, 86 | afterEl 87 | ); 88 | }; -------------------------------------------------------------------------------- /dist/css/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.withCss = exports.withPseudo = exports.withHover = exports.withBeforeAfter = exports.withMediaQuery = exports.Match = undefined; 7 | 8 | var _Match = require('./Match'); 9 | 10 | Object.defineProperty(exports, 'Match', { 11 | enumerable: true, 12 | get: function get() { 13 | return _interopRequireDefault(_Match).default; 14 | } 15 | }); 16 | 17 | var _MediaQuery = require('./MediaQuery'); 18 | 19 | var _BeforeAfter = require('./BeforeAfter'); 20 | 21 | var _Hover = require('./Hover'); 22 | 23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 24 | 25 | function withPseudo(Comp) { 26 | return (0, _BeforeAfter.withBeforeAfter)((0, _Hover.withHover)(Comp)); 27 | } 28 | 29 | function withCss(Comp) { 30 | return withPseudo((0, _MediaQuery.withMediaQuery)(Comp)); 31 | } 32 | 33 | exports.withMediaQuery = _MediaQuery.withMediaQuery; 34 | exports.withBeforeAfter = _BeforeAfter.withBeforeAfter; 35 | exports.withHover = _Hover.withHover; 36 | exports.withPseudo = withPseudo; 37 | exports.withCss = withCss; -------------------------------------------------------------------------------- /dist/grid/Col.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | var _react = require('react'); 12 | 13 | var _react2 = _interopRequireDefault(_react); 14 | 15 | var _fsts = require('fsts'); 16 | 17 | var _media = require('../media'); 18 | 19 | var _media2 = _interopRequireDefault(_media); 20 | 21 | var _GridStyle = require('./GridStyle'); 22 | 23 | var _GridStyle2 = _interopRequireDefault(_GridStyle); 24 | 25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 26 | 27 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 28 | 29 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 30 | 31 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 32 | 33 | var logger = new _fsts.Logger('Col'); 34 | 35 | var Col = function (_Component) { 36 | _inherits(Col, _Component); 37 | 38 | function Col(props) { 39 | _classCallCheck(this, Col); 40 | 41 | var _this = _possibleConstructorReturn(this, (Col.__proto__ || Object.getPrototypeOf(Col)).call(this, props)); 42 | 43 | _this.onBreakpoint = _this.onBreakpoint.bind(_this); 44 | 45 | _this.state = { 46 | vw: 'xs' 47 | }; 48 | return _this; 49 | } 50 | 51 | _createClass(Col, [{ 52 | key: 'cellCounts', 53 | value: function cellCounts() { 54 | var _props = this.props, 55 | xs = _props.xs, 56 | sm = _props.sm, 57 | md = _props.md, 58 | lg = _props.lg, 59 | xl = _props.xl; 60 | 61 | var counts = [_fsts.JS.undefinedThen(xs, ''), _fsts.JS.undefinedThen(sm, ''), _fsts.JS.undefinedThen(md, ''), _fsts.JS.undefinedThen(lg, ''), _fsts.JS.undefinedThen(xl, '')]; 62 | 63 | // back fill 64 | for (var i = 0; i < counts.length; i++) { 65 | var val = counts[i]; 66 | if (val !== '') { 67 | for (var j = i - 1; j >= 0; j--) { 68 | counts[j] = val; 69 | } 70 | break; 71 | } 72 | } 73 | 74 | // forward fill 75 | for (var i = 1; i < counts.length; i++) { 76 | if (counts[i] === '') { 77 | counts[i] = counts[i - 1]; 78 | } 79 | } 80 | 81 | return counts; 82 | } 83 | }, { 84 | key: 'cellCount', 85 | value: function cellCount() { 86 | var vw = this.state.vw; 87 | 88 | var index = { 89 | xs: 0, 90 | sm: 1, 91 | md: 2, 92 | lg: 3, 93 | xl: 4 94 | }[vw]; 95 | var counts = this.cellCounts(); 96 | return counts[index]; 97 | } 98 | }, { 99 | key: 'calcStyle', 100 | value: function calcStyle() { 101 | var count = this.cellCount(); 102 | return _GridStyle2.default['col' + count]; 103 | } 104 | }, { 105 | key: 'componentDidMount', 106 | value: function componentDidMount() { 107 | _media2.default.listenBreakpoint(this.onBreakpoint); 108 | } 109 | }, { 110 | key: 'componentWillUnmount', 111 | value: function componentWillUnmount() { 112 | _media2.default.unlistenBreakpoint(this.onBreakpoint); 113 | } 114 | }, { 115 | key: 'onBreakpoint', 116 | value: function onBreakpoint(vw) { 117 | logger.debug('on breakpoint ' + vw); 118 | this.setState({ vw: vw }); 119 | } 120 | }, { 121 | key: 'render', 122 | value: function render() { 123 | if (_fsts.Device.hasWindow()) { 124 | var style = this.props.style; 125 | 126 | var styl = Object.assign({}, this.calcStyle(), style); 127 | var p = _fsts.JS.lessProps(this.props, 'style'); 128 | return _react2.default.createElement( 129 | 'div', 130 | _extends({ className: 'fluid-react-col', style: styl }, p), 131 | this.props.children 132 | ); 133 | } 134 | 135 | var cls = 'fluid-react-col __fr_grid_col__'; 136 | var col = this.props.col; 137 | 138 | if (col) { 139 | cls += ' __fr_grid_col_' + col + '__'; 140 | } 141 | var counts = this.cellCounts(); 142 | if (counts[0] !== '') { 143 | // cellCounts ensures if there is any number then all should have number 144 | cls += ' __fr_grid_xs_' + counts[0] + '__'; 145 | cls += ' __fr_grid_sm_' + counts[1] + '__'; 146 | cls += ' __fr_grid_md_' + counts[2] + '__'; 147 | cls += ' __fr_grid_lg_' + counts[3] + '__'; 148 | cls += ' __fr_grid_xl_' + counts[4] + '__'; 149 | } 150 | return _react2.default.createElement( 151 | 'div', 152 | _extends({ className: cls }, this.props), 153 | this.props.children 154 | ); 155 | } 156 | }]); 157 | 158 | return Col; 159 | }(_react.Component); 160 | 161 | exports.default = Col; -------------------------------------------------------------------------------- /dist/grid/Container.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | var _react = require('react'); 12 | 13 | var _react2 = _interopRequireDefault(_react); 14 | 15 | var _fsts = require('fsts'); 16 | 17 | var _GridStyle = require('./GridStyle'); 18 | 19 | var _GridStyle2 = _interopRequireDefault(_GridStyle); 20 | 21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 22 | 23 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 24 | 25 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 26 | 27 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 28 | 29 | var Container = function (_Component) { 30 | _inherits(Container, _Component); 31 | 32 | function Container() { 33 | _classCallCheck(this, Container); 34 | 35 | return _possibleConstructorReturn(this, (Container.__proto__ || Object.getPrototypeOf(Container)).apply(this, arguments)); 36 | } 37 | 38 | _createClass(Container, [{ 39 | key: 'render', 40 | value: function render() { 41 | var style = this.props.style; 42 | 43 | var styl = Object.assign({}, style, _GridStyle2.default.container); 44 | var p = _fsts.JS.lessProps(this.props, 'style'); 45 | return _react2.default.createElement( 46 | 'div', 47 | _extends({ className: 'fluid-react-container', style: styl }, p), 48 | this.props.children 49 | ); 50 | } 51 | }]); 52 | 53 | return Container; 54 | }(_react.Component); 55 | 56 | exports.default = Container; -------------------------------------------------------------------------------- /dist/grid/GridCss.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _react = require('react'); 8 | 9 | var _react2 = _interopRequireDefault(_react); 10 | 11 | var _fsts = require('fsts'); 12 | 13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 14 | 15 | var basic = { 16 | __fr_grid_col__: { 17 | flex: '1 0 0', 18 | maxWidth: '100%', 19 | boxSizing: 'border-box' 20 | }, 21 | __fr_grid_col_0__: { 22 | display: 'none' 23 | }, 24 | __fr_grid_col_1__: { 25 | flex: '0 0 8.33333333%', 26 | maxWidth: '8.33333333%', 27 | boxSizing: 'border-box' 28 | }, 29 | __fr_grid_col_2__: { 30 | flex: '0 0 16.66666667%', 31 | maxWidth: '16.66666667%', 32 | boxSizing: 'border-box' 33 | }, 34 | __fr_grid_col_3__: { 35 | flex: '0 0 25%', 36 | maxWidth: '25%', 37 | boxSizing: 'border-box' 38 | }, 39 | __fr_grid_col_4__: { 40 | flex: '0 0 33.33333333%', 41 | maxWidth: '33.33333333%', 42 | boxSizing: 'border-box' 43 | }, 44 | __fr_grid_col_5__: { 45 | flex: '0 0 41.66666667%', 46 | maxWidth: '41.66666667%', 47 | boxSizing: 'border-box' 48 | }, 49 | __fr_grid_col_6__: { 50 | flex: '0 0 50%', 51 | maxWidth: '50%', 52 | boxSizing: 'border-box' 53 | }, 54 | __fr_grid_col_7__: { 55 | flex: '0 0 58.33333333%', 56 | maxWidth: '58.33333333%', 57 | boxSizing: 'border-box' 58 | }, 59 | __fr_grid_col_8__: { 60 | flex: '0 0 66.66666667%', 61 | maxWidth: '66.66666667%', 62 | boxSizing: 'border-box' 63 | }, 64 | __fr_grid_col_9__: { 65 | flex: '0 0 75%', 66 | maxWidth: '75%', 67 | boxSizing: 'border-box' 68 | }, 69 | __fr_grid_col_10__: { 70 | flex: '0 0 83.33333333%', 71 | maxWidth: '83.33333333%', 72 | boxSizing: 'border-box' 73 | }, 74 | __fr_grid_col_11__: { 75 | flex: '0 0 91.66666667%', 76 | maxWidth: '91.66666667%', 77 | boxSizing: 'border-box' 78 | }, 79 | __fr_grid_col_12__: { 80 | flex: '0 0 100%', 81 | maxWidth: '100%', 82 | boxSizing: 'border-box' 83 | } 84 | }; 85 | 86 | var queries = {}; 87 | 88 | queries['@media (max-width: 575px)'] = { 89 | __fr_grid_xs_0__: { 90 | display: 'none' 91 | }, 92 | __fr_grid_xs_1__: { 93 | flex: '0 0 8.33333333%', 94 | maxWidth: '8.33333333%', 95 | boxSizing: 'border-box' 96 | }, 97 | __fr_grid_xs_2__: { 98 | flex: '0 0 16.66666667%', 99 | maxWidth: '16.66666667%', 100 | boxSizing: 'border-box' 101 | }, 102 | __fr_grid_xs_3__: { 103 | flex: '0 0 25%', 104 | maxWidth: '25%', 105 | boxSizing: 'border-box' 106 | }, 107 | __fr_grid_xs_4__: { 108 | flex: '0 0 33.33333333%', 109 | maxWidth: '33.33333333%', 110 | boxSizing: 'border-box' 111 | }, 112 | __fr_grid_xs_5__: { 113 | flex: '0 0 41.66666667%', 114 | maxWidth: '41.66666667%', 115 | boxSizing: 'border-box' 116 | }, 117 | __fr_grid_xs_6__: { 118 | flex: '0 0 50%', 119 | maxWidth: '50%', 120 | boxSizing: 'border-box' 121 | }, 122 | __fr_grid_xs_7__: { 123 | flex: '0 0 58.33333333%', 124 | maxWidth: '58.33333333%', 125 | boxSizing: 'border-box' 126 | }, 127 | __fr_grid_xs_8__: { 128 | flex: '0 0 66.66666667%', 129 | maxWidth: '66.66666667%', 130 | boxSizing: 'border-box' 131 | }, 132 | __fr_grid_xs_9__: { 133 | flex: '0 0 75%', 134 | maxWidth: '75%', 135 | boxSizing: 'border-box' 136 | }, 137 | __fr_grid_xs_10__: { 138 | flex: '0 0 83.33333333%', 139 | maxWidth: '83.33333333%', 140 | boxSizing: 'border-box' 141 | }, 142 | __fr_grid_xs_11__: { 143 | flex: '0 0 91.66666667%', 144 | maxWidth: '91.66666667%', 145 | boxSizing: 'border-box' 146 | }, 147 | __fr_grid_xs_12__: { 148 | flex: '0 0 100%', 149 | maxWidth: '100%', 150 | boxSizing: 'border-box' 151 | } 152 | }; 153 | 154 | queries['@media (min-width: 576px) and (max-width: 767px)'] = { 155 | __fr_grid_sm_0__: { 156 | display: 'none' 157 | }, 158 | __fr_grid_sm_1__: { 159 | flex: '0 0 8.33333333%', 160 | maxWidth: '8.33333333%', 161 | boxSizing: 'border-box' 162 | }, 163 | __fr_grid_sm_2__: { 164 | flex: '0 0 16.66666667%', 165 | maxWidth: '16.66666667%', 166 | boxSizing: 'border-box' 167 | }, 168 | __fr_grid_sm_3__: { 169 | flex: '0 0 25%', 170 | maxWidth: '25%', 171 | boxSizing: 'border-box' 172 | }, 173 | __fr_grid_sm_4__: { 174 | flex: '0 0 33.33333333%', 175 | maxWidth: '33.33333333%', 176 | boxSizing: 'border-box' 177 | }, 178 | __fr_grid_sm_5__: { 179 | flex: '0 0 41.66666667%', 180 | maxWidth: '41.66666667%', 181 | boxSizing: 'border-box' 182 | }, 183 | __fr_grid_sm_6__: { 184 | flex: '0 0 50%', 185 | maxWidth: '50%', 186 | boxSizing: 'border-box' 187 | }, 188 | __fr_grid_sm_7__: { 189 | flex: '0 0 58.33333333%', 190 | maxWidth: '58.33333333%', 191 | boxSizing: 'border-box' 192 | }, 193 | __fr_grid_sm_8__: { 194 | flex: '0 0 66.66666667%', 195 | maxWidth: '66.66666667%', 196 | boxSizing: 'border-box' 197 | }, 198 | __fr_grid_sm_9__: { 199 | flex: '0 0 75%', 200 | maxWidth: '75%', 201 | boxSizing: 'border-box' 202 | }, 203 | __fr_grid_sm_10__: { 204 | flex: '0 0 83.33333333%', 205 | maxWidth: '83.33333333%', 206 | boxSizing: 'border-box' 207 | }, 208 | __fr_grid_sm_11__: { 209 | flex: '0 0 91.66666667%', 210 | maxWidth: '91.66666667%', 211 | boxSizing: 'border-box' 212 | }, 213 | __fr_grid_sm_12__: { 214 | flex: '0 0 100%', 215 | maxWidth: '100%', 216 | boxSizing: 'border-box' 217 | } 218 | }; 219 | 220 | queries['@media (min-width: 768px) and (max-width: 991px)'] = { 221 | __fr_grid_md_0__: { 222 | display: 'none' 223 | }, 224 | __fr_grid_md_1__: { 225 | flex: '0 0 8.33333333%', 226 | maxWidth: '8.33333333%', 227 | boxSizing: 'border-box' 228 | }, 229 | __fr_grid_md_2__: { 230 | flex: '0 0 16.66666667%', 231 | maxWidth: '16.66666667%', 232 | boxSizing: 'border-box' 233 | }, 234 | __fr_grid_md_3__: { 235 | flex: '0 0 25%', 236 | maxWidth: '25%', 237 | boxSizing: 'border-box' 238 | }, 239 | __fr_grid_md_4__: { 240 | flex: '0 0 33.33333333%', 241 | maxWidth: '33.33333333%', 242 | boxSizing: 'border-box' 243 | }, 244 | __fr_grid_md_5__: { 245 | flex: '0 0 41.66666667%', 246 | maxWidth: '41.66666667%', 247 | boxSizing: 'border-box' 248 | }, 249 | __fr_grid_md_6__: { 250 | flex: '0 0 50%', 251 | maxWidth: '50%', 252 | boxSizing: 'border-box' 253 | }, 254 | __fr_grid_md_7__: { 255 | flex: '0 0 58.33333333%', 256 | maxWidth: '58.33333333%', 257 | boxSizing: 'border-box' 258 | }, 259 | __fr_grid_md_8__: { 260 | flex: '0 0 66.66666667%', 261 | maxWidth: '66.66666667%', 262 | boxSizing: 'border-box' 263 | }, 264 | __fr_grid_md_9__: { 265 | flex: '0 0 75%', 266 | maxWidth: '75%', 267 | boxSizing: 'border-box' 268 | }, 269 | __fr_grid_md_10__: { 270 | flex: '0 0 83.33333333%', 271 | maxWidth: '83.33333333%', 272 | boxSizing: 'border-box' 273 | }, 274 | __fr_grid_md_11__: { 275 | flex: '0 0 91.66666667%', 276 | maxWidth: '91.66666667%', 277 | boxSizing: 'border-box' 278 | }, 279 | __fr_grid_md_12__: { 280 | flex: '0 0 100%', 281 | maxWidth: '100%', 282 | boxSizing: 'border-box' 283 | } 284 | }; 285 | 286 | queries['@media (min-width: 992px) and (max-width: 1199px)'] = { 287 | __fr_grid_lg_0__: { 288 | display: 'none' 289 | }, 290 | __fr_grid_lg_1__: { 291 | flex: '0 0 8.33333333%', 292 | maxWidth: '8.33333333%', 293 | boxSizing: 'border-box' 294 | }, 295 | __fr_grid_lg_2__: { 296 | flex: '0 0 16.66666667%', 297 | maxWidth: '16.66666667%', 298 | boxSizing: 'border-box' 299 | }, 300 | __fr_grid_lg_3__: { 301 | flex: '0 0 25%', 302 | maxWidth: '25%', 303 | boxSizing: 'border-box' 304 | }, 305 | __fr_grid_lg_4__: { 306 | flex: '0 0 33.33333333%', 307 | maxWidth: '33.33333333%', 308 | boxSizing: 'border-box' 309 | }, 310 | __fr_grid_lg_5__: { 311 | flex: '0 0 41.66666667%', 312 | maxWidth: '41.66666667%', 313 | boxSizing: 'border-box' 314 | }, 315 | __fr_grid_lg_6__: { 316 | flex: '0 0 50%', 317 | maxWidth: '50%', 318 | boxSizing: 'border-box' 319 | }, 320 | __fr_grid_lg_7__: { 321 | flex: '0 0 58.33333333%', 322 | maxWidth: '58.33333333%', 323 | boxSizing: 'border-box' 324 | }, 325 | __fr_grid_lg_8__: { 326 | flex: '0 0 66.66666667%', 327 | maxWidth: '66.66666667%', 328 | boxSizing: 'border-box' 329 | }, 330 | __fr_grid_lg_9__: { 331 | flex: '0 0 75%', 332 | maxWidth: '75%', 333 | boxSizing: 'border-box' 334 | }, 335 | __fr_grid_lg_10__: { 336 | flex: '0 0 83.33333333%', 337 | maxWidth: '83.33333333%', 338 | boxSizing: 'border-box' 339 | }, 340 | __fr_grid_lg_11__: { 341 | flex: '0 0 91.66666667%', 342 | maxWidth: '91.66666667%', 343 | boxSizing: 'border-box' 344 | }, 345 | __fr_grid_lg_12__: { 346 | flex: '0 0 100%', 347 | maxWidth: '100%', 348 | boxSizing: 'border-box' 349 | } 350 | }; 351 | 352 | queries['@media (min-width: 1200px)'] = { 353 | __fr_grid_xl_0__: { 354 | display: 'none' 355 | }, 356 | __fr_grid_xl_1__: { 357 | flex: '0 0 8.33333333%', 358 | maxWidth: '8.33333333%', 359 | boxSizing: 'border-box' 360 | }, 361 | __fr_grid_xl_2__: { 362 | flex: '0 0 16.66666667%', 363 | maxWidth: '16.66666667%', 364 | boxSizing: 'border-box' 365 | }, 366 | __fr_grid_xl_3__: { 367 | flex: '0 0 25%', 368 | maxWidth: '25%', 369 | boxSizing: 'border-box' 370 | }, 371 | __fr_grid_xl_4__: { 372 | flex: '0 0 33.33333333%', 373 | maxWidth: '33.33333333%', 374 | boxSizing: 'border-box' 375 | }, 376 | __fr_grid_xl_5__: { 377 | flex: '0 0 41.66666667%', 378 | maxWidth: '41.66666667%', 379 | boxSizing: 'border-box' 380 | }, 381 | __fr_grid_xl_6__: { 382 | flex: '0 0 50%', 383 | maxWidth: '50%', 384 | boxSizing: 'border-box' 385 | }, 386 | __fr_grid_xl_7__: { 387 | flex: '0 0 58.33333333%', 388 | maxWidth: '58.33333333%', 389 | boxSizing: 'border-box' 390 | }, 391 | __fr_grid_xl_8__: { 392 | flex: '0 0 66.66666667%', 393 | maxWidth: '66.66666667%', 394 | boxSizing: 'border-box' 395 | }, 396 | __fr_grid_xl_9__: { 397 | flex: '0 0 75%', 398 | maxWidth: '75%', 399 | boxSizing: 'border-box' 400 | }, 401 | __fr_grid_xl_10__: { 402 | flex: '0 0 83.33333333%', 403 | maxWidth: '83.33333333%', 404 | boxSizing: 'border-box' 405 | }, 406 | __fr_grid_xl_11__: { 407 | flex: '0 0 91.66666667%', 408 | maxWidth: '91.66666667%', 409 | boxSizing: 'border-box' 410 | }, 411 | __fr_grid_xl_12__: { 412 | flex: '0 0 100%', 413 | maxWidth: '100%', 414 | boxSizing: 'border-box' 415 | } 416 | }; 417 | 418 | var css = Object.keys(basic).map(function (cls) { 419 | return '.' + cls + _fsts.JS.styleToCss(basic[cls]); 420 | }).join(''); 421 | 422 | Object.keys(queries).forEach(function (key) { 423 | var styles = queries[key]; 424 | css += key + '{' + Object.keys(styles).map(function (cls) { 425 | return '.' + cls + _fsts.JS.styleToCss(styles[cls]); 426 | }).join('') + '}'; 427 | }); 428 | 429 | var style = function style(props) { 430 | return _react2.default.createElement('style', { dangerouslySetInnerHTML: { __html: css } }); 431 | }; 432 | 433 | exports.default = style; -------------------------------------------------------------------------------- /dist/grid/GridStyle.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | var Container = exports.Container = {}; 7 | 8 | var Row = exports.Row = { 9 | display: 'flex', 10 | flexWrap: 'wrap', 11 | position: 'relative' 12 | }; 13 | 14 | var Col = exports.Col = { 15 | flex: '1 0 0', 16 | maxWidth: '100%', 17 | boxSizing: 'border-box' 18 | }; 19 | 20 | var ColAuto = exports.ColAuto = { 21 | flex: '0 0 auto', 22 | maxWidth: '100%', 23 | width: 'auto', 24 | boxSizing: 'border-box' 25 | }; 26 | 27 | var Col0 = exports.Col0 = { 28 | display: 'none' 29 | }; 30 | 31 | var Col1 = exports.Col1 = { 32 | flex: '0 0 8.33333333%', 33 | maxWidth: '8.33333333%', 34 | boxSizing: 'border-box' 35 | }; 36 | 37 | var Col2 = exports.Col2 = { 38 | flex: '0 0 16.66666667%', 39 | maxWidth: '16.66666667%', 40 | boxSizing: 'border-box' 41 | }; 42 | 43 | var Col3 = exports.Col3 = { 44 | flex: '0 0 25%', 45 | maxWidth: '25%', 46 | boxSizing: 'border-box' 47 | }; 48 | 49 | var Col4 = exports.Col4 = { 50 | flex: '0 0 33.33333333%', 51 | maxWidth: '33.33333333%', 52 | boxSizing: 'border-box' 53 | }; 54 | 55 | var Col5 = exports.Col5 = { 56 | flex: '0 0 41.66666667%', 57 | maxWidth: '41.66666667%', 58 | boxSizing: 'border-box' 59 | }; 60 | 61 | var Col6 = exports.Col6 = { 62 | flex: '0 0 50%', 63 | maxWidth: '50%', 64 | boxSizing: 'border-box' 65 | }; 66 | 67 | var Col7 = exports.Col7 = { 68 | flex: '0 0 58.33333333%', 69 | maxWidth: '58.33333333%', 70 | boxSizing: 'border-box' 71 | }; 72 | 73 | var Col8 = exports.Col8 = { 74 | flex: '0 0 66.66666667%', 75 | maxWidth: '66.66666667%', 76 | boxSizing: 'border-box' 77 | }; 78 | 79 | var Col9 = exports.Col9 = { 80 | flex: '0 0 75%', 81 | maxWidth: '75%', 82 | boxSizing: 'border-box' 83 | }; 84 | 85 | var Col10 = exports.Col10 = { 86 | flex: '0 0 83.33333333%', 87 | maxWidth: '83.33333333%', 88 | boxSizing: 'border-box' 89 | }; 90 | 91 | var Col11 = exports.Col11 = { 92 | flex: '0 0 91.66666667%', 93 | maxWidth: '91.66666667%', 94 | boxSizing: 'border-box' 95 | }; 96 | 97 | var Col12 = exports.Col12 = { 98 | flex: '0 0 100%', 99 | maxWidth: '100%', 100 | boxSizing: 'border-box' 101 | }; 102 | 103 | var W100 = exports.W100 = { 104 | width: '100%' 105 | }; 106 | 107 | var GridStyle = { 108 | container: Container, 109 | 110 | row: Row, 111 | 112 | col: Col, 113 | colauto: ColAuto, 114 | col0: Col0, 115 | col1: Col1, 116 | col2: Col2, 117 | col3: Col3, 118 | col4: Col4, 119 | col5: Col5, 120 | col6: Col6, 121 | col7: Col7, 122 | col8: Col8, 123 | col9: Col9, 124 | col10: Col10, 125 | col11: Col11, 126 | col12: Col12, 127 | 128 | w100: W100 129 | }; 130 | 131 | exports.default = GridStyle; -------------------------------------------------------------------------------- /dist/grid/Row.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | var _react = require('react'); 12 | 13 | var _react2 = _interopRequireDefault(_react); 14 | 15 | var _fsts = require('fsts'); 16 | 17 | var _GridStyle = require('./GridStyle'); 18 | 19 | var _GridStyle2 = _interopRequireDefault(_GridStyle); 20 | 21 | var _GridCss = require('./GridCss'); 22 | 23 | var _GridCss2 = _interopRequireDefault(_GridCss); 24 | 25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 26 | 27 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 28 | 29 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 30 | 31 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 32 | 33 | var Row = function (_Component) { 34 | _inherits(Row, _Component); 35 | 36 | function Row() { 37 | _classCallCheck(this, Row); 38 | 39 | return _possibleConstructorReturn(this, (Row.__proto__ || Object.getPrototypeOf(Row)).apply(this, arguments)); 40 | } 41 | 42 | _createClass(Row, [{ 43 | key: 'render', 44 | value: function render() { 45 | var style = this.props.style; 46 | 47 | var styl = Object.assign({}, _GridStyle2.default.row, style); 48 | var p = _fsts.JS.lessProps(this.props, 'style'); 49 | 50 | if (_fsts.Device.hasWindow()) { 51 | return _react2.default.createElement( 52 | 'div', 53 | _extends({ className: 'fluid-react-row', style: styl }, p), 54 | this.props.children 55 | ); 56 | } 57 | 58 | return _react2.default.createElement( 59 | 'div', 60 | _extends({ className: 'fluid-react-row', style: styl }, p), 61 | _react2.default.createElement(_GridCss2.default, null), 62 | this.props.children 63 | ); 64 | } 65 | }]); 66 | 67 | return Row; 68 | }(_react.Component); 69 | 70 | exports.default = Row; -------------------------------------------------------------------------------- /dist/grid/W100.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 10 | 11 | var _react = require('react'); 12 | 13 | var _react2 = _interopRequireDefault(_react); 14 | 15 | var _fsts = require('fsts'); 16 | 17 | var _GridStyle = require('./GridStyle'); 18 | 19 | var _GridStyle2 = _interopRequireDefault(_GridStyle); 20 | 21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 22 | 23 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 24 | 25 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 26 | 27 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 28 | 29 | var W100 = function (_Component) { 30 | _inherits(W100, _Component); 31 | 32 | function W100() { 33 | _classCallCheck(this, W100); 34 | 35 | return _possibleConstructorReturn(this, (W100.__proto__ || Object.getPrototypeOf(W100)).apply(this, arguments)); 36 | } 37 | 38 | _createClass(W100, [{ 39 | key: 'render', 40 | value: function render() { 41 | var style = this.props.style; 42 | 43 | var styl = Object.assign({}, style, _GridStyle2.default.w100); 44 | var p = _fsts.JS.lessProps(this.props, 'style'); 45 | return _react2.default.createElement( 46 | 'div', 47 | _extends({ className: 'fluid-react-w100', style: styl }, p), 48 | this.props.children 49 | ); 50 | } 51 | }]); 52 | 53 | return W100; 54 | }(_react.Component); 55 | 56 | exports.default = W100; -------------------------------------------------------------------------------- /dist/grid/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _Container = require('./Container'); 8 | 9 | Object.defineProperty(exports, 'Container', { 10 | enumerable: true, 11 | get: function get() { 12 | return _interopRequireDefault(_Container).default; 13 | } 14 | }); 15 | 16 | var _Row = require('./Row'); 17 | 18 | Object.defineProperty(exports, 'Row', { 19 | enumerable: true, 20 | get: function get() { 21 | return _interopRequireDefault(_Row).default; 22 | } 23 | }); 24 | 25 | var _Col = require('./Col'); 26 | 27 | Object.defineProperty(exports, 'Col', { 28 | enumerable: true, 29 | get: function get() { 30 | return _interopRequireDefault(_Col).default; 31 | } 32 | }); 33 | 34 | var _W = require('./W100'); 35 | 36 | Object.defineProperty(exports, 'W100', { 37 | enumerable: true, 38 | get: function get() { 39 | return _interopRequireDefault(_W).default; 40 | } 41 | }); 42 | 43 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.MediaQuery = undefined; 7 | 8 | var _grid = require('./grid'); 9 | 10 | Object.keys(_grid).forEach(function (key) { 11 | if (key === "default" || key === "__esModule") return; 12 | Object.defineProperty(exports, key, { 13 | enumerable: true, 14 | get: function get() { 15 | return _grid[key]; 16 | } 17 | }); 18 | }); 19 | 20 | var _components = require('./components'); 21 | 22 | Object.keys(_components).forEach(function (key) { 23 | if (key === "default" || key === "__esModule") return; 24 | Object.defineProperty(exports, key, { 25 | enumerable: true, 26 | get: function get() { 27 | return _components[key]; 28 | } 29 | }); 30 | }); 31 | 32 | var _css = require('./css'); 33 | 34 | Object.keys(_css).forEach(function (key) { 35 | if (key === "default" || key === "__esModule") return; 36 | Object.defineProperty(exports, key, { 37 | enumerable: true, 38 | get: function get() { 39 | return _css[key]; 40 | } 41 | }); 42 | }); 43 | 44 | var _media = require('./media'); 45 | 46 | var _media2 = _interopRequireDefault(_media); 47 | 48 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 49 | 50 | exports.MediaQuery = _media2.default; -------------------------------------------------------------------------------- /dist/media/Empty.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 10 | 11 | var Empty = function () { 12 | function Empty() { 13 | _classCallCheck(this, Empty); 14 | } 15 | 16 | _createClass(Empty, [{ 17 | key: "listenBreakpoint", 18 | value: function listenBreakpoint() {} 19 | }, { 20 | key: "unlistenBreakpoint", 21 | value: function unlistenBreakpoint() {} 22 | }]); 23 | 24 | return Empty; 25 | }(); 26 | 27 | exports.default = Empty; -------------------------------------------------------------------------------- /dist/media/MatchMedia.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | var _fsts = require('fsts'); 10 | 11 | var _Query = require('./Query'); 12 | 13 | var _Query2 = _interopRequireDefault(_Query); 14 | 15 | var _Range = require('./Range'); 16 | 17 | var _Range2 = _interopRequireDefault(_Range); 18 | 19 | var _MediaQueryAtom = require('./MediaQueryAtom'); 20 | 21 | var _MediaQueryAtom2 = _interopRequireDefault(_MediaQueryAtom); 22 | 23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 24 | 25 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 26 | 27 | var logger = new _fsts.Logger('MatchMedia'); 28 | 29 | var MatchMedia = function () { 30 | function MatchMedia() { 31 | _classCallCheck(this, MatchMedia); 32 | 33 | this._breakpointMatch = this._breakpointMatch.bind(this); 34 | 35 | this._breakpointListeners = []; 36 | this._ranges = []; 37 | this._queries = {}; 38 | this._styles = []; 39 | 40 | if (_fsts.Device.hasWindow()) { 41 | this._ranges = [new _Range2.default('xs', this._breakpointMatch, null, '575px'), new _Range2.default('sm', this._breakpointMatch, '576px', '767px'), new _Range2.default('md', this._breakpointMatch, '768px', '991px'), new _Range2.default('lg', this._breakpointMatch, '992px', '1199px'), new _Range2.default('xl', this._breakpointMatch, '1200px', null)]; 42 | } 43 | } 44 | 45 | _createClass(MatchMedia, [{ 46 | key: 'listenBreakpoint', 47 | value: function listenBreakpoint(f) { 48 | var appended = _fsts.JS.appendUnique(this._breakpointListeners, f); 49 | if (appended) { 50 | this._queryForListener(f); 51 | } else { 52 | logger.debug('breakpoint listener already exists', f); 53 | return; 54 | } 55 | } 56 | }, { 57 | key: 'addQuery', 58 | value: function addQuery(name, query) { 59 | new _Query2.default(name, this._breakpointMatch, query); 60 | } 61 | }, { 62 | key: 'unlistenBreakpoint', 63 | value: function unlistenBreakpoint(f) { 64 | this._breakpointListeners = this._breakpointListeners.filter(function (func) { 65 | return func !== f; 66 | }); 67 | } 68 | }, { 69 | key: 'attach', 70 | value: function attach(style, notifier) { 71 | if (!style) { 72 | logger.warn('no style to attach'); 73 | return; 74 | } 75 | 76 | if (!notifier) { 77 | // default notifier logs new_style 78 | notifier = function notifier(new_style) { 79 | logger.debug('style modified', new_style); 80 | }; 81 | } 82 | 83 | var atoms = []; 84 | if (_fsts.JS.hasProps(style, '@media.*')) { 85 | var atom = new _MediaQueryAtom2.default(style, notifier); 86 | atoms.push(atom); 87 | } 88 | 89 | _fsts.JS.traverseProps(style, function (path, key, val) { 90 | if (_fsts.JS.hasProps(val, '@media.*')) { 91 | var _atom = new _MediaQueryAtom2.default(val, function (new_style) { 92 | notifier(style); // notify with root style. 93 | }); 94 | atoms.push(_atom); 95 | } 96 | }); 97 | 98 | this._styles.push({ 99 | style: style, 100 | atoms: atoms 101 | }); 102 | 103 | return style; 104 | } 105 | }, { 106 | key: 'detach', 107 | value: function detach(style) { 108 | var found = this._styles.filter(function (entry) { 109 | return entry.style === style; 110 | }); 111 | if (found.length > 0) { 112 | found[0].atoms.forEach(function (atom) { 113 | return atom.unlisten(); 114 | }); 115 | } 116 | } 117 | }, { 118 | key: '_breakpointMatch', 119 | value: function _breakpointMatch(match, name) { 120 | if (match.matches) { 121 | // in vw 122 | this._onBreakpoint(name); 123 | } else { 124 | // out vw 125 | } 126 | } 127 | }, { 128 | key: '_onBreakpoint', 129 | value: function _onBreakpoint(vw) { 130 | logger.debug('on breakpoint ' + vw); 131 | 132 | this._breakpointListeners.forEach(function (listener) { 133 | try { 134 | listener(vw); 135 | } catch (e) { 136 | logger.error('on breakpoint ' + vw + ' error', listener, e); 137 | } 138 | }); 139 | } 140 | }, { 141 | key: '_queryForListener', 142 | value: function _queryForListener(f) { 143 | var vw = 'xs'; 144 | for (var i = 0; i < this._ranges.length; i++) { 145 | var range = this._ranges[i]; 146 | if (range.matchMin()) { 147 | vw = range.name; 148 | } 149 | } 150 | f(vw); 151 | } 152 | }]); 153 | 154 | return MatchMedia; 155 | }(); 156 | 157 | exports.default = MatchMedia; -------------------------------------------------------------------------------- /dist/media/MediaQueryAtom.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | var _fsts = require('fsts'); 10 | 11 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 12 | 13 | var MediaQueryAtom = function () { 14 | function MediaQueryAtom(style, notifier) { 15 | _classCallCheck(this, MediaQueryAtom); 16 | 17 | if (!style) { 18 | return; 19 | } 20 | 21 | this._style = style; 22 | this._old_style = Object.assign({}, style); 23 | this._queries = []; 24 | this._notifier = notifier; 25 | 26 | this._init(); 27 | } 28 | 29 | _createClass(MediaQueryAtom, [{ 30 | key: 'unlisten', 31 | value: function unlisten() { 32 | this._queries.forEach(function (query) { 33 | var mql = query.mql, 34 | listener = query.listener; 35 | 36 | mql.removeListener(listener); 37 | }); 38 | } 39 | }, { 40 | key: '_init', 41 | value: function _init() { 42 | if (!_fsts.Device.hasWindow()) { 43 | return; 44 | } 45 | 46 | var that = this; 47 | var style = this._style; 48 | Object.keys(style).forEach(function (key) { 49 | if (!key.startsWith('@media')) { 50 | return; 51 | } 52 | 53 | var rules = key.split(/\s+/).slice(1).join(' '); 54 | if (!rules) { 55 | return; 56 | } 57 | 58 | var matchStyle = style[key]; 59 | var mql = window.matchMedia(rules); 60 | var listener = function listener(match) { 61 | matchStyle._matches = match.matches; 62 | that._applyMatches(); 63 | }; 64 | mql.addListener(listener); 65 | 66 | matchStyle._matches = mql.matches; 67 | that._queries.push({ 68 | matchStyle: matchStyle, 69 | mql: mql, 70 | listener: listener 71 | }); 72 | }); 73 | that._applyMatches(); 74 | } 75 | }, { 76 | key: '_applyMatches', 77 | value: function _applyMatches() { 78 | if (!this._notifier) { 79 | return; 80 | } // do nothing 81 | 82 | var new_style = Object.assign({}, this._old_style); 83 | this._queries.forEach(function (query) { 84 | var matchStyle = query.matchStyle; 85 | 86 | if (matchStyle._matches) { 87 | Object.assign(new_style, matchStyle); 88 | } 89 | }); 90 | 91 | this._notifier(new_style); 92 | } 93 | }]); 94 | 95 | return MediaQueryAtom; 96 | }(); 97 | 98 | exports.default = MediaQueryAtom; -------------------------------------------------------------------------------- /dist/media/Query.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 10 | 11 | var Query = function () { 12 | function Query(name, onMatch, query) { 13 | _classCallCheck(this, Query); 14 | 15 | this.name = name; 16 | this.onMatch = onMatch; 17 | 18 | this._match = this._match.bind(this); 19 | 20 | this._mql = window.matchMedia(query); 21 | this._mql.addListener(this._match); 22 | } 23 | 24 | _createClass(Query, [{ 25 | key: "match", 26 | value: function match() { 27 | return this._mql && this._mql.matches; 28 | } 29 | }, { 30 | key: "unlisten", 31 | value: function unlisten() { 32 | if (this._mql) { 33 | this._mql.removeListener(this._match); 34 | } 35 | } 36 | }, { 37 | key: "_match", 38 | value: function _match(match) { 39 | this.onMatch(match, this.name); 40 | } 41 | }]); 42 | 43 | return Query; 44 | }(); 45 | 46 | exports.default = Query; -------------------------------------------------------------------------------- /dist/media/Range.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 10 | 11 | var Range = function () { 12 | function Range(name, onMatch, min, max) { 13 | _classCallCheck(this, Range); 14 | 15 | this.name = name; 16 | this.onMatch = onMatch; 17 | 18 | this._match = this._match.bind(this); 19 | 20 | if (min) { 21 | this._min = window.matchMedia('(min-width: ' + min + ')'); 22 | this._min.addListener(this._match); 23 | } 24 | if (max) { 25 | this._max = window.matchMedia('(max-width: ' + max + ')'); 26 | this._max.addListener(this._match); 27 | } 28 | } 29 | 30 | _createClass(Range, [{ 31 | key: 'matchMin', 32 | value: function matchMin() { 33 | return !this._min || this._min.matches; 34 | } 35 | }, { 36 | key: 'matchMax', 37 | value: function matchMax() { 38 | return !this._max || this._max.matches; 39 | } 40 | }, { 41 | key: '_match', 42 | value: function _match(match) { 43 | this.onMatch(match, this.name); 44 | } 45 | }]); 46 | 47 | return Range; 48 | }(); 49 | 50 | exports.default = Range; -------------------------------------------------------------------------------- /dist/media/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _fsts = require('fsts'); 8 | 9 | var _Empty = require('./Empty'); 10 | 11 | var _Empty2 = _interopRequireDefault(_Empty); 12 | 13 | var _MatchMedia = require('./MatchMedia'); 14 | 15 | var _MatchMedia2 = _interopRequireDefault(_MatchMedia); 16 | 17 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 18 | 19 | var _instance = new _MatchMedia2.default(); 20 | 21 | exports.default = _instance; -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Fluid-React Demo 2 | 3 | Demo app for fluid-react. Build the whole UI with inline-styles, without any CSS. 4 | 5 | Live at: [https://richardzcode.github.io/fluid-react/index.html](https://richardzcode.github.io/fluid-react/index.html) 6 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluid-test", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "fluid-react": "file:..", 7 | "fsts": "0.0.24", 8 | "react": "^16.2.0", 9 | "react-dom": "^16.2.0", 10 | "react-fontawesome": "^1.6.1", 11 | "react-scripts": "1.0.17" 12 | }, 13 | "scripts": { 14 | "start": "react-scripts start", 15 | "build": "react-scripts build", 16 | "test": "react-scripts test --env=jsdom", 17 | "eject": "react-scripts eject" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardzcode/fluid-react/6a3978e656f14eec043b8ccb681ea50a3bcb2d07/example/public/favicon.ico -------------------------------------------------------------------------------- /example/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | Fluid React Demo 15 | 16 | 17 | 18 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import { 4 | Navbar, 5 | NavBrand, 6 | NavScroll, 7 | NavRight, 8 | NavNav, 9 | NavItem, 10 | 11 | Icon 12 | } from './bootstrap'; 13 | 14 | import { AppStyle } from './theme'; 15 | import { 16 | GridSection, 17 | MediaQuerySection, 18 | MatchSection, 19 | PseudoSection 20 | } from './containers'; 21 | 22 | const repo = 'https://github.com/richardzcode/fluid-react'; 23 | const stylejs = repo + '/blob/master/example/src/theme/Bootstrap.js'; 24 | 25 | class App extends Component { 26 | constructor(props) { 27 | super(props); 28 | 29 | this.state = { 30 | active: 'grid' 31 | } 32 | } 33 | 34 | openSourceCode() { 35 | window.location.href = stylejs; 36 | } 37 | 38 | openGitHub() { 39 | window.location.href = repo; 40 | } 41 | 42 | render() { 43 | const { active } = this.state; 44 | 45 | return ( 46 |
47 | 48 | F-R 49 | 50 | this.setState({ active: 'grid' })} 54 | >Grid 55 | this.setState({ active: 'mq' })} 59 | >Media Query 60 | this.setState({ active: 'match' })} 64 | >Match 65 | this.setState({ active: 'pseudo' })} 69 | >Pseudo 70 | 71 | 72 | 75 | 76 | 77 | 80 | 81 | GitHub 82 | 83 | 84 | 85 | 86 | {active === 'grid'? : null} 87 | {active === 'mq'? : null} 88 | {active === 'match'? : null} 89 | {active === 'pseudo'? : null} 90 | 91 |
92 | ); 93 | } 94 | } 95 | 96 | export default App; 97 | -------------------------------------------------------------------------------- /example/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 | }); 9 | -------------------------------------------------------------------------------- /example/src/bootstrap/Icon.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import FontAwesome from 'react-fontawesome'; 4 | import { withMediaQuery } from 'fluid-react'; 5 | 6 | import { Bootstrap } from '../theme'; 7 | 8 | class _Icon extends Component { 9 | render() { 10 | const { name } = this.props; 11 | return ( 12 | 13 | ) 14 | } 15 | } 16 | const Icon = withMediaQuery(_Icon); 17 | 18 | export { Icon }; 19 | -------------------------------------------------------------------------------- /example/src/bootstrap/Nav.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import { Div, Ul, Li } from 'fluid-react'; 4 | import { JS } from 'fsts'; 5 | 6 | import { Bootstrap } from '../theme'; 7 | import { Icon } from './Icon'; 8 | 9 | const Navbar = (props) => { 10 | return
{props.children}
11 | } 12 | 13 | const NavBrand = (props) => ( 14 |
{props.children}
15 | ) 16 | 17 | const NavScroll = (props) => ( 18 |
{props.children}
19 | ) 20 | 21 | const NavRight = (props) => ( 22 |
{props.children}
23 | ) 24 | 25 | const NavNav = (props) => { 26 | return 27 | } 28 | 29 | class NavItem extends Component { 30 | render() { 31 | const { style, active } = this.props; 32 | const styl = Object.assign( 33 | {}, 34 | Bootstrap.navItem, 35 | style, 36 | active? Bootstrap.navItem['.active'] : null 37 | ); 38 | const p = JS.lessProps(this.props, ['style', 'active']); 39 | return
  • {this.props.children}
  • 40 | } 41 | } 42 | 43 | class NavSidebar extends Component { 44 | constructor(props) { 45 | super(props); 46 | 47 | this.state = { 48 | collapsed: !!props.collapsed 49 | } 50 | } 51 | 52 | render() { 53 | const { collapsed } = this.state; 54 | return ( 55 |
    56 |
    this.setState({ collapsed: !this.state.collapsed })} 59 | >
    60 | {collapsed? null : {this.props.children} } 61 |
    62 | ) 63 | } 64 | } 65 | 66 | const NavSidebarNav = (props) => ( 67 | 68 | ) 69 | 70 | class NavSidebarItem extends Component { 71 | render() { 72 | const { style, active } = this.props; 73 | const styl = Object.assign( 74 | {}, 75 | Bootstrap.navSidebarItem, 76 | style, 77 | active? Bootstrap.navSidebarItem['.active'] : null 78 | ) 79 | const p = JS.lessProps(this.props, 'style'); 80 | return
  • {this.props.children}
  • 81 | } 82 | } 83 | 84 | export { 85 | Navbar, 86 | NavBrand, 87 | NavScroll, 88 | NavRight, 89 | NavNav, 90 | NavItem, 91 | NavSidebar, 92 | NavSidebarNav, 93 | NavSidebarItem 94 | }; 95 | -------------------------------------------------------------------------------- /example/src/bootstrap/Section.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Div, Pre } from 'fluid-react'; 4 | import { JS } from 'fsts'; 5 | 6 | import { Bootstrap } from '../theme'; 7 | 8 | const Section = (props) => ( 9 |
    {props.children}
    10 | ) 11 | 12 | const Panel = (props) => ( 13 |
    {props.children}
    14 | ) 15 | 16 | const Block = (props) => ( 17 |
    {props.children}
    18 | ) 19 | 20 | const Code = (props) => { 21 | const { source } = props; 22 | const p = JS.lessProps(props, 'source'); 23 | return ( 24 |
    {source}
    25 | ) 26 | } 27 | 28 | const H1 = (props) => ( 29 |
    {props.children}
    30 | ) 31 | 32 | const H2 = (props) => ( 33 |
    {props.children}
    34 | ) 35 | 36 | const H3 = (props) => ( 37 |
    {props.children}
    38 | ) 39 | 40 | export { 41 | Section, 42 | Panel, 43 | Block, 44 | Code, 45 | 46 | H1, 47 | H2, 48 | H3 49 | }; 50 | -------------------------------------------------------------------------------- /example/src/bootstrap/index.js: -------------------------------------------------------------------------------- 1 | export * from './Nav'; 2 | export * from './Icon'; 3 | export * from './Section'; 4 | -------------------------------------------------------------------------------- /example/src/components/grid/EqualWidth.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Container, Row, Col } from './GridWrapper'; 4 | import { 5 | Panel, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | 12 | 13 | One of three columns 14 | One of three columns 15 | One of three columns 16 | 17 | 18 | ` 19 | 20 | const EqualWidth = (props) => ( 21 | 22 |

    Equal Width

    23 | 24 | 25 | One of three columns 26 | One of three columns 27 | One of three columns 28 | 29 | 30 | 31 |
    32 | ) 33 | 34 | export default EqualWidth; 35 | -------------------------------------------------------------------------------- /example/src/components/grid/Fluid.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Container, Row, Col } from './GridWrapper'; 4 | import { 5 | Panel, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | 12 | 13 | 1 14 | 2 15 | 3 16 | 4 17 | 5 18 | 6 19 | 7 20 | 8 21 | 9 22 | 10 23 | 11 24 | 12 25 | 26 | 27 | ` 28 | 29 | const Fluid = (props) => ( 30 | 31 |

    Fluid

    32 | 33 | 34 | 1 35 | 2 36 | 3 37 | 4 38 | 5 39 | 6 40 | 7 41 | 8 42 | 9 43 | 10 44 | 11 45 | 12 46 | 47 | 48 | 49 |
    50 | ) 51 | 52 | export default Fluid; 53 | -------------------------------------------------------------------------------- /example/src/components/grid/GridWrapper.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { JS } from 'fsts'; 3 | 4 | import { 5 | Container as GContainer, 6 | Row as GRow, 7 | Col as GCol, 8 | W100 as GW100 9 | } from 'fluid-react'; 10 | 11 | const GridStyle = { 12 | container: { 13 | padding: '1.5rem', 14 | borderWidth: '.2rem', 15 | border: 'solid #f7f7f9' 16 | }, 17 | row: { 18 | margin: '0.5rem auto', 19 | backgroundColor: 'rgba(255,0,0,.1)' 20 | }, 21 | col: { 22 | padding: '.75rem 15px', 23 | backgroundColor: 'rgba(86,61,124,.15)', 24 | border: '1px solid rgba(86,61,124,.2)', 25 | maxHeight: '5rem' 26 | } 27 | } 28 | 29 | export const Container = (props) => ( 30 | 34 | {props.children} 35 | 36 | ) 37 | 38 | export const Row = (props) => ( 39 | 43 | {props.children} 44 | 45 | ) 46 | 47 | export const Col = (props) => ( 48 | 52 | {props.children} 53 | 54 | ) 55 | 56 | export const W100 = (props) => ( 57 | 61 | {props.children} 62 | 63 | ) 64 | -------------------------------------------------------------------------------- /example/src/components/grid/HorizontalAlignment.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Container, Row, Col } from './GridWrapper'; 4 | import { 5 | Panel, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | 12 | 13 | One of two columns 14 | One of two columns 15 | 16 | 17 | One of two columns 18 | One of two columns 19 | 20 | 21 | One of two columns 22 | One of two columns 23 | 24 | 25 | One of two columns 26 | One of two columns 27 | 28 | 29 | ` 30 | 31 | const HorizontalAlignment = (props) => ( 32 | 33 |

    Horizontal Alignment

    34 | 35 | 36 | One of two columns 37 | One of two columns 38 | 39 | 40 | One of two columns 41 | One of two columns 42 | 43 | 44 | One of two columns 45 | One of two columns 46 | 47 | 48 | One of two columns 49 | One of two columns 50 | 51 | 52 | 53 |
    54 | ) 55 | 56 | export default HorizontalAlignment; 57 | -------------------------------------------------------------------------------- /example/src/components/grid/MultiRow.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Container, Row, Col, W100 } from './GridWrapper'; 4 | import { 5 | Panel, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | 12 | 13 | col 14 | col 15 | 16 | col 17 | col 18 | 19 | 20 | ` 21 | 22 | const MultiRow = (props) => ( 23 | 24 |

    Multi-Row

    25 | 26 | 27 | col 28 | col 29 | 30 | col 31 | col 32 | 33 | 34 | 35 |
    36 | ) 37 | 38 | export default MultiRow; 39 | -------------------------------------------------------------------------------- /example/src/components/grid/Nest.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Container, Row, Col } from './GridWrapper'; 4 | import { 5 | Panel, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | 12 | 13 | 14 | Level 1: xs-9 15 | 16 | 17 | Level 2: xs-8, sm-6 18 | 19 | 20 | Level 2: xs-4, sm-6 21 | 22 | 23 | 24 | 25 | 26 | ` 27 | 28 | const Nest = (props) => ( 29 | 30 |

    Nest

    31 | 32 | 33 | 34 | Level 1: xs-9 35 | 36 | 37 | Level 2: xs-8, sm-6 38 | 39 | 40 | Level 2: xs-4, sm-6 41 | 42 | 43 | 44 | 45 | 46 | 47 |
    48 | ) 49 | 50 | export default Nest; 51 | -------------------------------------------------------------------------------- /example/src/components/grid/OneWidth.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Container, Row, Col } from './GridWrapper'; 4 | import { 5 | Panel, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | 12 | 13 | 1 of 3 14 | 2 of 3 (wider) 15 | 3 of 3 16 | 17 | 18 | 1 of 3 19 | 2 of 3 (wider) 20 | 3 of 3 21 | 22 | 23 | ` 24 | 25 | const OneWidth = (props) => ( 26 | 27 |

    Set One Width

    28 | 29 | 30 | 1 of 3 31 | 2 of 3 (wider) 32 | 3 of 3 33 | 34 | 35 | 1 of 3 36 | 2 of 3 (wider) 37 | 3 of 3 38 | 39 | 40 | 41 |
    42 | ) 43 | 44 | export default OneWidth; 45 | -------------------------------------------------------------------------------- /example/src/components/grid/SelfAlignment.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Container, Row, Col } from './GridWrapper'; 4 | import { 5 | Panel, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | 12 | 13 | 14 | One of three columns 15 | 16 | 17 | One of three columns 18 | 19 | 20 | One of three columns 21 | 22 | 23 | 24 | ` 25 | 26 | const SelfAlignment = (props) => ( 27 | 28 |

    Self Alignment

    29 | 30 | 31 | 32 | One of three columns 33 | 34 | 35 | One of three columns 36 | 37 | 38 | One of three columns 39 | 40 | 41 | 42 | 43 |
    44 | ) 45 | 46 | export default SelfAlignment; 47 | -------------------------------------------------------------------------------- /example/src/components/grid/VariableWidth.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Container, Row, Col } from './GridWrapper'; 4 | import { 5 | Panel, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | 12 | 13 | 1 of 3 14 | variable width content 15 | 1 of 3 16 | 17 | 18 | ` 19 | 20 | const VariableWidth = (props) => ( 21 | 22 |

    Variable Width

    23 | 24 | 25 | 1 of 3 26 | variable width content 27 | 1 of 3 28 | 29 | 30 | 31 |
    32 | ) 33 | 34 | export default VariableWidth; 35 | -------------------------------------------------------------------------------- /example/src/components/grid/VerticalAlignment.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Container, Row, Col } from './GridWrapper'; 4 | import { 5 | Panel, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | 12 | 13 | One of three columns 14 | One of three columns 15 | One of three columns 16 | 17 | 18 | One of three columns 19 | One of three columns 20 | One of three columns 21 | 22 | 23 | One of three columns 24 | One of three columns 25 | One of three columns 26 | 27 | 28 | ` 29 | 30 | const VerticalAlignment = (props) => ( 31 | 32 |

    Vertical Alignment

    33 | 34 | 35 | One of three columns 36 | One of three columns 37 | One of three columns 38 | 39 | 40 | One of three columns 41 | One of three columns 42 | One of three columns 43 | 44 | 45 | One of three columns 46 | One of three columns 47 | One of three columns 48 | 49 | 50 | 51 |
    52 | ) 53 | 54 | export default VerticalAlignment; 55 | -------------------------------------------------------------------------------- /example/src/components/grid/ZeroWidth.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Container, Row, Col } from './GridWrapper'; 4 | import { 5 | Panel, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | 12 | 13 | 1 of 2 14 | 2 of 2 15 | 16 | 17 | ` 18 | 19 | const ZeroWidth = (props) => ( 20 | 21 |

    Zero Width

    22 | 23 | 24 | 1 of 2 25 | 2 of 2 26 | 27 | 28 | 29 |
    30 | ) 31 | 32 | export default ZeroWidth; 33 | -------------------------------------------------------------------------------- /example/src/components/grid/index.js: -------------------------------------------------------------------------------- 1 | export { default as EqualWidth } from './EqualWidth'; 2 | export { default as Fluid } from './Fluid'; 3 | export { default as OneWidth } from './OneWidth'; 4 | export { default as VariableWidth } from './VariableWidth'; 5 | export { default as ZeroWidth } from './ZeroWidth'; 6 | export { default as MultiRow } from './MultiRow'; 7 | export { default as VerticalAlignment } from './VerticalAlignment'; 8 | export { default as SelfAlignment } from './SelfAlignment'; 9 | export { default as HorizontalAlignment } from './HorizontalAlignment'; 10 | export { default as Nest } from './Nest'; 11 | -------------------------------------------------------------------------------- /example/src/components/match/Listener.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import { MediaQuery } from 'fluid-react'; 4 | 5 | import { Row, Col } from '../grid/GridWrapper'; 6 | import { 7 | Panel, 8 | Block, 9 | Code, 10 | H3 11 | } from '../../bootstrap'; 12 | 13 | const source = ` 14 | const blockStyle = { 15 | backgroundColor: '#5bc0de', 16 | } 17 | 18 | const Mobile = (props) => ( 19 | 20 | No sidebar in Mobile version 21 | 22 | ) 23 | 24 | const Desktop = (props) => ( 25 | 26 | Desktop version 27 | Sidebar 28 | 29 | ) 30 | 31 | class Comp extends Component { 32 | constructor(props) { 33 | super(props); 34 | 35 | this.onBreakpoint = this.onBreakpoint.bind(this); 36 | 37 | this.state = { 38 | version: 'mobile' 39 | } 40 | } 41 | 42 | componentDidMount() { 43 | MediaQuery.listenBreakpoint(this.onBreakpoint); 44 | } 45 | 46 | componentWillUnmount() { 47 | MediaQuery.unlistenBreakpoint(this.onBreakpoint); 48 | } 49 | 50 | onBreakpoint(vw) { 51 | this.setState({ 52 | version: ['xs', 'sm'].includes(vw)? 'mobile' : 'desktop' 53 | }); 54 | } 55 | 56 | render() { 57 | const { version } = this.state; 58 | return ( 59 | (version === 'mobile')? : 60 | ) 61 | } 62 | } 63 | ` 64 | 65 | const blockStyle = { 66 | backgroundColor: '#5bc0de', 67 | } 68 | 69 | const Mobile = (props) => ( 70 | 71 | No sidebar in Mobile version 72 | 73 | ) 74 | 75 | const Desktop = (props) => ( 76 | 77 | Desktop version 78 | Sidebar 79 | 80 | ) 81 | 82 | class Comp extends Component { 83 | constructor(props) { 84 | super(props); 85 | 86 | this.onBreakpoint = this.onBreakpoint.bind(this); 87 | 88 | this.state = { 89 | version: 'mobile' 90 | } 91 | } 92 | 93 | componentDidMount() { 94 | MediaQuery.listenBreakpoint(this.onBreakpoint); 95 | } 96 | 97 | componentWillUnmount() { 98 | MediaQuery.unlistenBreakpoint(this.onBreakpoint); 99 | } 100 | 101 | onBreakpoint(vw) { 102 | this.setState({ 103 | version: ['xs', 'sm'].includes(vw)? 'mobile' : 'desktop' 104 | }); 105 | } 106 | 107 | render() { 108 | const { version } = this.state; 109 | return ( 110 | (version === 'mobile')? : 111 | ) 112 | } 113 | } 114 | 115 | const Listener = (props) => ( 116 | 117 |

    Listener

    118 | 119 | 120 |
    121 | ) 122 | 123 | export default Listener; 124 | -------------------------------------------------------------------------------- /example/src/components/match/MatchEl.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Match } from 'fluid-react'; 4 | 5 | import { 6 | Panel, 7 | Block, 8 | Code, 9 | H3 10 | } from '../../bootstrap'; 11 | 12 | const source = ` 13 | 14 | xs,sm 15 | 16 | 17 | md,lg 18 | 19 | 20 | xl 21 | 22 | ` 23 | 24 | const blockStyle = { 25 | backgroundColor: '#5bc0de', 26 | } 27 | 28 | const MatchEl = (props) => ( 29 | 30 |

    Match

    31 | 32 | xs,sm 33 | 34 | 35 | md,lg 36 | 37 | 38 | xl 39 | 40 | 41 |
    42 | ) 43 | 44 | export default MatchEl; 45 | -------------------------------------------------------------------------------- /example/src/components/match/index.js: -------------------------------------------------------------------------------- 1 | export { default as MatchEl } from './MatchEl'; 2 | export { default as Listener } from './Listener'; 3 | -------------------------------------------------------------------------------- /example/src/components/mediaquery/ResponsiveStyle.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { 4 | Panel, 5 | Block, 6 | Code, 7 | H3 8 | } from '../../bootstrap'; 9 | 10 | const source = ` 11 | const responsiveColor = { 12 | padding: '2rem', 13 | color: '#fff', 14 | backgroundColor: '#0275d8', 15 | borderColor: '#0275d8', 16 | '@media (min-width: 576px) and (max-width: 767px)': { 17 | backgroundColor: '#5cb85c', 18 | borderColor: '#5cb85c' 19 | }, 20 | '@media (min-width: 768px) and (max-width: 991px)': { 21 | backgroundColor: '#5bc0de', 22 | borderColor: '#5bc0de' 23 | }, 24 | '@media (min-width: 992px) and (max-width: 1199px)': { 25 | backgroundColor: '#f0ad4e', 26 | borderColor: '#f0ad4e' 27 | }, 28 | '@media (min-width: 1200px)': { 29 | backgroundColor: '#d9534f', 30 | borderColor: '#d9534f' 31 | } 32 | }; 33 | 34 | const ResponsiveBlock = (props) => ( 35 | Color changes with width 36 | ) 37 | ` 38 | 39 | const responsiveColor = { 40 | padding: '2rem', 41 | color: '#fff', 42 | backgroundColor: '#0275d8', 43 | borderColor: '#0275d8', 44 | '@media (min-width: 576px) and (max-width: 767px)': { 45 | backgroundColor: '#5cb85c', 46 | borderColor: '#5cb85c' 47 | }, 48 | '@media (min-width: 768px) and (max-width: 991px)': { 49 | backgroundColor: '#5bc0de', 50 | borderColor: '#5bc0de' 51 | }, 52 | '@media (min-width: 992px) and (max-width: 1199px)': { 53 | backgroundColor: '#f0ad4e', 54 | borderColor: '#f0ad4e' 55 | }, 56 | '@media (min-width: 1200px)': { 57 | backgroundColor: '#d9534f', 58 | borderColor: '#d9534f' 59 | } 60 | }; 61 | 62 | const ResponsiveStyle = (props) => ( 63 | 64 |

    Responsive Style

    65 | Color changes with width 66 | 67 |
    68 | ) 69 | 70 | export default ResponsiveStyle; 71 | -------------------------------------------------------------------------------- /example/src/components/mediaquery/index.js: -------------------------------------------------------------------------------- 1 | export { default as ResponsiveStyle } from './ResponsiveStyle'; 2 | -------------------------------------------------------------------------------- /example/src/components/pseudo/Before.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { withPseudo } from 'fluid-react'; 4 | 5 | import { 6 | Panel, 7 | Code, 8 | H3 9 | } from '../../bootstrap'; 10 | 11 | const source = ` 12 | const brandStyle = { 13 | fontSize: '24px', 14 | verticalAlign: 'top', 15 | padding: '4px', 16 | '::before': { 17 | content: '', 18 | display: 'inline-block', 19 | width: '64px', 20 | height: '32px', 21 | backgroundImage: 'url(https://reactjs.org/logo-og.png)', 22 | backgroundSize: '64px 32px' 23 | } 24 | } 25 | 26 | const BrandName = (props) => ( 27 | {props.children} 28 | ) 29 | 30 | export const Brand = withPseudo(BrandName); 31 | ` 32 | const brandStyle = { 33 | fontSize: '24px', 34 | verticalAlign: 'top', 35 | padding: '4px', 36 | '::before': { 37 | content: '', 38 | display: 'inline-block', 39 | width: '64px', 40 | height: '32px', 41 | backgroundImage: 'url(https://reactjs.org/logo-og.png)', 42 | backgroundSize: '64px 32px' 43 | } 44 | } 45 | 46 | const BrandName = (props) => ( 47 | {props.children} 48 | ) 49 | 50 | export const Brand = withPseudo(BrandName); 51 | 52 | const Before = (props) => ( 53 | 54 |

    ::brefore

    55 | React 56 | 57 |
    58 | ) 59 | 60 | export default Before; 61 | -------------------------------------------------------------------------------- /example/src/components/pseudo/index.js: -------------------------------------------------------------------------------- 1 | export { default as Before } from './Before'; 2 | -------------------------------------------------------------------------------- /example/src/containers/GridSection.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import { Container, Row, Col } from 'fluid-react'; 4 | 5 | import { Section } from '../bootstrap'; 6 | 7 | import Sidebar from './Sidebar'; 8 | 9 | import { 10 | EqualWidth, 11 | Fluid, 12 | OneWidth, 13 | VariableWidth, 14 | ZeroWidth, 15 | MultiRow, 16 | VerticalAlignment, 17 | SelfAlignment, 18 | HorizontalAlignment, 19 | Nest 20 | } from '../components/grid'; 21 | 22 | export default class GridSection extends Component { 23 | constructor(props) { 24 | super(props); 25 | 26 | this.activate = this.activate.bind(this); 27 | 28 | this.state = { 29 | active: 'equal_width' 30 | } 31 | } 32 | 33 | activate(name) { 34 | this.setState({ active: name }); 35 | } 36 | 37 | render() { 38 | const { active } = this.state; 39 | const items = [ 40 | { name: 'equal_width', title: 'Equal Width' }, 41 | { name: 'fluid', title: 'Fluid' }, 42 | { name: 'one_width', title: 'Set One Width' }, 43 | { name: 'variable_width', title: 'Variable Width' }, 44 | { name: 'zero_width', title: 'Zero Width' }, 45 | { name: 'multi_row', title: 'Multi-Row' }, 46 | { name: 'vertical_alignment', title: 'Vertical Alignment' }, 47 | { name: 'self_alignment', title: 'Self Alignment' }, 48 | { name: 'horizontal_alignment', title: 'Horizontal Alignment' }, 49 | { name: 'nest', title: 'Nest' } 50 | ]; 51 | return ( 52 |
    53 | 54 | 55 | 56 | 60 | 61 | 62 | { active === 'equal_width'? : null } 63 | { active === 'fluid'? : null } 64 | { active === 'one_width'? : null } 65 | { active === 'variable_width'? : null } 66 | { active === 'zero_width'? : null } 67 | { active === 'multi_row'? : null } 68 | { active === 'vertical_alignment'? : null } 69 | { active === 'self_alignment'? : null } 70 | { active === 'horizontal_alignment'? : null } 71 | { active === 'nest'? : null } 72 | 73 | 74 | 75 |
    76 | ) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /example/src/containers/MatchSection.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import { Container, Row, Col } from 'fluid-react'; 4 | 5 | import { Section } from '../bootstrap'; 6 | 7 | import Sidebar from './Sidebar'; 8 | 9 | import { 10 | Listener, 11 | MatchEl 12 | } from '../components/match'; 13 | 14 | export default class MatchSection extends Component { 15 | constructor(props) { 16 | super(props); 17 | 18 | this.activate = this.activate.bind(this); 19 | 20 | this.state = { 21 | active: 'match' 22 | } 23 | } 24 | 25 | activate(name) { 26 | this.setState({ active: name }); 27 | } 28 | 29 | render() { 30 | const { active } = this.state; 31 | const items = [ 32 | { name: 'match', title: 'Match' }, 33 | { name: 'listener', title: 'Listener' } 34 | ]; 35 | return ( 36 |
    37 | 38 | 39 | 40 | 44 | 45 | 46 | { active === 'match'? : null } 47 | { active === 'listener'? : null } 48 | 49 | 50 | 51 |
    52 | ) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /example/src/containers/MediaQuerySection.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import { Container, Row, Col } from 'fluid-react'; 4 | 5 | import { Section } from '../bootstrap'; 6 | 7 | import Sidebar from './Sidebar'; 8 | 9 | import { 10 | ResponsiveStyle 11 | } from '../components/mediaquery'; 12 | 13 | export default class MediaQuerySection extends Component { 14 | constructor(props) { 15 | super(props); 16 | 17 | this.activate = this.activate.bind(this); 18 | 19 | this.state = { 20 | active: 'responsive_style' 21 | } 22 | } 23 | 24 | activate(name) { 25 | this.setState({ active: name }); 26 | } 27 | 28 | render() { 29 | const { active } = this.state; 30 | const items = [ 31 | { name: 'responsive_style', title: 'Responsive Style' } 32 | ]; 33 | return ( 34 |
    35 | 36 | 37 | 38 | 42 | 43 | 44 | { active === 'responsive_style'? : null } 45 | 46 | 47 | 48 |
    49 | ) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /example/src/containers/PseudoSection.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import { Container, Row, Col } from 'fluid-react'; 4 | 5 | import { Section } from '../bootstrap'; 6 | 7 | import Sidebar from './Sidebar'; 8 | 9 | import { 10 | Before 11 | } from '../components/pseudo'; 12 | 13 | export default class PsudoSection extends Component { 14 | constructor(props) { 15 | super(props); 16 | 17 | this.activate = this.activate.bind(this); 18 | 19 | this.state = { 20 | active: 'before' 21 | } 22 | } 23 | 24 | activate(name) { 25 | this.setState({ active: name }); 26 | } 27 | 28 | render() { 29 | const { active } = this.state; 30 | const items = [ 31 | { name: 'before', title: '::before' } 32 | ]; 33 | return ( 34 |
    35 | 36 | 37 | 38 | 42 | 43 | 44 | { active === 'before'? : null } 45 | 46 | 47 | 48 |
    49 | ) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /example/src/containers/Sidebar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { 4 | NavSidebar, 5 | NavSidebarNav, 6 | NavSidebarItem 7 | } from '../bootstrap'; 8 | 9 | const Sidebar = (props) => { 10 | const { activate, items } = props; 11 | return ( 12 | 13 | 14 | { 15 | items.map(item => ( 16 | activate(item.name)} 19 | >{item.title} 20 | )) 21 | } 22 | 23 | 24 | ) 25 | } 26 | 27 | export default Sidebar; 28 | -------------------------------------------------------------------------------- /example/src/containers/index.js: -------------------------------------------------------------------------------- 1 | export { default as GridSection } from './GridSection'; 2 | export { default as MediaQuerySection } from './MediaQuerySection'; 3 | export { default as MatchSection } from './MatchSection'; 4 | export { default as PseudoSection } from './PseudoSection'; 5 | -------------------------------------------------------------------------------- /example/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /example/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 registerServiceWorker from './registerServiceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | registerServiceWorker(); 9 | -------------------------------------------------------------------------------- /example/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register() { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Lets check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl); 38 | } else { 39 | // Is not local host. Just register service worker 40 | registerValidSW(swUrl); 41 | } 42 | }); 43 | } 44 | } 45 | 46 | function registerValidSW(swUrl) { 47 | navigator.serviceWorker 48 | .register(swUrl) 49 | .then(registration => { 50 | registration.onupdatefound = () => { 51 | const installingWorker = registration.installing; 52 | installingWorker.onstatechange = () => { 53 | if (installingWorker.state === 'installed') { 54 | if (navigator.serviceWorker.controller) { 55 | // At this point, the old content will have been purged and 56 | // the fresh content will have been added to the cache. 57 | // It's the perfect time to display a "New content is 58 | // available; please refresh." message in your web app. 59 | console.log('New content is available; please refresh.'); 60 | } else { 61 | // At this point, everything has been precached. 62 | // It's the perfect time to display a 63 | // "Content is cached for offline use." message. 64 | console.log('Content is cached for offline use.'); 65 | } 66 | } 67 | }; 68 | }; 69 | }) 70 | .catch(error => { 71 | console.error('Error during service worker registration:', error); 72 | }); 73 | } 74 | 75 | function checkValidServiceWorker(swUrl) { 76 | // Check if the service worker can be found. If it can't reload the page. 77 | fetch(swUrl) 78 | .then(response => { 79 | // Ensure service worker exists, and that we really are getting a JS file. 80 | if ( 81 | response.status === 404 || 82 | response.headers.get('content-type').indexOf('javascript') === -1 83 | ) { 84 | // No service worker found. Probably a different app. Reload the page. 85 | navigator.serviceWorker.ready.then(registration => { 86 | registration.unregister().then(() => { 87 | window.location.reload(); 88 | }); 89 | }); 90 | } else { 91 | // Service worker found. Proceed as normal. 92 | registerValidSW(swUrl); 93 | } 94 | }) 95 | .catch(() => { 96 | console.log( 97 | 'No internet connection found. App is running in offline mode.' 98 | ); 99 | }); 100 | } 101 | 102 | export function unregister() { 103 | if ('serviceWorker' in navigator) { 104 | navigator.serviceWorker.ready.then(registration => { 105 | registration.unregister(); 106 | }); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /example/src/theme/AppStyle.js: -------------------------------------------------------------------------------- 1 | const AppStyle = { 2 | app: { 3 | fontFamily: `-apple-system, 4 | BlinkMacSystemFont, 5 | "Segoe UI", 6 | Roboto, 7 | "Helvetica Neue", 8 | Arial, 9 | sans-serif, 10 | "Apple Color Emoji", 11 | "Segoe UI Emoji", 12 | "Segoe UI Symbol" 13 | `, 14 | textAlign: 'center', 15 | lineHeight: '1.5rem' 16 | }, 17 | logo: { 18 | animation: 'App-logo-spin infinite 20s linear', 19 | height: '80px' 20 | }, 21 | header: { 22 | backgroundColor: '#222', 23 | height: '150px', 24 | padding: '20px', 25 | color: 'white' 26 | }, 27 | title: { 28 | fontSize: '1.5em' 29 | }, 30 | intro: { 31 | fontSize: 'large' 32 | }, 33 | content: { 34 | padding: '20px' 35 | }, 36 | 37 | h3: { 38 | fontWeight: '500', 39 | textAlign: 'left', 40 | marginBottom: '0.5rem' 41 | } 42 | } 43 | 44 | export default AppStyle; 45 | -------------------------------------------------------------------------------- /example/src/theme/Bootstrap.js: -------------------------------------------------------------------------------- 1 | const H = { 2 | fontWeight: '500', 3 | textAlign: 'left', 4 | marginBottom: '0.5rem' 5 | }; 6 | const H1 = Object.assign({}, H, { 7 | fontSize: '2.5rem' 8 | }); 9 | const H2 = Object.assign({}, H, { 10 | fontSize: '2rem' 11 | }); 12 | const H3 = Object.assign({}, H, { 13 | fontSize: '1.5rem' 14 | }); 15 | 16 | const Bootstrap = { 17 | navbar: { 18 | backgroundColor: '#563d7c', 19 | minHeight: '4rem', 20 | padding: '1rem', 21 | boxShadow: '0 0.5rem 1rem rgba(0,0,0,.05), inset 0 -1px 0 rgba(0,0,0,.1)', 22 | display: 'flex', 23 | flexDirection: 'column', 24 | alignItems: 'center', 25 | '@media (min-width: 768px)': { 26 | flexDirection: 'row' 27 | } 28 | }, 29 | navBrand: { 30 | display: 'inline-block', 31 | padding: '.45rem .3125rem', 32 | fontSize: '1.25rem', 33 | whiteSpace: 'nowrap', 34 | color: '#eee', 35 | border: '1px solid #ccc', 36 | borderRadius: '5px', 37 | alignSelf: 'center' 38 | }, 39 | navScroll: { 40 | maxWidth: '100%', 41 | height: '2.5rem', 42 | marginTop: '0.25rem', 43 | overflow: 'hidden' 44 | }, 45 | navRight: { 46 | display: 'flex', 47 | maxWidth: '100%', 48 | height: '2.5rem', 49 | marginTop: '0.25rem', 50 | overflow: 'hidden', 51 | marginLeft: 'auto', 52 | '@media (max-width: 767px)': { 53 | position: 'absolute', 54 | top: '.25rem', 55 | right: 0 56 | } 57 | }, 58 | navNav: { 59 | paddingLeft: '0', 60 | display: 'flex', 61 | listStyle: 'none', 62 | fontSize: '.875rem', 63 | color: '#cdbfe3', 64 | marginTop: '0.5rem', 65 | marginBottom: '0' 66 | }, 67 | navItem: { 68 | padding: '0 0.5rem', 69 | cursor: 'pointer', 70 | whiteSpace: 'nowrap', 71 | '.active': { 72 | color: '#eee' 73 | } 74 | }, 75 | navSidebar: { 76 | textAlign: 'left', 77 | overflow: 'hidden', 78 | padding: '0 1rem 1rem', 79 | borderRight: '1px solid #eee' 80 | }, 81 | navSidebarNav: { 82 | paddingLeft: '0', 83 | display: 'flex', 84 | flexDirection: 'column', 85 | listStyle: 'none', 86 | fontSize: '1rem', 87 | color: '#cdbfe3', 88 | marginTop: '0.5rem', 89 | marginBottom: '0' 90 | }, 91 | navSidebarItem: { 92 | padding: '0 0.5rem', 93 | cursor: 'pointer', 94 | whiteSpace: 'nowrap', 95 | color: 'rgba(0,0,0,.65)', 96 | lineHeight: '2rem', 97 | '.active': { 98 | color: '#000', 99 | fontWeight: '500' 100 | } 101 | }, 102 | 103 | icon: { 104 | fontSize: '1.5em', 105 | marginRight: '0.25em' 106 | }, 107 | 108 | section: { 109 | marginTop: '1rem' 110 | }, 111 | panel: { 112 | textAlign: 'left', 113 | padding: '0 1rem' 114 | }, 115 | block: { 116 | textAlign: 'center', 117 | padding: '1rem' 118 | }, 119 | 120 | code: { 121 | textAlign: 'left', 122 | backgroundColor: '#eee', 123 | margin: 0, 124 | padding: '0.5rem', 125 | lineHeight: '1.2em', 126 | marginBottom: '1rem', 127 | overflow: 'auto' 128 | }, 129 | 130 | h1: H1, 131 | h2: H2, 132 | h3: H3 133 | } 134 | 135 | export default Bootstrap; 136 | -------------------------------------------------------------------------------- /example/src/theme/index.js: -------------------------------------------------------------------------------- 1 | export { default as AppStyle } from './AppStyle'; 2 | export { default as Bootstrap } from './Bootstrap'; 3 | -------------------------------------------------------------------------------- /media/fluid_react.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richardzcode/fluid-react/6a3978e656f14eec043b8ccb681ea50a3bcb2d07/media/fluid_react.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluid-react", 3 | "version": "0.0.41", 4 | "description": "Grid system for React", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "build": "babel src --presets react,env --out-dir dist" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/richardzcode/fluid-react.git" 12 | }, 13 | "keywords": [ 14 | "Fluid", 15 | "Grid", 16 | "MediaQuery", 17 | "React" 18 | ], 19 | "author": "Richard Zhang ", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/richardzcode/fluid-react/issues" 23 | }, 24 | "homepage": "https://github.com/richardzcode/fluid-react#readme", 25 | "devDependencies": { 26 | "babel-cli": "^6.26.0", 27 | "babel-preset-env": "^1.6.1", 28 | "babel-preset-react": "^6.24.1", 29 | "react": "^16.2.0" 30 | }, 31 | "dependencies": { 32 | "fsts": "0.0.40" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/components/Dom.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { withMediaQuery } from '../css'; 4 | import { JS } from 'fsts'; 5 | 6 | const _Div = (props) => ( 7 |
    {props.children}
    8 | ) 9 | const Div = withMediaQuery(_Div); 10 | 11 | const _P = (props) => ( 12 |

    {props.children}

    13 | ) 14 | const P = withMediaQuery(_P); 15 | 16 | const _Span = (props) => ( 17 | {props.children} 18 | ) 19 | const Span = withMediaQuery(_Span); 20 | 21 | const _Label = (props) => ( 22 | 23 | ) 24 | const Label = withMediaQuery(_Label); 25 | 26 | const _Ul = (props) => ( 27 |
      {props.children}
    28 | ) 29 | const Ul = withMediaQuery(_Ul); 30 | 31 | const _Li = (props) => ( 32 |
  • {props.children}
  • 33 | ) 34 | const Li = withMediaQuery(_Li); 35 | 36 | const _Section = (props) => ( 37 |
    {props.children}
    38 | ) 39 | const Section = withMediaQuery(_Section); 40 | 41 | const _Header = (props) => ( 42 |
    {props.children}
    43 | ) 44 | const Header = withMediaQuery(_Header); 45 | 46 | const _Footer = (props) => ( 47 |
    {props.children}
    48 | ) 49 | const Footer = withMediaQuery(_Footer); 50 | 51 | const _Form = (props) => ( 52 |
    {props.children}
    53 | ) 54 | const Form = withMediaQuery(_Form); 55 | 56 | const _Input = (props) => ( 57 | {props.children} 58 | ) 59 | const Input = withMediaQuery(_Input); 60 | 61 | const _Textarea = (props) => ( 62 | 63 | ) 64 | const Textarea = withMediaQuery(_Textarea); 65 | 66 | const _Select = (props) => ( 67 | 68 | ) 69 | const Select = withMediaQuery(_Select); 70 | 71 | const _Option = (props) => ( 72 | 73 | ) 74 | const Option = withMediaQuery(_Option); 75 | 76 | const _Button = (props) => ( 77 | 78 | ) 79 | const Button = withMediaQuery(_Button); 80 | 81 | const _Pre = (props) => ( 82 |
    {props.children}
    83 | ) 84 | const Pre = withMediaQuery(_Pre); 85 | 86 | const _Code = (props) => ( 87 | {props.children} 88 | ) 89 | const Code = withMediaQuery(_Code); 90 | 91 | const _Article = (props) => ( 92 |
    {props.children}
    93 | ) 94 | const Article = withMediaQuery(_Article); 95 | 96 | const _Aside = (props) => ( 97 | 98 | ) 99 | const Aside = withMediaQuery(_Aside); 100 | 101 | const _Img = (props) => ( 102 | {props.children} 103 | ) 104 | const Img = withMediaQuery(_Img); 105 | 106 | const _Canvas = (props) => ( 107 | {props.children} 108 | ) 109 | const Canvas = withMediaQuery(_Canvas); 110 | 111 | const _Audio = (props) => ( 112 | 113 | ) 114 | const Audio = withMediaQuery(_Audio); 115 | 116 | const _Video = (props) => ( 117 | 118 | ) 119 | const Video = withMediaQuery(_Video); 120 | 121 | const _A = (props) => ( 122 | {props.children} 123 | ) 124 | const A = withMediaQuery(_A); 125 | 126 | const _H1 = (props) => ( 127 |

    {props.children}

    128 | ) 129 | const H1 = withMediaQuery(_H1); 130 | 131 | const _H2 = (props) => ( 132 |

    {props.children}

    133 | ) 134 | const H2 = withMediaQuery(_H2); 135 | 136 | const _H3 = (props) => ( 137 |

    {props.children}

    138 | ) 139 | const H3 = withMediaQuery(_H3); 140 | 141 | const _H4 = (props) => ( 142 |

    {props.children}

    143 | ) 144 | const H4 = withMediaQuery(_H4); 145 | 146 | const _H5 = (props) => ( 147 |
    {props.children}
    148 | ) 149 | const H5 = withMediaQuery(_H5); 150 | 151 | const _H6 = (props) => ( 152 |
    {props.children}
    153 | ) 154 | const H6 = withMediaQuery(_H6); 155 | 156 | const _Hr = (props) => ( 157 |
    {props.children} 158 | ) 159 | const Hr = withMediaQuery(_Hr); 160 | 161 | export { 162 | Div, 163 | P, 164 | Span, 165 | Label, 166 | Ul, 167 | Li, 168 | Section, 169 | Header, 170 | Footer, 171 | Form, 172 | Input, 173 | Textarea, 174 | Select, 175 | Option, 176 | Button, 177 | Pre, 178 | Code, 179 | Article, 180 | Aside, 181 | Img, 182 | Canvas, 183 | Audio, 184 | Video, 185 | A, 186 | H1, 187 | H2, 188 | H3, 189 | H4, 190 | H5, 191 | H6, 192 | Hr 193 | }; 194 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | export * from './Dom'; 2 | -------------------------------------------------------------------------------- /src/css/BeforeAfter.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { JS } from 'fsts'; 3 | 4 | export function withBeforeAfter(Comp) { 5 | return class extends Component { 6 | render() { 7 | const style = this.props.style || {} 8 | const p = JS.lessProps(this.props, 'style'); 9 | const styl = JS.lessProps(style, '@media.*'); 10 | return beforeAfter() 11 | } 12 | } 13 | } 14 | 15 | const beforeAfter = (el) => { 16 | const style = el.props.style || {}; 17 | const before = style['::before']; 18 | const after = style['::after']; 19 | if (!before && !after) { return el; } 20 | 21 | let beforeEl = null; 22 | if (before) { 23 | const content = before.content; 24 | const styl = JS.lessProps(before, 'content'); 25 | beforeEl = {content}; 26 | } 27 | 28 | let afterEl = null; 29 | if (after) { 30 | const content = after.content; 31 | const styl = JS.lessProps(after, 'content'); 32 | afterEl = {content}; 33 | } 34 | 35 | return ( 36 | 37 | {beforeEl} 38 | {el} 39 | {afterEl} 40 | 41 | ) 42 | } 43 | -------------------------------------------------------------------------------- /src/css/Hover.js: -------------------------------------------------------------------------------- 1 | import React, { Component, Fragment } from 'react'; 2 | import { JS } from 'fsts'; 3 | 4 | export function withHover(Comp) { 5 | return class extends Component { 6 | constructor(props) { 7 | super(props); 8 | 9 | this.mouseEnterHandler = this.mouseEnterHandler.bind(this); 10 | this.mouseLeaveHandler = this.mouseLeaveHandler.bind(this); 11 | 12 | this.state = { hover: false } 13 | } 14 | 15 | mouseEnterHandler() { 16 | this.setState({ hover: true }); 17 | } 18 | 19 | mouseLeaveHandler() { 20 | this.setState({ hover: false }); 21 | } 22 | 23 | render() { 24 | let style = this.props.style; 25 | if (!style || !style[':hover']) { 26 | return {this.props.children} 27 | } 28 | 29 | const { hover } = this.state; 30 | const p = JS.lessProps(this.props, 'style'); 31 | if (hover) { 32 | style = style[':hover']; 33 | } else { 34 | style = JS.lessProps(style, ':hover'); 35 | } 36 | return ( 37 | 43 | {this.props.children} 44 | 45 | ) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/css/Match.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import MediaQuery from '../media'; 4 | 5 | export default class Match extends Component { 6 | constructor(props) { 7 | super(props); 8 | 9 | this.onBreakpoint = this.onBreakpoint.bind(this); 10 | 11 | this.state = { mq: '' } 12 | } 13 | 14 | componentDidMount() { 15 | MediaQuery.listenBreakpoint(this.onBreakpoint); 16 | } 17 | 18 | componentWillUnmount() { 19 | MediaQuery.unlistenBreakpoint(this.onBreakpoint); 20 | } 21 | 22 | onBreakpoint(query_name) { 23 | this.setState({ 24 | mq: query_name 25 | }); 26 | } 27 | 28 | render() { 29 | const { show } = this.props; 30 | const { mq } = this.state; 31 | 32 | if (show && show.split(',').filter(name => name.trim() === mq).length == 0) { 33 | return null; 34 | } 35 | 36 | return ( 37 |
    38 | {this.props.children} 39 |
    40 | ) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/css/MediaQuery.js: -------------------------------------------------------------------------------- 1 | import React, { Component, Fragment } from 'react'; 2 | 3 | import { JS, Device } from 'fsts'; 4 | 5 | import MediaQuery from '../media'; 6 | 7 | export function withMediaQuery(Comp) { 8 | return class extends Component { 9 | constructor(props) { 10 | super(props); 11 | 12 | this.state = { style: props.style || {} }; 13 | } 14 | 15 | componentDidUpdate(prevProps, prevState) { 16 | if (this.props.style !== prevProps.style) { 17 | this.attachStyle(); 18 | } 19 | } 20 | 21 | componentDidMount() { 22 | this.attachStyle(); 23 | } 24 | 25 | componentWillUnmount() { 26 | MediaQuery.detach(this._style); 27 | } 28 | 29 | attachStyle() { 30 | const hasWindow = Device.hasWindow(); 31 | 32 | if (this._style) { MediaQuery.detach(this._style); } 33 | 34 | this._style = Object.assign({}, this.props.style); 35 | if (hasWindow) { 36 | this.setState({ style: this._style }); 37 | return MediaQuery.attach(this._style, (new_style) => { 38 | this.setState({ style: new_style }); 39 | }); 40 | } 41 | 42 | const queries = {}; 43 | Object.keys(this._style) 44 | .filter(key => key.startsWith('@media')) 45 | .forEach(key => queries[key] = this._style[key]); 46 | if (Object.keys(queries).length > 0) { 47 | this._style['__fr_class__'] = '__fr_mq_' + JS.cheapId() + '__'; 48 | this._style['__fr_queries__'] = queries; 49 | } 50 | return JS.lessProps(this._style, '@media.*'); 51 | } 52 | 53 | render() { 54 | if (Device.hasWindow()) { 55 | const style = this.state; 56 | const styl = JS.lessProps(style, '@media.*'); 57 | const p = JS.lessProps(this.props, 'style'); 58 | return 59 | } 60 | 61 | const style = this.attachStyle(); 62 | if (!style['__fr_class__']) { 63 | const p = JS.lessProps(this.props, 'style'); 64 | return 65 | } 66 | 67 | const cls = style['__fr_class__']; 68 | const queries = style['__fr_queries__']; 69 | const styl = JS.lessProps(style, '__fr.*'); 70 | let css = '.' + cls + JS.styleToCss(styl); 71 | Object.keys(queries) 72 | .forEach(key => { 73 | css += key + '{' 74 | + '.' + cls + JS.styleToCss(queries[key]) 75 | + '}'; 76 | }); 77 | 78 | const p = JS.lessProps(this.props, 'style'); 79 | return ( 80 | 81 | 82 | 83 | 84 | ); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/css/index.js: -------------------------------------------------------------------------------- 1 | import { withMediaQuery } from './MediaQuery'; 2 | import { withBeforeAfter } from './BeforeAfter'; 3 | import { withHover } from './Hover'; 4 | 5 | export { default as Match } from './Match'; 6 | 7 | function withPseudo(Comp) { 8 | return withBeforeAfter(withHover(Comp)); 9 | } 10 | 11 | function withCss(Comp) { 12 | return withPseudo(withMediaQuery(Comp)); 13 | } 14 | 15 | export { withMediaQuery, withBeforeAfter, withHover, withPseudo, withCss }; 16 | -------------------------------------------------------------------------------- /src/grid/Col.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | import { Logger, JS, Device } from 'fsts'; 4 | 5 | import MediaQuery from '../media'; 6 | import GridStyle from './GridStyle'; 7 | 8 | const logger = new Logger('Col'); 9 | 10 | export default class Col extends Component { 11 | constructor(props) { 12 | super(props); 13 | 14 | this.onBreakpoint = this.onBreakpoint.bind(this); 15 | 16 | this.state = { 17 | vw: 'xs' 18 | } 19 | } 20 | 21 | cellCounts() { 22 | const { xs, sm, md, lg, xl } = this.props; 23 | const counts = [ 24 | JS.undefinedThen(xs, ''), 25 | JS.undefinedThen(sm, ''), 26 | JS.undefinedThen(md, ''), 27 | JS.undefinedThen(lg, ''), 28 | JS.undefinedThen(xl, '') 29 | ] 30 | 31 | // back fill 32 | for (var i = 0; i < counts.length; i++) { 33 | const val = counts[i]; 34 | if (val !== '') { 35 | for (var j = i - 1; j >= 0; j--) { counts[j] = val; } 36 | break; 37 | } 38 | } 39 | 40 | // forward fill 41 | for (var i = 1; i < counts.length; i++) { 42 | if (counts[i] === '') { counts[i] = counts[i - 1]; } 43 | } 44 | 45 | return counts; 46 | } 47 | 48 | cellCount() { 49 | const { vw } = this.state; 50 | const index = { 51 | xs: 0, 52 | sm: 1, 53 | md: 2, 54 | lg: 3, 55 | xl: 4 56 | }[vw] 57 | const counts = this.cellCounts(); 58 | return counts[index]; 59 | } 60 | 61 | calcStyle() { 62 | const count = this.cellCount(); 63 | return GridStyle['col' + count]; 64 | } 65 | 66 | componentDidMount() { 67 | MediaQuery.listenBreakpoint(this.onBreakpoint); 68 | } 69 | 70 | componentWillUnmount() { 71 | MediaQuery.unlistenBreakpoint(this.onBreakpoint); 72 | } 73 | 74 | onBreakpoint(vw) { 75 | logger.debug('on breakpoint ' + vw); 76 | this.setState({ vw: vw }); 77 | } 78 | 79 | render() { 80 | if (Device.hasWindow()) { 81 | const { style } = this.props; 82 | const styl = Object.assign( 83 | {}, 84 | this.calcStyle(), 85 | style 86 | ); 87 | const p = JS.lessProps(this.props, 'style'); 88 | return ( 89 |
    90 | {this.props.children} 91 |
    92 | ) 93 | } 94 | 95 | let cls = 'fluid-react-col __fr_grid_col__'; 96 | const { col } = this.props; 97 | if (col) { cls += ' __fr_grid_col_' + col + '__'; } 98 | const counts = this.cellCounts(); 99 | if (counts[0] !== '') { 100 | // cellCounts ensures if there is any number then all should have number 101 | cls += ' __fr_grid_xs_' + counts[0] + '__'; 102 | cls += ' __fr_grid_sm_' + counts[1] + '__'; 103 | cls += ' __fr_grid_md_' + counts[2] + '__'; 104 | cls += ' __fr_grid_lg_' + counts[3] + '__'; 105 | cls += ' __fr_grid_xl_' + counts[4] + '__'; 106 | } 107 | return ( 108 |
    109 | {this.props.children} 110 |
    111 | ) 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/grid/Container.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import { JS } from 'fsts'; 4 | 5 | import GridStyle from './GridStyle'; 6 | 7 | export default class Container extends Component { 8 | render() { 9 | const { style } = this.props; 10 | const styl = Object.assign( 11 | {}, 12 | style, 13 | GridStyle.container 14 | ); 15 | const p = JS.lessProps(this.props, 'style'); 16 | return ( 17 |
    18 | {this.props.children} 19 |
    20 | ) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/grid/GridCss.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { JS } from 'fsts'; 3 | 4 | const basic = { 5 | __fr_grid_col__: { 6 | flex: '1 0 0', 7 | maxWidth: '100%', 8 | boxSizing: 'border-box' 9 | }, 10 | __fr_grid_col_0__: { 11 | display: 'none' 12 | }, 13 | __fr_grid_col_1__: { 14 | flex: '0 0 8.33333333%', 15 | maxWidth: '8.33333333%', 16 | boxSizing: 'border-box' 17 | }, 18 | __fr_grid_col_2__: { 19 | flex: '0 0 16.66666667%', 20 | maxWidth: '16.66666667%', 21 | boxSizing: 'border-box' 22 | }, 23 | __fr_grid_col_3__: { 24 | flex: '0 0 25%', 25 | maxWidth: '25%', 26 | boxSizing: 'border-box' 27 | }, 28 | __fr_grid_col_4__: { 29 | flex: '0 0 33.33333333%', 30 | maxWidth: '33.33333333%', 31 | boxSizing: 'border-box' 32 | }, 33 | __fr_grid_col_5__: { 34 | flex: '0 0 41.66666667%', 35 | maxWidth: '41.66666667%', 36 | boxSizing: 'border-box' 37 | }, 38 | __fr_grid_col_6__: { 39 | flex: '0 0 50%', 40 | maxWidth: '50%', 41 | boxSizing: 'border-box' 42 | }, 43 | __fr_grid_col_7__: { 44 | flex: '0 0 58.33333333%', 45 | maxWidth: '58.33333333%', 46 | boxSizing: 'border-box' 47 | }, 48 | __fr_grid_col_8__: { 49 | flex: '0 0 66.66666667%', 50 | maxWidth: '66.66666667%', 51 | boxSizing: 'border-box' 52 | }, 53 | __fr_grid_col_9__: { 54 | flex: '0 0 75%', 55 | maxWidth: '75%', 56 | boxSizing: 'border-box' 57 | }, 58 | __fr_grid_col_10__: { 59 | flex: '0 0 83.33333333%', 60 | maxWidth: '83.33333333%', 61 | boxSizing: 'border-box' 62 | }, 63 | __fr_grid_col_11__: { 64 | flex: '0 0 91.66666667%', 65 | maxWidth: '91.66666667%', 66 | boxSizing: 'border-box' 67 | }, 68 | __fr_grid_col_12__: { 69 | flex: '0 0 100%', 70 | maxWidth: '100%', 71 | boxSizing: 'border-box' 72 | } 73 | }; 74 | 75 | const queries = {}; 76 | 77 | queries['@media (max-width: 575px)'] = { 78 | __fr_grid_xs_0__: { 79 | display: 'none' 80 | }, 81 | __fr_grid_xs_1__: { 82 | flex: '0 0 8.33333333%', 83 | maxWidth: '8.33333333%', 84 | boxSizing: 'border-box' 85 | }, 86 | __fr_grid_xs_2__: { 87 | flex: '0 0 16.66666667%', 88 | maxWidth: '16.66666667%', 89 | boxSizing: 'border-box' 90 | }, 91 | __fr_grid_xs_3__: { 92 | flex: '0 0 25%', 93 | maxWidth: '25%', 94 | boxSizing: 'border-box' 95 | }, 96 | __fr_grid_xs_4__: { 97 | flex: '0 0 33.33333333%', 98 | maxWidth: '33.33333333%', 99 | boxSizing: 'border-box' 100 | }, 101 | __fr_grid_xs_5__: { 102 | flex: '0 0 41.66666667%', 103 | maxWidth: '41.66666667%', 104 | boxSizing: 'border-box' 105 | }, 106 | __fr_grid_xs_6__: { 107 | flex: '0 0 50%', 108 | maxWidth: '50%', 109 | boxSizing: 'border-box' 110 | }, 111 | __fr_grid_xs_7__: { 112 | flex: '0 0 58.33333333%', 113 | maxWidth: '58.33333333%', 114 | boxSizing: 'border-box' 115 | }, 116 | __fr_grid_xs_8__: { 117 | flex: '0 0 66.66666667%', 118 | maxWidth: '66.66666667%', 119 | boxSizing: 'border-box' 120 | }, 121 | __fr_grid_xs_9__: { 122 | flex: '0 0 75%', 123 | maxWidth: '75%', 124 | boxSizing: 'border-box' 125 | }, 126 | __fr_grid_xs_10__: { 127 | flex: '0 0 83.33333333%', 128 | maxWidth: '83.33333333%', 129 | boxSizing: 'border-box' 130 | }, 131 | __fr_grid_xs_11__: { 132 | flex: '0 0 91.66666667%', 133 | maxWidth: '91.66666667%', 134 | boxSizing: 'border-box' 135 | }, 136 | __fr_grid_xs_12__: { 137 | flex: '0 0 100%', 138 | maxWidth: '100%', 139 | boxSizing: 'border-box' 140 | } 141 | }; 142 | 143 | queries['@media (min-width: 576px) and (max-width: 767px)'] = { 144 | __fr_grid_sm_0__: { 145 | display: 'none' 146 | }, 147 | __fr_grid_sm_1__: { 148 | flex: '0 0 8.33333333%', 149 | maxWidth: '8.33333333%', 150 | boxSizing: 'border-box' 151 | }, 152 | __fr_grid_sm_2__: { 153 | flex: '0 0 16.66666667%', 154 | maxWidth: '16.66666667%', 155 | boxSizing: 'border-box' 156 | }, 157 | __fr_grid_sm_3__: { 158 | flex: '0 0 25%', 159 | maxWidth: '25%', 160 | boxSizing: 'border-box' 161 | }, 162 | __fr_grid_sm_4__: { 163 | flex: '0 0 33.33333333%', 164 | maxWidth: '33.33333333%', 165 | boxSizing: 'border-box' 166 | }, 167 | __fr_grid_sm_5__: { 168 | flex: '0 0 41.66666667%', 169 | maxWidth: '41.66666667%', 170 | boxSizing: 'border-box' 171 | }, 172 | __fr_grid_sm_6__: { 173 | flex: '0 0 50%', 174 | maxWidth: '50%', 175 | boxSizing: 'border-box' 176 | }, 177 | __fr_grid_sm_7__: { 178 | flex: '0 0 58.33333333%', 179 | maxWidth: '58.33333333%', 180 | boxSizing: 'border-box' 181 | }, 182 | __fr_grid_sm_8__: { 183 | flex: '0 0 66.66666667%', 184 | maxWidth: '66.66666667%', 185 | boxSizing: 'border-box' 186 | }, 187 | __fr_grid_sm_9__: { 188 | flex: '0 0 75%', 189 | maxWidth: '75%', 190 | boxSizing: 'border-box' 191 | }, 192 | __fr_grid_sm_10__: { 193 | flex: '0 0 83.33333333%', 194 | maxWidth: '83.33333333%', 195 | boxSizing: 'border-box' 196 | }, 197 | __fr_grid_sm_11__: { 198 | flex: '0 0 91.66666667%', 199 | maxWidth: '91.66666667%', 200 | boxSizing: 'border-box' 201 | }, 202 | __fr_grid_sm_12__: { 203 | flex: '0 0 100%', 204 | maxWidth: '100%', 205 | boxSizing: 'border-box' 206 | } 207 | }; 208 | 209 | queries['@media (min-width: 768px) and (max-width: 991px)'] = { 210 | __fr_grid_md_0__: { 211 | display: 'none' 212 | }, 213 | __fr_grid_md_1__: { 214 | flex: '0 0 8.33333333%', 215 | maxWidth: '8.33333333%', 216 | boxSizing: 'border-box' 217 | }, 218 | __fr_grid_md_2__: { 219 | flex: '0 0 16.66666667%', 220 | maxWidth: '16.66666667%', 221 | boxSizing: 'border-box' 222 | }, 223 | __fr_grid_md_3__: { 224 | flex: '0 0 25%', 225 | maxWidth: '25%', 226 | boxSizing: 'border-box' 227 | }, 228 | __fr_grid_md_4__: { 229 | flex: '0 0 33.33333333%', 230 | maxWidth: '33.33333333%', 231 | boxSizing: 'border-box' 232 | }, 233 | __fr_grid_md_5__: { 234 | flex: '0 0 41.66666667%', 235 | maxWidth: '41.66666667%', 236 | boxSizing: 'border-box' 237 | }, 238 | __fr_grid_md_6__: { 239 | flex: '0 0 50%', 240 | maxWidth: '50%', 241 | boxSizing: 'border-box' 242 | }, 243 | __fr_grid_md_7__: { 244 | flex: '0 0 58.33333333%', 245 | maxWidth: '58.33333333%', 246 | boxSizing: 'border-box' 247 | }, 248 | __fr_grid_md_8__: { 249 | flex: '0 0 66.66666667%', 250 | maxWidth: '66.66666667%', 251 | boxSizing: 'border-box' 252 | }, 253 | __fr_grid_md_9__: { 254 | flex: '0 0 75%', 255 | maxWidth: '75%', 256 | boxSizing: 'border-box' 257 | }, 258 | __fr_grid_md_10__: { 259 | flex: '0 0 83.33333333%', 260 | maxWidth: '83.33333333%', 261 | boxSizing: 'border-box' 262 | }, 263 | __fr_grid_md_11__: { 264 | flex: '0 0 91.66666667%', 265 | maxWidth: '91.66666667%', 266 | boxSizing: 'border-box' 267 | }, 268 | __fr_grid_md_12__: { 269 | flex: '0 0 100%', 270 | maxWidth: '100%', 271 | boxSizing: 'border-box' 272 | } 273 | }; 274 | 275 | queries['@media (min-width: 992px) and (max-width: 1199px)'] = { 276 | __fr_grid_lg_0__: { 277 | display: 'none' 278 | }, 279 | __fr_grid_lg_1__: { 280 | flex: '0 0 8.33333333%', 281 | maxWidth: '8.33333333%', 282 | boxSizing: 'border-box' 283 | }, 284 | __fr_grid_lg_2__: { 285 | flex: '0 0 16.66666667%', 286 | maxWidth: '16.66666667%', 287 | boxSizing: 'border-box' 288 | }, 289 | __fr_grid_lg_3__: { 290 | flex: '0 0 25%', 291 | maxWidth: '25%', 292 | boxSizing: 'border-box' 293 | }, 294 | __fr_grid_lg_4__: { 295 | flex: '0 0 33.33333333%', 296 | maxWidth: '33.33333333%', 297 | boxSizing: 'border-box' 298 | }, 299 | __fr_grid_lg_5__: { 300 | flex: '0 0 41.66666667%', 301 | maxWidth: '41.66666667%', 302 | boxSizing: 'border-box' 303 | }, 304 | __fr_grid_lg_6__: { 305 | flex: '0 0 50%', 306 | maxWidth: '50%', 307 | boxSizing: 'border-box' 308 | }, 309 | __fr_grid_lg_7__: { 310 | flex: '0 0 58.33333333%', 311 | maxWidth: '58.33333333%', 312 | boxSizing: 'border-box' 313 | }, 314 | __fr_grid_lg_8__: { 315 | flex: '0 0 66.66666667%', 316 | maxWidth: '66.66666667%', 317 | boxSizing: 'border-box' 318 | }, 319 | __fr_grid_lg_9__: { 320 | flex: '0 0 75%', 321 | maxWidth: '75%', 322 | boxSizing: 'border-box' 323 | }, 324 | __fr_grid_lg_10__: { 325 | flex: '0 0 83.33333333%', 326 | maxWidth: '83.33333333%', 327 | boxSizing: 'border-box' 328 | }, 329 | __fr_grid_lg_11__: { 330 | flex: '0 0 91.66666667%', 331 | maxWidth: '91.66666667%', 332 | boxSizing: 'border-box' 333 | }, 334 | __fr_grid_lg_12__: { 335 | flex: '0 0 100%', 336 | maxWidth: '100%', 337 | boxSizing: 'border-box' 338 | } 339 | }; 340 | 341 | queries['@media (min-width: 1200px)'] = { 342 | __fr_grid_xl_0__: { 343 | display: 'none' 344 | }, 345 | __fr_grid_xl_1__: { 346 | flex: '0 0 8.33333333%', 347 | maxWidth: '8.33333333%', 348 | boxSizing: 'border-box' 349 | }, 350 | __fr_grid_xl_2__: { 351 | flex: '0 0 16.66666667%', 352 | maxWidth: '16.66666667%', 353 | boxSizing: 'border-box' 354 | }, 355 | __fr_grid_xl_3__: { 356 | flex: '0 0 25%', 357 | maxWidth: '25%', 358 | boxSizing: 'border-box' 359 | }, 360 | __fr_grid_xl_4__: { 361 | flex: '0 0 33.33333333%', 362 | maxWidth: '33.33333333%', 363 | boxSizing: 'border-box' 364 | }, 365 | __fr_grid_xl_5__: { 366 | flex: '0 0 41.66666667%', 367 | maxWidth: '41.66666667%', 368 | boxSizing: 'border-box' 369 | }, 370 | __fr_grid_xl_6__: { 371 | flex: '0 0 50%', 372 | maxWidth: '50%', 373 | boxSizing: 'border-box' 374 | }, 375 | __fr_grid_xl_7__: { 376 | flex: '0 0 58.33333333%', 377 | maxWidth: '58.33333333%', 378 | boxSizing: 'border-box' 379 | }, 380 | __fr_grid_xl_8__: { 381 | flex: '0 0 66.66666667%', 382 | maxWidth: '66.66666667%', 383 | boxSizing: 'border-box' 384 | }, 385 | __fr_grid_xl_9__: { 386 | flex: '0 0 75%', 387 | maxWidth: '75%', 388 | boxSizing: 'border-box' 389 | }, 390 | __fr_grid_xl_10__: { 391 | flex: '0 0 83.33333333%', 392 | maxWidth: '83.33333333%', 393 | boxSizing: 'border-box' 394 | }, 395 | __fr_grid_xl_11__: { 396 | flex: '0 0 91.66666667%', 397 | maxWidth: '91.66666667%', 398 | boxSizing: 'border-box' 399 | }, 400 | __fr_grid_xl_12__: { 401 | flex: '0 0 100%', 402 | maxWidth: '100%', 403 | boxSizing: 'border-box' 404 | } 405 | }; 406 | 407 | let css = Object.keys(basic) 408 | .map(cls => '.' + cls + JS.styleToCss(basic[cls])) 409 | .join(''); 410 | 411 | Object.keys(queries) 412 | .forEach(key => { 413 | const styles = queries[key]; 414 | css += key + '{' 415 | + Object.keys(styles) 416 | .map(cls => '.' + cls + JS.styleToCss(styles[cls])) 417 | .join('') 418 | + '}'; 419 | }); 420 | 421 | const style = props => ( 422 | 423 | ) 424 | 425 | export default style; 426 | -------------------------------------------------------------------------------- /src/grid/GridStyle.js: -------------------------------------------------------------------------------- 1 | export const Container = { 2 | } 3 | 4 | export const Row = { 5 | display: 'flex', 6 | flexWrap: 'wrap', 7 | position: 'relative' 8 | } 9 | 10 | export const Col = { 11 | flex: '1 0 0', 12 | maxWidth: '100%', 13 | boxSizing: 'border-box' 14 | } 15 | 16 | export const ColAuto = { 17 | flex: '0 0 auto', 18 | maxWidth: '100%', 19 | width: 'auto', 20 | boxSizing: 'border-box' 21 | } 22 | 23 | export const Col0 = { 24 | display: 'none' 25 | } 26 | 27 | export const Col1 = { 28 | flex: '0 0 8.33333333%', 29 | maxWidth: '8.33333333%', 30 | boxSizing: 'border-box' 31 | } 32 | 33 | export const Col2 = { 34 | flex: '0 0 16.66666667%', 35 | maxWidth: '16.66666667%', 36 | boxSizing: 'border-box' 37 | } 38 | 39 | export const Col3 = { 40 | flex: '0 0 25%', 41 | maxWidth: '25%', 42 | boxSizing: 'border-box' 43 | } 44 | 45 | export const Col4 = { 46 | flex: '0 0 33.33333333%', 47 | maxWidth: '33.33333333%', 48 | boxSizing: 'border-box' 49 | } 50 | 51 | export const Col5 = { 52 | flex: '0 0 41.66666667%', 53 | maxWidth: '41.66666667%', 54 | boxSizing: 'border-box' 55 | } 56 | 57 | export const Col6 = { 58 | flex: '0 0 50%', 59 | maxWidth: '50%', 60 | boxSizing: 'border-box' 61 | } 62 | 63 | export const Col7 = { 64 | flex: '0 0 58.33333333%', 65 | maxWidth: '58.33333333%', 66 | boxSizing: 'border-box' 67 | } 68 | 69 | export const Col8 = { 70 | flex: '0 0 66.66666667%', 71 | maxWidth: '66.66666667%', 72 | boxSizing: 'border-box' 73 | } 74 | 75 | export const Col9 = { 76 | flex: '0 0 75%', 77 | maxWidth: '75%', 78 | boxSizing: 'border-box' 79 | } 80 | 81 | export const Col10 = { 82 | flex: '0 0 83.33333333%', 83 | maxWidth: '83.33333333%', 84 | boxSizing: 'border-box' 85 | } 86 | 87 | export const Col11 = { 88 | flex: '0 0 91.66666667%', 89 | maxWidth: '91.66666667%', 90 | boxSizing: 'border-box' 91 | } 92 | 93 | export const Col12 = { 94 | flex: '0 0 100%', 95 | maxWidth: '100%', 96 | boxSizing: 'border-box' 97 | } 98 | 99 | export const W100 = { 100 | width: '100%' 101 | } 102 | 103 | const GridStyle = { 104 | container: Container, 105 | 106 | row: Row, 107 | 108 | col: Col, 109 | colauto: ColAuto, 110 | col0: Col0, 111 | col1: Col1, 112 | col2: Col2, 113 | col3: Col3, 114 | col4: Col4, 115 | col5: Col5, 116 | col6: Col6, 117 | col7: Col7, 118 | col8: Col8, 119 | col9: Col9, 120 | col10: Col10, 121 | col11: Col11, 122 | col12: Col12, 123 | 124 | w100: W100 125 | } 126 | 127 | export default GridStyle; 128 | -------------------------------------------------------------------------------- /src/grid/Row.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import { JS, Device } from 'fsts'; 4 | 5 | import GridStyle from './GridStyle'; 6 | import GridCss from './GridCss'; 7 | 8 | export default class Row extends Component { 9 | render() { 10 | const { style } = this.props; 11 | const styl = Object.assign( 12 | {}, 13 | GridStyle.row, 14 | style 15 | ); 16 | const p = JS.lessProps(this.props, 'style'); 17 | 18 | if (Device.hasWindow()) { 19 | return ( 20 |
    21 | {this.props.children} 22 |
    23 | ) 24 | } 25 | 26 | return ( 27 |
    28 | 29 | {this.props.children} 30 |
    31 | ) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/grid/W100.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import { JS } from 'fsts'; 4 | 5 | import GridStyle from './GridStyle'; 6 | 7 | export default class W100 extends Component { 8 | render() { 9 | const { style } = this.props; 10 | const styl = Object.assign( 11 | {}, 12 | style, 13 | GridStyle.w100 14 | ); 15 | const p = JS.lessProps(this.props, 'style'); 16 | return ( 17 |
    18 | {this.props.children} 19 |
    20 | ) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/grid/index.js: -------------------------------------------------------------------------------- 1 | export { default as Container } from './Container'; 2 | export { default as Row } from './Row'; 3 | export { default as Col } from './Col'; 4 | export { default as W100 } from './W100'; 5 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import MediaQuery from './media'; 2 | 3 | export { MediaQuery }; 4 | export * from './grid'; 5 | export * from './components'; 6 | export * from './css'; 7 | -------------------------------------------------------------------------------- /src/media/Empty.js: -------------------------------------------------------------------------------- 1 | export default class Empty { 2 | listenBreakpoint() { 3 | } 4 | 5 | unlistenBreakpoint() { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/media/MatchMedia.js: -------------------------------------------------------------------------------- 1 | import { Logger, JS, Device } from 'fsts'; 2 | 3 | import Query from './Query'; 4 | import Range from './Range'; 5 | import MediaQueryAtom from './MediaQueryAtom'; 6 | 7 | const logger = new Logger('MatchMedia'); 8 | 9 | export default class MatchMedia { 10 | constructor() { 11 | this._breakpointMatch = this._breakpointMatch.bind(this); 12 | 13 | this._breakpointListeners = []; 14 | this._ranges = []; 15 | this._queries = {}; 16 | this._styles = []; 17 | 18 | if (Device.hasWindow()) { 19 | this._ranges = [ 20 | new Range('xs', this._breakpointMatch, null, '575px'), 21 | new Range('sm', this._breakpointMatch, '576px', '767px'), 22 | new Range('md', this._breakpointMatch, '768px', '991px'), 23 | new Range('lg', this._breakpointMatch, '992px', '1199px'), 24 | new Range('xl', this._breakpointMatch, '1200px', null) 25 | ]; 26 | } 27 | } 28 | 29 | listenBreakpoint(f) { 30 | const appended = JS.appendUnique(this._breakpointListeners, f); 31 | if (appended) { 32 | this._queryForListener(f); 33 | } else { 34 | logger.debug('breakpoint listener already exists', f); 35 | return; 36 | } 37 | } 38 | 39 | addQuery(name, query) { 40 | new Query(name, this._breakpointMatch, query); 41 | } 42 | 43 | unlistenBreakpoint(f) { 44 | this._breakpointListeners = this._breakpointListeners.filter( 45 | func => func !== f 46 | ) 47 | } 48 | 49 | attach(style, notifier) { 50 | if (!style) { 51 | logger.warn('no style to attach'); 52 | return; 53 | } 54 | 55 | if (!notifier) { // default notifier logs new_style 56 | notifier = (new_style) => { 57 | logger.debug('style modified', new_style); 58 | } 59 | } 60 | 61 | const atoms = []; 62 | if (JS.hasProps(style, '@media.*')) { 63 | const atom = new MediaQueryAtom(style, notifier); 64 | atoms.push(atom); 65 | } 66 | 67 | JS.traverseProps(style, (path, key, val) => { 68 | if (JS.hasProps(val, '@media.*')) { 69 | const atom = new MediaQueryAtom(val, (new_style) => { 70 | notifier(style); // notify with root style. 71 | }); 72 | atoms.push(atom); 73 | } 74 | }); 75 | 76 | this._styles.push({ 77 | style: style, 78 | atoms: atoms 79 | }); 80 | 81 | return style; 82 | } 83 | 84 | detach(style) { 85 | const found = this._styles.filter(entry => entry.style === style); 86 | if (found.length > 0) { 87 | found[0].atoms.forEach(atom => atom.unlisten()); 88 | } 89 | } 90 | 91 | _breakpointMatch(match, name) { 92 | if (match.matches) { 93 | // in vw 94 | this._onBreakpoint(name); 95 | } else { 96 | // out vw 97 | } 98 | } 99 | 100 | _onBreakpoint(vw) { 101 | logger.debug('on breakpoint ' + vw); 102 | 103 | this._breakpointListeners.forEach(listener => { 104 | try { 105 | listener(vw); 106 | } catch (e) { 107 | logger.error('on breakpoint ' + vw + ' error', listener, e); 108 | } 109 | }); 110 | } 111 | 112 | _queryForListener(f) { 113 | let vw = 'xs'; 114 | for (var i = 0; i < this._ranges.length; i++) { 115 | const range = this._ranges[i]; 116 | if (range.matchMin()) { vw = range.name; } 117 | } 118 | f(vw); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/media/MediaQueryAtom.js: -------------------------------------------------------------------------------- 1 | import { Device } from 'fsts'; 2 | 3 | export default class MediaQueryAtom { 4 | constructor(style, notifier) { 5 | if (!style) { return; } 6 | 7 | this._style = style; 8 | this._old_style = Object.assign({}, style); 9 | this._queries = []; 10 | this._notifier = notifier; 11 | 12 | this._init(); 13 | } 14 | 15 | unlisten() { 16 | this._queries.forEach(query => { 17 | const { mql, listener } = query; 18 | mql.removeListener(listener); 19 | }); 20 | } 21 | 22 | _init() { 23 | if (!Device.hasWindow()) { return; } 24 | 25 | const that = this; 26 | const style = this._style; 27 | Object.keys(style).forEach(key => { 28 | if (!key.startsWith('@media')) { return; } 29 | 30 | const rules = key.split(/\s+/).slice(1).join(' '); 31 | if (!rules) { return; } 32 | 33 | const matchStyle = style[key]; 34 | const mql = window.matchMedia(rules); 35 | const listener = (match) => { 36 | matchStyle._matches = match.matches; 37 | that._applyMatches(); 38 | }; 39 | mql.addListener(listener); 40 | 41 | matchStyle._matches = mql.matches; 42 | that._queries.push({ 43 | matchStyle: matchStyle, 44 | mql: mql, 45 | listener: listener 46 | }); 47 | }); 48 | that._applyMatches(); 49 | } 50 | 51 | _applyMatches() { 52 | if (!this._notifier) { return; } // do nothing 53 | 54 | const new_style = Object.assign({}, this._old_style); 55 | this._queries.forEach(query => { 56 | const { matchStyle } = query; 57 | if (matchStyle._matches) { 58 | Object.assign(new_style, matchStyle); 59 | } 60 | }); 61 | 62 | this._notifier(new_style); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/media/Query.js: -------------------------------------------------------------------------------- 1 | export default class Query { 2 | constructor(name, onMatch, query) { 3 | this.name = name; 4 | this.onMatch = onMatch; 5 | 6 | this._match = this._match.bind(this); 7 | 8 | this._mql = window.matchMedia(query); 9 | this._mql.addListener(this._match); 10 | } 11 | 12 | match() { 13 | return this._mql && this._mql.matches; 14 | } 15 | 16 | unlisten() { 17 | if (this._mql) { this._mql.removeListener(this._match); } 18 | } 19 | 20 | _match(match) { 21 | this.onMatch(match, this.name); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/media/Range.js: -------------------------------------------------------------------------------- 1 | export default class Range { 2 | constructor(name, onMatch, min, max) { 3 | this.name = name; 4 | this.onMatch = onMatch; 5 | 6 | this._match = this._match.bind(this); 7 | 8 | if (min) { 9 | this._min = window.matchMedia('(min-width: ' + min + ')'); 10 | this._min.addListener(this._match); 11 | } 12 | if (max) { 13 | this._max = window.matchMedia('(max-width: ' + max + ')'); 14 | this._max.addListener(this._match); 15 | } 16 | } 17 | 18 | matchMin() { 19 | return !this._min || this._min.matches; 20 | } 21 | 22 | matchMax() { 23 | return !this._max || this._max.matches; 24 | } 25 | 26 | _match(match) { 27 | this.onMatch(match, this.name); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/media/index.js: -------------------------------------------------------------------------------- 1 | import { Device } from 'fsts'; 2 | 3 | import Empty from './Empty'; 4 | import MatchMedia from './MatchMedia'; 5 | 6 | const _instance = new MatchMedia(); 7 | 8 | export default _instance; 9 | --------------------------------------------------------------------------------