├── .babelrc
├── .editorconfig
├── .eslintrc
├── .gitignore
├── .huskyrc
├── .lintstagedrc
├── LICENSE
├── README.md
├── package.json
├── public
├── favicon.ico
└── index.html
├── src
├── assets
│ └── css
│ │ ├── base.css
│ │ └── normalize.css
├── components
│ ├── App.js
│ ├── atoms
│ │ ├── Box
│ │ │ ├── Box.js
│ │ │ └── index.js
│ │ ├── Button
│ │ │ ├── Button.js
│ │ │ └── index.js
│ │ ├── Col
│ │ │ ├── Col.js
│ │ │ └── index.js
│ │ ├── ColBox
│ │ │ ├── ColBox.js
│ │ │ └── index.js
│ │ ├── Container
│ │ │ ├── Container.js
│ │ │ └── index.js
│ │ ├── Divider
│ │ │ ├── Divider.js
│ │ │ └── index.js
│ │ ├── Flex
│ │ │ ├── Flex.js
│ │ │ └── index.js
│ │ ├── InputField
│ │ │ ├── InputField.js
│ │ │ └── index.js
│ │ ├── Link
│ │ │ ├── Link.js
│ │ │ └── index.js
│ │ ├── Row
│ │ │ ├── Row.js
│ │ │ └── index.js
│ │ ├── Text
│ │ │ ├── Text.js
│ │ │ └── index.js
│ │ ├── Textarea
│ │ │ ├── Textarea.js
│ │ │ └── index.js
│ │ └── Title
│ │ │ ├── Title.js
│ │ │ └── index.js
│ ├── index.js
│ ├── molecules
│ │ └── Card
│ │ │ ├── Card.js
│ │ │ └── index.js
│ ├── organisms
│ │ └── Header
│ │ │ ├── Header.js
│ │ │ └── index.js
│ ├── pages
│ │ └── HomePage
│ │ │ ├── HomePage.js
│ │ │ └── index.js
│ └── templates
│ │ └── BaseTemplate
│ │ ├── BaseTemplate.js
│ │ └── index.js
├── index.js
└── theme.js
├── styleguide
├── App.js
├── index.js
├── pages
│ ├── components
│ │ ├── box.js
│ │ ├── button.js
│ │ ├── card.js
│ │ ├── divider.js
│ │ ├── flex.js
│ │ ├── index.js
│ │ ├── inputField.js
│ │ ├── link.js
│ │ ├── text.js
│ │ ├── textarea.js
│ │ └── title.js
│ ├── core-values.js
│ ├── index.js
│ ├── introduction.mdx
│ ├── principles.js
│ └── style
│ │ ├── color.js
│ │ ├── index.js
│ │ ├── theme.js
│ │ └── typography.js
├── public
│ ├── favicon.ico
│ └── index.html
├── routes.js
├── src
│ ├── assets
│ │ ├── css
│ │ │ └── highlight.css
│ │ └── img
│ │ │ ├── footer_illustration.svg
│ │ │ ├── icons
│ │ │ ├── components.svg
│ │ │ ├── core-values.svg
│ │ │ ├── principles.svg
│ │ │ └── style.svg
│ │ │ └── logo.svg
│ └── components
│ │ ├── atoms
│ │ └── LiveEditor
│ │ │ ├── LiveEditor.js
│ │ │ ├── index.js
│ │ │ └── theme.js
│ │ ├── molecules
│ │ ├── PropsTable
│ │ │ ├── PropsTable.js
│ │ │ └── index.js
│ │ ├── Sidebar
│ │ │ ├── Sidebar.js
│ │ │ ├── index.js
│ │ │ └── styles.js
│ │ └── TopNav
│ │ │ ├── TopNav.js
│ │ │ └── index.js
│ │ ├── pages
│ │ ├── HomePage
│ │ │ ├── HomePage.js
│ │ │ └── index.js
│ │ ├── InnerPage
│ │ │ ├── InnerPage.js
│ │ │ └── index.js
│ │ └── NotFoundPage
│ │ │ ├── NotFoundPage.js
│ │ │ └── index.js
│ │ └── templates
│ │ └── BaseTemplate
│ │ ├── BaseTemplate.js
│ │ └── index.js
└── utils.js
├── tmp
└── cover.png
├── webpack
├── webpack.config.babel.js
├── webpack.config.base.js
└── webpack.config.guide.babel.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env", "@babel/preset-react"],
3 | "plugins": ["@babel/plugin-proposal-class-properties", "react-docgen"],
4 | "env": {
5 | "development": {
6 | "plugins": ["react-hot-loader/babel", "babel-plugin-styled-components"]
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | indent_style = space
7 | indent_size = 2
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 | end_of_line = lf
12 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": [
4 | "airbnb",
5 | "prettier",
6 | "prettier/react"
7 | ],
8 | "env": {
9 | "browser": true,
10 | "node": true
11 | },
12 | "plugins": [
13 | "react",
14 | "prettier"
15 | ],
16 | "settings": {
17 | "import/resolver": {
18 | "node": {
19 | "paths": ["src"]
20 | }
21 | }
22 | },
23 | "rules": {
24 | "no-unused-expressions": 0,
25 | "react/jsx-filename-extension": [2, {
26 | "extensions": [".js", ".jsx"]
27 | }],
28 | "react/jsx-one-expression-per-line": 0,
29 | "react/require-default-props": 0,
30 | "prettier/prettier": ["error", {
31 | "singleQuote": true,
32 | "trailingComma": "all"
33 | }],
34 | "import/prefer-default-export": "off"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea
3 |
4 | /docs
5 | /trash
6 | /dist
7 | /node_modules
8 |
9 | /npm-debug.log*
10 | /yarn-debug.log*
11 | /yarn-error.log*
12 |
13 | *.sh
14 |
--------------------------------------------------------------------------------
/.huskyrc:
--------------------------------------------------------------------------------
1 | {
2 | "hooks": {
3 | "pre-commit": "yarn staged"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.lintstagedrc:
--------------------------------------------------------------------------------
1 | {
2 | ".eslintrc": "node_modules/.bin/eslint --fix",
3 | ".babelrc": "node_modules/.bin/eslint --fix",
4 | "src/**/*.{js,jsx}": "node_modules/.bin/eslint --fix",
5 | "styleguide/**/*.{js,jsx}": "node_modules/.bin/eslint --fix",
6 | "webpack/**/*.{js,jsx}": "node_modules/.bin/eslint --fix"
7 | }
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018
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 | 
2 |
3 | # Pulse Boilerplate
4 |
5 | We've created this React based boilerplate during our research on the Design System approach.
6 | It consists of modern tools and basic [Atomic Design](http://bradfrost.com/blog/post/atomic-web-design/) structure.
7 |
8 | ## Features
9 |
10 | - Up to date tools and practices for Design System creation
11 | - Focused on [Atomic Design](http://bradfrost.com/blog/post/atomic-web-design/) methodology and naming convention
12 | - Clear and understandable structure of folders
13 | - Documentation
14 | - Highly customizable: themes, pages, templates
15 | - Easy to work with styles using [styled system](https://styled-system.com/getting-started/)
16 |
17 | ## What's included
18 |
19 | #### The actual versions of:
20 |
21 | - webpack, babel, react, react-router
22 | - hot-reloading
23 | - eslint ([airbnb config](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb)) — code linter
24 | - [prettier](https://prettier.io/) — code formatter
25 | - [styled-components](https://www.styled-components.com/) — css-in-js
26 | - [styled-system](https://github.com/jxnblk/styled-system) — stylize your components at an advanced level
27 |
28 | ## Setup
29 |
30 | #### Install dependencies
31 | ```sh
32 | npm install
33 | ```
34 |
35 | #### Run development server
36 | ```sh
37 | npm run dev
38 | ```
39 |
40 | *Project will be running at [http://localhost:3000/](http://localhost:3000/)*
41 |
42 | #### Generate production build
43 | ```sh
44 | npm run build
45 | ```
46 |
47 | *Will create the `dist` folder*
48 |
49 | ## Style guide and documentation
50 |
51 | #### Run a development server
52 | ```sh
53 | npm run guide
54 | ```
55 |
56 | *Style guide will run at [http://localhost:6060/](http://localhost:6060/)*
57 |
58 | ## ESLint
59 |
60 | Run and get code review (you can pass a `--fix` setting that will try to solve a problem automatically)
61 | ```sh
62 | npm run eslint
63 | ```
64 |
65 | ## Theming
66 | We use [styled components theming](https://www.styled-components.com/docs/advanced#theming). The styled system provides great [theme-based](https://github.com/styled-system/styled-system/blob/master/docs/getting-started.md#theming) [style props](https://github.com/styled-system/styled-system/blob/master/docs/api.md) for building [responsive](https://github.com/jxnblk/styled-system/blob/master/docs/responsive-styles.md) design systems with React.
67 |
68 | ## A few words about Atomic Design
69 |
70 | Atomic design is a methodology composed of five distinct stages working together to create interface design systems in a more deliberate and hierarchical manner. The five stages of atomic design are: __atoms__, __molecules__, __organisms__, __templates__, __pages__. To get more info about methodology, check out [the original article](http://atomicdesign.bradfrost.com/chapter-2/).
71 |
72 | ## TODO
73 |
74 | - [x] styled components
75 | - [x] styled system
76 | - [ ] tests (Jest)
77 |
78 | ## Got questions or suggestions?
79 | Simply reach through [our website](https://heartbeat.ua/lets-talk)
80 |
81 | ## License
82 |
83 | MIT.
84 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pulse-boilerplate",
3 | "version": "1.1.0",
4 | "description": "React based boilerplate for creating scalable and well documented Design Systems.",
5 | "main": "src/index.js",
6 | "scripts": {
7 | "dev": "cross-env NODE_ENV=development webpack-dev-server --mode development --inline --hot --progress --config webpack/webpack.config.babel.js",
8 | "guide": "cross-env NODE_ENV=development webpack-dev-server --mode development --inline --hot --progress --config webpack/webpack.config.guide.babel.js",
9 | "build": "cross-env NODE_ENV=production webpack --mode production --progress --config webpack/webpack.config.babel.js",
10 | "guide:build": "cross-env NODE_ENV=production webpack --mode production --progress --config webpack/webpack.config.guide.babel.js",
11 | "eslint": "eslint src styleguide webpack",
12 | "staged": "node_modules/.bin/lint-staged"
13 | },
14 | "author": "Heartbeat agency",
15 | "license": "MIT",
16 | "devDependencies": {
17 | "@babel/cli": "^7.5.5",
18 | "@babel/core": "^7.5.5",
19 | "@babel/plugin-proposal-class-properties": "^7.5.5",
20 | "@babel/plugin-syntax-dynamic-import": "^7.2.0",
21 | "@babel/preset-env": "^7.5.5",
22 | "@babel/preset-react": "^7.0.0",
23 | "@babel/register": "^7.5.5",
24 | "@hot-loader/react-dom": "^16.8.6",
25 | "babel-eslint": "^10.0.2",
26 | "babel-loader": "^8.0.6",
27 | "babel-plugin-react-docgen": "^3.1.0",
28 | "babel-plugin-styled-components": "^1.10.0",
29 | "clean-webpack-plugin": "^2.0.2",
30 | "copy-webpack-plugin": "^5.0.3",
31 | "cross-env": "^5.2.0",
32 | "css-loader": "^2.1.1",
33 | "eslint": "^5.16.0",
34 | "eslint-config-airbnb": "^17.1.1",
35 | "eslint-config-prettier": "^4.3.0",
36 | "eslint-plugin-import": "^2.18.2",
37 | "eslint-plugin-jsx-a11y": "^6.2.3",
38 | "eslint-plugin-prettier": "^3.1.0",
39 | "eslint-plugin-react": "^7.14.2",
40 | "file-loader": "^3.0.1",
41 | "html-loader": "^0.5.5",
42 | "html-webpack-plugin": "^3.2.0",
43 | "husky": "^2.3.0",
44 | "lint-staged": "^8.1.7",
45 | "mini-css-extract-plugin": "^0.6.0",
46 | "optimize-css-assets-webpack-plugin": "^5.0.3",
47 | "prettier": "^1.18.2",
48 | "style-loader": "^0.23.1",
49 | "terser-webpack-plugin": "^1.3.0",
50 | "url-loader": "^1.1.2",
51 | "webpack": "^4.36.1",
52 | "webpack-cli": "^3.3.6",
53 | "webpack-dev-server": "^3.7.2",
54 | "webpack-merge": "^4.2.1"
55 | },
56 | "dependencies": {
57 | "@mdx-js/loader": "^1.1.0",
58 | "@mdx-js/react": "^1.0.27",
59 | "clean-tag": "2.0.3",
60 | "lodash": "^4.17.15",
61 | "path-parse": "^1.0.6",
62 | "prop-types": "^15.7.2",
63 | "react": "^16.8.6",
64 | "react-dom": "^16.8.6",
65 | "react-highlight": "^0.12.0",
66 | "react-hot-loader": "^4.12.8",
67 | "react-live": "^2.1.2",
68 | "react-router-dom": "^5.0.1",
69 | "styled-components": "^4.2.0",
70 | "styled-system": "^4.2.2"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heartbeatua/Pulse-Boilerplate/57647172b1a1041cd8731c2802a3989eb1aaab3e/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Pulse Boilerplate
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/assets/css/base.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | html {
6 | -webkit-tap-highlight-color: transparent;
7 | }
8 |
9 | body {
10 | -webkit-font-smoothing: antialiased;
11 | -moz-osx-font-smoothing: grayscale;
12 | }
13 |
14 | img {
15 | vertical-align: middle;
16 | }
17 |
18 | button,
19 | textarea,
20 | input {
21 | font: inherit;
22 | color: inherit;
23 | }
24 |
--------------------------------------------------------------------------------
/src/assets/css/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /* Document
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Correct the line height in all browsers.
8 | * 2. Prevent adjustments of font size after orientation changes in iOS.
9 | */
10 |
11 | html {
12 | line-height: 1.15; /* 1 */
13 | -webkit-text-size-adjust: 100%; /* 2 */
14 | }
15 |
16 | /* Sections
17 | ========================================================================== */
18 |
19 | /**
20 | * Remove the margin in all browsers.
21 | */
22 |
23 | body {
24 | margin: 0;
25 | }
26 |
27 | /**
28 | * Render the `main` element consistently in IE.
29 | */
30 |
31 | main {
32 | display: block;
33 | }
34 |
35 | /**
36 | * Correct the font size and margin on `h1` elements within `section` and
37 | * `article` contexts in Chrome, Firefox, and Safari.
38 | */
39 |
40 | h1 {
41 | font-size: 2em;
42 | margin: 0.67em 0;
43 | }
44 |
45 | /* Grouping content
46 | ========================================================================== */
47 |
48 | /**
49 | * 1. Add the correct box sizing in Firefox.
50 | * 2. Show the overflow in Edge and IE.
51 | */
52 |
53 | hr {
54 | box-sizing: content-box; /* 1 */
55 | height: 0; /* 1 */
56 | overflow: visible; /* 2 */
57 | }
58 |
59 | /**
60 | * 1. Correct the inheritance and scaling of font size in all browsers.
61 | * 2. Correct the odd `em` font sizing in all browsers.
62 | */
63 |
64 | pre {
65 | font-family: monospace, monospace; /* 1 */
66 | font-size: 1em; /* 2 */
67 | }
68 |
69 | /* Text-level semantics
70 | ========================================================================== */
71 |
72 | /**
73 | * Remove the gray background on active links in IE 10.
74 | */
75 |
76 | a {
77 | background-color: transparent;
78 | }
79 |
80 | /**
81 | * 1. Remove the bottom border in Chrome 57-
82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
83 | */
84 |
85 | abbr[title] {
86 | border-bottom: none; /* 1 */
87 | text-decoration: underline; /* 2 */
88 | text-decoration: underline dotted; /* 2 */
89 | }
90 |
91 | /**
92 | * Add the correct font weight in Chrome, Edge, and Safari.
93 | */
94 |
95 | b,
96 | strong {
97 | font-weight: bolder;
98 | }
99 |
100 | /**
101 | * 1. Correct the inheritance and scaling of font size in all browsers.
102 | * 2. Correct the odd `em` font sizing in all browsers.
103 | */
104 |
105 | code,
106 | kbd,
107 | samp {
108 | font-family: monospace, monospace; /* 1 */
109 | font-size: 1em; /* 2 */
110 | }
111 |
112 | /**
113 | * Add the correct font size in all browsers.
114 | */
115 |
116 | small {
117 | font-size: 80%;
118 | }
119 |
120 | /**
121 | * Prevent `sub` and `sup` elements from affecting the line height in
122 | * all browsers.
123 | */
124 |
125 | sub,
126 | sup {
127 | font-size: 75%;
128 | line-height: 0;
129 | position: relative;
130 | vertical-align: baseline;
131 | }
132 |
133 | sub {
134 | bottom: -0.25em;
135 | }
136 |
137 | sup {
138 | top: -0.5em;
139 | }
140 |
141 | /* Embedded content
142 | ========================================================================== */
143 |
144 | /**
145 | * Remove the border on images inside links in IE 10.
146 | */
147 |
148 | img {
149 | border-style: none;
150 | }
151 |
152 | /* Forms
153 | ========================================================================== */
154 |
155 | /**
156 | * 1. Change the font styles in all browsers.
157 | * 2. Remove the margin in Firefox and Safari.
158 | */
159 |
160 | button,
161 | input,
162 | optgroup,
163 | select,
164 | textarea {
165 | font-family: inherit; /* 1 */
166 | font-size: 100%; /* 1 */
167 | line-height: 1.15; /* 1 */
168 | margin: 0; /* 2 */
169 | }
170 |
171 | /**
172 | * Show the overflow in IE.
173 | * 1. Show the overflow in Edge.
174 | */
175 |
176 | button,
177 | input { /* 1 */
178 | overflow: visible;
179 | }
180 |
181 | /**
182 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
183 | * 1. Remove the inheritance of text transform in Firefox.
184 | */
185 |
186 | button,
187 | select { /* 1 */
188 | text-transform: none;
189 | }
190 |
191 | /**
192 | * Correct the inability to style clickable types in iOS and Safari.
193 | */
194 |
195 | button,
196 | [type="button"],
197 | [type="reset"],
198 | [type="submit"] {
199 | -webkit-appearance: button;
200 | }
201 |
202 | /**
203 | * Remove the inner border and padding in Firefox.
204 | */
205 |
206 | button::-moz-focus-inner,
207 | [type="button"]::-moz-focus-inner,
208 | [type="reset"]::-moz-focus-inner,
209 | [type="submit"]::-moz-focus-inner {
210 | border-style: none;
211 | padding: 0;
212 | }
213 |
214 | /**
215 | * Restore the focus styles unset by the previous rule.
216 | */
217 |
218 | button:-moz-focusring,
219 | [type="button"]:-moz-focusring,
220 | [type="reset"]:-moz-focusring,
221 | [type="submit"]:-moz-focusring {
222 | outline: 1px dotted ButtonText;
223 | }
224 |
225 | /**
226 | * Correct the padding in Firefox.
227 | */
228 |
229 | fieldset {
230 | padding: 0.35em 0.75em 0.625em;
231 | }
232 |
233 | /**
234 | * 1. Correct the text wrapping in Edge and IE.
235 | * 2. Correct the color inheritance from `fieldset` elements in IE.
236 | * 3. Remove the padding so developers are not caught out when they zero out
237 | * `fieldset` elements in all browsers.
238 | */
239 |
240 | legend {
241 | box-sizing: border-box; /* 1 */
242 | color: inherit; /* 2 */
243 | display: table; /* 1 */
244 | max-width: 100%; /* 1 */
245 | padding: 0; /* 3 */
246 | white-space: normal; /* 1 */
247 | }
248 |
249 | /**
250 | * Add the correct vertical alignment in Chrome, Firefox, and Opera.
251 | */
252 |
253 | progress {
254 | vertical-align: baseline;
255 | }
256 |
257 | /**
258 | * Remove the default vertical scrollbar in IE 10+.
259 | */
260 |
261 | textarea {
262 | overflow: auto;
263 | }
264 |
265 | /**
266 | * 1. Add the correct box sizing in IE 10.
267 | * 2. Remove the padding in IE 10.
268 | */
269 |
270 | [type="checkbox"],
271 | [type="radio"] {
272 | box-sizing: border-box; /* 1 */
273 | padding: 0; /* 2 */
274 | }
275 |
276 | /**
277 | * Correct the cursor style of increment and decrement buttons in Chrome.
278 | */
279 |
280 | [type="number"]::-webkit-inner-spin-button,
281 | [type="number"]::-webkit-outer-spin-button {
282 | height: auto;
283 | }
284 |
285 | /**
286 | * 1. Correct the odd appearance in Chrome and Safari.
287 | * 2. Correct the outline style in Safari.
288 | */
289 |
290 | [type="search"] {
291 | -webkit-appearance: textfield; /* 1 */
292 | outline-offset: -2px; /* 2 */
293 | }
294 |
295 | /**
296 | * Remove the inner padding in Chrome and Safari on macOS.
297 | */
298 |
299 | [type="search"]::-webkit-search-decoration {
300 | -webkit-appearance: none;
301 | }
302 |
303 | /**
304 | * 1. Correct the inability to style clickable types in iOS and Safari.
305 | * 2. Change font properties to `inherit` in Safari.
306 | */
307 |
308 | ::-webkit-file-upload-button {
309 | -webkit-appearance: button; /* 1 */
310 | font: inherit; /* 2 */
311 | }
312 |
313 | /* Interactive
314 | ========================================================================== */
315 |
316 | /*
317 | * Add the correct display in Edge, IE 10+, and Firefox.
318 | */
319 |
320 | details {
321 | display: block;
322 | }
323 |
324 | /*
325 | * Add the correct display in all browsers.
326 | */
327 |
328 | summary {
329 | display: list-item;
330 | }
331 |
332 | /* Misc
333 | ========================================================================== */
334 |
335 | /**
336 | * Add the correct display in IE 10+.
337 | */
338 |
339 | template {
340 | display: none;
341 | }
342 |
343 | /**
344 | * Add the correct display in IE 10.
345 | */
346 |
347 | [hidden] {
348 | display: none;
349 | }
350 |
--------------------------------------------------------------------------------
/src/components/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { BrowserRouter, Switch, Route } from 'react-router-dom';
3 | import { hot } from 'react-hot-loader/root';
4 | import { ThemeProvider } from 'styled-components';
5 | import theme from '../theme';
6 | import HomePage from './pages/HomePage';
7 | import '../assets/css/normalize.css';
8 | import '../assets/css/base.css';
9 |
10 | const App = () => (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 |
20 | export default hot(App);
21 |
--------------------------------------------------------------------------------
/src/components/atoms/Box/Box.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styled from 'styled-components';
3 | import tag from 'clean-tag';
4 | import {
5 | space,
6 | width,
7 | fontSize,
8 | color,
9 | fontFamily,
10 | textAlign,
11 | lineHeight,
12 | fontWeight,
13 | fontStyle,
14 | letterSpacing,
15 | display,
16 | maxWidth,
17 | minWidth,
18 | height,
19 | maxHeight,
20 | minHeight,
21 | verticalAlign,
22 | alignItems,
23 | justifyContent,
24 | flexWrap,
25 | flexDirection,
26 | flex,
27 | alignContent,
28 | justifyItems,
29 | justifySelf,
30 | alignSelf,
31 | order,
32 | flexBasis,
33 | gridGap,
34 | gridRowGap,
35 | gridColumnGap,
36 | gridColumn,
37 | gridRow,
38 | gridArea,
39 | gridAutoFlow,
40 | gridAutoRows,
41 | gridAutoColumns,
42 | gridTemplateRows,
43 | gridTemplateColumns,
44 | gridTemplateAreas,
45 | background,
46 | backgroundImage,
47 | backgroundSize,
48 | backgroundPosition,
49 | backgroundRepeat,
50 | borderRadius,
51 | borderColor,
52 | borders,
53 | boxShadow,
54 | opacity,
55 | overflow,
56 | position,
57 | zIndex,
58 | top,
59 | right,
60 | bottom,
61 | left,
62 | textStyle,
63 | colorStyle,
64 | buttonStyle,
65 | } from 'styled-system';
66 |
67 | const StyledBox = styled(tag)`
68 | ${space};
69 | ${width};
70 | ${fontSize};
71 | ${color};
72 | ${fontFamily};
73 | ${textAlign};
74 | ${lineHeight};
75 | ${fontWeight};
76 | ${fontStyle};
77 | ${letterSpacing};
78 | ${display};
79 | ${maxWidth};
80 | ${minWidth};
81 | ${height};
82 | ${maxHeight};
83 | ${minHeight};
84 | ${verticalAlign};
85 | ${alignItems};
86 | ${justifyContent};
87 | ${flexWrap};
88 | ${flexDirection};
89 | ${flex};
90 | ${alignContent};
91 | ${justifyItems};
92 | ${justifySelf};
93 | ${alignSelf};
94 | ${order};
95 | ${flexBasis};
96 | ${gridGap};
97 | ${gridRowGap};
98 | ${gridColumnGap};
99 | ${gridColumn};
100 | ${gridRow};
101 | ${gridArea};
102 | ${gridAutoFlow};
103 | ${gridAutoRows};
104 | ${gridAutoColumns};
105 | ${gridTemplateRows};
106 | ${gridTemplateColumns};
107 | ${gridTemplateAreas};
108 | ${background};
109 | ${backgroundImage};
110 | ${backgroundSize};
111 | ${backgroundPosition};
112 | ${backgroundRepeat};
113 | ${borderRadius};
114 | ${borderColor};
115 | ${borders};
116 | ${boxShadow};
117 | ${opacity};
118 | ${overflow};
119 | ${position};
120 | ${zIndex};
121 | ${top};
122 | ${right};
123 | ${bottom};
124 | ${left};
125 | ${textStyle};
126 | ${colorStyle};
127 | ${buttonStyle};
128 | `;
129 |
130 | const Box = props => ;
131 |
132 | Box.propTypes = {
133 | ...space.propTypes,
134 | ...width.propTypes,
135 | ...fontSize.propTypes,
136 | ...color.propTypes,
137 | ...fontFamily.propTypes,
138 | ...textAlign.propTypes,
139 | ...lineHeight.propTypes,
140 | ...fontWeight.propTypes,
141 | ...fontStyle.propTypes,
142 | ...letterSpacing.propTypes,
143 | ...display.propTypes,
144 | ...maxWidth.propTypes,
145 | ...minWidth.propTypes,
146 | ...height.propTypes,
147 | ...maxHeight.propTypes,
148 | ...minHeight.propTypes,
149 | ...verticalAlign.propTypes,
150 | ...alignItems.propTypes,
151 | ...justifyContent.propTypes,
152 | ...flexWrap.propTypes,
153 | ...flexDirection.propTypes,
154 | ...flex.propTypes,
155 | ...alignContent.propTypes,
156 | ...justifyItems.propTypes,
157 | ...justifySelf.propTypes,
158 | ...alignSelf.propTypes,
159 | ...order.propTypes,
160 | ...flexBasis.propTypes,
161 | ...gridGap.propTypes,
162 | ...gridRowGap.propTypes,
163 | ...gridColumnGap.propTypes,
164 | ...gridColumn.propTypes,
165 | ...gridRow.propTypes,
166 | ...gridArea.propTypes,
167 | ...gridAutoFlow.propTypes,
168 | ...gridAutoRows.propTypes,
169 | ...gridAutoColumns.propTypes,
170 | ...gridTemplateRows.propTypes,
171 | ...gridTemplateColumns.propTypes,
172 | ...gridTemplateAreas.propTypes,
173 | ...background.propTypes,
174 | ...backgroundImage.propTypes,
175 | ...backgroundSize.propTypes,
176 | ...backgroundPosition.propTypes,
177 | ...backgroundRepeat.propTypes,
178 | ...borderRadius.propTypes,
179 | ...borderColor.propTypes,
180 | ...borders.propTypes,
181 | ...boxShadow.propTypes,
182 | ...opacity.propTypes,
183 | ...overflow.propTypes,
184 | ...position.propTypes,
185 | ...zIndex.propTypes,
186 | ...top.propTypes,
187 | ...right.propTypes,
188 | ...bottom.propTypes,
189 | ...left.propTypes,
190 | ...textStyle.propTypes,
191 | ...colorStyle.propTypes,
192 | ...buttonStyle.propTypes,
193 | };
194 |
195 | export default Box;
196 |
--------------------------------------------------------------------------------
/src/components/atoms/Box/index.js:
--------------------------------------------------------------------------------
1 | import Box from './Box';
2 |
3 | export default Box;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/Button/Button.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled, { css } from 'styled-components';
4 | import { NavLink } from 'react-router-dom';
5 | import { space, display, maxWidth, fontSize, themeGet } from 'styled-system';
6 |
7 | const width = ({ wide }) => wide === 'true' && '100%';
8 | const cursor = ({ disabled }) => (disabled ? 'not-allowed' : 'pointer');
9 | const opacity = ({ disabled }) => disabled && '0.65';
10 | const btnBg = ({ color, skin }) =>
11 | themeGet(skin === 'outline' ? `colors.white` : `colors.${color}`);
12 | const btnColor = ({ color, skin }) =>
13 | themeGet(skin === 'fill' ? `colors.white` : `colors.${color}`);
14 |
15 | const styles = css`
16 | ${display};
17 | vertical-align: middle;
18 | text-align: center;
19 | text-decoration: none;
20 | touch-action: manipulation;
21 | outline: none;
22 | user-select: none;
23 | transition: 0.1s ease;
24 | border-radius: 0;
25 | text-transform: lowercase;
26 | width: ${width};
27 | cursor: ${cursor};
28 | opacity: ${opacity};
29 | color: ${btnColor};
30 | background: ${btnBg};
31 | padding: 10px 23px;
32 | line-height: 1.5;
33 | ${space};
34 | ${fontSize};
35 | ${maxWidth};
36 | border: 1px solid ${({ color }) => themeGet(`colors.${color}`)};
37 | ${({ disabled }) =>
38 | !disabled &&
39 | css`
40 | &:hover {
41 | border-color: ${themeGet('colors.black')};
42 | background: ${({ color, skin }) =>
43 | themeGet(
44 | color === 'black' && skin === 'fill'
45 | ? 'colors.white'
46 | : 'colors.black',
47 | )};
48 | color: ${({ color, skin }) =>
49 | themeGet(
50 | color === 'black' && skin === 'fill'
51 | ? 'colors.black'
52 | : 'colors.white',
53 | )};
54 | }
55 | `};
56 | `;
57 |
58 | const StyledNavLink = styled(NavLink)`
59 | ${styles};
60 | `;
61 | const StyledLink = styled.a`
62 | ${styles};
63 | `;
64 | const StyledButton = styled.button`
65 | ${styles};
66 | `;
67 |
68 | const Button = ({ to, href, type, wide, disabled, ...rest }) => {
69 | const isWide = wide.toString();
70 | const DefaultBtn = (
71 |
72 | );
73 | if (disabled) {
74 | return DefaultBtn;
75 | }
76 | if (to) {
77 | return ;
78 | }
79 | if (href) {
80 | return (
81 |
88 | );
89 | }
90 | return DefaultBtn;
91 | };
92 |
93 | Button.propTypes = {
94 | color: PropTypes.oneOf(['brand', 'cta', 'black']),
95 | skin: PropTypes.oneOf(['fill', 'outline']),
96 | wide: PropTypes.bool,
97 | disabled: PropTypes.bool,
98 | type: PropTypes.oneOf(['submit', 'button']),
99 | display: PropTypes.string,
100 | fontSize: PropTypes.string,
101 | ...space.propTypes,
102 | ...maxWidth.propTypes,
103 | };
104 |
105 | Button.defaultProps = {
106 | color: 'black',
107 | skin: 'fill',
108 | type: 'button',
109 | display: 'inline-block',
110 | fontSize: 's',
111 | disabled: false,
112 | wide: false,
113 | };
114 |
115 | export default Button;
116 |
--------------------------------------------------------------------------------
/src/components/atoms/Button/index.js:
--------------------------------------------------------------------------------
1 | import Button from './Button';
2 |
3 | export default Button;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/Col/Col.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styled from 'styled-components';
3 | import PropTypes from 'prop-types';
4 | import { style, top } from 'styled-system';
5 | import ColBox from '../ColBox';
6 |
7 | const flex = style({
8 | prop: 'width',
9 | cssProperty: 'flex',
10 | transformValue(n) {
11 | switch (n) {
12 | case 'auto':
13 | return '1 1 0%';
14 | case 'contains':
15 | return '0 0 auto';
16 | default:
17 | return `0 0 ${n * 100}%;`;
18 | }
19 | },
20 | });
21 |
22 | const StyledCol = styled(ColBox)`
23 | position: relative;
24 | ${flex};
25 | ${top};
26 | padding-left: ${({ gap }) => (gap ? `${gap / 2}px` : null)};
27 | padding-right: ${({ gap }) => (gap ? `${gap / 2}px` : null)};
28 | `;
29 |
30 | const Col = props => ;
31 |
32 | Col.propTypes = {
33 | width: PropTypes.oneOfType([
34 | PropTypes.array,
35 | PropTypes.number,
36 | PropTypes.string,
37 | ]),
38 | ...ColBox.propTypes,
39 | };
40 |
41 | Col.defaultProps = {
42 | width: 'auto',
43 | };
44 |
45 | export default Col;
46 |
--------------------------------------------------------------------------------
/src/components/atoms/Col/index.js:
--------------------------------------------------------------------------------
1 | import Col from './Col';
2 |
3 | export default Col;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/ColBox/ColBox.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styled from 'styled-components';
3 | import {
4 | space,
5 | fontSize,
6 | color,
7 | fontFamily,
8 | textAlign,
9 | lineHeight,
10 | fontWeight,
11 | fontStyle,
12 | letterSpacing,
13 | display,
14 | maxWidth,
15 | minWidth,
16 | height,
17 | maxHeight,
18 | minHeight,
19 | size,
20 | verticalAlign,
21 | alignItems,
22 | justifyContent,
23 | flexWrap,
24 | flexDirection,
25 | flex,
26 | alignContent,
27 | justifyItems,
28 | justifySelf,
29 | alignSelf,
30 | order,
31 | flexBasis,
32 | gridGap,
33 | gridRowGap,
34 | gridColumnGap,
35 | gridColumn,
36 | gridRow,
37 | gridArea,
38 | gridAutoFlow,
39 | gridAutoRows,
40 | gridAutoColumns,
41 | gridTemplateRows,
42 | gridTemplateColumns,
43 | gridTemplateAreas,
44 | background,
45 | backgroundImage,
46 | backgroundSize,
47 | backgroundPosition,
48 | backgroundRepeat,
49 | borderRadius,
50 | borderColor,
51 | borders,
52 | boxShadow,
53 | opacity,
54 | overflow,
55 | position,
56 | zIndex,
57 | top,
58 | right,
59 | bottom,
60 | left,
61 | textStyle,
62 | colorStyle,
63 | buttonStyle,
64 | } from 'styled-system';
65 |
66 | const StyledBox = styled.div`
67 | ${space};
68 | ${fontSize};
69 | ${color};
70 | ${fontFamily};
71 | ${textAlign};
72 | ${lineHeight};
73 | ${fontWeight};
74 | ${fontStyle};
75 | ${letterSpacing};
76 | ${display};
77 | ${maxWidth};
78 | ${minWidth};
79 | ${height};
80 | ${maxHeight};
81 | ${minHeight};
82 | ${size};
83 | ${verticalAlign};
84 | ${alignItems};
85 | ${justifyContent};
86 | ${flexWrap};
87 | ${flexDirection};
88 | ${flex};
89 | ${alignContent};
90 | ${justifyItems};
91 | ${justifySelf};
92 | ${alignSelf};
93 | ${order};
94 | ${flexBasis};
95 | ${gridGap};
96 | ${gridRowGap};
97 | ${gridColumnGap};
98 | ${gridColumn};
99 | ${gridRow};
100 | ${gridArea};
101 | ${gridAutoFlow};
102 | ${gridAutoRows};
103 | ${gridAutoColumns};
104 | ${gridTemplateRows};
105 | ${gridTemplateColumns};
106 | ${gridTemplateAreas};
107 | ${background};
108 | ${backgroundImage};
109 | ${backgroundSize};
110 | ${backgroundPosition};
111 | ${backgroundRepeat};
112 | ${borderRadius};
113 | ${borders};
114 | ${borderColor};
115 | ${boxShadow};
116 | ${opacity};
117 | ${overflow};
118 | ${position};
119 | ${zIndex};
120 | ${top};
121 | ${right};
122 | ${bottom};
123 | ${left};
124 | ${textStyle};
125 | ${colorStyle};
126 | ${buttonStyle};
127 | `;
128 |
129 | const ColBox = props => ;
130 |
131 | ColBox.propTypes = {
132 | ...space.propTypes,
133 | ...fontSize.propTypes,
134 | ...color.propTypes,
135 | ...fontFamily.propTypes,
136 | ...textAlign.propTypes,
137 | ...lineHeight.propTypes,
138 | ...fontWeight.propTypes,
139 | ...fontStyle.propTypes,
140 | ...letterSpacing.propTypes,
141 | ...display.propTypes,
142 | ...maxWidth.propTypes,
143 | ...minWidth.propTypes,
144 | ...height.propTypes,
145 | ...maxHeight.propTypes,
146 | ...minHeight.propTypes,
147 | ...size.propTypes,
148 | ...verticalAlign.propTypes,
149 | ...alignItems.propTypes,
150 | ...justifyContent.propTypes,
151 | ...flexWrap.propTypes,
152 | ...flexDirection.propTypes,
153 | ...flex.propTypes,
154 | ...alignContent.propTypes,
155 | ...justifyItems.propTypes,
156 | ...justifySelf.propTypes,
157 | ...alignSelf.propTypes,
158 | ...order.propTypes,
159 | ...flexBasis.propTypes,
160 | ...gridGap.propTypes,
161 | ...gridRowGap.propTypes,
162 | ...gridColumnGap.propTypes,
163 | ...gridColumn.propTypes,
164 | ...gridRow.propTypes,
165 | ...gridArea.propTypes,
166 | ...gridAutoFlow.propTypes,
167 | ...gridAutoRows.propTypes,
168 | ...gridAutoColumns.propTypes,
169 | ...gridTemplateRows.propTypes,
170 | ...gridTemplateColumns.propTypes,
171 | ...gridTemplateAreas.propTypes,
172 | ...background.propTypes,
173 | ...backgroundImage.propTypes,
174 | ...backgroundSize.propTypes,
175 | ...backgroundPosition.propTypes,
176 | ...backgroundRepeat.propTypes,
177 | ...borderRadius.propTypes,
178 | ...borderColor.propTypes,
179 | ...borders.propTypes,
180 | ...boxShadow.propTypes,
181 | ...opacity.propTypes,
182 | ...overflow.propTypes,
183 | ...position.propTypes,
184 | ...zIndex.propTypes,
185 | ...top.propTypes,
186 | ...right.propTypes,
187 | ...bottom.propTypes,
188 | ...left.propTypes,
189 | ...textStyle.propTypes,
190 | ...colorStyle.propTypes,
191 | ...buttonStyle.propTypes,
192 | };
193 |
194 | export default ColBox;
195 |
--------------------------------------------------------------------------------
/src/components/atoms/ColBox/index.js:
--------------------------------------------------------------------------------
1 | import ColBox from './ColBox';
2 |
3 | export default ColBox;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/Container/Container.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled from 'styled-components';
4 | import Box from '../Box';
5 |
6 | const StyledContainer = styled(Box)`
7 | position: relative;
8 | box-sizing: content-box;
9 | `;
10 |
11 | const Container = props => ;
12 |
13 | Container.propTypes = {
14 | pl: PropTypes.oneOfType([
15 | PropTypes.array,
16 | PropTypes.number,
17 | PropTypes.string,
18 | ]),
19 | pr: PropTypes.oneOfType([
20 | PropTypes.array,
21 | PropTypes.number,
22 | PropTypes.string,
23 | ]),
24 | mx: PropTypes.oneOfType([
25 | PropTypes.array,
26 | PropTypes.number,
27 | PropTypes.string,
28 | ]),
29 | maxWidth: PropTypes.oneOfType([
30 | PropTypes.array,
31 | PropTypes.number,
32 | PropTypes.string,
33 | ]),
34 | ...Box.propTypes,
35 | };
36 |
37 | Container.defaultProps = {
38 | pl: 's',
39 | pr: 's',
40 | mx: 'auto',
41 | maxWidth: 'l',
42 | };
43 |
44 | export default Container;
45 |
--------------------------------------------------------------------------------
/src/components/atoms/Container/index.js:
--------------------------------------------------------------------------------
1 | import Container from './Container';
2 |
3 | export default Container;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/Divider/Divider.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Box from '../Box';
4 |
5 | const Divider = props => ;
6 |
7 | Divider.propTypes = {
8 | bg: PropTypes.string,
9 | height: PropTypes.oneOfType([
10 | PropTypes.string,
11 | PropTypes.number,
12 | PropTypes.array,
13 | ]),
14 | width: PropTypes.oneOfType([
15 | PropTypes.string,
16 | PropTypes.number,
17 | PropTypes.array,
18 | ]),
19 | ...Box.propTypes,
20 | };
21 |
22 | Divider.defaultProps = {
23 | bg: 'grayscale.400',
24 | width: 'auto',
25 | height: '1px',
26 | };
27 |
28 | export default Divider;
29 |
--------------------------------------------------------------------------------
/src/components/atoms/Divider/index.js:
--------------------------------------------------------------------------------
1 | import Divider from './Divider';
2 |
3 | export default Divider;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/Flex/Flex.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Box from '../Box';
4 |
5 | const Flex = props => ;
6 |
7 | Flex.propTypes = {
8 | display: PropTypes.string,
9 | ...Box.propTypes,
10 | };
11 | Flex.defaultProps = {
12 | display: 'flex',
13 | };
14 |
15 | export default Flex;
16 |
--------------------------------------------------------------------------------
/src/components/atoms/Flex/index.js:
--------------------------------------------------------------------------------
1 | import Flex from './Flex';
2 |
3 | export default Flex;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/InputField/InputField.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled from 'styled-components';
4 | import { width, height, themeGet, space } from 'styled-system';
5 | import tag from 'clean-tag';
6 |
7 | const StyledInput = styled(tag.input)`
8 | ${width};
9 | ${height};
10 | ${space};
11 | display: inline-block;
12 | vertical-align: middle;
13 | border: 0;
14 | padding: 0;
15 | border-bottom: 1px solid;
16 | background: ${themeGet('colors.white')};
17 | outline: 0;
18 | -webkit-appearance: none;
19 | border-radius: 0;
20 | line-height: normal;
21 | font-size: ${themeGet('fontSizes.m')}px;
22 | `;
23 |
24 | const InputField = props => ;
25 |
26 | InputField.propTypes = {
27 | width: PropTypes.oneOfType([
28 | PropTypes.array,
29 | PropTypes.number,
30 | PropTypes.string,
31 | ]),
32 | height: PropTypes.string,
33 | };
34 | InputField.defaultProps = {
35 | width: '100%',
36 | height: '42px',
37 | };
38 |
39 | export default InputField;
40 |
--------------------------------------------------------------------------------
/src/components/atoms/InputField/index.js:
--------------------------------------------------------------------------------
1 | import InputField from './InputField';
2 |
3 | export default InputField;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/Link/Link.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styled, { css } from 'styled-components';
3 | import PropTypes from 'prop-types';
4 | import { NavLink } from 'react-router-dom';
5 | import { color, space, display, width, height, borders } from 'styled-system';
6 |
7 | const styles = css`
8 | ${({ underline }) => underline && `border-bottom: ${underline}px solid`};
9 | ${({ underline }) =>
10 | underline &&
11 | css`
12 | &:hover {
13 | border-bottom-color: transparent;
14 | }
15 | `};
16 | cursor: pointer;
17 | text-decoration: none;
18 | ${space};
19 | ${color};
20 | ${display};
21 | ${width};
22 | ${height};
23 | ${borders};
24 | `;
25 |
26 | const StyledLink = styled.a`
27 | ${styles};
28 | `;
29 | const StyledNavLink = styled(NavLink)`
30 | ${styles};
31 | `;
32 |
33 | const Link = ({ to, href, ...rest }) => {
34 | if (to) {
35 | return ;
36 | }
37 | if (href) {
38 | return (
39 |
46 | );
47 | }
48 | return (
49 |
55 | );
56 | };
57 |
58 | Link.propTypes = {
59 | to: PropTypes.string,
60 | href: PropTypes.string,
61 | underline: PropTypes.number,
62 | color: PropTypes.string,
63 | ...space.propTypes,
64 | ...color.propTypes,
65 | ...display.propTypes,
66 | ...width.propTypes,
67 | ...height.propTypes,
68 | ...borders.propTypes,
69 | };
70 | Link.defaultProps = {
71 | underline: 0,
72 | color: 'inherit',
73 | };
74 |
75 | export default Link;
76 |
--------------------------------------------------------------------------------
/src/components/atoms/Link/index.js:
--------------------------------------------------------------------------------
1 | import Link from './Link';
2 |
3 | export default Link;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/Row/Row.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled from 'styled-components';
4 | import Box from '../Box';
5 | import { space } from '../../../theme';
6 |
7 | const StyledRow = styled(Box)`
8 | display: flex;
9 | flex-wrap: wrap;
10 | margin-left: ${({ gap }) => (gap ? `-${gap / 2}px` : null)};
11 | margin-right: ${({ gap }) => (gap ? `-${gap / 2}px` : null)};
12 | `;
13 |
14 | const Row = ({ children, ...rest }) => {
15 | const { gap } = rest;
16 | return (
17 |
18 | {React.Children.map(children, child =>
19 | React.cloneElement(child, { gap }),
20 | )}
21 |
22 | );
23 | };
24 |
25 | Row.propTypes = {
26 | children: PropTypes.node.isRequired,
27 | gap: PropTypes.number,
28 | ...Box.propTypes,
29 | };
30 |
31 | Row.defaultProps = {
32 | gap: space.l,
33 | };
34 |
35 | export default Row;
36 |
--------------------------------------------------------------------------------
/src/components/atoms/Row/index.js:
--------------------------------------------------------------------------------
1 | import Row from './Row';
2 |
3 | export default Row;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/Text/Text.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Box from '../Box';
4 |
5 | const Text = props => ;
6 |
7 | Text.propTypes = {
8 | as: PropTypes.string,
9 | fontSize: PropTypes.oneOfType([
10 | PropTypes.string,
11 | PropTypes.array,
12 | PropTypes.number,
13 | ]),
14 | m: PropTypes.oneOfType([PropTypes.string, PropTypes.array, PropTypes.number]),
15 | ...Box.propTypes,
16 | };
17 | Text.defaultProps = {
18 | as: 'p',
19 | m: '0 0 1.1em',
20 | };
21 |
22 | export default Text;
23 |
--------------------------------------------------------------------------------
/src/components/atoms/Text/index.js:
--------------------------------------------------------------------------------
1 | import Text from './Text';
2 |
3 | export default Text;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/Textarea/Textarea.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled from 'styled-components';
4 | import { themeGet, height, space } from 'styled-system';
5 | import tag from 'clean-tag';
6 |
7 | const StyledTextarea = styled(tag.textarea)`
8 | vertical-align: top;
9 | width: 100%;
10 | ${height};
11 | ${space};
12 | border: 0;
13 | border-bottom: 1px solid;
14 | background: ${themeGet('colors.white')};
15 | outline: 0;
16 | -webkit-appearance: none;
17 | border-radius: 0;
18 | font-size: ${themeGet('fontSizes.m')}px;
19 | resize: none;
20 | `;
21 |
22 | const Textarea = props => ;
23 |
24 | Textarea.propTypes = {
25 | height: PropTypes.string,
26 | p: PropTypes.string,
27 | };
28 | Textarea.defaultProps = {
29 | height: '120px',
30 | p: '13px 0',
31 | };
32 |
33 | export default Textarea;
34 |
--------------------------------------------------------------------------------
/src/components/atoms/Textarea/index.js:
--------------------------------------------------------------------------------
1 | import Textarea from './Textarea';
2 |
3 | export default Textarea;
4 |
--------------------------------------------------------------------------------
/src/components/atoms/Title/Title.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled from 'styled-components';
4 | import {
5 | themeGet,
6 | space,
7 | fontWeight,
8 | display,
9 | fontFamily,
10 | } from 'styled-system';
11 | import tag from 'clean-tag';
12 |
13 | const spaceDefault = ({ mb = 'l', mt = 0, m, ...rest }) =>
14 | m === undefined ? { mt, mb, ...rest } : { m, ...rest };
15 |
16 | const StyledTitle = styled(tag)`
17 | line-height: ${({ size }) => themeGet(`lineHeights.heading.${size}`)};
18 | font-size: ${({ size }) => themeGet(`fontSizes.heading.${size}`)}px;
19 | ${props => space(spaceDefault(props))};
20 | ${fontWeight};
21 | ${display};
22 | ${fontFamily};
23 | `;
24 |
25 | const Title = props => ;
26 |
27 | Title.propTypes = {
28 | fontWeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
29 | fontFamily: PropTypes.oneOf(['heading', 'bodyText']),
30 | as: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div']),
31 | size: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5']),
32 | ...space.propTypes,
33 | ...display.propTypes,
34 | };
35 | Title.defaultProps = {
36 | as: 'h2',
37 | size: 'h2',
38 | fontWeight: 'bold',
39 | fontFamily: 'heading',
40 | };
41 |
42 | export default Title;
43 |
--------------------------------------------------------------------------------
/src/components/atoms/Title/index.js:
--------------------------------------------------------------------------------
1 | import Title from './Title';
2 |
3 | export default Title;
4 |
--------------------------------------------------------------------------------
/src/components/index.js:
--------------------------------------------------------------------------------
1 | import Box from './atoms/Box';
2 | import Flex from './atoms/Flex';
3 | import Link from './atoms/Link';
4 | import Button from './atoms/Button';
5 | import Divider from './atoms/Divider';
6 | import Text from './atoms/Text';
7 | import Title from './atoms/Title';
8 | import Textarea from './atoms/Textarea';
9 | import InputField from './atoms/InputField';
10 | import Container from './atoms/Container';
11 | import Row from './atoms/Row';
12 | import Col from './atoms/Col';
13 | import Card from './molecules/Card';
14 |
15 | export {
16 | Box,
17 | Flex,
18 | Link,
19 | Button,
20 | Divider,
21 | Text,
22 | Title,
23 | Textarea,
24 | InputField,
25 | Container,
26 | Row,
27 | Col,
28 | Card,
29 | };
30 |
--------------------------------------------------------------------------------
/src/components/molecules/Card/Card.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled from 'styled-components';
4 | import { space } from 'styled-system';
5 | import { pick, keys } from 'lodash';
6 | import Title from '../../atoms/Title';
7 | import Text from '../../atoms/Text';
8 | import Box from '../../atoms/Box';
9 | import Link from '../../atoms/Link';
10 |
11 | const StyledCard = styled(Link)`
12 | display: block;
13 | height: 100%;
14 | transition: box-shadow 0.1s ease;
15 | &:hover {
16 | box-shadow: 0 0 0 6px;
17 | }
18 | `;
19 |
20 | const Card = ({ to, icon, title, text, name, border, ...rest }) => {
21 | // eslint-disable-next-line
22 | const spaces = pick(rest, keys(space.propTypes));
23 | return (
24 |
25 | {icon && (
26 |
27 |
28 |

29 |
30 |
31 | )}
32 |
33 | {title}
34 |
35 |
42 |
43 | );
44 | };
45 |
46 | Card.propTypes = {
47 | border: PropTypes.string,
48 | p: PropTypes.string,
49 | to: PropTypes.string,
50 | icon: PropTypes.node,
51 | title: PropTypes.string,
52 | text: PropTypes.string,
53 | name: PropTypes.string,
54 | ...space.propTypes,
55 | };
56 |
57 | Card.defaultProps = {
58 | border: '2px solid',
59 | p: '56px',
60 | };
61 |
62 | export default Card;
63 |
--------------------------------------------------------------------------------
/src/components/molecules/Card/index.js:
--------------------------------------------------------------------------------
1 | import Card from './Card';
2 |
3 | export default Card;
4 |
--------------------------------------------------------------------------------
/src/components/organisms/Header/Header.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Header = () => ;
4 |
5 | export default Header;
6 |
--------------------------------------------------------------------------------
/src/components/organisms/Header/index.js:
--------------------------------------------------------------------------------
1 | import Header from './Header';
2 |
3 | export default Header;
4 |
--------------------------------------------------------------------------------
/src/components/pages/HomePage/HomePage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import BaseTemplate from '../../templates/BaseTemplate';
3 | import Header from '../../organisms/Header';
4 |
5 | export default () => }>Home page;
6 |
--------------------------------------------------------------------------------
/src/components/pages/HomePage/index.js:
--------------------------------------------------------------------------------
1 | import HomePage from './HomePage';
2 |
3 | export default HomePage;
4 |
--------------------------------------------------------------------------------
/src/components/templates/BaseTemplate/BaseTemplate.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled from 'styled-components';
4 |
5 | const Wrapper = styled.div``;
6 |
7 | const BaseTemplate = ({ header, children }) => (
8 |
9 | {header}
10 | {children}
11 |
12 | );
13 |
14 | BaseTemplate.propTypes = {
15 | header: PropTypes.node,
16 | children: PropTypes.node,
17 | };
18 |
19 | export default BaseTemplate;
20 |
--------------------------------------------------------------------------------
/src/components/templates/BaseTemplate/index.js:
--------------------------------------------------------------------------------
1 | import BaseTemplate from './BaseTemplate';
2 |
3 | export default BaseTemplate;
4 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from 'react-dom';
3 | import App from './components/App';
4 |
5 | render(, document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/src/theme.js:
--------------------------------------------------------------------------------
1 | const colors = {
2 | black: '#191919',
3 | white: '#fff',
4 | brand: '#62e6ac',
5 | cta: '#ff8c5f',
6 | link: '#1755b7',
7 | error: '#ff4d4d',
8 | success: '#75de50',
9 | grayscale: {
10 | 300: '#e3e3e3',
11 | 400: '#d2d2d2',
12 | 600: '#a3a3a3',
13 | 800: '#7d7d7d',
14 | },
15 | };
16 |
17 | const fonts = {
18 | heading: "'Josefin Sans', sans-serif",
19 | bodyText: "'Open Sans', sans-serif",
20 | };
21 |
22 | const fontSizes = {
23 | xs: 14,
24 | s: 16,
25 | m: 18,
26 | l: 20,
27 | heading: {
28 | h1: 182,
29 | h2: 101,
30 | h3: 79,
31 | h4: 47,
32 | h5: 29,
33 | },
34 | };
35 |
36 | const lineHeights = {
37 | l: 1.5,
38 | heading: {
39 | h1: 0.8,
40 | h2: 1.06,
41 | h3: 1.14,
42 | h4: 1.25,
43 | h5: 1.32,
44 | },
45 | };
46 |
47 | const maxWidths = {
48 | s: '768px',
49 | m: '992px',
50 | l: '1226px',
51 | };
52 |
53 | const breakpoints = Object.values(maxWidths);
54 |
55 | breakpoints.s = maxWidths.s;
56 | breakpoints.m = maxWidths.m;
57 | breakpoints.l = maxWidths.l;
58 |
59 | const space = {
60 | xs: 8,
61 | s: 16,
62 | m: 24,
63 | l: 32,
64 | xl: 40,
65 | xxl: 48,
66 | };
67 |
68 | module.exports = {
69 | colors,
70 | fonts,
71 | fontSizes,
72 | lineHeights,
73 | breakpoints,
74 | space,
75 | maxWidths,
76 | };
77 |
--------------------------------------------------------------------------------
/styleguide/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ThemeProvider } from 'styled-components';
3 | import { BrowserRouter, Switch, Route } from 'react-router-dom';
4 | import { hot } from 'react-hot-loader/root';
5 | import { MDXProvider } from '@mdx-js/react';
6 | import theme from '../src/theme';
7 | import routes from './routes';
8 | import BaseTemplate from './src/components/templates/BaseTemplate';
9 | import NotFoundPage from './src/components/pages/NotFoundPage';
10 | import Title from '../src/components/atoms/Title';
11 | import Text from '../src/components/atoms/Text';
12 | import '../src/assets/css/normalize.css';
13 | import '../src/assets/css/base.css';
14 | import './src/assets/css/highlight.css';
15 |
16 | const markdown = {
17 | h1: props => ,
18 | h2: props => ,
19 | h3: props => ,
20 | h4: props => ,
21 | p: props => ,
22 | };
23 |
24 | const App = () => (
25 |
26 |
27 |
28 |
29 | {routes.map(({ key, path, component: Component }) => (
30 | (
35 |
36 |
37 |
38 | )}
39 | />
40 | ))}
41 |
42 |
43 |
44 |
45 |
46 | );
47 |
48 | export default hot(App);
49 |
--------------------------------------------------------------------------------
/styleguide/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from 'react-dom';
3 | import App from './App';
4 |
5 | render(, document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/styleguide/pages/components/box.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../src/components/atoms/Title';
3 | import Box from '../../../src/components/atoms/Box';
4 | import Text from '../../../src/components/atoms/Text';
5 | import LiveEditor from '../../src/components/atoms/LiveEditor';
6 | import PropsTable from '../../src/components/molecules/PropsTable';
7 |
8 | const scope = { Box };
9 | const code = `I am a box.`;
10 |
11 | export default () => (
12 | <>
13 | Box
14 |
15 |
16 | The Box is an element, which can be modified by yourself
17 | as you need. It is like a "div" on steroids.
18 |
19 |
20 | >
21 | );
22 |
--------------------------------------------------------------------------------
/styleguide/pages/components/button.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../src/components/atoms/Title';
3 | import Button from '../../../src/components/atoms/Button';
4 | import LiveEditor from '../../src/components/atoms/LiveEditor';
5 | import PropsTable from '../../src/components/molecules/PropsTable';
6 |
7 | const scope = { Button };
8 | const code1 = ``;
9 | const code2 = ``;
10 | const code3 = ``;
11 | const code4 = ``;
12 | const code5 = ``;
13 | const code6 = ``;
14 |
15 | export default () => (
16 | <>
17 | Button
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | >
26 | );
27 |
--------------------------------------------------------------------------------
/styleguide/pages/components/card.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../src/components/atoms/Title';
3 | import Card from '../../../src/components/molecules/Card';
4 | import LiveEditor from '../../src/components/atoms/LiveEditor';
5 | import PropsTable from '../../src/components/molecules/PropsTable';
6 |
7 | const scope = { Card };
8 | const code = ``;
9 |
10 | export default () => (
11 | <>
12 | Card
13 |
14 |
15 | >
16 | );
17 |
--------------------------------------------------------------------------------
/styleguide/pages/components/divider.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../src/components/atoms/Title';
3 | import Divider from '../../../src/components/atoms/Divider';
4 | import LiveEditor from '../../src/components/atoms/LiveEditor';
5 | import PropsTable from '../../src/components/molecules/PropsTable';
6 |
7 | const scope = { Divider };
8 | const code1 = ``;
9 | const code2 = ``;
10 |
11 | export default () => (
12 | <>
13 | Divider
14 |
15 |
16 |
17 | >
18 | );
19 |
--------------------------------------------------------------------------------
/styleguide/pages/components/flex.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../src/components/atoms/Title';
3 | import Box from '../../../src/components/atoms/Box';
4 | import Flex from '../../../src/components/atoms/Flex';
5 | import Text from '../../../src/components/atoms/Text';
6 | import LiveEditor from '../../src/components/atoms/LiveEditor';
7 | import PropsTable from '../../src/components/molecules/PropsTable';
8 |
9 | const scope = { Box, Flex, Text };
10 | const code = `
11 |
12 | Box 1
13 |
14 |
15 | Box 2
16 |
17 |
18 | Box 3
19 |
20 | `;
21 |
22 | export default () => (
23 | <>
24 | Flex
25 |
26 |
27 | The Flex is an element, used as a Box wrapper to combine
28 | them in one single row.
29 |
30 |
31 | >
32 | );
33 |
--------------------------------------------------------------------------------
/styleguide/pages/components/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Redirect } from 'react-router-dom';
3 |
4 | export default () => ;
5 |
--------------------------------------------------------------------------------
/styleguide/pages/components/inputField.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../src/components/atoms/Title';
3 | import InputField from '../../../src/components/atoms/InputField';
4 | import LiveEditor from '../../src/components/atoms/LiveEditor';
5 | import PropsTable from '../../src/components/molecules/PropsTable';
6 |
7 | const scope = { InputField };
8 | const code = ``;
9 |
10 | export default () => (
11 | <>
12 | Input Field
13 |
14 |
15 | >
16 | );
17 |
--------------------------------------------------------------------------------
/styleguide/pages/components/link.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../src/components/atoms/Title';
3 | import Link from '../../../src/components/atoms/Link';
4 | import LiveEditor from '../../src/components/atoms/LiveEditor';
5 | import PropsTable from '../../src/components/molecules/PropsTable';
6 |
7 | const scope = { Link };
8 | const code1 = `Pure`;
9 | const code2 = `Introduction`;
10 | const code3 = `Heartbeat agency`;
11 |
12 | export default () => (
13 | <>
14 | Link
15 |
16 |
17 |
18 |
19 | >
20 | );
21 |
--------------------------------------------------------------------------------
/styleguide/pages/components/text.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../src/components/atoms/Title';
3 | import Text from '../../../src/components/atoms/Text';
4 | import LiveEditor from '../../src/components/atoms/LiveEditor';
5 | import PropsTable from '../../src/components/molecules/PropsTable';
6 |
7 | const scope = { Text };
8 | const code1 = `Bread has long been a foundational part of the human diet, but a revolt against it has been building for years — and seems to be reaching a crescendo.`;
9 | const code2 = `<>
10 |
11 | Bread has long been a foundational part of the human diet, but a revolt against it has been building for years — and seems to be reaching a crescendo.
12 |
13 |
14 | Bread has long been a foundational part of the human diet, but a revolt against it has been building for years — and seems to be reaching a crescendo.
15 |
16 |
17 | Bread has long been a foundational part of the human diet, but a revolt against it has been building for years — and seems to be reaching a crescendo.
18 |
19 | >`;
20 |
21 | export default () => (
22 | <>
23 | Text
24 |
25 |
26 |
27 | >
28 | );
29 |
--------------------------------------------------------------------------------
/styleguide/pages/components/textarea.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../src/components/atoms/Title';
3 | import Textarea from '../../../src/components/atoms/Textarea';
4 | import LiveEditor from '../../src/components/atoms/LiveEditor';
5 | import PropsTable from '../../src/components/molecules/PropsTable';
6 |
7 | const scope = { Textarea };
8 | const code = ``;
9 |
10 | export default () => (
11 | <>
12 | Textarea
13 |
14 |
15 | >
16 | );
17 |
--------------------------------------------------------------------------------
/styleguide/pages/components/title.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../src/components/atoms/Title';
3 | import LiveEditor from '../../src/components/atoms/LiveEditor';
4 | import PropsTable from '../../src/components/molecules/PropsTable';
5 |
6 | const scope = { Title };
7 | const code1 = `Pulse`;
8 | const code2 = `Pulse`;
9 | const code3 = `Pulse`;
10 | const code4 = `Pulse`;
11 | const code5 = `Pulse`;
12 |
13 | export default () => (
14 | <>
15 | Title
16 |
17 |
18 |
19 |
20 |
21 |
22 | >
23 | );
24 |
--------------------------------------------------------------------------------
/styleguide/pages/core-values.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../src/components/atoms/Title';
3 | import Text from '../../src/components/atoms/Text';
4 |
5 | export default () => (
6 | <>
7 |
8 | Core values
9 |
10 |
11 | Pulse Boilerplate is a react based advanced tool, which can help you build
12 | your own design system. You can very easily document your code, create
13 | your style guides, live components and other things.
14 |
15 | >
16 | );
17 |
--------------------------------------------------------------------------------
/styleguide/pages/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styled from 'styled-components';
3 | import Box from '../../src/components/atoms/Box';
4 | import Text from '../../src/components/atoms/Text';
5 | import Title from '../../src/components/atoms/Title';
6 | import Card from '../../src/components/molecules/Card';
7 | import Col from '../../src/components/atoms/Col';
8 | import Row from '../../src/components/atoms/Row';
9 | import Container from '../../src/components/atoms/Container';
10 | import Divider from '../../src/components/atoms/Divider';
11 | import Link from '../../src/components/atoms/Link';
12 | import logo from '../src/assets/img/logo.svg';
13 | import bg from '../src/assets/img/footer_illustration.svg';
14 | import iconStyle from '../src/assets/img/icons/style.svg';
15 | import iconComp from '../src/assets/img/icons/components.svg';
16 | import iconCoreValue from '../src/assets/img/icons/core-values.svg';
17 | import iconPrinciples from '../src/assets/img/icons/principles.svg';
18 |
19 | const Content = styled(Box)`
20 | background: url(${bg}) no-repeat 50% calc(100% + 400px);
21 | `;
22 |
23 | export default () => (
24 | <>
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | .pulse
34 |
35 |
36 | React based boilerplate for creating scalable and well documented
37 | Design Systems.
38 |
39 |
47 |
48 |
49 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
67 |
73 |
74 |
75 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | Pulse v1.1
93 |
94 | Opening is always so exciting.
95 |
96 |
100 | find out more...
101 |
102 |
103 |
104 |
105 |
106 |
107 | Resources
108 |
109 |
110 | Guides and articles we create to help digital product teams make
111 | their products better.
112 |
113 |
114 |
115 | find out more...
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | Did you like it?
124 |
125 |
126 | We are currently creating, documenting and updating our process
127 | of Design System creation.
128 |
129 |
130 |
134 | find out more...
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | >
143 | );
144 |
--------------------------------------------------------------------------------
/styleguide/pages/introduction.mdx:
--------------------------------------------------------------------------------
1 | # Pulse Boilerplate
2 |
3 | Pulse Boilerplate is a react based advanced tool, which can help you build
4 | your own design system. You can very easily document your code, create
5 | your style guides, live components and other things.
6 |
--------------------------------------------------------------------------------
/styleguide/pages/principles.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../src/components/atoms/Title';
3 | import Text from '../../src/components/atoms/Text';
4 |
5 | export default () => (
6 | <>
7 |
8 | Principles
9 |
10 |
11 | Pulse Boilerplate is a react based advanced tool, which can help you build
12 | your own design system. You can very easily document your code, create
13 | your style guides, live components and other things.
14 |
15 | >
16 | );
17 |
--------------------------------------------------------------------------------
/styleguide/pages/style/color.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled, { withTheme } from 'styled-components';
4 | import { themeGet } from 'styled-system';
5 | import Box from '../../../src/components/atoms/Box';
6 | import Flex from '../../../src/components/atoms/Flex';
7 | import Text from '../../../src/components/atoms/Text';
8 | import Title from '../../../src/components/atoms/Title';
9 |
10 | const StyledColorBox = styled(Box)`
11 | width: ${({ size }) => (size === 'm' ? '122px' : '100px')};
12 | height: ${({ size }) => (size === 'm' ? '122px' : '100px')};
13 | border-radius: 10px;
14 | `;
15 | const ColorBox = ({ color, size = 'm', theme }) => (
16 |
17 |
18 | {color}
19 |
20 |
21 | {themeGet(`colors.${color}`)({ theme })}
22 |
23 |
28 |
29 | );
30 |
31 | ColorBox.propTypes = {
32 | color: PropTypes.string,
33 | size: PropTypes.string,
34 | theme: PropTypes.objectOf(PropTypes.any),
35 | };
36 |
37 | const ColorBoxWithTheme = withTheme(ColorBox);
38 |
39 | export default () => (
40 | <>
41 | Colors
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | >
56 | );
57 |
--------------------------------------------------------------------------------
/styleguide/pages/style/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Redirect } from 'react-router-dom';
3 |
4 | export default () => ;
5 |
--------------------------------------------------------------------------------
/styleguide/pages/style/theme.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Highlight from 'react-highlight';
3 | import theme from '../../../src/theme';
4 | import Title from '../../../src/components/atoms/Title';
5 |
6 | export default () => (
7 | <>
8 | Theme
9 | {JSON.stringify(theme, null, ' ')}
10 | >
11 | );
12 |
--------------------------------------------------------------------------------
/styleguide/pages/style/typography.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { withTheme } from 'styled-components';
4 | import Box from '../../../src/components/atoms/Box';
5 | import Flex from '../../../src/components/atoms/Flex';
6 | import Text from '../../../src/components/atoms/Text';
7 | import Title from '../../../src/components/atoms/Title';
8 | import Divider from '../../../src/components/atoms/Divider';
9 |
10 | const Typography = ({ theme }) => (
11 | <>
12 |
13 | Typography
14 |
15 |
16 |
17 |
18 |
19 | Josefin Sans
20 |
21 | Headings
22 |
23 |
24 |
25 |
26 | Open Sans
27 |
28 | Body text
29 |
30 |
31 |
32 |
33 | Heading H1
34 |
35 |
36 | {' '}
37 | {theme.fontSizes.heading.h1}
38 | pt
39 |
40 | Heading H2
41 |
42 | {' '}
43 | {theme.fontSizes.heading.h2}
44 | pt
45 |
46 |
47 | Heading H3
48 |
49 |
50 | {' '}
51 | {theme.fontSizes.heading.h3}
52 | pt
53 |
54 |
55 | Heading H4
56 |
57 |
58 | {' '}
59 | {theme.fontSizes.heading.h4}
60 | pt
61 |
62 |
63 | Heading H5
64 |
65 |
66 | {' '}
67 | {theme.fontSizes.heading.h5}
68 | pt
69 |
70 |
71 | Body text
72 |
73 |
74 | {' '}
75 | {theme.fontSizes.l}
76 | pt
77 |
78 | Body text
79 |
80 | {' '}
81 | {theme.fontSizes.m}
82 | pt
83 |
84 |
85 | Body text
86 |
87 |
88 | {' '}
89 | {theme.fontSizes.s}
90 | pt
91 |
92 |
93 | Body text
94 |
95 |
96 | {' '}
97 | {theme.fontSizes.xs}
98 | pt
99 |
100 | >
101 | );
102 |
103 | Typography.propTypes = {
104 | theme: PropTypes.objectOf(PropTypes.any),
105 | };
106 |
107 | export default withTheme(Typography);
108 |
--------------------------------------------------------------------------------
/styleguide/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heartbeatua/Pulse-Boilerplate/57647172b1a1041cd8731c2802a3989eb1aaab3e/styleguide/public/favicon.ico
--------------------------------------------------------------------------------
/styleguide/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Pulse Boilerplate — Style Guide
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/styleguide/routes.js:
--------------------------------------------------------------------------------
1 | import pathParse from 'path-parse';
2 | import { sortBy, filter } from 'lodash';
3 |
4 | const context = require.context('./pages', true, /\.(js|mdx)$/);
5 |
6 | const routes = context.keys().map(key => {
7 | const { dir, ext, name } = pathParse(key.replace(/\.\//, ''));
8 | const path = key
9 | .replace(ext, '')
10 | .replace(/\./, '')
11 | .replace(/\/index/, '');
12 |
13 | return {
14 | key,
15 | dirname: dir,
16 | name: name === 'index' && dir ? dir : name,
17 | path: path || '/',
18 | component: context(key).default,
19 | };
20 | });
21 |
22 | const organisedRoutes = routes.reduce((accum, route, i, array) => {
23 | const { dirname, key } = route;
24 | if (!dirname || key.search(/index/) !== -1) {
25 | const subDir = filter(
26 | array,
27 | o => o.dirname === dirname && o.dirname !== o.name,
28 | );
29 | accum.push(dirname ? { ...route, subDir } : route);
30 | }
31 | return accum;
32 | }, []);
33 |
34 | const sortedRoutes = sortBy(organisedRoutes, ({ name }) =>
35 | [
36 | 'index',
37 | 'introduction',
38 | 'core-values',
39 | 'principles',
40 | 'style',
41 | 'components',
42 | ].indexOf(name),
43 | );
44 |
45 | export default routes;
46 | export { sortedRoutes };
47 |
--------------------------------------------------------------------------------
/styleguide/src/assets/css/highlight.css:
--------------------------------------------------------------------------------
1 | .hljs{display:block;overflow-x:auto;color: #7d7d7d;}.hljs,.hljs-subst{}.hljs-comment{color:#888888}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#191919}.hljs-title,.hljs-section{color:#191919;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-selector-pseudo{color:#BC6060}.hljs-literal{color:#78A960}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}
2 |
--------------------------------------------------------------------------------
/styleguide/src/assets/img/footer_illustration.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/styleguide/src/assets/img/icons/components.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/styleguide/src/assets/img/icons/core-values.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/styleguide/src/assets/img/icons/principles.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/styleguide/src/assets/img/icons/style.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/styleguide/src/assets/img/logo.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/styleguide/src/components/atoms/LiveEditor/LiveEditor.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { withTheme } from 'styled-components';
4 | import {
5 | LiveProvider,
6 | LiveEditor as ReactLiveEditor,
7 | LiveError,
8 | LivePreview,
9 | } from 'react-live';
10 | import editorTheme from './theme';
11 | import Box from '../../../../../src/components/atoms/Box';
12 |
13 | const LiveEditor = ({ theme, ...rest }) => {
14 | const { colors, fontSizes } = theme;
15 | return (
16 |
17 |
18 |
19 |
20 |
21 |
22 |
28 |
29 |
38 |
39 |
40 | );
41 | };
42 |
43 | LiveEditor.propTypes = {
44 | theme: PropTypes.objectOf(PropTypes.any),
45 | };
46 |
47 | export default withTheme(LiveEditor);
48 |
--------------------------------------------------------------------------------
/styleguide/src/components/atoms/LiveEditor/index.js:
--------------------------------------------------------------------------------
1 | import LiveEditor from './LiveEditor';
2 |
3 | export default LiveEditor;
4 |
--------------------------------------------------------------------------------
/styleguide/src/components/atoms/LiveEditor/theme.js:
--------------------------------------------------------------------------------
1 | // Duotone Light
2 | // Author: Simurai, adapted from DuoTone themes for Atom (http://simurai.com/projects/2016/01/01/duotone-themes)
3 | // Conversion: Bram de Haan (http://atelierbram.github.io/Base2Tone-prism/output/prism/prism-base2tone-evening-dark.css)
4 | // Generated with Base16 Builder (https://github.com/base16-builder/base16-builder)
5 |
6 | export default {
7 | plain: {
8 | backgroundColor: '#faf8f5',
9 | color: '#728fcb',
10 | },
11 | styles: [
12 | {
13 | types: ['comment', 'prolog', 'doctype', 'cdata', 'punctuation'],
14 | style: {
15 | color: '#b6ad9a',
16 | },
17 | },
18 | {
19 | types: ['namespace'],
20 | style: {
21 | opacity: 0.7,
22 | },
23 | },
24 | {
25 | types: ['tag', 'operator', 'number'],
26 | style: {
27 | color: '#063289',
28 | },
29 | },
30 | {
31 | types: ['property', 'function'],
32 | style: {
33 | color: '#b29762',
34 | },
35 | },
36 | {
37 | types: ['tag-id', 'selector', 'atrule-id'],
38 | style: {
39 | color: '#2d2006',
40 | },
41 | },
42 | {
43 | types: ['attr-name'],
44 | style: {
45 | color: '#896724',
46 | },
47 | },
48 | {
49 | types: [
50 | 'boolean',
51 | 'string',
52 | 'entity',
53 | 'url',
54 | 'attr-value',
55 | 'keyword',
56 | 'control',
57 | 'directive',
58 | 'unit',
59 | 'statement',
60 | 'regex',
61 | 'at-rule',
62 | ],
63 | style: {
64 | color: '#728fcb',
65 | },
66 | },
67 | {
68 | types: ['placeholder', 'variable'],
69 | style: {
70 | color: '#93abdc',
71 | },
72 | },
73 | {
74 | types: ['deleted'],
75 | style: {
76 | textDecorationLine: 'line-through',
77 | },
78 | },
79 | {
80 | types: ['inserted'],
81 | style: {
82 | textDecorationLine: 'underline',
83 | },
84 | },
85 | {
86 | types: ['italic'],
87 | style: {
88 | fontStyle: 'italic',
89 | },
90 | },
91 | {
92 | types: ['important', 'bold'],
93 | style: {
94 | fontWeight: 'bold',
95 | },
96 | },
97 | {
98 | types: ['important'],
99 | style: {
100 | color: '#896724',
101 | },
102 | },
103 | ],
104 | };
105 |
--------------------------------------------------------------------------------
/styleguide/src/components/molecules/PropsTable/PropsTable.js:
--------------------------------------------------------------------------------
1 | import React, { Component, Fragment } from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled from 'styled-components';
4 | import tag from 'clean-tag';
5 | import { isEmpty, omit } from 'lodash';
6 | import { themeGet, width } from 'styled-system';
7 | import Link from '../../../../../src/components/atoms/Link';
8 |
9 | const StyledTable = styled(tag.table)`
10 | border-collapse: collapse;
11 | text-align: left;
12 | font-size: ${themeGet('fontSizes.s')}px;
13 | margin-bottom: ${themeGet('space.xl')}px;
14 | ${width};
15 | td,
16 | th {
17 | padding: 6px 10px;
18 | border: 1px solid ${themeGet('colors.grayscale.300')};
19 | }
20 | `;
21 |
22 | class PropsTable extends Component {
23 | static propTypes = {
24 | component: PropTypes.func.isRequired,
25 | };
26 |
27 | state = {
28 | isOpenedStyledProps: false,
29 | };
30 |
31 | toggleStyledProps = () => {
32 | this.setState(prevState => ({
33 | isOpenedStyledProps: !prevState.isOpenedStyledProps,
34 | }));
35 | };
36 |
37 | render() {
38 | const { component } = this.props;
39 | const { isOpenedStyledProps } = this.state;
40 | // eslint-disable-next-line
41 | const allProps = component.propTypes;
42 | // eslint-disable-next-line
43 | const componentProps = component.__docgenInfo.props;
44 | const componentPropsKeys = componentProps && Object.keys(componentProps);
45 | const styledProps = omit(allProps, componentPropsKeys);
46 | const styledPropsKeys = Object.keys(styledProps);
47 |
48 | return (
49 | <>
50 | {componentProps && (
51 |
52 |
53 |
54 | Prop name |
55 | Type |
56 | Default |
57 | Description |
58 |
59 |
60 |
61 | {componentPropsKeys.map(obj => {
62 | const { defaultValue, type, description } = componentProps[obj];
63 | const val = defaultValue ? defaultValue.value : '';
64 | return (
65 |
66 | {obj} |
67 | {type.name} |
68 | {val.replace(/'/gi, '')} |
69 |
70 | {description}
71 | {type.value &&
72 | type.value.map(({ value, name }, i) => {
73 | const n = type.name === 'enum' ? value : name;
74 | return (
75 |
76 | {i ? ', ' : 'One of: '}
77 | {n.replace(/'/gi, '')}
78 |
79 | );
80 | })}
81 | |
82 |
83 | );
84 | })}
85 |
86 |
87 | )}
88 | {!isEmpty(styledProps) && (
89 |
90 |
91 |
92 |
96 | Styled system prop names
97 | |
98 |
99 |
100 |
101 |
102 |
103 | {styledPropsKeys.map((prop, i) => `${i ? ', ' : ''}${prop}`)}.
104 | (
105 |
109 | reference table
110 |
111 | )
112 | |
113 |
114 |
115 |
116 | )}
117 | >
118 | );
119 | }
120 | }
121 |
122 | export default PropsTable;
123 |
--------------------------------------------------------------------------------
/styleguide/src/components/molecules/PropsTable/index.js:
--------------------------------------------------------------------------------
1 | import PropsTable from './PropsTable';
2 |
3 | export default PropsTable;
4 |
--------------------------------------------------------------------------------
/styleguide/src/components/molecules/Sidebar/Sidebar.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { withRouter } from 'react-router-dom';
4 | import { SubMenu, StyledSidebar, Nav, NavLinkItem } from './styles';
5 | import { sortedRoutes as routes } from '../../../../routes';
6 | import { formatPageName } from '../../../../utils';
7 | import Box from '../../../../../src/components/atoms/Box';
8 | import logo from '../../../assets/img/logo.svg';
9 |
10 | const Sidebar = ({ location }) => {
11 | const { pathname } = location;
12 | const getDir = routes.find(({ dirname }) => {
13 | if (!dirname) return null;
14 | return pathname.search(dirname) !== -1;
15 | });
16 |
17 | return (
18 |
19 |
20 |
21 |
22 |
40 |
41 | );
42 | };
43 |
44 | Sidebar.propTypes = {
45 | location: PropTypes.objectOf(PropTypes.string),
46 | };
47 |
48 | export default withRouter(Sidebar);
49 |
--------------------------------------------------------------------------------
/styleguide/src/components/molecules/Sidebar/index.js:
--------------------------------------------------------------------------------
1 | import Sidebar from './Sidebar';
2 |
3 | export default Sidebar;
4 |
--------------------------------------------------------------------------------
/styleguide/src/components/molecules/Sidebar/styles.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 | import { themeGet, space } from 'styled-system';
3 | import Link from '../../../../../src/components/atoms/Link';
4 |
5 | const SubMenu = styled.ul`
6 | list-style: none;
7 | padding: 0 0 14px;
8 | margin: 30px 0;
9 | border-bottom: 1px solid ${themeGet('colors.grayscale.400')};
10 | `;
11 |
12 | const StyledSidebar = styled.aside`
13 | flex-shrink: 0;
14 | width: 240px;
15 | min-height: calc(100vh - 80px);
16 | padding-right: ${themeGet('space.xxl')}px;
17 | border-right: 1px solid ${themeGet('colors.grayscale.400')};
18 | `;
19 |
20 | const Nav = styled.nav`
21 | position: sticky;
22 | top: ${themeGet('space.xl')}px;
23 | ${space};
24 | `;
25 |
26 | const NavLinkItem = styled(Link)`
27 | border-left: 4px solid transparent;
28 |
29 | &.active {
30 | color: ${themeGet('colors.black')};
31 | border-color: ${themeGet('colors.black')};
32 | }
33 | `;
34 |
35 | export { SubMenu, StyledSidebar, Nav, NavLinkItem };
36 |
--------------------------------------------------------------------------------
/styleguide/src/components/molecules/TopNav/TopNav.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styled from 'styled-components';
3 | import { themeGet } from 'styled-system';
4 | import { sortedRoutes as routes } from '../../../../routes';
5 | import { formatPageName } from '../../../../utils';
6 | import Flex from '../../../../../src/components/atoms/Flex';
7 | import Link from '../../../../../src/components/atoms/Link';
8 |
9 | const StyledLink = styled(Link)`
10 | border-bottom: 3px solid transparent;
11 |
12 | &.active {
13 | color: ${themeGet('colors.black')};
14 | border-bottom-color: ${themeGet('colors.black')};
15 | }
16 | `;
17 |
18 | const TopNav = () => (
19 |
20 | {routes.map(({ key, name, path, dirname }) => (
21 |
29 | {name === 'index' ? '.pulse' : formatPageName(name)}
30 |
31 | ))}
32 |
33 | );
34 |
35 | export default TopNav;
36 |
--------------------------------------------------------------------------------
/styleguide/src/components/molecules/TopNav/index.js:
--------------------------------------------------------------------------------
1 | import TopNav from './TopNav';
2 |
3 | export default TopNav;
4 |
--------------------------------------------------------------------------------
/styleguide/src/components/pages/HomePage/HomePage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Box from '../../../../../src/components/atoms/Box';
3 |
4 | const HomePage = props => ;
5 |
6 | export default HomePage;
7 |
--------------------------------------------------------------------------------
/styleguide/src/components/pages/HomePage/index.js:
--------------------------------------------------------------------------------
1 | import HomePage from './HomePage';
2 |
3 | export default HomePage;
4 |
--------------------------------------------------------------------------------
/styleguide/src/components/pages/InnerPage/InnerPage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled from 'styled-components';
4 | import { themeGet } from 'styled-system';
5 | import TopNav from '../../molecules/TopNav';
6 | import Sidebar from '../../molecules/Sidebar';
7 | import Box from '../../../../../src/components/atoms/Box';
8 |
9 | const Content = styled(Box)`
10 | flex: 1;
11 | padding: 0 80px ${themeGet('space.xxl')}px;
12 | max-width: 100%;
13 | overflow: hidden;
14 | `;
15 |
16 | const LayoutInner = styled.div`
17 | display: flex;
18 | padding-top: ${themeGet('space.xl')}px;
19 | padding-left: ${themeGet('space.xl')}px;
20 | padding-bottom: ${themeGet('space.xl')}px;
21 | `;
22 |
23 | const InnerPage = ({ children }) => (
24 |
25 |
26 |
27 |
28 | {children}
29 |
30 |
31 | );
32 |
33 | InnerPage.propTypes = {
34 | children: PropTypes.node,
35 | };
36 |
37 | export default InnerPage;
38 |
--------------------------------------------------------------------------------
/styleguide/src/components/pages/InnerPage/index.js:
--------------------------------------------------------------------------------
1 | import InnerPage from './InnerPage';
2 |
3 | export default InnerPage;
4 |
--------------------------------------------------------------------------------
/styleguide/src/components/pages/NotFoundPage/NotFoundPage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Title from '../../../../../src/components/atoms/Title';
3 | import BaseTemplate from '../../templates/BaseTemplate';
4 |
5 | const NotFoundPage = () => (
6 |
7 | Page not found
8 |
9 | );
10 |
11 | export default NotFoundPage;
12 |
--------------------------------------------------------------------------------
/styleguide/src/components/pages/NotFoundPage/index.js:
--------------------------------------------------------------------------------
1 | import NotFoundPage from './NotFoundPage';
2 |
3 | export default NotFoundPage;
4 |
--------------------------------------------------------------------------------
/styleguide/src/components/templates/BaseTemplate/BaseTemplate.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import styled from 'styled-components';
4 | import { withRouter } from 'react-router-dom';
5 | import { themeGet as tg } from 'styled-system';
6 | import HomePage from '../../pages/HomePage';
7 | import InnerPage from '../../pages/InnerPage';
8 |
9 | const Wrapper = styled.div`
10 | font-family: ${tg('fonts.bodyText')};
11 | font-size: ${tg('fontSizes.m')}px;
12 | color: ${tg('colors.black')};
13 | line-height: ${tg('lineHeights.l')};
14 | `;
15 |
16 | const BaseTemplate = ({ location, children }) => {
17 | const { pathname } = location;
18 | return (
19 |
20 | {pathname === '/' ? (
21 | {children}
22 | ) : (
23 | {children}
24 | )}
25 |
26 | );
27 | };
28 |
29 | BaseTemplate.propTypes = {
30 | location: PropTypes.objectOf(PropTypes.any),
31 | children: PropTypes.node,
32 | };
33 |
34 | export default withRouter(BaseTemplate);
35 |
--------------------------------------------------------------------------------
/styleguide/src/components/templates/BaseTemplate/index.js:
--------------------------------------------------------------------------------
1 | import BaseTemplate from './BaseTemplate';
2 |
3 | export default BaseTemplate;
4 |
--------------------------------------------------------------------------------
/styleguide/utils.js:
--------------------------------------------------------------------------------
1 | const unhyphenate = str => str.replace(/(\w)(-)(\w)/g, '$1 $3');
2 | const upperFirst = str => str.charAt(0).toUpperCase() + str.slice(1);
3 | const formatPageName = str => upperFirst(unhyphenate(str));
4 |
5 | export { formatPageName };
6 |
--------------------------------------------------------------------------------
/tmp/cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heartbeatua/Pulse-Boilerplate/57647172b1a1041cd8731c2802a3989eb1aaab3e/tmp/cover.png
--------------------------------------------------------------------------------
/webpack/webpack.config.babel.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import merge from 'webpack-merge';
3 | import HtmlWebpackPlugin from 'html-webpack-plugin';
4 | import MiniCssExtractPlugin from 'mini-css-extract-plugin';
5 | import CopyWebpackPlugin from 'copy-webpack-plugin';
6 | import baseConfig from './webpack.config.base';
7 |
8 | const devMode = process.env.NODE_ENV !== 'production';
9 |
10 | const config = {
11 | entry: {
12 | main: './src/index.js',
13 | },
14 | output: {
15 | path: path.resolve(__dirname, '../dist'),
16 | filename: `js/[name]${!devMode ? '.[hash:8]' : ''}.js`,
17 | publicPath: '/',
18 | },
19 | plugins: [
20 | new HtmlWebpackPlugin({
21 | template: './public/index.html',
22 | filename: 'index.html',
23 | }),
24 | new MiniCssExtractPlugin({
25 | filename: 'css/[name].[contenthash:8].css',
26 | }),
27 | new CopyWebpackPlugin([
28 | {
29 | from: './public',
30 | to: './',
31 | },
32 | ]),
33 | ],
34 | devServer: {
35 | port: 3000,
36 | contentBase: path.join(__dirname, './dist'),
37 | compress: true,
38 | historyApiFallback: true,
39 | host: '0.0.0.0',
40 | },
41 | };
42 |
43 | export default merge(baseConfig, config);
44 |
--------------------------------------------------------------------------------
/webpack/webpack.config.base.js:
--------------------------------------------------------------------------------
1 | import CleanWebpackPlugin from 'clean-webpack-plugin';
2 | import MiniCssExtractPlugin from 'mini-css-extract-plugin';
3 | import OptimizeCSSAssetsPlugin from 'optimize-css-assets-webpack-plugin';
4 | import TerserPlugin from 'terser-webpack-plugin';
5 |
6 | const devMode = process.env.NODE_ENV !== 'production';
7 |
8 | const config = {
9 | resolve: {
10 | alias: {
11 | 'react-dom': '@hot-loader/react-dom',
12 | },
13 | },
14 | module: {
15 | rules: [
16 | {
17 | test: /\.js$/,
18 | exclude: /node_modules/,
19 | use: {
20 | loader: 'babel-loader',
21 | },
22 | },
23 | {
24 | test: /\.css$/,
25 | use: [
26 | devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
27 | 'css-loader',
28 | ],
29 | },
30 | {
31 | test: /\.(png|jpg|gif|svg)$/,
32 | use: [
33 | {
34 | loader: 'url-loader',
35 | options: {
36 | limit: 8192,
37 | fallback: 'file-loader',
38 | name: 'img/[name].[hash:8].[ext]',
39 | },
40 | },
41 | ],
42 | },
43 | {
44 | test: /\.html$/,
45 | use: [
46 | {
47 | loader: 'html-loader',
48 | options: {
49 | minimize: false,
50 | },
51 | },
52 | ],
53 | },
54 | {
55 | test: /\.mdx?$/,
56 | use: ['babel-loader', '@mdx-js/loader'],
57 | },
58 | ],
59 | },
60 | optimization: {
61 | minimizer: [new TerserPlugin(), new OptimizeCSSAssetsPlugin()],
62 | },
63 | devtool: devMode ? 'source-map' : false,
64 | plugins: [],
65 | };
66 |
67 | if (!devMode) {
68 | config.plugins.push(new CleanWebpackPlugin());
69 | }
70 |
71 | export default config;
72 |
--------------------------------------------------------------------------------
/webpack/webpack.config.guide.babel.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import merge from 'webpack-merge';
3 | import HtmlWebpackPlugin from 'html-webpack-plugin';
4 | import MiniCssExtractPlugin from 'mini-css-extract-plugin';
5 | import CopyWebpackPlugin from 'copy-webpack-plugin';
6 | import baseConfig from './webpack.config.base';
7 |
8 | const devMode = process.env.NODE_ENV !== 'production';
9 |
10 | const config = {
11 | entry: {
12 | main: './styleguide/index.js',
13 | },
14 | output: {
15 | path: path.resolve(__dirname, '../docs'),
16 | filename: `js/[name]${!devMode ? '.[hash:8]' : ''}.js`,
17 | publicPath: '/',
18 | },
19 | plugins: [
20 | new HtmlWebpackPlugin({
21 | template: './styleguide/public/index.html',
22 | filename: 'index.html',
23 | }),
24 | new MiniCssExtractPlugin({
25 | filename: 'css/[name].[contenthash:8].css',
26 | }),
27 | new CopyWebpackPlugin([
28 | {
29 | from: './styleguide/public',
30 | to: './',
31 | },
32 | ]),
33 | ],
34 | devServer: {
35 | port: 6060,
36 | contentBase: path.join(__dirname, '../docs'),
37 | compress: true,
38 | historyApiFallback: true,
39 | host: '0.0.0.0',
40 | },
41 | };
42 |
43 | export default merge(baseConfig, config);
44 |
--------------------------------------------------------------------------------