├── assets ├── .gitkeep └── loading.gif ├── .babelrc ├── .gitignore ├── .jshintrc ├── src ├── less │ ├── fonts │ │ ├── lato │ │ │ ├── lato-black.eot │ │ │ ├── lato-black.ttf │ │ │ ├── lato-black.woff │ │ │ ├── lato-bold.eot │ │ │ ├── lato-bold.ttf │ │ │ ├── lato-bold.woff │ │ │ ├── lato-italic.eot │ │ │ ├── lato-italic.ttf │ │ │ ├── lato-light.eot │ │ │ ├── lato-light.ttf │ │ │ ├── lato-light.woff │ │ │ ├── lato-italic.woff │ │ │ ├── lato-regular.eot │ │ │ ├── lato-regular.ttf │ │ │ ├── lato-regular.woff │ │ │ ├── lato-bolditalic.eot │ │ │ ├── lato-bolditalic.ttf │ │ │ └── lato-bolditalic.woff │ │ └── glyphicons │ │ │ ├── flat-ui-icons-regular.eot │ │ │ ├── flat-ui-icons-regular.ttf │ │ │ └── flat-ui-icons-regular.woff │ ├── mixins │ │ ├── center-block.less │ │ ├── text-emphasis.less │ │ ├── resize.less │ │ ├── size.less │ │ ├── background-variant.less │ │ ├── opacity.less │ │ ├── background-clip.less │ │ ├── text-overflow.less │ │ ├── tab-focus.less │ │ ├── nav-divider.less │ │ ├── reset-filter.less │ │ ├── pallets.less │ │ ├── responsive-visibility.less │ │ ├── navbar-vertical-align.less │ │ ├── border-radius.less │ │ ├── hide-text.less │ │ ├── pagination.less │ │ ├── clearfix.less │ │ ├── switches.less │ │ ├── image.less │ │ ├── buttons.less │ │ ├── select.less │ │ ├── forms.less │ │ ├── grid.less │ │ ├── gradients.less │ │ └── vendor-prefixes.less │ ├── .csslintrc │ ├── modules │ │ ├── progress-bars.less │ │ ├── tiles.less │ │ ├── share.less │ │ ├── thumbnails.less │ │ ├── typeahead.less │ │ ├── print.less │ │ ├── code.less │ │ ├── pager.less │ │ ├── scaffolding.less │ │ ├── footer.less │ │ ├── palette.less │ │ ├── tooltip.less │ │ ├── slider.less │ │ ├── login.less │ │ ├── button-groups.less │ │ ├── todo-list.less │ │ ├── local-fonts.less │ │ ├── tagsinput.less │ │ ├── input-groups.less │ │ ├── buttons.less │ │ ├── type.less │ │ ├── radiocheck.less │ │ ├── dropdowns.less │ │ ├── glyphicons.less │ │ ├── switch.less │ │ ├── forms.less │ │ ├── video.less │ │ ├── pagination.less │ │ ├── select.less │ │ └── navbar.less │ ├── mixins.less │ ├── flat-ui.less │ ├── spaces.less │ └── .csscomb.json ├── utils │ └── HistoryContainer.js ├── routes │ ├── About.js │ └── Home.js ├── index.js ├── App.js └── routes.js ├── server ├── app.js └── server.js ├── .eslintrc ├── webpack.development.js ├── index.html ├── webpack.config.js ├── LICENSE ├── package.json ├── README.md └── webpack.client.js /assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0", "react"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | .DS_Store 4 | static 5 | .idea -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "newcap": false 6 | } 7 | -------------------------------------------------------------------------------- /assets/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/assets/loading.gif -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-black.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-black.eot -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-black.ttf -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-black.woff -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-bold.eot -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-bold.ttf -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-bold.woff -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-italic.eot -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-italic.ttf -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-light.eot -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-light.ttf -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-light.woff -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-italic.woff -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-regular.eot -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-regular.ttf -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-regular.woff -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-bolditalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-bolditalic.eot -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-bolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-bolditalic.ttf -------------------------------------------------------------------------------- /src/less/fonts/lato/lato-bolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/lato/lato-bolditalic.woff -------------------------------------------------------------------------------- /src/utils/HistoryContainer.js: -------------------------------------------------------------------------------- 1 | let _router; 2 | export default { 3 | set(router){ 4 | _router = router; 5 | }, 6 | get(){ 7 | return _router; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/fonts/glyphicons/flat-ui-icons-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/glyphicons/flat-ui-icons-regular.eot -------------------------------------------------------------------------------- /src/less/fonts/glyphicons/flat-ui-icons-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/glyphicons/flat-ui-icons-regular.ttf -------------------------------------------------------------------------------- /src/less/fonts/glyphicons/flat-ui-icons-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactjs-id/react-webpack-starter/HEAD/src/less/fonts/glyphicons/flat-ui-icons-regular.woff -------------------------------------------------------------------------------- /server/app.js: -------------------------------------------------------------------------------- 1 | require('node-jsx').install({ 2 | extension: '.jsx', 3 | harmony: true 4 | }) 5 | require("babel-core/register") 6 | // transpile es6 to es5 7 | require("./server"); -------------------------------------------------------------------------------- /src/less/mixins/center-block.less: -------------------------------------------------------------------------------- 1 | // Center-align a block level element 2 | 3 | .center-block() { 4 | display: block; 5 | margin-left: auto; 6 | margin-right: auto; 7 | } 8 | -------------------------------------------------------------------------------- /src/less/mixins/text-emphasis.less: -------------------------------------------------------------------------------- 1 | // Typography 2 | 3 | .text-emphasis-variant(@color) { 4 | color: @color; 5 | a&:hover { 6 | color: darken(@color, 10%); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/less/mixins/resize.less: -------------------------------------------------------------------------------- 1 | // Resize anything 2 | 3 | .resizable(@direction) { 4 | resize: @direction; // Options: horizontal, vertical, both 5 | overflow: auto; // Safari fix 6 | } 7 | -------------------------------------------------------------------------------- /src/less/mixins/size.less: -------------------------------------------------------------------------------- 1 | // Sizing shortcuts 2 | 3 | .size(@width; @height) { 4 | width: @width; 5 | height: @height; 6 | } 7 | 8 | .square(@size) { 9 | .size(@size; @size); 10 | } 11 | -------------------------------------------------------------------------------- /src/less/mixins/background-variant.less: -------------------------------------------------------------------------------- 1 | // Contextual backgrounds 2 | 3 | .bg-variant(@color) { 4 | background-color: @color; 5 | a&:hover { 6 | background-color: darken(@color, 10%); 7 | } 8 | } -------------------------------------------------------------------------------- /src/less/mixins/opacity.less: -------------------------------------------------------------------------------- 1 | // Opacity 2 | 3 | .opacity(@opacity) { 4 | opacity: @opacity; 5 | // IE8 filter 6 | @opacity-ie: (@opacity * 100); 7 | filter: ~"alpha(opacity=@{opacity-ie})"; 8 | } 9 | -------------------------------------------------------------------------------- /src/less/mixins/background-clip.less: -------------------------------------------------------------------------------- 1 | // Background clip 2 | .background-clip(@clip: border-box) { 3 | -webkit-background-clip: @clip; 4 | -moz-background-clip: @clip; 5 | background-clip: @clip; 6 | } -------------------------------------------------------------------------------- /src/routes/About.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class About extends React.Component { 4 | render(){ 5 | return ( 6 |

About me and you

7 | ) 8 | } 9 | } 10 | 11 | export default About; -------------------------------------------------------------------------------- /src/less/mixins/text-overflow.less: -------------------------------------------------------------------------------- 1 | // Text overflow 2 | // Requires inline-block or block for proper styling 3 | 4 | .text-overflow() { 5 | overflow: hidden; 6 | text-overflow: ellipsis; 7 | white-space: nowrap; 8 | } 9 | -------------------------------------------------------------------------------- /src/less/mixins/tab-focus.less: -------------------------------------------------------------------------------- 1 | // WebKit-style focus 2 | 3 | .tab-focus() { 4 | // Default 5 | outline: thin dotted; 6 | // WebKit 7 | outline: 5px auto -webkit-focus-ring-color; 8 | outline-offset: -2px; 9 | } 10 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import ReactDOMServer from 'react-dom/server'; 4 | import routes from './routes'; 5 | 6 | // render to the DOM 7 | ReactDOM.render(routes, document.getElementById('root')); 8 | -------------------------------------------------------------------------------- /src/less/mixins/nav-divider.less: -------------------------------------------------------------------------------- 1 | // Horizontal dividers 2 | // 3 | // Dividers (basically an hr) within dropdowns and nav lists 4 | 5 | .nav-divider(@color: #e5e5e5) { 6 | height: 2px; 7 | margin: 3px 0; 8 | overflow: hidden; 9 | background-color: @color; 10 | } 11 | -------------------------------------------------------------------------------- /src/less/mixins/reset-filter.less: -------------------------------------------------------------------------------- 1 | // Reset filters for IE 2 | // 3 | // When you need to remove a gradient background, do not forget to use this to reset 4 | // the IE filter for IE9 and below. 5 | 6 | .reset-filter() { 7 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)")); 8 | } 9 | -------------------------------------------------------------------------------- /src/less/mixins/pallets.less: -------------------------------------------------------------------------------- 1 | // Pallet color variants 2 | // 3 | 4 | .pallet-variant(@first-color, @second-color) { 5 | .palette-@{first-color} { 6 | background-color: ~"@{@{first-color}}"; 7 | } 8 | .palette-@{second-color} { 9 | background-color: ~"@{@{second-color}}"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/routes/Home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Link} from 'react-router'; 3 | 4 | class Home extends React.Component { 5 | render(){ 6 | return ( 7 |
8 |

Home of a

9 | Go to about page 10 |
11 | ) 12 | } 13 | } 14 | 15 | export default Home; -------------------------------------------------------------------------------- /src/less/mixins/responsive-visibility.less: -------------------------------------------------------------------------------- 1 | // Responsive utilities 2 | 3 | // 4 | // More easily include all the states for responsive-utilities.less. 5 | .responsive-visibility() { 6 | display: block !important; 7 | table& { display: table; } 8 | tr& { display: table-row !important; } 9 | th&, 10 | td& { display: table-cell !important; } 11 | } 12 | 13 | .responsive-invisibility() { 14 | display: none !important; 15 | } 16 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "jsx": true, 4 | "modules": true 5 | }, 6 | "env": { 7 | "browser": true, 8 | "node": true 9 | }, 10 | "parser": "babel-eslint", 11 | "rules": { 12 | "quotes": [2, "single"], 13 | "strict": [2, "never"], 14 | "react/jsx-uses-react": 2, 15 | "react/jsx-uses-vars": 2, 16 | "react/react-in-jsx-scope": 2 17 | }, 18 | "plugins": [ 19 | "react" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /webpack.development.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var WebpackDevServer = require('webpack-dev-server'); 3 | var config = require('./webpack.config'); 4 | 5 | new WebpackDevServer(webpack(config), { 6 | publicPath: config.output.publicPath, 7 | hot: true, 8 | historyApiFallback: true 9 | }).listen(3000, 'localhost', function (err, result) { 10 | if (err) { 11 | console.log(err); 12 | } 13 | 14 | console.log('Listening at localhost:3000'); 15 | }); 16 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | Grid, Row, Col, Form, FormGroup, Input, Button 4 | } from 'react-bootstrap'; 5 | // load less file 6 | require('./less/flat-ui.less'); 7 | 8 | class App extends Component { 9 | constructor(props){ 10 | super(props) 11 | } 12 | render() { 13 | return ( 14 | 15 | 16 | {this.props.children} 17 | 18 | 19 | ); 20 | } 21 | } 22 | 23 | export default App; -------------------------------------------------------------------------------- /src/less/mixins/navbar-vertical-align.less: -------------------------------------------------------------------------------- 1 | // Navbar vertical align 2 | // ------------------------- 3 | // Vertically center elements in the navbar. 4 | // Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin. 5 | 6 | .navbar-vertical-align(@element-height; @navbar-height: @navbar-height-base) { 7 | padding-top: ((@navbar-height - @element-height) / 2); 8 | padding-bottom: ((@navbar-height - @element-height) / 2); 9 | } 10 | -------------------------------------------------------------------------------- /src/less/mixins/border-radius.less: -------------------------------------------------------------------------------- 1 | // Single side border-radius 2 | 3 | .border-top-radius(@radius) { 4 | border-top-right-radius: @radius; 5 | border-top-left-radius: @radius; 6 | } 7 | .border-right-radius(@radius) { 8 | border-bottom-right-radius: @radius; 9 | border-top-right-radius: @radius; 10 | } 11 | .border-bottom-radius(@radius) { 12 | border-bottom-right-radius: @radius; 13 | border-bottom-left-radius: @radius; 14 | } 15 | .border-left-radius(@radius) { 16 | border-bottom-left-radius: @radius; 17 | border-top-left-radius: @radius; 18 | } 19 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sample App 4 | 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/less/.csslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "adjoining-classes": false, 3 | "box-sizing": false, 4 | "box-model": false, 5 | "compatible-vendor-prefixes": false, 6 | "floats": false, 7 | "font-sizes": false, 8 | "gradients": false, 9 | "important": false, 10 | "known-properties": false, 11 | "outline-none": false, 12 | "qualified-headings": false, 13 | "regex-selectors": false, 14 | "shorthand": false, 15 | "text-indent": false, 16 | "unique-headings": false, 17 | "universal-selector": false, 18 | "unqualified-attributes": false, 19 | 20 | "fallback-colors": false, 21 | "font-faces": false 22 | } 23 | -------------------------------------------------------------------------------- /src/less/mixins/hide-text.less: -------------------------------------------------------------------------------- 1 | // CSS image replacement 2 | // 3 | // Heads up! v3 launched with with only `.hide-text()`, but per our pattern for 4 | // mixins being reused as classes with the same name, this doesn't hold up. As 5 | // of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. 6 | // 7 | // Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757 8 | 9 | // Deprecated as of v3.0.1 (will be removed in v4) 10 | .hide-text() { 11 | font: ~"0/0" a; 12 | color: transparent; 13 | text-shadow: none; 14 | background-color: transparent; 15 | border: 0; 16 | } 17 | 18 | // New mixin to use as of v3.0.1 19 | .text-hide() { 20 | .hide-text(); 21 | } 22 | -------------------------------------------------------------------------------- /src/less/mixins/pagination.less: -------------------------------------------------------------------------------- 1 | // Pagination variants 2 | 3 | .pagination-variant(@color, @hover, @active) { 4 | ul { 5 | background-color: @color; 6 | 7 | li { 8 | &.previous { 9 | > a { 10 | border-right-color: mix(@color, white, 66%); 11 | } 12 | } 13 | > a, > span { 14 | border-left-color: mix(@color, white, 66%); 15 | 16 | &:hover, &:focus { 17 | background-color: @hover; 18 | } 19 | &:active { 20 | background-color: @active; 21 | } 22 | } 23 | &.active { 24 | > a, > span { 25 | background-color: @active; 26 | } 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import express from 'express'; 4 | 5 | // App bootstrap 6 | let app = express(); 7 | 8 | // assets 9 | app.use("/assets", express.static(path.resolve(__dirname + "/../assets"))); 10 | 11 | 12 | // webpack assets 13 | app.use("/static", express.static(path.resolve(__dirname + "/../static"))); 14 | 15 | // root app 16 | app.use((req, res)=>{ 17 | let rootHtml = fs.readFileSync(path.resolve(__dirname + "/../index.html"), { encoding: 'utf8'}); 18 | return res.status(200).send(rootHtml); 19 | }); 20 | 21 | // start server 22 | const port = process.env.PORT || 3000; 23 | app.listen(port, (err)=>{ 24 | console.log("Listening on port "+ port); 25 | }) -------------------------------------------------------------------------------- /src/less/mixins/clearfix.less: -------------------------------------------------------------------------------- 1 | // Clearfix 2 | // 3 | // For modern browsers 4 | // 1. The space content is one way to avoid an Opera bug when the 5 | // contenteditable attribute is included anywhere else in the document. 6 | // Otherwise it causes space to appear at the top and bottom of elements 7 | // that are clearfixed. 8 | // 2. The use of `table` rather than `block` is only necessary if using 9 | // `:before` to contain the top-margins of child elements. 10 | // 11 | // Source: http://nicolasgallagher.com/micro-clearfix-hack/ 12 | 13 | .clearfix() { 14 | &:before, 15 | &:after { 16 | content: " "; // 1 17 | display: table; // 2 18 | } 19 | &:after { 20 | clear: both; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/less/modules/progress-bars.less: -------------------------------------------------------------------------------- 1 | // 2 | // Progress bars 3 | // -------------------------------------------------- 4 | 5 | // Outer container 6 | .progress { 7 | background: mix(@brand-primary, white, 10%); 8 | border-radius: 32px; 9 | height: @progress-height; 10 | box-shadow: none; 11 | } 12 | 13 | // Bar of progress 14 | .progress-bar { 15 | background: @brand-secondary; 16 | line-height: @progress-height; 17 | box-shadow: none; 18 | } 19 | 20 | // Variations 21 | // ------------------------- 22 | 23 | .progress-bar-success { 24 | background-color: @brand-success; 25 | } 26 | .progress-bar-warning { 27 | background-color: @brand-warning; 28 | } 29 | .progress-bar-danger { 30 | background-color: @brand-danger; 31 | } 32 | .progress-bar-info { 33 | background-color: @brand-info; 34 | } 35 | -------------------------------------------------------------------------------- /src/less/modules/tiles.less: -------------------------------------------------------------------------------- 1 | // 2 | // Tiles 3 | // ------------------------------------------------- 4 | 5 | .tile { 6 | background-color: @tiles-bg; 7 | border-radius: @tiles-border-radius; 8 | padding: 14px; 9 | margin-bottom: 20px; 10 | position: relative; 11 | text-align: center; 12 | 13 | .tile-hot-ribbon { 14 | display: block; 15 | position: absolute; 16 | right: -4px; 17 | top: -4px; 18 | width: 82px; 19 | } 20 | p { 21 | font-size: 15px; 22 | margin-bottom: 33px; 23 | } 24 | } 25 | .tile-image { 26 | height: 100px; 27 | margin: 31px 0 27px; 28 | vertical-align: bottom; 29 | 30 | &.big-illustration { 31 | height: 111px; 32 | margin-top: 20px; 33 | width: 112px; 34 | } 35 | } 36 | .tile-title { 37 | font-size: 20px; 38 | margin: 0; 39 | } 40 | -------------------------------------------------------------------------------- /src/less/modules/share.less: -------------------------------------------------------------------------------- 1 | // 2 | // Sharing box 3 | // -------------------------------------------------- 4 | 5 | // Module color variable 6 | @share-color: mix(@brand-primary, @inverse, 8%); 7 | 8 | .share { 9 | background-color: @share-color; 10 | position: relative; 11 | border-radius: @border-radius-large; 12 | 13 | ul { 14 | list-style-type: none; 15 | margin: 0; 16 | padding: 15px; 17 | } 18 | li { 19 | font-size: @component-font-size-base; 20 | line-height: 1.4; 21 | padding-top: 11px; 22 | .clearfix(); 23 | 24 | &:first-child { 25 | padding-top: 0; 26 | } 27 | } 28 | .toggle { 29 | float: right; 30 | margin: 0; 31 | } 32 | .btn { 33 | .border-top-radius(0); 34 | } 35 | } 36 | 37 | .share-label { 38 | float: left; 39 | font-size: 15px; 40 | line-height: 1.4; 41 | padding-top: 5px; 42 | width: 50%; 43 | } 44 | -------------------------------------------------------------------------------- /src/less/modules/thumbnails.less: -------------------------------------------------------------------------------- 1 | // 2 | // Thumbnails 3 | // -------------------------------------------------- 4 | 5 | 6 | // Mixin and adjust the regular image class 7 | .thumbnail { 8 | display: block; 9 | padding: @thumbnail-padding; 10 | margin-bottom: 5px; 11 | line-height: @line-height-base; 12 | background-color: @thumbnail-bg; 13 | border: 2px solid @thumbnail-border; 14 | border-radius: @thumbnail-border-radius; 15 | transition: border .25s ease-in-out; 16 | 17 | > img, 18 | a > img { 19 | .img-responsive(); 20 | margin-left: auto; 21 | margin-right: auto; 22 | } 23 | 24 | // Add a hover state for linked versions only 25 | a&:hover, 26 | a&:focus, 27 | a&.active { 28 | border-color: @link-color; 29 | } 30 | 31 | // Image captions 32 | .caption { 33 | padding: @thumbnail-caption-padding; 34 | color: @thumbnail-caption-color; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import createBrowserHistory from 'history/lib/createBrowserHistory'; 3 | import createHashHistory from 'history/lib/createHashHistory'; 4 | import HistoryContainer from './utils/HistoryContainer'; 5 | 6 | import { Router, Route, IndexRoute } from 'react-router'; 7 | 8 | // Components 9 | 10 | import App from './App'; 11 | import About from './routes/About'; 12 | import Home from './routes/Home'; 13 | 14 | // history pushstate 15 | let history; 16 | 17 | if(!global.__SERVER__) history = (Modernizr && Modernizr.history)? createBrowserHistory(): createHashHistory(); 18 | HistoryContainer.set(history); 19 | 20 | // routes 21 | 22 | let routes = ( 23 | 24 | 25 | 26 | 27 | 28 | 29 | ) 30 | 31 | export default routes; -------------------------------------------------------------------------------- /src/less/modules/typeahead.less: -------------------------------------------------------------------------------- 1 | // 2 | // Typeahead 3 | // -------------------------------------------------- 4 | 5 | .twitter-typeahead { 6 | width: 100%; 7 | 8 | .tt-dropdown-menu { 9 | width: 100%; 10 | margin-top: 5px; 11 | border: 2px solid @brand-secondary; 12 | padding: 5px 0; 13 | background-color: @inverse; 14 | border-radius: @border-radius-large; 15 | } 16 | 17 | .tt-suggestion { 18 | p { 19 | padding: 6px 14px; 20 | font-size: ceil((@component-font-size-base * 0.933)); 21 | line-height: 1.429; // ~20px 22 | margin: 0; 23 | } 24 | 25 | &:first-child, 26 | &:last-child { 27 | p { 28 | padding: 6px 14px; 29 | } 30 | } 31 | &.tt-is-under-cursor, // Deprecated 32 | &.tt-cursor { 33 | cursor: pointer; 34 | color: #fff; 35 | background-color: mix(@brand-secondary, black, 85%); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/less/mixins/switches.less: -------------------------------------------------------------------------------- 1 | // Switch variants 2 | 3 | .switch-variant(@handle-color, @handle-bg, @label-border, @label-bg) { 4 | color: @handle-color; 5 | background-color: @handle-bg; 6 | 7 | // second handler "label" 8 | ~ .@{switch-name}-handle-off:before { 9 | background-color: @label-bg; 10 | border-color: @label-border; 11 | } 12 | 13 | // second handler inset shadow 14 | .@{switch-name}-on & { 15 | ~ .@{switch-name}-handle-off { 16 | box-shadow: inset 16px 0 0 @handle-bg; 17 | } 18 | } 19 | } 20 | 21 | // Switch handle-off variant 22 | .switch-handle-off-variant(@handle-name, @handle-border, @handle-bg) { 23 | // second heandler outset shadow 24 | & ~ .@{switch-name}-handle-off.@{switch-name}-@{handle-name} { 25 | box-shadow: ~"inset 0 0 transparent, -16px 0 0 @{handle-border}"; 26 | } 27 | // second heandler "label" 28 | ~ .@{switch-name}-handle-off.@{switch-name}-@{handle-name}:before { 29 | border-color: @handle-border; 30 | background-color: @handle-bg; 31 | } 32 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | module.exports = { 5 | devtool: 'source-maps', 6 | entry: [ 7 | 'webpack-dev-server/client?http://localhost:3000', 8 | 'webpack/hot/only-dev-server', 9 | './src/index' 10 | ], 11 | output: { 12 | path: path.join(__dirname, 'static'), 13 | filename: 'bundle.js', 14 | publicPath: '/static/' 15 | }, 16 | plugins: [ 17 | new webpack.HotModuleReplacementPlugin(), 18 | ], 19 | module: { 20 | loaders: [{ 21 | test: /\.js$/, 22 | loaders: ['react-hot', 'babel'], 23 | include: path.join(__dirname, 'src') 24 | }, 25 | { 26 | test: /\.less$/, 27 | loader: 'style-loader!css-loader!less-loader' 28 | }, 29 | { 30 | test: /\.css$/, 31 | loader: 'style-loader!css-loader' 32 | }, 33 | { 34 | test : /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, 35 | loader : 'file-loader' 36 | } 37 | ] 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Donny Stark 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------------------------------- 3 | 4 | // Utilities 5 | @import "mixins/hide-text.less"; 6 | @import "mixins/opacity.less"; 7 | @import "mixins/image.less"; 8 | @import "mixins/reset-filter.less"; 9 | @import "mixins/resize.less"; 10 | @import "mixins/responsive-visibility.less"; 11 | @import "mixins/size.less"; 12 | @import "mixins/tab-focus.less"; 13 | @import "mixins/text-emphasis.less"; 14 | @import "mixins/text-overflow.less"; 15 | @import "mixins/vendor-prefixes.less"; 16 | @import "mixins/background-clip.less"; 17 | 18 | // Components 19 | @import "mixins/buttons.less"; 20 | @import "mixins/select.less"; 21 | @import "mixins/pagination.less"; 22 | @import "mixins/nav-divider.less"; 23 | @import "mixins/forms.less"; 24 | @import "mixins/switches.less"; 25 | @import "mixins/pallets.less"; 26 | 27 | // Skins 28 | @import "mixins/background-variant.less"; 29 | @import "mixins/border-radius.less"; 30 | @import "mixins/gradients.less"; 31 | 32 | // Layout 33 | @import "mixins/clearfix.less"; 34 | @import "mixins/center-block.less"; 35 | @import "mixins/navbar-vertical-align.less"; 36 | @import "mixins/grid.less"; 37 | -------------------------------------------------------------------------------- /src/less/modules/print.less: -------------------------------------------------------------------------------- 1 | /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ 2 | 3 | // ========================================================================== 4 | // Print styles. 5 | // Inlined to avoid the additional HTTP request: h5bp.com/r 6 | // ========================================================================== 7 | 8 | @media print { 9 | .btn { 10 | border-style: solid; 11 | border-width: 2px; 12 | } 13 | .dropdown-menu { 14 | background: #fff !important; 15 | border: 2px solid #ddd; 16 | } 17 | .input-group-rounded .input-group-btn { 18 | & + .form-control, 19 | & + .select2-search input[type="text"] { 20 | padding-left: 10px; 21 | } 22 | } 23 | .form-control { 24 | border: 2px solid #ddd !important; 25 | } 26 | .bootstrap-switch { 27 | height: 33px; 28 | width: 84px; 29 | border: 2px solid #bdc3c7; 30 | } 31 | .tooltip { 32 | border: 2px solid #bdc3c7; 33 | } 34 | .progress, .ui-slider { 35 | background: #ddd !important; 36 | } 37 | .progress-bar, .ui-slider-range, .ui-slider-handle { 38 | background: #bdc3c7 !important; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/less/modules/code.less: -------------------------------------------------------------------------------- 1 | // 2 | // Code (inline and blocK) 3 | // -------------------------------------------------- 4 | 5 | 6 | // Inline and block code styles 7 | code, 8 | kbd, 9 | pre, 10 | samp { 11 | font-family: @font-family-monospace; 12 | } 13 | 14 | // Inline code 15 | code { 16 | padding: 2px 6px; 17 | font-size: 85%; 18 | color: @code-color; 19 | background-color: @code-bg; 20 | border-radius: @border-radius-base; 21 | } 22 | 23 | // User input typically entered via keyboard 24 | kbd { 25 | padding: 2px 6px; 26 | font-size: 85%; 27 | color: @kbd-color; 28 | background-color: @kbd-bg; 29 | border-radius: @border-radius-base; 30 | box-shadow: none; 31 | } 32 | 33 | // Blocks of code 34 | pre { 35 | padding: ((@line-height-computed - 6) / 3); 36 | margin: 0 0 (@line-height-computed / 2); 37 | font-size: (@font-size-base - 5); // 18px to 13px 38 | line-height: @line-height-base; 39 | color: @pre-color; 40 | background-color: @pre-bg; 41 | border: 2px solid @pre-border-color; 42 | border-radius: @pre-border-radius; 43 | white-space: pre; 44 | } 45 | 46 | // Enable scrollable blocks of code 47 | .pre-scrollable { 48 | max-height: @pre-scrollable-max-height; 49 | } -------------------------------------------------------------------------------- /src/less/mixins/image.less: -------------------------------------------------------------------------------- 1 | // Image Mixins 2 | // - Responsive image 3 | // - Retina image 4 | 5 | 6 | // Responsive image 7 | // 8 | // Keep images from scaling beyond the width of their parents. 9 | .img-responsive(@display: block) { 10 | display: @display; 11 | max-width: 100%; // Part 1: Set a maximum relative to the parent 12 | height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching 13 | } 14 | 15 | 16 | // Retina image 17 | // 18 | // Short retina mixin for setting background-image and -size. Note that the 19 | // spelling of `min--moz-device-pixel-ratio` is intentional. 20 | .img-retina(@file-1x; @file-2x; @width-1x; @height-1x) { 21 | background-image: url("@{file-1x}"); 22 | 23 | @media 24 | only screen and (-webkit-min-device-pixel-ratio: 2), 25 | only screen and ( min--moz-device-pixel-ratio: 2), 26 | only screen and ( -o-min-device-pixel-ratio: 2/1), 27 | only screen and ( min-device-pixel-ratio: 2), 28 | only screen and ( min-resolution: 192dpi), 29 | only screen and ( min-resolution: 2dppx) { 30 | background-image: url("@{file-2x}"); 31 | background-size: @width-1x @height-1x; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/less/modules/pager.less: -------------------------------------------------------------------------------- 1 | // 2 | // Pager 3 | // -------------------------------------------------- 4 | 5 | .pager { 6 | background-color: @pager-bg; 7 | border-radius: @pager-border-radius; 8 | color: @pager-color; 9 | font-size: 16px; 10 | font-weight: 700; 11 | display: inline-block; 12 | 13 | li { 14 | &:first-child { 15 | > a, 16 | > span { 17 | border-left: none; 18 | border-radius: @pager-border-radius 0 0 @pager-border-radius; 19 | } 20 | } 21 | 22 | > a, 23 | > span { 24 | background: none; 25 | border: none; 26 | border-left: 2px solid mix(@brand-primary, black, 85%); 27 | color: @inverse; 28 | padding: @pager-padding; 29 | text-decoration: none; 30 | white-space: nowrap; 31 | border-radius: 0 @pager-border-radius @pager-border-radius 0; 32 | line-height: 1.313; 33 | 34 | &:hover, 35 | &:focus { 36 | background-color: @pager-hover-bg; 37 | } 38 | &:active { 39 | background-color: @pager-active-bg; 40 | } 41 | 42 | // Add some spacing between the icon and text 43 | [class*="fui-"] + span { 44 | margin-left: 8px; 45 | } 46 | span + [class*="fui-"] { 47 | margin-left: 8px; 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/less/modules/scaffolding.less: -------------------------------------------------------------------------------- 1 | // 2 | // Scaffolding 3 | // -------------------------------------------------- 4 | 5 | 6 | // Body reset 7 | // ------------------------- 8 | 9 | body { 10 | font-family: @font-family-base; 11 | font-size: @font-size-base; 12 | line-height: @line-height-base; 13 | color: @text-color; 14 | background-color: @body-bg; 15 | } 16 | 17 | // Links 18 | // ------------------------- 19 | 20 | a { 21 | color: @link-color; 22 | text-decoration: none; 23 | transition: .25s; 24 | 25 | &:hover, 26 | &:focus { 27 | color: @link-hover-color; 28 | text-decoration: @link-hover-decoration; 29 | } 30 | &:focus { 31 | outline: none; 32 | } 33 | } 34 | 35 | // Images 36 | // ------------------------- 37 | 38 | // Rounded corners 39 | .img-rounded { 40 | border-radius: @border-radius-large; 41 | } 42 | 43 | // Image thumbnails 44 | // 45 | // Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`. 46 | .img-thumbnail { 47 | padding: @thumbnail-padding; 48 | line-height: @line-height-base; 49 | background-color: @thumbnail-bg; 50 | border: 2px solid @thumbnail-border; 51 | border-radius: @thumbnail-border-radius; 52 | transition: all .25s ease-in-out; 53 | 54 | // Keep them at most 100% wide 55 | .img-responsive(inline-block); 56 | } 57 | 58 | // Description text under image 59 | .img-comment { 60 | font-size: ceil((@font-size-base * 0.8333)); // ~15px 61 | line-height: 1.2; 62 | font-style: italic; 63 | margin: 24px 0; 64 | } -------------------------------------------------------------------------------- /src/less/flat-ui.less: -------------------------------------------------------------------------------- 1 | // 2 | // Flat UI main stylesheet that aggregates all modules 3 | // -------------------------------------------------- 4 | 5 | // Loading config with variables (changing them leads to changing a color scheme) 6 | @import "variables"; 7 | 8 | // Utility mixins for greater good 9 | @import "mixins"; 10 | 11 | // Loading custom fonts 12 | // @import url("https://fonts.googleapis.com/css?family=Lato:400,700,700italic,900,400italic,300"); 13 | @import "modules/local-fonts"; 14 | @import "modules/glyphicons"; 15 | 16 | // Modules 17 | @import "modules/scaffolding"; 18 | @import "modules/type"; 19 | @import "modules/code"; 20 | @import "modules/thumbnails"; 21 | @import "modules/buttons"; 22 | @import "modules/button-groups"; 23 | @import "modules/forms"; 24 | @import "modules/input-groups"; 25 | @import "modules/radiocheck"; 26 | @import "modules/tagsinput"; 27 | @import "modules/typeahead"; 28 | @import "modules/progress-bars"; 29 | @import "modules/slider"; 30 | @import "modules/pager"; 31 | @import "modules/pagination"; 32 | @import "modules/tooltip"; 33 | @import "modules/dropdowns"; 34 | @import "modules/select"; 35 | @import "modules/tiles"; 36 | @import "modules/navbar"; 37 | @import "modules/switch"; 38 | @import "modules/share"; 39 | @import "modules/video"; 40 | @import "modules/todo-list"; 41 | 42 | // Examples 43 | @import "modules/palette"; 44 | // @import "modules/login"; 45 | @import "modules/footer"; 46 | 47 | // Spaces 48 | @import "spaces"; 49 | 50 | //Print styles 51 | @import "modules/print"; 52 | -------------------------------------------------------------------------------- /src/less/modules/footer.less: -------------------------------------------------------------------------------- 1 | // 2 | // Footer 3 | // -------------------------------------------------- 4 | 5 | footer { 6 | background-color: mix(@brand-primary, @inverse, 9%); 7 | color: mix(@brand-primary, @inverse, 34%); 8 | font-size: 15px; 9 | padding: 0; 10 | 11 | a { 12 | color: mix(@brand-primary, @inverse, 50%); 13 | font-weight: 700; 14 | } 15 | p { 16 | font-size: 15px; 17 | line-height: 20px; 18 | margin-bottom: 10px; 19 | } 20 | } 21 | 22 | .footer-title { 23 | margin: 0 0 22px; 24 | padding-top: 21px; 25 | font-size: 24px; 26 | line-height: 40px; 27 | } 28 | 29 | .footer-brand { 30 | display: block; 31 | margin-bottom: 26px; 32 | width: 220px; 33 | 34 | img { 35 | width: 216px; 36 | } 37 | } 38 | 39 | // Footer banner 40 | .footer-banner { 41 | background-color: @brand-secondary; 42 | color: mix(@brand-secondary, @inverse, 20%); 43 | margin-left: 42px; 44 | min-height: 316px; 45 | padding: 0 30px 30px; 46 | 47 | .footer-title { 48 | color: @inverse; 49 | } 50 | a { 51 | color: lighten(@brand-secondary, 42%); 52 | text-decoration: underline; 53 | 54 | &:hover { 55 | text-decoration: none; 56 | } 57 | } 58 | ul { 59 | list-style-type: none; 60 | margin: 0 0 26px; 61 | padding: 0; 62 | 63 | li { 64 | border-top: 1px solid lighten(@brand-secondary, 2%); 65 | line-height: 19px; 66 | padding: 6px 0; 67 | 68 | &:first-child { 69 | border-top: none; 70 | padding-top: 1px; 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/less/mixins/buttons.less: -------------------------------------------------------------------------------- 1 | // Button variants 2 | // 3 | .button-variant(@color; @background; @hover-background; @active-background; @disabled-background: @gray-light) { 4 | color: @color; 5 | background-color: @background; 6 | 7 | &:hover, 8 | &.hover, 9 | &:focus, 10 | &:active, 11 | &.active, 12 | .open > .dropdown-toggle& { 13 | color: @color; 14 | background-color: @hover-background; 15 | border-color: @hover-background; 16 | } 17 | &:active, 18 | &.active, 19 | .open > .dropdown-toggle& { 20 | background: @active-background; 21 | border-color: @active-background; 22 | } 23 | &.disabled, 24 | &[disabled], 25 | fieldset[disabled] & { 26 | &, 27 | &:hover, 28 | &.hover, 29 | &:focus, 30 | &:active, 31 | &.active { 32 | background-color: @disabled-background; 33 | border-color: @background; 34 | } 35 | } 36 | 37 | .badge { 38 | color: @background; 39 | background-color: @inverse; 40 | } 41 | } 42 | 43 | // Button sizes 44 | .button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) { 45 | padding: @padding-vertical @padding-horizontal; 46 | font-size: @font-size; 47 | line-height: @line-height; 48 | border-radius: @border-radius; 49 | } 50 | 51 | // Social button variants 52 | .social-button-variant(@color; @background) { 53 | color: @color; 54 | background-color: @background; 55 | 56 | &:hover, 57 | &:focus { 58 | background-color: mix(@background, white, 80%); 59 | } 60 | &:active, 61 | &.active { 62 | background-color: mix(@background, black, 85%); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/less/mixins/select.less: -------------------------------------------------------------------------------- 1 | // Select variants 2 | // 3 | 4 | .select-variant(@color; @background; @hover-background; @active-background; @disabled-background: @gray-light; @arrow-color) { 5 | .select2-choice { 6 | color: @color; 7 | background-color: @background; 8 | 9 | &:hover, 10 | &.hover, 11 | &:focus, 12 | &:active { 13 | color: @color; 14 | background-color: @hover-background; 15 | border-color: @hover-background; 16 | } 17 | &:active { 18 | background: @active-background; 19 | border-color: @active-background; 20 | } 21 | .select2-container-disabled& { 22 | &, 23 | &:hover, 24 | &:focus, 25 | &:active { 26 | background-color: @disabled-background; 27 | border-color: @background; 28 | } 29 | } 30 | 31 | .select2-arrow { 32 | border-top-color: @arrow-color; 33 | } 34 | } 35 | } 36 | 37 | .select-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) { 38 | .button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius); 39 | padding-right: (@padding-horizontal * 2 + 9px); 40 | min-height: round((@line-height*@font-size + 2*@padding-vertical)); // we need min-height for empty ones 41 | } 42 | 43 | .multiple-select-variant(@background; @hover-background; @border-color) { 44 | .select2-container-multi& { 45 | border-color: @border-color; 46 | 47 | .select2-search-choice { 48 | background-color: @background; 49 | 50 | &:hover { 51 | background-color: @hover-background; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/less/modules/palette.less: -------------------------------------------------------------------------------- 1 | // 2 | // Palette 3 | // -------------------------------------------------- 4 | 5 | .pallete-item { 6 | width: 140px; 7 | float: left; 8 | margin: 0 0 20px 20px; 9 | } 10 | .palette { 11 | font-size: ceil((@component-font-size-base * 0.933)); // ~14px 12 | line-height: 1.214; // ~17px 13 | color: @inverse; 14 | margin: 0; 15 | padding: 15px; 16 | text-transform: uppercase; 17 | 18 | dt, 19 | dd { 20 | line-height: 1.429; 21 | } 22 | dt { 23 | display: block; 24 | font-weight: bold; 25 | opacity: .8; 26 | } 27 | dd { 28 | font-weight: 300; 29 | margin-left: 0; 30 | opacity: .8; 31 | -webkit-font-smoothing: subpixel-antialiased; 32 | } 33 | } 34 | 35 | // 36 | // Pallet grid 37 | // -------------------------------------------------- 38 | .pallet-variant(~"turquoise", ~"green-sea"); 39 | .pallet-variant(~"emerald", ~"nephritis"); 40 | .pallet-variant(~"peter-river", ~"belize-hole"); 41 | .pallet-variant(~"amethyst", ~"wisteria"); 42 | .pallet-variant(~"wet-asphalt", ~"midnight-blue"); 43 | 44 | .pallet-variant(~"sun-flower", ~"orange"); 45 | .pallet-variant(~"carrot", ~"pumpkin"); 46 | .pallet-variant(~"alizarin", ~"pomegranate"); 47 | .pallet-variant(~"clouds", ~"silver"); 48 | .pallet-variant(~"concrete", ~"asbestos"); 49 | 50 | .palette-clouds { 51 | color: #bdc3c7; 52 | } 53 | 54 | // Palette paragraph 55 | .palette-paragraph { 56 | color: #7f8c8d; 57 | font-size: 12px; 58 | line-height: 17px; 59 | 60 | span { 61 | color: #bdc3c7; 62 | } 63 | } 64 | 65 | // Headline 66 | .palette-headline { 67 | color: #7f8c8d; 68 | font-size: 13px; 69 | font-weight: 700; 70 | margin-top: -3px; 71 | } 72 | -------------------------------------------------------------------------------- /src/less/modules/tooltip.less: -------------------------------------------------------------------------------- 1 | // 2 | // Tooltips 3 | // -------------------------------------------------- 4 | 5 | // Base class 6 | .tooltip { 7 | font-size: ceil((@component-font-size-base * 0.933)); // ~14px 8 | line-height: 1.286; // 18px 9 | z-index: @zindex-tooltip; 10 | 11 | &.in { .opacity(@tooltip-opacity); } 12 | &.top { margin-top: -5px; padding: @tooltip-arrow-width 0; } 13 | &.right { margin-left: 5px; padding: 0 @tooltip-arrow-width; } 14 | &.bottom { margin-top: 5px; padding: @tooltip-arrow-width 0; } 15 | &.left { margin-left: -5px; padding: 0 @tooltip-arrow-width; } 16 | } 17 | 18 | // Wrapper for the tooltip content 19 | .tooltip-inner { 20 | max-width: @tooltip-max-width; 21 | line-height: 1.286; // 18px 22 | padding: 12px 12px; 23 | color: @tooltip-color; 24 | background-color: @tooltip-bg; 25 | border-radius: @border-radius-large; 26 | } 27 | 28 | // Arrows 29 | .tooltip { 30 | &.top .tooltip-arrow { 31 | margin-left: -@tooltip-arrow-width; 32 | border-width: @tooltip-arrow-width @tooltip-arrow-width 0; 33 | border-top-color: @tooltip-arrow-color; 34 | } 35 | &.right .tooltip-arrow { 36 | margin-top: -@tooltip-arrow-width; 37 | border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0; 38 | border-right-color: @tooltip-arrow-color; 39 | } 40 | &.left .tooltip-arrow { 41 | margin-top: -@tooltip-arrow-width; 42 | border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width; 43 | border-left-color: @tooltip-arrow-color; 44 | } 45 | &.bottom .tooltip-arrow { 46 | margin-left: -@tooltip-arrow-width; 47 | border-width: 0 @tooltip-arrow-width @tooltip-arrow-width; 48 | border-bottom-color: @tooltip-arrow-color; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-webpack-starter", 3 | "version": "0.0.2", 4 | "description": "React + Webpack + Express isomorphic universal configuration starter", 5 | "scripts": { 6 | "start": "node server/app.js", 7 | "dev": "node webpack.development.js", 8 | "build": "node ./node_modules/webpack/bin/webpack.js --verbose --colors --display-error-details --config webpack.client.js", 9 | "lint": "eslint src" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/rromadhoni/react-webpack-starter.git" 14 | }, 15 | "keywords": [ 16 | "react", 17 | "reactjs", 18 | "hot", 19 | "reload", 20 | "hmr", 21 | "live", 22 | "edit", 23 | "webpack" 24 | ], 25 | "author": "Donny Stark", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/rromadhoni/react-webpack-starter/issues" 29 | }, 30 | "homepage": "https://github.com/rromadhoni/react-webpack-starter", 31 | "devDependencies": { 32 | "babel-core": "^6.0.20", 33 | "babel-eslint": "^4.1.3", 34 | "babel-loader": "^6.0.1", 35 | "babel-preset-es2015": "^6.0.15", 36 | "babel-preset-react": "^6.0.15", 37 | "babel-preset-stage-0": "^6.0.15", 38 | "css-loader": "^0.23.0", 39 | "eslint-plugin-react": "^3.6.2", 40 | "file-loader": "^0.8.4", 41 | "less": "^2.5.3", 42 | "less-loader": "^2.2.1", 43 | "react-hot-loader": "^1.3.0", 44 | "style-loader": "^0.13.0", 45 | "webpack": "^1.12.2", 46 | "webpack-dev-server": "^1.12.1" 47 | }, 48 | "dependencies": { 49 | "babel": "^6.1.18", 50 | "babel-polyfill": "^6.2.0", 51 | "body-parser": "^1.14.1", 52 | "browsernizr": "^2.0.1", 53 | "express": "^4.13.3", 54 | "extract-text-webpack-plugin": "^0.9.1", 55 | "history": "1.13.1", 56 | "node-jsx": "^0.13.3", 57 | "piping": "^0.3.0", 58 | "react": "^0.14.0", 59 | "react-bootstrap": "^0.27.3", 60 | "react-dom": "^0.14.0", 61 | "react-router": "^1.0.0" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | React Webpack Starter - ReactJS Indonesia 2 | ===================== 3 | 4 | Konfigurasi minimal untuk memulai project baru ReactJS. 5 | Menggunakan standar ES6 oleh babel. 6 | 7 | ## Syarat Sistem 8 | 9 | Untuk dapat menjalankan starter ini setidaknya sistem anda harus sudah terinstal NodeJS, versi terbaru direkomendasikan 10 | 11 | ## Penggunaan 12 | 13 | ### Jalankan server 14 | 15 | ``` 16 | npm install 17 | npm run build 18 | npm start 19 | open http://localhost:3000 20 | ``` 21 | 22 | ### Development 23 | 24 | ``` 25 | npm install 26 | npm run dev 27 | open http://localhost:3000 28 | ``` 29 | 30 | 31 | 32 | ### Linting 33 | 34 | Linting untuk react. 35 | 36 | ``` 37 | npm run lint 38 | ``` 39 | ### Panduan 40 | 41 | ``` 42 | . 43 | ├── LICENSE 44 | ├── README.md 45 | ├── static => aset hasil ekstraksi webpack 46 | ├── assets => aset statis 47 | │   └── loading.gif 48 | ├── index.html => entri index.html 49 | ├── package.json 50 | ├── server => direktori server 51 | │   ├── app.js 52 | │   └── server.js => static express server 53 | ├── src => semua aset frontend 54 | │   ├── App.js => root component 55 | │   ├── index.js => boot 56 | │   ├── routes => direktory untuk komponen 57 | │   │   ├── About.js => komponen react 58 | │   │   └── Home.js => komponen react 59 | │   ├── routes.js => routing (hashbang atau pushstate) 60 | │   └── utils => direktori untuk helper 61 | │   └── HistoryContainer.js => history pushstate container 62 | ├── webpack.client.js => konfigurasi webpack untuk build 63 | ├── webpack.config.js => konfigurasi webpack untuk development 64 | └── webpack.development.js => webpack dev server (termasuk hot-loader) 65 | ``` 66 | 67 | 68 | 69 | ### Dependencies 70 | 71 | * React 72 | * Webpack 73 | * [webpack-dev-server](https://github.com/webpack/webpack-dev-server) 74 | * [babel-loader](https://github.com/babel/babel-loader) 75 | * [react-hot-loader](https://github.com/gaearon/react-hot-loader) 76 | * [react-router](https://github.com/rackt/react-router) 77 | * [express](http://expressjs.com/) 78 | 79 | -------------------------------------------------------------------------------- /src/less/modules/slider.less: -------------------------------------------------------------------------------- 1 | // Slider 2 | // -------------------------------------------------- 3 | 4 | // Default controls 5 | // ------------------------- 6 | 7 | .ui-slider { 8 | .progress(); 9 | margin-bottom: 20px; 10 | position: relative; 11 | cursor: pointer; 12 | } 13 | 14 | .ui-slider-handle { 15 | background-color: @slider-handle-bg; 16 | border-radius: 50%; 17 | cursor: pointer; 18 | height: 18px; 19 | position: absolute; 20 | width: 18px; 21 | z-index: 2; 22 | transition: background .25s; 23 | 24 | &:hover, 25 | &:focus { 26 | background-color: @slider-handle-hover-bg; 27 | outline: none; 28 | } 29 | &:active { 30 | background-color: @slider-handle-active-bg; 31 | } 32 | } 33 | 34 | .ui-slider-range { 35 | background-color: @slider-range-bg; 36 | display: block; 37 | height: 100%; 38 | position: absolute; 39 | z-index: 1; 40 | } 41 | 42 | // Segments 43 | // ------------------------- 44 | .ui-slider-segment { 45 | background-color: @slider-segment-bg; 46 | border-radius: 50%; 47 | height: 6px; 48 | width: 6px; 49 | } 50 | 51 | // Values 52 | // ------------------------- 53 | .ui-slider-value { 54 | float: right; 55 | font-size: @slider-value-font-size; 56 | margin-top: @slider-height; 57 | 58 | &.first { 59 | clear: left; 60 | float: left; 61 | } 62 | } 63 | 64 | // Horizontal orientation 65 | // ------------------------- 66 | 67 | .ui-slider-horizontal { 68 | .ui-slider-handle { 69 | margin-left: -9px; 70 | top: -3px; 71 | 72 | &[style*="100"] { 73 | margin-left: -15px; 74 | } 75 | } 76 | .ui-slider-range { 77 | border-radius: 30px 0 0 30px; 78 | } 79 | .ui-slider-segment { 80 | float: left; 81 | margin: 3px -6px 0 0; 82 | } 83 | } 84 | 85 | // Vertical orientation 86 | // ------------------------- 87 | 88 | .ui-slider-vertical { 89 | width: @slider-height; 90 | 91 | .ui-slider-handle { 92 | margin-left: -3px; 93 | margin-bottom: -11px; 94 | top: auto; 95 | } 96 | .ui-slider-range { 97 | width: 100%; 98 | bottom: 0; 99 | border-radius: 0 0 30px 30px; 100 | } 101 | .ui-slider-segment { 102 | position: absolute; 103 | right: 3px; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /webpack.client.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | module.exports = { 6 | entry: [ 7 | './src/index' 8 | ], 9 | output: { 10 | path: path.join(__dirname, 'static'), 11 | filename: 'bundle.js', 12 | publicPath: '/static/' 13 | }, 14 | plugins: [ 15 | new webpack.DefinePlugin({__CLIENT__: true, __SERVER__: false}), 16 | new webpack.DefinePlugin({"process.env": {NODE_ENV: '"production"'}}), 17 | new webpack.optimize.DedupePlugin(), 18 | new webpack.optimize.OccurenceOrderPlugin(), 19 | new webpack.optimize.UglifyJsPlugin({ 20 | compress: { 21 | warnings: false, 22 | properties: true, 23 | sequences: true, 24 | dead_code: true, 25 | conditionals: true, 26 | comparisons: true, 27 | evaluate: true, 28 | booleans: true, 29 | unused: true, 30 | loops: true, 31 | hoist_funs: true, 32 | cascade: true, 33 | if_return: true, 34 | join_vars: true, 35 | drop_console: true, 36 | drop_debugger: true, 37 | unsafe: true, 38 | hoist_vars: true, 39 | negate_iife: true, 40 | }, 41 | mangle: { 42 | toplevel: true, 43 | sort: true, 44 | eval: true, 45 | properties: true 46 | }, 47 | output: { 48 | space_colon: false, 49 | comments: function(node, comment) { 50 | var text = comment.value; 51 | var type = comment.type; 52 | if (type == "comment2") { 53 | // multiline comment 54 | return /@copyright/i.test(text); 55 | } 56 | } 57 | } 58 | }), 59 | new ExtractTextPlugin('[name].css') 60 | ], 61 | module: { 62 | loaders: [{ 63 | test: /\.js$/, 64 | loaders: ['babel'], 65 | include: path.join(__dirname, 'src') 66 | }, 67 | { 68 | test: /\.less$/, 69 | loader: ExtractTextPlugin.extract('style-loader', 'css-loader!less-loader') 70 | }, 71 | { 72 | test: /\.css$/, 73 | loader: 'style-loader!css-loader' 74 | }, 75 | { 76 | test : /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, 77 | loader : 'file-loader' 78 | } 79 | ], 80 | postLoaders: [], 81 | noParse: /\.min\.js/ 82 | }, 83 | node: { 84 | __dirname: true, 85 | fs: 'empty' 86 | } 87 | }; 88 | -------------------------------------------------------------------------------- /src/less/modules/login.less: -------------------------------------------------------------------------------- 1 | // 2 | // Login screen 3 | // -------------------------------------------------- 4 | 5 | // Module color variable 6 | @form-color: mix(@brand-primary, @inverse, 9%); 7 | 8 | .login { 9 | background: url(../img/login/imac.png) 0 0 no-repeat; 10 | background-size: 940px 778px; 11 | color: @inverse; 12 | margin-bottom: 77px; 13 | padding: 38px 38px 267px; 14 | position: relative; 15 | } 16 | 17 | .login-screen { 18 | background-color: @brand-secondary; 19 | min-height: 473px; 20 | padding: 123px 199px 33px 306px; 21 | } 22 | 23 | .login-icon { 24 | left: 200px; 25 | position: absolute; 26 | top: 160px; 27 | width: 96px; 28 | 29 | > img { 30 | display: block; 31 | margin-bottom: 6px; 32 | width: 100%; 33 | } 34 | > h4 { 35 | font-size: 17px; 36 | font-weight: 300; 37 | line-height: 34px; 38 | opacity: .95; 39 | 40 | small { 41 | color: inherit; 42 | display: block; 43 | font-size: inherit; 44 | font-weight: 700; 45 | } 46 | } 47 | } 48 | 49 | // LOGIN FORM 50 | // ----------- 51 | .login-form { 52 | background-color: @form-color; 53 | padding: 24px 23px 20px; 54 | position: relative; 55 | border-radius: @border-radius-large; 56 | 57 | .control-group { 58 | margin-bottom: 6px; 59 | position: relative; 60 | } 61 | .login-field { 62 | border-color: transparent; 63 | font-size: 17px; 64 | text-indent: 3px; 65 | 66 | &:focus { 67 | border-color: @brand-secondary; 68 | 69 | & + .login-field-icon { 70 | color: @brand-secondary; 71 | } 72 | } 73 | } 74 | .login-field-icon { 75 | color: mix(@gray, @inverse, 60%); 76 | font-size: 16px; 77 | position: absolute; 78 | right: 15px; 79 | top: 3px; 80 | transition: all .25s; 81 | } 82 | } 83 | 84 | .login-link { 85 | color: mix(@gray, @inverse, 60%); 86 | display: block; 87 | font-size: 13px; 88 | margin-top: 15px; 89 | text-align: center; 90 | } 91 | 92 | // Retina support 93 | @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (-moz-min-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 2) { 94 | .login { 95 | background-image: url(../img/login/imac-2x.png); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/less/modules/button-groups.less: -------------------------------------------------------------------------------- 1 | // 2 | // Button groups 3 | // -------------------------------------------------- 4 | 5 | 6 | .btn-group { 7 | > .btn { 8 | & + .btn { 9 | margin-left: 0; 10 | } 11 | & + .dropdown-toggle { 12 | border-left: 2px solid fade(@brand-primary, 15%); 13 | padding: 10px 12px; 14 | 15 | .caret { 16 | margin-left: 3px; 17 | margin-right: 3px; 18 | } 19 | } 20 | &.btn-gh + .dropdown-toggle { 21 | .caret { 22 | margin-left: 7px; 23 | margin-right: 7px; 24 | } 25 | } 26 | &.btn-sm + .dropdown-toggle { 27 | .caret { 28 | margin-left: 0; 29 | margin-right: 0; 30 | } 31 | } 32 | } 33 | } 34 | 35 | .dropdown-toggle { 36 | .caret { 37 | margin-left: 8px; 38 | } 39 | } 40 | 41 | // Sizing 42 | // 43 | // Remix the default button sizing classes into new ones for easier manipulation. 44 | 45 | .btn-group-xs > .btn { 46 | &:extend(.btn-xs); 47 | 48 | & + .dropdown-toggle { 49 | padding: 6px 9px; 50 | } 51 | } 52 | 53 | .btn-group-sm > .btn { 54 | &:extend(.btn-sm); 55 | 56 | & + .dropdown-toggle { 57 | padding: 9px 13px; 58 | } 59 | } 60 | 61 | .btn-group-lg > .btn { 62 | &:extend(.btn-lg); 63 | 64 | & + .dropdown-toggle { 65 | padding: 10px 19px; 66 | } 67 | } 68 | 69 | .btn-group-hg > .btn { 70 | &:extend(.btn-hg); 71 | 72 | & + .dropdown-toggle { 73 | padding: 13px 20px; 74 | } 75 | } 76 | 77 | 78 | 79 | // Carets in other button sizes 80 | .btn-xs .caret { 81 | border-width: @caret-width-xs-vertical @caret-width-xs 0; 82 | border-bottom-width: 0; 83 | } 84 | .btn-lg .caret { 85 | border-width: @caret-width-base-vertical @caret-width-base 0; 86 | border-bottom-width: 0; 87 | } 88 | // Upside down carets for .dropup 89 | .dropup .btn-lg .caret { 90 | border-width: 0 @caret-width-base @caret-width-base-vertical; 91 | } 92 | .dropup .btn-xs .caret { 93 | border-width: 0 @caret-width-xs @caret-width-xs-vertical; 94 | } 95 | 96 | .btn-group > .btn, 97 | .btn-group > .dropdown-menu, 98 | .btn-group > .popover { 99 | font-weight: 400; 100 | } 101 | 102 | .btn-group:focus .dropdown-toggle { 103 | outline: none; 104 | transition: .25s; 105 | } 106 | 107 | // The clickable button for toggling the menu 108 | // Remove the gradient and set the same inset shadow as the :active state 109 | .btn-group.open .dropdown-toggle { 110 | color: fade(@btn-default-color, 75%); 111 | box-shadow: none; 112 | } 113 | 114 | // Other button locations 115 | // Button with icon inside 116 | .btn-toolbar .btn { 117 | &.active { 118 | color: @btn-default-color; 119 | } 120 | > [class^="fui-"] { 121 | font-size: @icon-normal; 122 | margin: 0 1px; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/less/spaces.less: -------------------------------------------------------------------------------- 1 | // Should be used to modify the default spacing between objects (not between nodes of * the same object) 2 | // p,m = padding,margin 3 | // a,t,r,b,l,h,v = all,top,right,bottom,left,horizontal,vertical 4 | // x,s,m,l,n = extra-small(@x),small(@s),medium(@m),large(@l),none(0px) 5 | @x: 3px; 6 | @s: 5px; 7 | @m: 10px; 8 | @l: 20px; 9 | 10 | .last-col { 11 | overflow: hidden; 12 | } 13 | 14 | .ptn, .pvn, .pan { 15 | padding-top: 0; 16 | } 17 | 18 | .ptx, .pvx, .pax { 19 | padding-top: @x; 20 | } 21 | 22 | .pts, .pvs, .pas { 23 | padding-top: @s; 24 | } 25 | 26 | .ptm, .pvm, .pam { 27 | padding-top: @m; 28 | } 29 | 30 | .ptl, .pvl, .pal { 31 | padding-top: @l; 32 | } 33 | 34 | .prn, .phn, .pan { 35 | padding-right: 0; 36 | } 37 | 38 | .prx, .phx, .pax { 39 | padding-right: @x; 40 | } 41 | 42 | .prs, .phs, .pas { 43 | padding-right: @s; 44 | } 45 | 46 | .prm, .phm, .pam { 47 | padding-right: @m; 48 | } 49 | 50 | .prl, .phl, .pal { 51 | padding-right: @l; 52 | } 53 | 54 | .pbn, .pvn, .pan { 55 | padding-bottom: 0; 56 | } 57 | 58 | .pbx, .pvx, .pax { 59 | padding-bottom: @x; 60 | } 61 | 62 | .pbs, .pvs, .pas { 63 | padding-bottom: @s; 64 | } 65 | 66 | .pbm, .pvm, .pam { 67 | padding-bottom: @m; 68 | } 69 | 70 | .pbl, .pvl, .pal { 71 | padding-bottom: @l; 72 | } 73 | 74 | .pln, .phn, .pan { 75 | padding-left: 0; 76 | } 77 | 78 | .plx, .phx, .pax { 79 | padding-left: @x; 80 | } 81 | 82 | .pls, .phs, .pas { 83 | padding-left: @s; 84 | } 85 | 86 | .plm, .phm, .pam { 87 | padding-left: @m; 88 | } 89 | 90 | .pll, .phl, .pal { 91 | padding-left: @l; 92 | } 93 | 94 | .mtn, .mvn, .man { 95 | margin-top: 0px; 96 | } 97 | 98 | .mtx, .mvx, .max { 99 | margin-top: @x; 100 | } 101 | 102 | .mts, .mvs, .mas { 103 | margin-top: @s; 104 | } 105 | 106 | .mtm, .mvm, .mam { 107 | margin-top: @m; 108 | } 109 | 110 | .mtl, .mvl, .mal { 111 | margin-top: @l; 112 | } 113 | 114 | .mrn, .mhn, .man { 115 | margin-right: 0px; 116 | } 117 | 118 | .mrx, .mhx, .max { 119 | margin-right: @x; 120 | } 121 | 122 | .mrs, .mhs, .mas { 123 | margin-right: @s; 124 | } 125 | 126 | .mrm, .mhm, .mam { 127 | margin-right: @m; 128 | } 129 | 130 | .mrl, .mhl, .mal { 131 | margin-right: @l; 132 | } 133 | 134 | .mbn, .mvn, .man { 135 | margin-bottom: 0px; 136 | } 137 | 138 | .mbx, .mvx, .max { 139 | margin-bottom: @x; 140 | } 141 | 142 | .mbs, .mvs, .mas { 143 | margin-bottom: @s; 144 | } 145 | 146 | .mbm, .mvm, .mam { 147 | margin-bottom: @m; 148 | } 149 | 150 | .mbl, .mvl, .mal { 151 | margin-bottom: @l; 152 | } 153 | 154 | .mln, .mhn, .man { 155 | margin-left: 0px; 156 | } 157 | 158 | .mlx, .mhx, .max { 159 | margin-left: @x; 160 | } 161 | 162 | .mls, .mhs, .mas { 163 | margin-left: @s; 164 | } 165 | 166 | .mlm, .mhm, .mam { 167 | margin-left: @m; 168 | } 169 | 170 | .mll, .mhl, .mal { 171 | margin-left: @l; 172 | } 173 | -------------------------------------------------------------------------------- /src/less/modules/todo-list.less: -------------------------------------------------------------------------------- 1 | // 2 | // Todo list 3 | // -------------------------------------------------- 4 | 5 | .todo { 6 | color: @todo-color; 7 | margin-bottom: 20px; 8 | border-radius: @todo-border-radius; 9 | 10 | ul { 11 | background-color: @todo-bg-active; 12 | margin: 0; 13 | padding: 0; 14 | list-style-type: none; 15 | border-radius: 0 0 @todo-border-radius @todo-border-radius; 16 | } 17 | li { 18 | background: @todo-bg; 19 | background-size: 20px 20px; 20 | cursor: pointer; 21 | font-size: ceil((@component-font-size-base * 0.933)); // ~14px 22 | line-height: 1.214; 23 | margin-top: 2px; 24 | padding: 18px 42px 21px 25px; 25 | position: relative; 26 | transition: .25s; 27 | 28 | &:first-child { 29 | margin-top: 0; 30 | } 31 | &:last-child { 32 | border-radius: 0 0 @todo-border-radius @todo-border-radius; 33 | padding-bottom: 21px; 34 | } 35 | &.todo-done { 36 | background: transparent; 37 | color: @todo-color-active; 38 | 39 | .todo-name { 40 | color: @todo-color-active; 41 | } 42 | } 43 | &:after { 44 | content: " "; 45 | display: block; 46 | width: 20px; 47 | height: 20px; 48 | position: absolute; 49 | top: 50%; 50 | right: 22px; 51 | margin-top: -10px; 52 | background: @todo-name-color; 53 | border-radius: 50%; 54 | } 55 | &.todo-done:after { 56 | content: "\e60a"; 57 | font-family: 'Flat-UI-Icons'; 58 | text-align: center; 59 | font-size: ceil((@component-font-size-base * 0.786)); // ~11px 60 | line-height: 21px; 61 | font-style: normal; 62 | font-weight: normal; 63 | font-variant: normal; 64 | text-transform: none; 65 | -webkit-font-smoothing: antialiased; 66 | -moz-osx-font-smoothing: grayscale; 67 | background: @todo-color-active; 68 | color: @todo-bg-active; 69 | } 70 | } 71 | } 72 | 73 | .todo-search { 74 | position: relative; 75 | background: @todo-search-bg; 76 | background-size: 16px 16px; 77 | border-radius: @todo-border-radius @todo-border-radius 0 0; 78 | color: @todo-search-color; 79 | padding: 19px 25px 20px; 80 | 81 | &:before { 82 | position: absolute; 83 | font-family: 'Flat-UI-Icons'; 84 | content: "\e630"; 85 | font-size: 16px; 86 | line-height: 17px; 87 | display: inline-block; 88 | top: 50%; 89 | left: 92%; 90 | margin: -.5em 0 0 -1em; 91 | } 92 | } 93 | 94 | .todo-search-field { 95 | background: none; 96 | border: none; 97 | color: @todo-search-color; 98 | font-size: 19px; 99 | font-weight: 700; 100 | margin: 0; 101 | line-height: 23px; 102 | padding: 5px 0; 103 | text-indent: 0; 104 | box-shadow: none; 105 | .placeholder(@todo-search-color); 106 | outline: none; 107 | } 108 | 109 | .todo-icon { 110 | float: left; 111 | font-size: 24px; 112 | padding: 11px 22px 0 0; 113 | } 114 | 115 | .todo-content { 116 | padding-top: 1px; 117 | overflow: hidden; 118 | } 119 | 120 | .todo-name { 121 | color: @todo-name-color; 122 | font-size: 17px; 123 | margin: 1px 0 3px; 124 | } 125 | -------------------------------------------------------------------------------- /src/less/modules/local-fonts.less: -------------------------------------------------------------------------------- 1 | // 2 | // Fonts 3 | // -------------------------------------------------- 4 | 5 | @font-face { 6 | font-family: 'Lato'; 7 | src: url('@{local-font-path}@{local-font-name-black}.eot'); 8 | src: url('@{local-font-path}@{local-font-name-black}.eot?#iefix') format('embedded-opentype'), 9 | url('@{local-font-path}@{local-font-name-black}.woff') format('woff'), 10 | url('@{local-font-path}@{local-font-name-black}.ttf') format('truetype'), 11 | url('@{local-font-path}@{local-font-name-black}.svg#@{local-font-svg-id-black}') format('svg'); 12 | font-weight: 900; 13 | font-style: normal; 14 | } 15 | 16 | @font-face { 17 | font-family: 'Lato'; 18 | src: url('@{local-font-path}@{local-font-name-bold}.eot'); 19 | src: url('@{local-font-path}@{local-font-name-bold}.eot?#iefix') format('embedded-opentype'), 20 | url('@{local-font-path}@{local-font-name-bold}.woff') format('woff'), 21 | url('@{local-font-path}@{local-font-name-bold}.ttf') format('truetype'), 22 | url('@{local-font-path}@{local-font-name-bold}.svg#@{local-font-svg-id-bold}') format('svg'); 23 | font-weight: bold; 24 | font-style: normal; 25 | } 26 | 27 | @font-face { 28 | font-family: 'Lato'; 29 | src: url('@{local-font-path}@{local-font-name-bold-italic}.eot'); 30 | src: url('@{local-font-path}@{local-font-name-bold-italic}.eot?#iefix') format('embedded-opentype'), 31 | url('@{local-font-path}@{local-font-name-bold-italic}.woff') format('woff'), 32 | url('@{local-font-path}@{local-font-name-bold-italic}.ttf') format('truetype'), 33 | url('@{local-font-path}@{local-font-name-bold-italic}.svg#@{local-font-svg-id-bold-italic}') format('svg'); 34 | font-weight: bold; 35 | font-style: italic; 36 | } 37 | 38 | @font-face { 39 | font-family: 'Lato'; 40 | src: url('@{local-font-path}@{local-font-name-italic}.eot'); 41 | src: url('@{local-font-path}@{local-font-name-italic}.eot?#iefix') format('embedded-opentype'), 42 | url('@{local-font-path}@{local-font-name-italic}.woff') format('woff'), 43 | url('@{local-font-path}@{local-font-name-italic}.ttf') format('truetype'), 44 | url('@{local-font-path}@{local-font-name-italic}.svg#@{local-font-svg-id-italic}') format('svg'); 45 | font-weight: normal; 46 | font-style: italic; 47 | } 48 | 49 | @font-face { 50 | font-family: 'Lato'; 51 | src: url('@{local-font-path}@{local-font-name-light}.eot'); 52 | src: url('@{local-font-path}@{local-font-name-light}.eot?#iefix') format('embedded-opentype'), 53 | url('@{local-font-path}@{local-font-name-light}.woff') format('woff'), 54 | url('@{local-font-path}@{local-font-name-light}.ttf') format('truetype'), 55 | url('@{local-font-path}@{local-font-name-light}.svg#@{local-font-svg-id-light}') format('svg'); 56 | font-weight: 300; 57 | font-style: normal; 58 | } 59 | 60 | @font-face { 61 | font-family: 'Lato'; 62 | src: url('@{local-font-path}@{local-font-name}.eot'); 63 | src: url('@{local-font-path}@{local-font-name}.eot?#iefix') format('embedded-opentype'), 64 | url('@{local-font-path}@{local-font-name}.woff') format('woff'), 65 | url('@{local-font-path}@{local-font-name}.ttf') format('truetype'), 66 | url('@{local-font-path}@{local-font-name}.svg#@{local-font-svg-id}') format('svg'); 67 | font-weight: normal; 68 | font-style: normal; 69 | } 70 | -------------------------------------------------------------------------------- /src/less/mixins/forms.less: -------------------------------------------------------------------------------- 1 | // Form validation states 2 | // 3 | // Used in forms.less to generate the form validation CSS for warnings, errors, 4 | // and successes. 5 | 6 | .form-control-validation(@text-color: @brand-primary; @border-color: @gray-light; @background-color: @inverse) { 7 | // Color the label and help text 8 | .help-block, 9 | .control-label, 10 | .radio, 11 | .checkbox, 12 | .radio-inline, 13 | .checkbox-inline { 14 | color: @text-color; 15 | } 16 | // Set the border and box shadow on specific inputs to match 17 | .form-control { 18 | color: @text-color; 19 | border-color: @border-color; 20 | box-shadow: none; 21 | .placeholder(@text-color); 22 | 23 | &:focus { 24 | border-color: @border-color; 25 | box-shadow: none; 26 | } 27 | } 28 | // Set validation states also for addons 29 | .input-group-addon { 30 | color: @text-color; 31 | border-color: @border-color; 32 | background-color: @background-color; 33 | } 34 | .form-control-feedback { 35 | color: @text-color; 36 | } 37 | } 38 | 39 | // Form control focus state 40 | // 41 | // Generate a customized focus state and for any input with the specified color, 42 | // which defaults to the `@input-focus-border` variable. 43 | // 44 | // We highly encourage you to not customize the default value, but instead use 45 | // this to tweak colors on an as-needed basis. This aesthetic change is based on 46 | // WebKit's default styles, but applicable to a wider range of browsers. Its 47 | // usability and accessibility should be taken into account with any change. 48 | // 49 | // Example usage: change the default blue border and shadow to white for better 50 | // contrast against a dark gray background. 51 | 52 | .form-control-focus(@color: @brand-secondary) { 53 | .form-group.focus &, 54 | &:focus { 55 | border-color: @color; 56 | outline: 0; 57 | box-shadow: none; 58 | } 59 | } 60 | 61 | // Form control sizing 62 | // 63 | // Relative text size, padding, and border-radii changes for form controls. For 64 | // horizontal sizing, wrap controls in the predefined grid classes. `