├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .jsbeautifyrc
├── .jscsrc
├── LICENSE
├── README.md
├── app
├── App.js
├── App.scss
├── animations.js
├── components
│ ├── page
│ │ ├── HomePage.js
│ │ ├── PageAnimations.js
│ │ ├── page.js
│ │ └── page.scss
│ └── sections
│ │ ├── section.js
│ │ └── section.scss
├── index.tpl.html
├── main.js
└── styles
│ ├── background.scss
│ ├── colors.scss
│ ├── flexbox.scss
│ ├── fonts.scss
│ ├── reset.scss
│ ├── typeplate
│ ├── _typeplate-extends.scss
│ ├── _typeplate-fonts.scss
│ ├── _typeplate-functions.scss
│ ├── _typeplate-helpers.scss
│ ├── _typeplate-mixins.scss
│ ├── _typeplate-styles.scss
│ ├── _typeplate-vars.scss
│ └── _typeplate.scss
│ ├── typography.scss
│ ├── vars.scss
│ ├── wrapper.scss
│ └── z-index.scss
├── images
├── hire_bg.png
├── play_bg.jpg
└── work_bg.jpg
├── package.json
├── server.js
├── settings
├── dev.json
└── prod.json
├── webpack.config.js
└── webpack.production.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react", "stage-0"],
3 | "env":{
4 | "production":{
5 | "plugins": [
6 | "transform-react-display-name",
7 | "transform-runtime",
8 | "transform-decorators-legacy"
9 | ]
10 | },
11 | "dev":{
12 | "plugins": [
13 | "transform-react-display-name",
14 | "transform-runtime",
15 | "transform-decorators-legacy",
16 | ["react-transform", {
17 | "transforms": [{
18 | "transform": "react-transform-hmr",
19 | "imports": ["react"],
20 | "locals": ["module"]
21 | }, {
22 | "transform": "react-transform-catch-errors",
23 | "imports": ["react", "redbox-react"]
24 | }]
25 | }]
26 | ]
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | coverage
4 | webpack.*.js
5 | *Server.js
6 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint", // https://github.com/babel/babel-eslint
3 | "env": {
4 | "browser": true,
5 | "node": true,
6 | "mocha": true
7 | },
8 | "globals": {
9 | "expect": true,
10 | "sinon": true,
11 | "__DEV__": true
12 | },
13 | "ecmaFeatures": {
14 | "arrowFunctions": true,
15 | "blockBindings": true,
16 | "classes": true,
17 | "defaultParams": true,
18 | "destructuring": true,
19 | "forOf": true,
20 | "generators": false,
21 | "modules": true,
22 | "objectLiteralComputedProperties": true,
23 | "objectLiteralDuplicateProperties": false,
24 | "objectLiteralShorthandMethods": true,
25 | "objectLiteralShorthandProperties": true,
26 | "spread": true,
27 | "superInFunctions": true,
28 | "templateStrings": true,
29 | "jsx": true
30 | },
31 | "rules": {
32 | "no-var": 2, // http://eslint.org/docs/rules/no-var
33 | "prefer-const": 2, // http://eslint.org/docs/rules/prefer-const
34 |
35 | /**
36 | * Variables
37 | */
38 | "no-shadow": 2, // http://eslint.org/docs/rules/no-shadow
39 | "no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names
40 | "no-undef": 2, // http://eslint.org/docs/rules/no-undef
41 | "no-unused-vars": [2, { // http://eslint.org/docs/rules/no-unused-vars
42 | "vars": "local",
43 | "args": "after-used"
44 | }],
45 | "no-use-before-define": 2, // http://eslint.org/docs/rules/no-use-before-define
46 |
47 | /**
48 | * Possible errors
49 | */
50 | "no-cond-assign": [2, "always"], // http://eslint.org/docs/rules/no-cond-assign
51 | "no-console": 1, // http://eslint.org/docs/rules/no-console
52 | "no-debugger": 1, // http://eslint.org/docs/rules/no-debugger
53 | "no-alert": 1, // http://eslint.org/docs/rules/no-alert
54 | "no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition
55 | "no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys
56 | "no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case
57 | "no-empty": 2, // http://eslint.org/docs/rules/no-empty
58 | "no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign
59 | "no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast
60 | "no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi
61 | "no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign
62 | "no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations
63 | "no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp
64 | "no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace
65 | "no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls
66 | "no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays
67 | "no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable
68 | "use-isnan": 2, // http://eslint.org/docs/rules/use-isnan
69 | "block-scoped-var": 2, // http://eslint.org/docs/rules/block-scoped-var
70 |
71 | /**
72 | * Best practices
73 | */
74 | "consistent-return": 2, // http://eslint.org/docs/rules/consistent-return
75 | "curly": [2, "multi-line"], // http://eslint.org/docs/rules/curly
76 | "default-case": 2, // http://eslint.org/docs/rules/default-case
77 | "dot-notation": [2, { // http://eslint.org/docs/rules/dot-notation
78 | "allowKeywords": true
79 | }],
80 | "eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq
81 | "guard-for-in": 2, // http://eslint.org/docs/rules/guard-for-in
82 | "no-caller": 2, // http://eslint.org/docs/rules/no-caller
83 | "no-else-return": 2, // http://eslint.org/docs/rules/no-else-return
84 | "no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null
85 | "no-eval": 2, // http://eslint.org/docs/rules/no-eval
86 | "no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native
87 | "no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind
88 | "no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough
89 | "no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal
90 | "no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval
91 | "no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks
92 | "no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func
93 | "no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str
94 | "no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign
95 | "no-new": 2, // http://eslint.org/docs/rules/no-new
96 | "no-new-func": 2, // http://eslint.org/docs/rules/no-new-func
97 | "no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers
98 | "no-octal": 2, // http://eslint.org/docs/rules/no-octal
99 | "no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape
100 | "no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign
101 | "no-proto": 2, // http://eslint.org/docs/rules/no-proto
102 | "no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare
103 | "no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign
104 | "no-script-url": 2, // http://eslint.org/docs/rules/no-script-url
105 | "no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare
106 | "no-sequences": 2, // http://eslint.org/docs/rules/no-sequences
107 | "no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal
108 | "no-with": 2, // http://eslint.org/docs/rules/no-with
109 | "radix": 2, // http://eslint.org/docs/rules/radix
110 | "vars-on-top": 2, // http://eslint.org/docs/rules/vars-on-top
111 | "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife
112 | "yoda": 2, // http://eslint.org/docs/rules/yoda
113 |
114 | /**
115 | * Style
116 | */
117 | "indent": [2, 2], // http://eslint.org/docs/rules/indent
118 | "brace-style": [
119 | 2, // http://eslint.org/docs/rules/brace-style
120 | "1tbs", {
121 | "allowSingleLine": true
122 | }
123 | ],
124 | "quotes": [
125 | 2, "single", "avoid-escape" // http://eslint.org/docs/rules/quotes
126 | ],
127 | "camelcase": [2, { // http://eslint.org/docs/rules/camelcase
128 | "properties": "never"
129 | }],
130 | "comma-spacing": [2, { // http://eslint.org/docs/rules/comma-spacing
131 | "before": false,
132 | "after": true
133 | }],
134 | "comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style
135 | "eol-last": 2, // http://eslint.org/docs/rules/eol-last
136 | "func-names": 1, // http://eslint.org/docs/rules/func-names
137 | "key-spacing": [2, { // http://eslint.org/docs/rules/key-spacing
138 | "beforeColon": false,
139 | "afterColon": true
140 | }],
141 | "new-cap": [0, { // http://eslint.org/docs/rules/new-cap
142 | "newIsCap": true
143 | }],
144 | "no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines
145 | "max": 2
146 | }],
147 | "no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary
148 | "no-new-object": 2, // http://eslint.org/docs/rules/no-new-object
149 | "no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func
150 | "no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces
151 | "no-extra-parens": [2, "functions"], // http://eslint.org/docs/rules/no-extra-parens
152 | "no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle
153 | "one-var": [2, "never"], // http://eslint.org/docs/rules/one-var
154 | "padded-blocks": [2, "never"], // http://eslint.org/docs/rules/padded-blocks
155 | "semi": [2, "always"], // http://eslint.org/docs/rules/semi
156 | "semi-spacing": [2, { // http://eslint.org/docs/rules/semi-spacing
157 | "before": false,
158 | "after": true
159 | }],
160 | "space-after-keywords": 2, // http://eslint.org/docs/rules/space-after-keywords
161 | "space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks
162 | "space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren
163 | "space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops
164 | "space-return-throw-case": 2, // http://eslint.org/docs/rules/space-return-throw-case
165 | "spaced-comment": [2, "always", {// http://eslint.org/docs/rules/spaced-comment
166 | "exceptions": ["-", "+"],
167 | "markers": ["=", "!"] // space here to support sprockets directives
168 | }],
169 | // React
170 | "jsx-quotes": [2, "prefer-double"],
171 | "react/display-name": 0,
172 | "react/jsx-boolean-value": 1,
173 | "react/jsx-no-undef": 2,
174 | "react/jsx-sort-prop-types": 0,
175 | "react/jsx-sort-props": 0,
176 | "react/jsx-uses-react": 1,
177 | "react/jsx-uses-vars": 1,
178 | "react/no-did-mount-set-state": [2, "allow-in-func"],
179 | "react/no-did-update-set-state": 2,
180 | "react/no-multi-comp": 2,
181 | "react/no-unknown-property": 2,
182 | "react/prop-types": 2,
183 | "react/react-in-jsx-scope": 2,
184 | "react/self-closing-comp": 2,
185 | "react/sort-comp": 2,
186 | "react/wrap-multilines": 2
187 | },
188 | "plugins": [
189 | "react"
190 | ]
191 | }
192 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | dist
4 | *.log
5 | coverage
6 |
--------------------------------------------------------------------------------
/.jsbeautifyrc:
--------------------------------------------------------------------------------
1 | {
2 | "html": {
3 | "allowed_file_extensions": [html", "xml", "svg"],
4 | "brace_style": "collapse",
5 | "end_with_newline": false,
6 | "indent_char": " ",
7 | "indent_handlebars": false,
8 | "indent_inner_html": false,
9 | "indent_scripts": "keep",
10 | "indent_size": 2,
11 | "max_preserve_newlines": 0,
12 | "preserve_newlines": true,
13 | "wrap_line_length": 0
14 | },
15 | "css": {
16 | "allowed_file_extensions": ["css", "scss", "sass", "less", "styl"],
17 | "end_with_newline": false,
18 | "indent_char": " ",r
19 | "indent_size": 2,
20 | "newline_between_rules": true,
21 | "selector_separator": " ",
22 | "selector_separator_newline": true
23 | },
24 | "js": {
25 | "allowed_file_extensions": ["js", "json"],
26 | "brace_style": "collapse",
27 | "break_chained_methods": false,
28 | "indent_char": " ",
29 | "indent_level": 0,
30 | "indent_size": 2,
31 | "indent_with_tabs": false,
32 | "keep_array_indentation": false,
33 | "keep_function_indentation": false,
34 | "max_preserve_newlines": 0,
35 | "preserve_newlines": true,
36 | "space_after_anon_function": false,
37 | "space_before_conditional": true,
38 | "space_in_empty_paren": false,
39 | "space_in_paren": false,
40 | "unescape_strings": false,
41 | "wrap_line_length": 0
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/.jscsrc:
--------------------------------------------------------------------------------
1 | {
2 | "esprima": "babel-jscs",
3 | "esnext": true,
4 | "requireCurlyBraces": ["else", "for", "while", "do", "try", "catch", "case", "default"],
5 | "requireSpaceAfterKeywords": [
6 | "if",
7 | "else",
8 | "for", "while", "do", "switch", "return", "try", "catch"
9 | ],
10 | "requireParenthesesAroundIIFE": true,
11 | "requireSpacesInConditionalExpression": true,
12 | "requireSpacesInFunctionExpression": {
13 | "beforeOpeningCurlyBrace": true
14 | },
15 | "requireSpacesInFunctionDeclaration": {
16 | "beforeOpeningCurlyBrace": true
17 | },
18 | "disallowMultipleVarDecl": "exceptUndefined",
19 | "requireBlocksOnNewline": 1,
20 | "disallowPaddingNewlinesInBlocks": true,
21 | "disallowEmptyBlocks": true,
22 | "disallowSpacesInsideObjectBrackets": "all",
23 | "disallowSpacesInsideArrayBrackets": "all",
24 | "disallowSpacesInsideParentheses": true,
25 | "disallowSpaceAfterObjectKeys": true,
26 | "requireCommaBeforeLineBreak": true,
27 | "disallowSpacesInCallExpression": true,
28 | "requireSpaceBeforeObjectValues": true,
29 | "requireOperatorBeforeLineBreak": [
30 | "?",
31 | "+",
32 | "-",
33 | "/",
34 | "*",
35 | "=",
36 | "==",
37 | "===",
38 | "!=",
39 | "!==",
40 | ">",
41 | ">=",
42 | "<",
43 | "<=",
44 | "||",
45 | "&&"
46 | ],
47 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
48 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
49 | "requireSpaceBeforeBinaryOperators": [
50 | "?", "+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="
51 | ],
52 | "requireSpaceAfterBinaryOperators": [
53 | "?", "+", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="
54 | ],
55 | "disallowSpaceAfterBinaryOperators": ["!"],
56 | "disallowImplicitTypeConversion": ["numeric", "boolean", "binary", "string"],
57 | "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties",
58 | "disallowKeywords": ["with"],
59 | "disallowMultipleLineStrings": true,
60 | "disallowMultipleLineBreaks": true,
61 | "validateLineBreaks": "LF",
62 | "validateQuoteMarks": null,
63 | "validateIndentation": 2,
64 | "disallowMixedSpacesAndTabs": true,
65 | "disallowTrailingWhitespace": true,
66 | "disallowTrailingComma": true,
67 | "disallowKeywordsOnNewLine": ["else", "catch"],
68 | "requireLineFeedAtFileEnd": true,
69 | "maximumLineLength": {
70 | "value": 150,
71 | "allowUrlComments": true
72 | },
73 | "requireCapitalizedConstructors": true,
74 | "requireDotNotation": true,
75 | "requireSpaceAfterLineComment": true,
76 | "validateParameterSeparator": ", ",
77 | "disallowNewlineBeforeBlockStatements": true,
78 | "requirePaddingNewlinesBeforeKeywords": [
79 | "do",
80 | "for",
81 | "if",
82 | "switch",
83 | "try",
84 | "void",
85 | "while",
86 | "with",
87 | "return"
88 | ],
89 | "excludeFiles": ["node_modules/**", "dist", "coverage"]
90 | }
91 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Christian Alfoni
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React CSSModules Sass Boilerplate
2 | This repo contains boilerplate for using [React CSS Modules](https://github.com/gajus/react-css-modules) with SASS. It's built using webpack.
3 |
4 |
5 | ## Get Started
6 | Run `npm install` then `npm run startdev`
7 |
8 | To build and run for production, run `npm run build` then `npm run start`.
9 |
--------------------------------------------------------------------------------
/app/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import styles from './App.scss';
5 |
6 | class App extends React.Component {
7 |
8 | render() {
9 | const { children } = this.props;
10 |
11 | return (
12 |
13 | {children}
14 |
15 | )
16 | }
17 | }
18 |
19 | export default App;
20 |
--------------------------------------------------------------------------------
/app/App.scss:
--------------------------------------------------------------------------------
1 | @import "./styles/reset";
2 | @import "./styles/fonts";
3 | @import "./styles/vars";
4 | @import "./styles/typeplate/typeplate";
5 | @import "./styles/z-index";
6 |
7 | *{
8 | box-sizing: border-box;
9 | }
10 |
11 | body{
12 | font-family: $sansSerif;
13 | font-weight: 400;
14 | background-color: darken(white, 10%);
15 | }
16 |
17 | a{
18 | text-decoration: none;
19 | }
20 |
--------------------------------------------------------------------------------
/app/animations.js:
--------------------------------------------------------------------------------
1 | export function AnimateItem(item, animation){
2 | TweenMax.to(item, animation.duration, animation.properties)
3 | }
4 |
--------------------------------------------------------------------------------
/app/components/page/HomePage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Page from './page.js';
3 | import Section from '../sections/section.js';
4 |
5 | class HomePage extends React.Component{
6 |
7 | render(){
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 | )
16 | }
17 |
18 | }
19 |
20 | export default HomePage;
21 |
--------------------------------------------------------------------------------
/app/components/page/PageAnimations.js:
--------------------------------------------------------------------------------
1 | import gsap from 'gsap';
2 |
3 | let PageAnimations = {
4 | defaults: {
5 | duration: .5,
6 | properties: {
7 | opacity: 1,
8 | ease: Power4.easeOut
9 | }
10 | }
11 | }
12 |
13 | PageAnimations.animateIn = {
14 | duration: PageAnimations.defaults.duration,
15 | properties: PageAnimations.defaults.properties
16 | }
17 |
18 | PageAnimations.animateOut = {
19 | duration: PageAnimations.defaults.duration,
20 | properties: {
21 | opacity: 0,
22 | ease: Power2.easeOut
23 | }
24 | }
25 |
26 | export default PageAnimations;
27 |
--------------------------------------------------------------------------------
/app/components/page/page.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import PageAnimations from './PageAnimations.js';
4 | import { AnimateItem } from '../../animations.js'
5 |
6 | import CSSModules from 'react-css-modules';
7 | import styles from './page.scss';
8 | import wrapperStyles from '../../styles/wrapper.scss';
9 |
10 |
11 | // Write your package code here!
12 | @CSSModules(styles, {allowMultiple: true})
13 | class Page extends React.Component{
14 |
15 | componentDidMount(){
16 | let animation = this.props.animation || PageAnimations.animateIn;
17 | AnimateItem(this._page, PageAnimations.animateIn);
18 | }
19 |
20 | render(){
21 |
22 | const { children } = this.props;
23 |
24 | return(
25 | this._page = c } styleName="base">
26 | {children}
27 |
28 | )
29 | }
30 | };
31 |
32 | export default Page;
33 |
--------------------------------------------------------------------------------
/app/components/page/page.scss:
--------------------------------------------------------------------------------
1 | .base{
2 | composes: container from '../../styles/flexbox.scss';
3 | position: relative;
4 | min-height: 100vh;
5 | background-color: darken(white, 10%);
6 | background-size: cover;
7 | background-position: center center;
8 | opacity: 0;
9 | transition: opacity 300ms ease-out;
10 | }
11 |
--------------------------------------------------------------------------------
/app/components/sections/section.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import CSSModules from 'react-css-modules';
4 | import styles from './section.scss';
5 |
6 | @CSSModules(styles, {allowMultiple: true})
7 | class Section extends React.Component{
8 |
9 | _renderPostTitle(){
10 | const title = this.props.title.match(/.{1,2}/g);
11 | return title.map( (fragment, index) => {
12 | return {fragment}
13 | })
14 | }
15 |
16 | render(){
17 |
18 | const { type, backgroundImage } = this.props;
19 | const bg = {
20 | backgroundImage: "url('" + backgroundImage + "')",
21 | };
22 |
23 | const bgClass = backgroundImage ? 'with_background' : '';
24 |
25 | return(
26 |
27 |
{this._renderPostTitle()}
28 | {this.props.children}
29 |
30 | )
31 | }
32 | }
33 |
34 | export default Section;
35 |
--------------------------------------------------------------------------------
/app/components/sections/section.scss:
--------------------------------------------------------------------------------
1 | .base{
2 | composes: child_1 container justify_center from '../../styles/flexbox.scss';
3 | position: relative;
4 | }
5 |
6 | .primary{
7 | composes: base;
8 | composes: priamry primary_bg from '../../styles/colors.scss';
9 | }
10 |
11 | .secondary{
12 | composes: base;
13 | composes: secondary_bg from '../../styles/colors.scss';
14 | }
15 |
16 | .dark{
17 | composes: base;
18 | composes: dark_bg from '../../styles/colors.scss';
19 | }
20 |
21 | .tertiary{
22 | composes: base;
23 | composes: tertiary_bg from '../../styles/colors.scss';
24 | }
25 |
26 | .with_background{
27 | composes: cover center from '../../styles/background.scss';
28 | position: relative;
29 |
30 | &:after{
31 | background-color: fade-out(black, .65);
32 | }
33 | }
34 |
35 | .title{
36 | composes: strong uppercase center bold from '../../styles/typography.scss';
37 | composes: self_center from '../../styles/flexbox.scss';
38 | // background-color: fade-out(white, .2);
39 | border: 10px solid fade-out(black, .8);
40 | color: white;
41 | font-size: 6vw;
42 | line-height: 5vw;
43 | padding: 1rem 2rem;
44 | }
45 |
--------------------------------------------------------------------------------
/app/index.tpl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React CSSModules Sass boilerplate
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/main.js:
--------------------------------------------------------------------------------
1 | import 'babel-polyfill';
2 |
3 | import React from 'react';
4 | import { render } from 'react-dom';
5 |
6 | import { Router, browserHistory, IndexRoute, Route } from 'react-router';
7 |
8 | import App from './App.js';
9 | import HomePage from './components/page/HomePage.js';
10 |
11 |
12 | render((
13 |
14 |
15 |
16 |
17 |
18 | ), document.getElementById('root'))
19 |
--------------------------------------------------------------------------------
/app/styles/background.scss:
--------------------------------------------------------------------------------
1 | .cover{
2 | background-size: cover;
3 | }
4 |
5 | .center{
6 | background-position: center center;
7 | }
8 |
9 | .with_overlay{
10 | &:after{
11 | content: '';
12 | position: absolute;
13 | top: 0;
14 | left: 0;
15 | height: 100%;
16 | width: 100%;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/styles/colors.scss:
--------------------------------------------------------------------------------
1 | @import "vars";
2 |
3 | .primary_bg{
4 | background-color: $primary;
5 | }
6 |
7 | .secondary_bg{
8 | background-color: $secondary;
9 | }
10 |
11 | .tertiary_bg{
12 | background-color: $tertiary;
13 | }
14 |
15 | .quaternary_bg{
16 | background-color: $quaternary;
17 | }
18 |
19 | .dark_bg{
20 | background-color: $dark;
21 | }
22 |
23 | .faded_dark_bg{
24 | background-color: fade-out($dark, .1);
25 | }
26 |
27 | .red-border{
28 | border-color: darken($red, 10%);
29 | }
30 |
31 | .dark-border{
32 | border-color: darken($dark, 10%);
33 | }
34 |
35 | .primary{
36 | color: $primary;
37 | }
38 |
39 | .dark{
40 | color: $dark;
41 | }
42 |
--------------------------------------------------------------------------------
/app/styles/flexbox.scss:
--------------------------------------------------------------------------------
1 | .container{
2 | display: flex;
3 | }
4 |
5 | .child_1{
6 | flex: 1;
7 | }
8 |
9 | .justify_center{
10 | justify-content: center;
11 | }
12 |
13 | .self_center{
14 | align-self: center;
15 | }
16 |
--------------------------------------------------------------------------------
/app/styles/fonts.scss:
--------------------------------------------------------------------------------
1 | @import url(http://fonts.googleapis.com/css?family=Lora:400,700,400italic);
2 | @import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700);
3 |
--------------------------------------------------------------------------------
/app/styles/reset.scss:
--------------------------------------------------------------------------------
1 | /** * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/) * http://cssreset.com */html, body, div, span, applet, object, iframe,h1, h2, h3, h4, h5, h6, p, blockquote, pre,a, abbr, acronym, address, big, cite, code,del, dfn, em, img, ins, kbd, q, s, samp,small, strike, strong, sub, sup, tt, var,b, u, i, center,dl, dt, dd, ol, ul, li,fieldset, form, label, legend,table, caption, tbody, tfoot, thead, tr, th, td,article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary,time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;}/* HTML5 display-role reset for older browsers */article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block;}body { line-height: 1;}ol, ul { list-style: none;}blockquote, q { quotes: none;}blockquote:before, blockquote:after,q:before, q:after { content: ''; content: none;}table { border-collapse: collapse; border-spacing: 0;}
2 |
--------------------------------------------------------------------------------
/app/styles/typeplate/_typeplate-extends.scss:
--------------------------------------------------------------------------------
1 | // $Ampersands
2 | // -------------------------------------//
3 | // Call your custom ampersand on any element.
4 | //
5 | // @markup Dewey Cheat 'em & Howe
6 | // @example .ampersand { @extend %typl8-amp-placeholder; }
7 |
8 | %typl8-amp-placeholder {
9 | @include typl8-ampersand($typl8-amp-fontface, $typl8-amp-fontfamily);
10 | }
11 |
12 |
13 | // $Blockquote
14 | // -------------------------------------//
15 | // Style your blockquote citations
16 | //
17 | // @example .citation { @extend %typl8-cite; }
18 |
19 | %typl8-cite {
20 | @include typl8-cite-style($typl8-cite-display, $typl8-cite-align, $typl8-cite-font-size);
21 | }
22 |
23 |
24 | // $Wordwrap
25 | // -------------------------------------//
26 | // Control word wrapping and breaks in your text.
27 | //
28 | // 'normal' Lines may only break at normal word break points.
29 | // 'break-word' Unbreakable words may be broken at arbitrary points.
30 | //
31 | // @example article { @extend %typl8-breakword; }
32 |
33 | %typl8-breakword {
34 | word-wrap: break-word;
35 | }
36 |
37 | %typl8-normal-wrap {
38 | word-wrap: normal;
39 | }
40 |
41 | %typl8-inherit-wrap {
42 | word-wrap: auto;
43 | }
44 |
45 |
46 | // $OpenType
47 | // -------------------------------------//
48 | // Control OpenType feature settings where desired.
49 | //
50 | // @use
51 | // smallcaps body { @extend %typl8-ot--smcp; }
52 | // text figures body { @extend %typl8-ot--onum; }
53 |
54 | %typl8-ot--smcp {
55 | @each $prefix in $typl8-prefixes {
56 | #{$prefix}font-feature-settings: "smcp";
57 | }
58 | }
59 |
60 | %typl8-ot--onum {
61 | @each $prefix in $typl8-prefixes {
62 | #{$prefix}font-feature-settings: 'onum';
63 | }
64 | }
--------------------------------------------------------------------------------
/app/styles/typeplate/_typeplate-fonts.scss:
--------------------------------------------------------------------------------
1 | // $Unicode-Range-Ampersand
2 | // -------------------------------------//
3 |
4 | @font-face {
5 | font-family: '#{$typl8-amp-fontface}';
6 | src: $typl8-amp-src;
7 | unicode-range: U+0026;
8 | }
9 |
10 | @font-face {
11 | font-family: '#{$typl8-amp-fontface}'; // fallback
12 | src: $typl8-amp-fallback;
13 | unicode-range: U+270C;
14 | }
15 |
16 |
17 | // $Icon-Font-Helper
18 | // -------------------------------------//
19 | // Loading multiple icon fonts using Compass
20 | //
21 | // 1. Install Compass.
22 | // 2. Create a 'fonts' directory in the root of your project.
23 | // 3. Specify within your 'config.rb' the following line…
24 | // fonts_dir = "name-of-your-fonts-directory" ( i.e. fonts_dir = "fonts" )
25 | // 4. Set your '$typl8-icon-fonts' variable as noted
26 |
27 | @if ($typl8-icon-fonts != null) {
28 | @each $font in $typl8-icon-fonts {
29 | @include font-face($font,
30 | font-files(
31 | '#{$font}/#{$font}.woff',
32 | '#{$font}/#{$font}.ttf',
33 | '#{$font}/#{$font}.svg', svg
34 | ),
35 | '#{$font}/#{$font}.eot'
36 | )
37 | }
38 | }
--------------------------------------------------------------------------------
/app/styles/typeplate/_typeplate-functions.scss:
--------------------------------------------------------------------------------
1 | // $Context Calculator
2 | // -------------------------------------//
3 | // target / context = result
4 | //
5 | // @example p { font-size: typl8-context-calc(24, 16, px, 18 * 1.65); }
6 |
7 | @function typl8-context-calc($scale, $base, $value) {
8 | @return ($scale/$base) + $value;
9 | }
10 |
11 |
12 | // $Measure-Margin
13 | // -------------------------------------//
14 | // divide 1 unit of measure by given font-size & return relative value
15 |
16 | @function typl8-measure-margin($scale, $measure, $value) {
17 | $pixelValue: $scale/$measure; // ($measure/$scale) issue#40 https://github.com/typeplate/starter-kit/issues/40
18 | $remValue: $pixelValue * $typl8-font-base;
19 |
20 | @if $value == rem {
21 | @return $pixelValue + $value;
22 | } @else if $value == em {
23 | @return ($remValue/$scale) + $value;
24 | } @else {
25 | @return $remValue * 1px;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/styles/typeplate/_typeplate-helpers.scss:
--------------------------------------------------------------------------------
1 | // $Dropcap
2 | // -------------------------------------//
3 |
4 | .typl8-drop-cap {
5 | @include typl8-dropcap(
6 | $typl8-dropcap-float-position,
7 | $typl8-dropcap-font-size,
8 | $typl8-dropcap-font-family,
9 | $typl8-dropcap-txt-indent,
10 | $typl8-dropcap-margin,
11 | $typl8-dropcap-padding,
12 | $typl8-dropcap-color,
13 | $typl8-dropcap-line-height,
14 | $typl8-dropcap-bg
15 | );
16 | }
17 |
18 | // @notes
19 | // combats our sibling paragraph syling and indentation
20 | p + .typl8-drop-cap {
21 | text-indent: 0;
22 | margin-top: 0;
23 | }
24 |
25 |
26 | // $Definition-Lists
27 | // -------------------------------------//
28 | /**
29 | * Lining Definition Style Markup
30 | *
31 |
32 |
33 |
34 |
35 | *
36 | * Extend this object into your markup.
37 | *
38 | */
39 |
40 | .typl8-lining {
41 | @include typl8-definition-list-style(lining);
42 | }
43 |
44 | /**
45 | * Dictionary Definition Style Markup
46 | *
47 |
48 |
49 |
50 |
51 | *
52 | * Extend this object into your markup.
53 | *
54 | */
55 |
56 | .typl8-dictionary-style {
57 | @include typl8-definition-list-style(dictionary-style);
58 | }
59 |
60 |
61 | // $Blockquote-Markup
62 | // -------------------------------------//
63 | /**
64 | * Blockquote Markup
65 | *
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | *
77 | * Extend this object into your markup.
78 | *
79 | */
80 |
81 |
82 | // $Pull-Quotes
83 | // -------------------------------------//
84 | // @notes
85 | // http://24ways.org/2005/swooshy-curly-quotes-without-images
86 |
87 | /**
88 | * Pull Quotes Markup
89 | *
90 |
95 | *
96 | * Extend this object into your custom stylesheet.
97 | *
98 | */
99 |
100 | .typl8-pull-quote {
101 | @include typl8-pull-quotes(
102 | $typl8-pull-quote-fontsize,
103 | $typl8-pull-quote-opacity,
104 | $typl8-pull-quote-color
105 | );
106 | }
107 |
108 |
109 | // $Figures
110 | // -------------------------------------//
111 | /**
112 | * Figures Markup
113 | *
114 |
115 |
116 | Fig. X.X |
117 |
118 |
119 | *
120 | * Extend this object into your markup.
121 | *
122 | */
123 |
124 |
125 | // $Footnotes
126 | // -------------------------------------//
127 | /**
128 | * Footnote Markup : Replace 'X' with your unique number for each footnote
129 | *
130 |
131 |
132 |
137 |
138 | *
139 | * Extend this object into your markup.
140 | *
141 | */
--------------------------------------------------------------------------------
/app/styles/typeplate/_typeplate-mixins.scss:
--------------------------------------------------------------------------------
1 | // $Typescale
2 | // -------------------------------------//
3 |
4 | @mixin typl8-typescale($scale, $base, $value, $measure:"") {
5 | @if $value == rem {
6 | font-size: $scale * 1px;
7 | // font-size: typl8-context-calc($scale, $base, $value);
8 | } @else if $value == em {
9 | font-size: typl8-context-calc($scale, $base, $value);
10 | } @else {
11 | font-size: $scale * 1px;
12 | }
13 |
14 | @if $measure != "" {
15 | @if $value == rem {
16 | // margin-bottom: typl8-measure-margin($scale, $measure, $value: px);
17 | margin-bottom: typl8-measure-margin($scale, $measure, $value);
18 | } @else if $value == em {
19 | margin-bottom: typl8-measure-margin($scale, $measure, $value: em);
20 | } @else {
21 | margin-bottom: typl8-measure-margin($scale, $measure, $value: px);
22 | }
23 | }
24 | }
25 |
26 |
27 | // $Headings
28 | // https://github.com/typeplate/starter-kit/issues/27
29 | // -------------------------------------//
30 | // Props to Harry Roberts for this trick.
31 | //
32 | // @notes
33 | // optimizeLegibility Enables ligatures and kerning
34 | // single line height Fixes large spaces when a heading wraps two lines
35 |
36 | %typl8-hN {
37 | text-rendering: optimizeLegibility;
38 | line-height: 1;
39 | margin-top: 0;
40 | color: $typl8-heading-color;
41 | }
42 |
43 | @mixin typl8-headings() {
44 | @each $name, $size in $typl8-scale {
45 | .#{$name} {
46 | @extend %typl8-hN;
47 | @include typl8-typescale(
48 | $size,
49 | $typl8-font-base,
50 | $typl8-typescale-unit,
51 | $typl8-measure
52 | );
53 | }
54 | }
55 | }
56 |
57 | @mixin typl8-headings-style() {
58 | @each $h, $size in $typl8-headings {
59 | #{$h} {
60 | @extend .#{$size};
61 | }
62 | }
63 | }
64 |
65 |
66 | // $Hypens
67 | // -------------------------------------//
68 | // @notes
69 | // http://caniuse.com/#search=hyphens
70 | // http://trentwalton.com/2011/09/07/css-hyphenation
71 | //
72 | // @values [ none | manual | auto ]
73 |
74 | @mixin typl8-hyphens($val) {
75 | @each $prefix in $typl8-prefixes {
76 | #{$prefix}hyphens: $val;
77 | }
78 | }
79 |
80 |
81 | // $Smallcaps
82 | // -------------------------------------//
83 | // @notes
84 | // http://caniuse.com/#search=font-variant
85 | // http://blog.hypsometry.com/articles/true-small-capitals-with-font-face
86 | // 'font-variant' depends on the font family in use.
87 | // Some font-families don't support small caps
88 | // or don't provide them with their Webfont.
89 |
90 | @mixin typl8-smallcaps($color, $font-weight) {
91 | @each $prefix in $typl8-prefixes {
92 | #{$prefix}font-variant: small-caps;
93 | }
94 | font-weight: $font-weight;
95 | text-transform: lowercase;
96 | color: $color;
97 | }
98 |
99 |
100 | // $Fontsize-Adjust
101 | // -------------------------------------//
102 | // @notes
103 | // firefox 17+ only (as of Feb. 2013)
104 | // correct x-height for fallback fonts.
105 | // requires secret formula yet to be discovered.
106 |
107 | @mixin typl8-font-size-adjust($adjust-value) {
108 | font-size-adjust: $adjust-value;
109 | }
110 |
111 |
112 | // $Ampersand
113 | // -------------------------------------//
114 |
115 | @mixin typl8-ampersand($typl8-amp-fontfamily...) {
116 | font-family: $typl8-amp-fontfamily;
117 | }
118 |
119 |
120 | // $Blockquote
121 | // -------------------------------------//
122 | // "-" is your citation flourish.
123 | //
124 | // I always say important things because I'm so smart
125 | // - Super Important Person
126 | //
127 | // @example .your-class-name { @include typl8-blockquote("-"); }
128 |
129 | @mixin typl8-blockquote($citation-flourish) {
130 | p {
131 | &:last-of-type {
132 | margin-bottom: -#{$typl8-line-height/2}em;
133 | }
134 | }
135 |
136 | + figcaption {
137 | @extend %typl8-cite;
138 |
139 | &:before {
140 | content: $citation-flourish;
141 | }
142 | }
143 | }
144 |
145 | @mixin typl8-cite-style($display, $text-align, $font-size) {
146 | display: $display;
147 | font-size: $font-size;
148 | text-align: $text-align;
149 | }
150 |
151 |
152 | // $Pull-Quotes
153 | // -------------------------------------//
154 |
155 | @mixin typl8-pull-quotes($fontsize, $opacity, $color) {
156 | position: relative;
157 | padding: typl8-context-calc($fontsize, $fontsize, em);
158 |
159 | &:before,
160 | &:after {
161 | height: typl8-context-calc($fontsize, $fontsize, em);
162 | opacity: $opacity;
163 | position: absolute;
164 | font-size: $fontsize;
165 | color: $color;
166 | }
167 |
168 | &:before {
169 | content: '“';
170 | top: 0;
171 | left: 0;
172 | }
173 |
174 | &:after {
175 | content: '”';
176 | bottom: 0;
177 | right: 0;
178 | }
179 | }
180 |
181 |
182 | // $Dropcap
183 | // -------------------------------------//
184 | // Add styling to intro paragraphs using a dropcap
185 | //
186 | // @markup Lorem ipsum dolor sit amet
187 | // @example .dropcap { @include typl8-dropcap; }
188 |
189 | @mixin typl8-dropcap(
190 | $float-position,
191 | $font-size,
192 | $font-family,
193 | $txt-indent,
194 | $margin,
195 | $padding,
196 | $color,
197 | $line-height,
198 | $bg
199 | ) {
200 | &:first-letter {
201 | float: $float-position;
202 | margin: $margin;
203 | padding: $padding;
204 | font-size: $font-size;
205 | font-family: $font-family;
206 | line-height: $line-height;
207 | text-indent: $txt-indent;
208 | background: $bg;
209 | color: $color;
210 | }
211 | }
212 |
213 |
214 | // $Code
215 | // -------------------------------------//
216 |
217 | @mixin typl8-white-space($wrap-space) {
218 | @if $wrap-space == 'pre-wrap' {
219 | white-space: #{-moz-}$wrap-space;
220 | white-space: $wrap-space;
221 | } @else {
222 | white-space: $wrap-space;
223 | }
224 | }
225 |
226 |
227 | // $Definition-Lists
228 | // -------------------------------------//
229 | // @notes
230 | // http://lea.verou.me/2012/02/flexible-multiline-definition-lists-with-2-lines-of-css
231 | // http://lea.verou.me/2012/02/flexible-multiline-definition-lists-with-2-lines-of-css
232 |
233 | @mixin typl8-definition-list-style($style) {
234 | @if $style == lining {
235 | dt,
236 | dd {
237 | display: inline;
238 | margin: 0;
239 | }
240 |
241 | dt,
242 | dd {
243 | & + dt {
244 | &:before {
245 | content: "\A";
246 | white-space: pre;
247 | }
248 | }
249 | }
250 |
251 | dd {
252 | & + dd {
253 | &:before {
254 | content: ", ";
255 | }
256 | }
257 | &:before {
258 | content: ": ";
259 | margin-left: -0.2rem; //removes extra space between the dt and the colon
260 | }
261 | }
262 | }
263 |
264 | @if $style == dictionary-style {
265 | dt {
266 | display: inline;
267 | counter-reset: definitions;
268 | & + dt {
269 | &:before {
270 | content: ", ";
271 | margin-left: -0.2rem; // removes extra space between the dt and the comma
272 | }
273 | }
274 | }
275 |
276 | dd {
277 | display: block;
278 | counter-increment: definitions;
279 | &:before {
280 | content: counter(definitions, decimal) ". ";
281 | }
282 | }
283 | }
284 | }
285 |
--------------------------------------------------------------------------------
/app/styles/typeplate/_typeplate-styles.scss:
--------------------------------------------------------------------------------
1 | // $Global
2 | // -------------------------------------//
3 |
4 | html {
5 | @if $typl8-custom-font {
6 | font: $typl8-font-weight #{$typl8-font-size + "%"}/#{$typl8-line-height} $typl8-custom-font, $typl8-font-family;
7 | } @else {
8 | font: $typl8-font-weight #{$typl8-font-size + "%"}/#{$typl8-line-height} $typl8-font-family;
9 | }
10 | }
11 |
12 | body {
13 | @extend %typl8-breakword;
14 | // @include typl8-hyphens(auto);
15 | color: $typl8-copy-color;
16 | }
17 |
18 | h1,h2,h3,h4,h5,h6{
19 | font-family: $serif;
20 | }
21 |
22 |
23 | // $Headings
24 | // http://codepen.io/grayghostvisuals/pen/IKsbw
25 | // -------------------------------------//
26 |
27 | @include typl8-headings;
28 | @include typl8-headings-style;
29 |
30 |
31 | // $Parargraphs
32 | // -------------------------------------//
33 |
34 | p {
35 | margin: auto auto $typl8-indent-val;
36 | @if $typl8-paragraph-spacing == true {
37 | & + p {
38 | text-indent: $typl8-indent-val;
39 | margin-top: -$typl8-indent-val;
40 | }
41 | }
42 | }
43 |
44 | // $Blockquotes
45 | // -------------------------------------//
46 |
47 | blockquote {
48 | + figcaption cite {
49 | @extend %typl8-cite;
50 | }
51 | }
52 |
53 |
54 | // $Legal Text
55 | // -------------------------------------//
56 |
57 | small {
58 | font-size: $typl8-small-print-size;
59 | }
60 |
61 |
62 | // $Hyphenation
63 | // -------------------------------------//
64 | // @notes
65 | // http://meyerweb.com/eric/thoughts/2012/12/17/where-to-avoid-css-hyphenation
66 |
67 | input,
68 | abbr,
69 | acronym,
70 | blockquote,
71 | code,
72 | kbd,
73 | q,
74 | samp,
75 | var {
76 | @include typl8-hyphens(none);
77 | }
78 |
79 |
80 | // $Codeblocks
81 | // -------------------------------------//
82 |
83 | pre {
84 | @include typl8-white-space(pre);
85 |
86 | code {
87 | @extend %typl8-normal-wrap;
88 | @include typl8-white-space(pre-wrap);
89 | }
90 | }
91 |
92 | code {
93 | @include typl8-white-space(pre);
94 | font-family: monospace;
95 | }
96 |
97 |
98 | // $Smallcaps
99 | // -------------------------------------//
100 |
101 | abbr {
102 | @include typl8-smallcaps($typl8-smcps-color, $typl8-smcps-weight);
103 | &[title]:hover {
104 | cursor: help;
105 | }
106 | }
--------------------------------------------------------------------------------
/app/styles/typeplate/_typeplate-vars.scss:
--------------------------------------------------------------------------------
1 | // $Base
2 | // -------------------------------------//
3 | // General base styles for type
4 | //
5 | // $typl8-custom-font [<"Custom-Font-Name">[, ]]
6 | // $typl8-font-size 112.5% converts to an 18px base
7 | // $typl8-font-base converts % base value to a px value (16 * (112.5/100) = 18)
8 | // $typl8-font-family non-font-face stack
9 |
10 | $typl8-serif-boolean: true !default;
11 | $typl8-custom-font: false !default;
12 | $typl8-font-family: if($typl8-serif-boolean, serif, sans-serif) !default;
13 | $typl8-font-weight: normal !default;
14 | $typl8-line-height: 1.65 !default;
15 | $typl8-font-size: 112.5 !default;
16 | $typl8-font-base: 16 * ($typl8-font-size/100) !default;
17 | $typl8-measure: $typl8-font-base * $typl8-line-height !default;
18 | $typl8-prefixes: -webkit-, -moz-, -ms-, '' !default;
19 |
20 |
21 | // $Paragraphs
22 | // -------------------------------------//
23 | // Controls paragraphs vertical whitespace
24 | // for subsequent paragraphs.
25 | //
26 | // $typl8-paragraph-spacing [<'false'> | <'true'>]
27 |
28 | $typl8-paragraph-spacing: false !default;
29 | $typl8-indent-val: 1.5em !default;
30 |
31 |
32 | // $Small-Print
33 | // -------------------------------------//
34 |
35 | $typl8-small-print-size: 65% !default;
36 |
37 |
38 | // $Base-Colors
39 | // -------------------------------------//
40 |
41 | $typl8-heading-color: #222 !default;
42 | $typl8-copy-color: #444 !default;
43 |
44 |
45 | // $Ampersands
46 | // -------------------------------------//
47 |
48 | $typl8-amp-fontface: Ampersand !default;
49 | $typl8-amp-fontfamily: Verdana, sans-serif !default;
50 | $typl8-amp-src: local('Georgia'), local('Garamond'), local('Palatino'), local('Book Antiqua') !default;
51 | $typl8-amp-fallback: local('Georgia') !default;
52 |
53 |
54 | // $Icon-Font-Helper
55 | // -------------------------------------//
56 | // Link single or multiple icon font sets. Requires Compass
57 | //
58 | // single icon font $typl8-icon-fonts: (icon-name);
59 | // multiple icon fonts $typl8-icon-fonts: (icon-name1, icon-name2, icon-name3);
60 |
61 | $typl8-icon-fonts: null !default;
62 |
63 |
64 | // $Typescale
65 | // -------------------------------------//
66 | // Greek heading names and scale using base font-size
67 | //
68 | // typl8-tera 117 = 18 × 6.5
69 | // typl8-giga 90 = 18 × 5
70 | // typl8-mega 72 = 18 × 4
71 | // typl8-alpha 60 = 18 × 3.3333
72 | // typl8-beta 48 = 18 × 2.6667
73 | // typl8-gamma 36 = 18 × 2
74 | // typl8-delta 24 = 18 × 1.3333
75 | // typl8-epsilon 21 = 18 × 1.1667
76 | // typl8-zeta 18 = 18 × 1
77 |
78 | $typl8-scale: (
79 | typl8-tera: 117,
80 | typl8-giga: 90,
81 | typl8-mega: 72,
82 | typl8-alpha: 60,
83 | typl8-beta: 48,
84 | typl8-gamma: 36,
85 | typl8-delta: 24,
86 | typl8-epsilon: 21,
87 | typl8-zeta: 18,
88 | ) !default;
89 |
90 | $typl8-headings: (
91 | h1: typl8-mega,
92 | h2: typl8-alpha,
93 | h3: typl8-beta,
94 | h4: typl8-gamma,
95 | h5: typl8-delta,
96 | h6: typl8-zeta
97 | ) !default;
98 |
99 |
100 | // $Typescale Unit
101 | // -------------------------------------//
102 |
103 | $typl8-typescale-unit: rem !default;
104 |
105 |
106 | // $Pull-Quotes
107 | // -------------------------------------//
108 |
109 | $typl8-pull-quote-fontsize: 4em !default;
110 | $typl8-pull-quote-opacity: 0.5 !default;
111 | $typl8-pull-quote-color: #dc976e !default;
112 |
113 |
114 | // $Citations
115 | // -------------------------------------//
116 |
117 | $typl8-cite-display: block !default;
118 | $typl8-cite-align: right !default;
119 | $typl8-cite-font-size: inherit !default;
120 |
121 |
122 | // $Small-Caps
123 | // -------------------------------------//
124 |
125 | $typl8-smcps-color: gray !default;
126 | $typl8-smcps-weight: 600 !default;
127 |
128 |
129 | // $DropCap
130 | // -------------------------------------//
131 |
132 | $typl8-dropcap-float-position: left !default;
133 | $typl8-dropcap-font-size: 4em !default;
134 | $typl8-dropcap-font-family: inherit !default;
135 | $typl8-dropcap-txt-indent: 0 !default;
136 | $typl8-dropcap-margin: 10px 10px 0 0 !default;
137 | $typl8-dropcap-padding: 0 20px !default;
138 | $typl8-dropcap-color: inherit !default;
139 | $typl8-dropcap-line-height: 1 !default;
140 | $typl8-dropcap-bg: transparent !default;
--------------------------------------------------------------------------------
/app/styles/typeplate/_typeplate.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | Typeplate : Starter Kit
3 | URL ........... http://typeplate.com
4 | Version ....... 2.1.0
5 | Github ........ https://github.com/typeplate/starter-kit
6 | Authors ....... Dennis Gaebel (@gryghostvisuals) & Zachary Kain (@zakkain)
7 | License ....... Creative Commmons Attribution 3.0
8 | License URL ... https://github.com/typeplate/starter-kit/blob/master/license.txt
9 | */
10 |
11 | @import "typeplate-vars";
12 | @import "typeplate-fonts";
13 | @import "typeplate-functions";
14 | @import "typeplate-mixins";
15 | @import "typeplate-extends";
16 | @import "typeplate-styles";
17 | @import "typeplate-helpers";
--------------------------------------------------------------------------------
/app/styles/typography.scss:
--------------------------------------------------------------------------------
1 | .black{
2 | font-weight: 900;
3 | }
4 |
5 | .bold{
6 | font-weight: 700;
7 | }
8 |
9 | .thin{
10 | font-weight: 100;
11 | }
12 |
13 | .uppercase{
14 | text-transform: uppercase;
15 | }
16 |
17 | .center{
18 | text-align: center;
19 | }
20 |
--------------------------------------------------------------------------------
/app/styles/vars.scss:
--------------------------------------------------------------------------------
1 | $serif: 'proxima-nova', Helvetica, serif;
2 | $sansSerif: 'proxima-nova', Helvetica, sans-serif;
3 |
4 | $primary: #e71e2d;
5 | $secondary: #510a0d;
6 | $tertiary: #3dbbd0;
7 | $quaternary: #8C3B6C;
8 | $green: #2E294E;
9 | $red: #E71D36;
10 | $dark: #1b1e1f;
11 | $lightGrey: #f3f3f3;
12 | $borderGrey: #e0e0e0;
13 | $twitter: #55acee;
14 |
15 | // Breakpoints
16 | // ------------------------- Source: http://blog.scur.pl/2012/06/variable-media-queries-less-css/
17 | $highdensity: "only screen and (-webkit-min-device-pixel-ratio: 1.5)",
18 | "only screen and (min--moz-device-pixel-ratio: 1.5)",
19 | "only screen and (-o-min-device-pixel-ratio: 3/2)",
20 | "only screen and (min-device-pixel-ratio: 1.5)";
21 | $mobile: "only screen and (max-width: 568px)";
22 | $mobile-landscape: "only screen and (min-device-width: 320px) and (max-device-width: 640px) and (orientation: landscape)";
23 | $tablet: "only screen and (min-width: 569px) and (max-width: 980px)";
24 | $desktop: "only screen and (min-width: 981px) and (max-width: 1200px)";
25 | $desktop-xl: "only screen and (min-width: 1201px)";
26 |
27 | :global {
28 |
29 | .dark_background{
30 | background-color: $dark;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/styles/wrapper.scss:
--------------------------------------------------------------------------------
1 | .base{
2 | margin-left: auto;
3 | margin-right: auto;
4 | height: 100%;
5 | }
6 |
7 | .main{
8 | composes: base;
9 | position: relative;
10 | width: 95%;
11 | max-width: 900px;
12 | }
13 |
14 | .form{
15 | composes: base;
16 | max-width: 500px;
17 | border-radius: 3px;
18 | padding: 1rem;
19 |
20 | &:not(last-of-type){
21 | margin-bottom: 1.5rem;
22 | }
23 | }
24 |
25 | .form__white{
26 | composes: form;
27 | background-color: white;
28 | }
29 |
30 | .tight{
31 | composes: base;
32 | max-width: 750px;
33 | }
34 |
35 | .full{
36 | max-width: 100%;
37 | }
38 |
39 | .flex{
40 | composes: main;
41 | display: flex;
42 | justify-content: space-between;
43 | }
44 |
--------------------------------------------------------------------------------
/app/styles/z-index.scss:
--------------------------------------------------------------------------------
1 | :global{
2 |
3 | .alerts__container{
4 | z-index: 1000;
5 | }
6 |
7 | .header__base{
8 | z-index: 900;
9 | }
10 |
11 | .modal__base{
12 | z-index: 875;
13 | }
14 |
15 | .page__element{
16 | z-index: 1;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/images/hire_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/react-cssmodules-sass-boilerplate/73f8c414ae988cfadbf62ce1aff688472139fe51/images/hire_bg.png
--------------------------------------------------------------------------------
/images/play_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/react-cssmodules-sass-boilerplate/73f8c414ae988cfadbf62ce1aff688472139fe51/images/play_bg.jpg
--------------------------------------------------------------------------------
/images/work_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ramsaylanier/react-cssmodules-sass-boilerplate/73f8c414ae988cfadbf62ce1aff688472139fe51/images/work_bg.jpg
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webpack-express-boilerplate",
3 | "version": "0.1.0",
4 | "description": "A boilerplate for running a Webpack workflow in Node express",
5 | "main": "server.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/christianalfoni/webpack-express-boilerplate.git"
9 | },
10 | "keywords": [
11 | "express",
12 | "webpack",
13 | "node"
14 | ],
15 | "author": "Christian Alfoni",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/christianalfoni/webpack-express-boilerplate/issues"
19 | },
20 | "homepage": "https://github.com/christianalfoni/webpack-express-boilerplate",
21 | "scripts": {
22 | "test": "",
23 | "start": "NODE_ENV=production node ./dist/server.js",
24 | "startdev": "NODE_ENV=dev babel-node --debug ./server.js",
25 | "startdevprod": "NODE_ENV=production babel-node --debug ./server.js",
26 | "build-server": "babel -d ./dist ./server.js ./webpack.config.js",
27 | "build": "rimraf dist && NODE_ENV=production webpack --config ./webpack.production.config.js --progress --profile --colors && npm run build-server",
28 | "eslint": "eslint .",
29 | "jscs": "jscs ."
30 | },
31 | "dependencies": {
32 | "babel-polyfill": "^6.3.14",
33 | "browser-sync": "^2.11.0",
34 | "extract-text-webpack-plugin": "^0.8.2",
35 | "hapi": "^11.1.4",
36 | "history": "^1.17.0",
37 | "lodash": "^3.10.1",
38 | "mysql": "^2.10.0",
39 | "react": "^0.14.5",
40 | "react-css-modules": "^3.7.4",
41 | "react-dom": "^0.14.5",
42 | "react-router": "^2.0.0-rc4"
43 | },
44 | "devDependencies": {
45 | "autoprefixer": "^6.0.3",
46 | "babel": "^6.3.25",
47 | "babel-cli": "^6.3.17",
48 | "babel-core": "^6.3.26",
49 | "babel-eslint": "^5.0.0-beta6",
50 | "babel-loader": "^6.2.0",
51 | "babel-plugin-react-transform": "^2.0.0-beta1",
52 | "babel-plugin-transform-decorators-legacy": "1.x.x",
53 | "babel-plugin-transform-react-display-name": "^6.3.13",
54 | "babel-plugin-transform-runtime": "6.x.x",
55 | "babel-polyfill": "6.x.x",
56 | "babel-preset-es2015": "^6.3.13",
57 | "babel-preset-react": "^6.3.13",
58 | "babel-preset-stage-0": "^6.3.13",
59 | "babel-relay-plugin": "^0.6.1",
60 | "babel-runtime": "^6.9.2",
61 | "browser-sync-webpack-plugin": "^1.0.1",
62 | "chai": "^3.2.0",
63 | "css-loader": "^0.19.0",
64 | "eslint": "^1.5.0",
65 | "eslint-plugin-react": "^3.4.2",
66 | "express": "^4.13.3",
67 | "extract-text-webpack-plugin": "^0.8.2",
68 | "gsap": "^1.18.2",
69 | "html-webpack-plugin": "^1.6.1",
70 | "jscs": "^2.1.1",
71 | "jsdom": "^6.5.1",
72 | "json-loader": "^0.5.3",
73 | "mocha": "^2.3.3",
74 | "mocha-jsdom": "^1.0.0",
75 | "node-sass": "^3.4.2",
76 | "null-loader": "^0.1.1",
77 | "postcss-loader": "^0.6.0",
78 | "react-addons-test-utils": "^0.14.3",
79 | "react-transform-catch-errors": "^1.0.0",
80 | "react-transform-hmr": "^1.0.0",
81 | "redbox-react": "^1.2.0",
82 | "rimraf": "^2.4.3",
83 | "sass-loader": "^3.1.2",
84 | "sinon": "^1.16.1",
85 | "sinon-chai": "^2.8.0",
86 | "stats-webpack-plugin": "^0.2.1",
87 | "style-loader": "^0.13.0",
88 | "webpack": "^1.12.9",
89 | "webpack-dev-middleware": "^1.2.0",
90 | "webpack-dev-server": "^1.14.0",
91 | "webpack-hot-middleware": "^2.2.0",
92 | "write-file-webpack-plugin": "^3.1.6"
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | /* eslint no-console: 0 */
2 | import path from 'path';
3 | import express from 'express';
4 | import webpack from 'webpack';
5 | import WebpackDevServer from 'webpack-dev-server';
6 | import webpackMiddleware from 'webpack-dev-middleware';
7 | import webpackHotMiddleware from 'webpack-hot-middleware';
8 | import config from './webpack.config.js';
9 |
10 | const isDeveloping = process.env.NODE_ENV !== 'production';
11 | const APP_PORT = isDeveloping ? 3000 : process.env.PORT || 3000;
12 |
13 | let app = express();
14 |
15 | if (isDeveloping) {
16 |
17 | const compiler = webpack(config);
18 |
19 | app = new WebpackDevServer(compiler, {
20 | hot: true,
21 | historyApiFallback: true,
22 | contentBase: 'src',
23 | publicPath: config.output.publicPath,
24 | stats: {
25 | colors: true,
26 | hash: false,
27 | timings: true,
28 | chunks: false,
29 | chunkModules: false,
30 | modules: false
31 | }
32 | });
33 |
34 | app.use(webpackHotMiddleware(compiler));
35 |
36 | } else {
37 | app.use(express.static('./dist'));
38 | app.get('*', function response(req, res, next) {
39 | res.sendFile(path.join(__dirname, '/index.html'));
40 | });
41 | }
42 |
43 | app.listen(APP_PORT, () => {
44 | console.log(`App is now running on http://localhost:${APP_PORT}`);
45 | });
46 |
--------------------------------------------------------------------------------
/settings/dev.json:
--------------------------------------------------------------------------------
1 | {
2 | "ENV":"Dev",
3 | "wp_prefix": "wp_",
4 | "uploads": "http://wordpressexpress.dev/wp-content/uploads/",
5 | "database": {
6 | "name": "wpexpress_dev",
7 | "username": "root",
8 | "password": "",
9 | "host": "127.0.0.1"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/settings/prod.json:
--------------------------------------------------------------------------------
1 | {
2 | "ENV":"Prod",
3 | "wp-prefix": "wp_",
4 | "database": {
5 | "name": "wpexpress_dev",
6 | "username": "root",
7 | "password": "",
8 | "host": "127.0.0.1"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var path = require('path');
4 | var webpack = require('webpack');
5 | var HtmlWebpackPlugin = require('html-webpack-plugin');
6 |
7 | const devServer = {
8 | contentBase: path.resolve(__dirname, './app'),
9 | outputPath: path.join(__dirname, './dist'),
10 | colors: true,
11 | quiet: false,
12 | noInfo: false,
13 | publicPath: '/',
14 | historyApiFallback: false,
15 | host: '127.0.0.1',
16 | port: 3000,
17 | hot: true
18 | };
19 |
20 | module.exports = {
21 | devtool: 'eval-source-map',
22 | debug: true,
23 | devServer: devServer,
24 | entry: [
25 | 'webpack/hot/dev-server',
26 | 'webpack-hot-middleware/client?reload=true',
27 | path.join(__dirname, 'app/main.js')
28 | ],
29 | output: {
30 | path: path.join(__dirname, '/dist/'),
31 | filename: '[name].js',
32 | publicPath: devServer.publicPath
33 | },
34 | module: {
35 | loaders: [
36 | {
37 | test: /\.js?$/,
38 | loader: 'babel',
39 | exclude: /node_modules|lib/,
40 | },
41 | {
42 | test: /\.json?$/,
43 | loader: 'json'
44 | },
45 | {
46 | test: /\.css$/,
47 | loader: 'style!css?modules&localIdentName=[name]---[local]---[hash:base64:5]'
48 | },
49 | {
50 | test: /\.scss$/,
51 | loaders: [
52 | 'style?sourceMap',
53 | 'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]',
54 | 'sass?sourceMap'
55 | ],
56 | exclude: /node_modules|lib/
57 | },
58 | ],
59 | },
60 | plugins: [
61 | new HtmlWebpackPlugin({
62 | template: 'app/index.tpl.html',
63 | inject: 'body',
64 | filename: 'index.html'
65 | }),
66 | new webpack.optimize.OccurenceOrderPlugin(),
67 | new webpack.HotModuleReplacementPlugin(),
68 | new webpack.NoErrorsPlugin(),
69 | new webpack.DefinePlugin({
70 | 'process.env.NODE_ENV': JSON.stringify('dev')
71 | })
72 | ],
73 | node: {
74 | fs: 'empty'
75 | }
76 | };
77 |
--------------------------------------------------------------------------------
/webpack.production.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var path = require('path');
4 | var webpack = require('webpack');
5 | var HtmlWebpackPlugin = require('html-webpack-plugin');
6 | var ExtractTextPlugin = require('extract-text-webpack-plugin');
7 | var StatsPlugin = require('stats-webpack-plugin');
8 |
9 | module.exports = {
10 | entry: [
11 | path.join(__dirname, 'app/main.js')
12 | ],
13 | output: {
14 | path: path.join(__dirname, '/dist/'),
15 | filename: '[name]-[hash].min.js'
16 | },
17 | plugins: [
18 | new ExtractTextPlugin('/app.min.css', {
19 | allChunks: true
20 | }),
21 | new HtmlWebpackPlugin({
22 | template: 'app/index.tpl.html',
23 | inject: 'body',
24 | filename: 'index.html'
25 | }),
26 | new webpack.optimize.OccurenceOrderPlugin(),
27 | new webpack.optimize.UglifyJsPlugin({
28 | compressor: {
29 | warnings: false,
30 | screw_ie8: true
31 | }
32 | }),
33 | new webpack.DefinePlugin({
34 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
35 | })
36 | ],
37 | module: {
38 | loaders: [
39 | {
40 | test: /\.js?$/,
41 | loader: 'babel',
42 | exclude: /node_modules|lib/,
43 | },
44 | {
45 | test: /\.json?$/,
46 | loader: 'json'
47 | },
48 | {
49 | test: /\.css$/,
50 | loader: 'style!css?modules&localIdentName=[name]---[local]---[hash:base64:5]'
51 | },
52 | {
53 | test: /\.scss$/,
54 | loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]!sass'),
55 | exclude: /node_modules|lib/,
56 | },
57 | ],
58 | }
59 | };
60 |
--------------------------------------------------------------------------------