├── .env ├── public ├── favicon.ico ├── manifest.json └── index.html ├── src ├── css │ ├── _addons │ │ ├── _clearfix.scss │ │ ├── _font-face.scss │ │ ├── _ratios.scss │ │ ├── _link-colors.scss │ │ ├── _px-to-rem.scss │ │ ├── _px-to-em.scss │ │ ├── _colour-manager.scss │ │ └── _family.scss │ ├── _base │ │ ├── _forms.scss │ │ ├── _colours.scss │ │ ├── _base.scss │ │ ├── _easings.scss │ │ └── _type.scss │ └── app.scss ├── components │ ├── icon.js │ └── header.js ├── .htaccess ├── containers │ ├── home.js │ └── shell.js ├── index.js ├── images │ └── sprite │ │ └── logo.svg └── utils │ └── registerServiceWorker.js ├── .gitignore ├── .editorconfig ├── package.json └── README.md /.env: -------------------------------------------------------------------------------- 1 | REACT_APP_API_BASE_URI=localhost:3000 2 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neverbland/neverbuild/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/css/_addons/_clearfix.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix() { 2 | &::after { 3 | content: ""; 4 | display: table; 5 | clear: both; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/css/_base/_forms.scss: -------------------------------------------------------------------------------- 1 | %disabled-state { 2 | cursor: not-allowed; 3 | } 4 | 5 | // Allow only vertical resizing of textareas. 6 | textarea { 7 | resize: vertical; 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # testing 7 | coverage 8 | 9 | # production 10 | build 11 | 12 | # misc 13 | .DS_Store 14 | npm-debug.log 15 | -------------------------------------------------------------------------------- /src/components/icon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function Icon({ 4 | glyph, 5 | className 6 | }) { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /src/components/header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Icon from './icon'; 4 | 5 | import logo from '../images/sprite/logo.svg'; 6 | 7 | const Header = () => ( 8 |
9 | 10 |
11 | ); 12 | 13 | export default Header; 14 | -------------------------------------------------------------------------------- /src/.htaccess: -------------------------------------------------------------------------------- 1 | # Turn mod_rewrite on 2 | RewriteEngine On 3 | 4 | # File exists? Pass it through. 5 | RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] 6 | RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d 7 | RewriteRule ^ - [L] 8 | 9 | # Not found? Rewrite to index. 10 | RewriteRule ^ /index.html [L] 11 | -------------------------------------------------------------------------------- /src/css/_base/_colours.scss: -------------------------------------------------------------------------------- 1 | $black: #000; 2 | 3 | $colour: #333333; 4 | $background-colour: #f7f5f2; 5 | $selection-colour: #b3d4fc; 6 | $heading-colour: #333333; 7 | $link-colour: #939393; 8 | $link-colour-hovered: #000000; 9 | $code-colour: #444444; 10 | $blockquote-colour: #6f6f6f; 11 | $hr-colour: #dddddd; 12 | -------------------------------------------------------------------------------- /src/containers/home.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | class Home extends Component { 4 | componentWillMount() { 5 | // Code goes here... 6 | } 7 | render() { 8 | return ( 9 |
10 |

Home

11 |
12 | ); 13 | } 14 | } 15 | 16 | export default Home; 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /src/css/_addons/_font-face.scss: -------------------------------------------------------------------------------- 1 | @mixin font-face($family, $src, $weight: normal, $style: normal) { 2 | @font-face { 3 | font-family: $family; 4 | src: url("#{$src}.eot") format("embedded-opentype"), url("#{$src}.woff") format("woff"), url("#{$src}.ttf") format("truetype"); 5 | font-style: $style; 6 | font-weight: $weight; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/containers/shell.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import Header from '../components/header'; 4 | 5 | class Shell extends Component { 6 | componentWillMount() { 7 | // Code goes here... 8 | } 9 | render() { 10 | return ( 11 |
12 |
13 | {this.props.children} 14 |
15 | ); 16 | } 17 | } 18 | 19 | export default Shell; 20 | -------------------------------------------------------------------------------- /src/css/_addons/_ratios.scss: -------------------------------------------------------------------------------- 1 | .ratio-11 { 2 | height: 0; 3 | padding-bottom: 100%; // 1:1 4 | } 5 | 6 | .ratio-169 { 7 | height: 0; 8 | padding-bottom: 56.25%; // 16:9 9 | } 10 | 11 | .ratio-916 { 12 | height: 0; 13 | padding-bottom: 177%; // 9:16 14 | } 15 | 16 | .ratio-43 { 17 | height: 0; 18 | padding-bottom: 75%; // 4:3 19 | } 20 | 21 | .ratio-34 { 22 | height: 0; 23 | padding-bottom: 133%; // 3:4 24 | } 25 | -------------------------------------------------------------------------------- /src/css/_addons/_link-colors.scss: -------------------------------------------------------------------------------- 1 | @mixin link-colors($normal, $hover: false, $active: false, $visited: false, $focus: false) { 2 | color: $normal; 3 | @if $visited { 4 | &:visited { 5 | color: $visited; 6 | } 7 | } 8 | @if $focus { 9 | &:focus { 10 | color: $focus; 11 | } 12 | } 13 | @if $hover { 14 | &:hover { 15 | color: $hover; 16 | } 17 | } 18 | @if $active { 19 | &:active { 20 | color: $active; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/css/_addons/_px-to-rem.scss: -------------------------------------------------------------------------------- 1 | // Convert pixels to rems 2 | // eg. for a relational value of 12px write rem(12) 3 | // Assumes $em-base is the font-size of 4 | 5 | $em-base: 16px; 6 | 7 | @function strip-units($value) { 8 | @return ($value / ($value * 0 + 1)); 9 | } 10 | 11 | @function rem($pxval) { 12 | @if not unitless($pxval) { 13 | $pxval: strip-units($pxval); 14 | } 15 | 16 | $base: $em-base; 17 | @if not unitless($base) { 18 | $base: strip-units($base); 19 | } 20 | @return ($pxval / $base) * 1rem; 21 | } 22 | -------------------------------------------------------------------------------- /src/css/_addons/_px-to-em.scss: -------------------------------------------------------------------------------- 1 | // Convert pixels to ems 2 | // eg. for a relational value of 12px write em(12) when the parent is 16px 3 | // if the parent is another value say 24px write em(12, 24) 4 | 5 | $em-base: 16px !default; 6 | 7 | @function strip-units($value) { 8 | @return ($value / ($value * 0 + 1)); 9 | } 10 | 11 | @function em($pxval, $base: $em-base) { 12 | @if not unitless($pxval) { 13 | $pxval: strip-units($pxval); 14 | } 15 | @if not unitless($base) { 16 | $base: strip-units($base); 17 | } 18 | @return ($pxval / $base) * 1em; 19 | } 20 | -------------------------------------------------------------------------------- /src/css/_base/_base.scss: -------------------------------------------------------------------------------- 1 | html { 2 | box-sizing: border-box; 3 | font-family: $base-font; 4 | font-size: 100%; 5 | } 6 | 7 | *, 8 | *:after, 9 | *:before { 10 | box-sizing: inherit; 11 | } 12 | 13 | body { 14 | background-color: $background-colour; 15 | color: $colour; 16 | position: relative; 17 | } 18 | 19 | *::selection { 20 | background: $selection-colour; 21 | text-shadow: none; 22 | } 23 | 24 | %no-list-style, 25 | .no-list-style { 26 | list-style: none; 27 | } 28 | 29 | ul { 30 | &.no-list-style { 31 | @extend %no-list-style; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { Router, Route, browserHistory } from 'react-router'; 4 | 5 | import registerServiceWorker from './utils/registerServiceWorker'; 6 | 7 | import Shell from './containers/shell'; 8 | import Home from './containers/home'; 9 | 10 | // eslint-disable-next-line 11 | import './css/app.scss'; 12 | 13 | ReactDOM.render( 14 | 15 | 16 | 17 | 18 | , 19 | document.getElementById('root') 20 | ); 21 | 22 | registerServiceWorker(); -------------------------------------------------------------------------------- /src/css/_addons/_colour-manager.scss: -------------------------------------------------------------------------------- 1 | // from http://sass-guidelin.es/#lightening-and-darkening-colors 2 | // 3 | // Slightly lighten a color 4 | // @access public 5 | // @param {Color} $color - color to tint 6 | // @param {Number} $percentage - percentage of `$color` in returned color 7 | // @return {Color} 8 | @function tint($color, $percentage) { 9 | @return mix(white, $color, $percentage); 10 | } 11 | 12 | // Slightly darken a color 13 | // @access public 14 | // @param {Color} $color - color to shade 15 | // @param {Number} $percentage - percentage of `$color` in returned color 16 | // @return {Color} 17 | @function shade($color, $percentage) { 18 | @return mix(black, $color, $percentage); 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "neverbuild", 3 | "version": "0.3.0", 4 | "private": true, 5 | "engines": { 6 | "node": ">=4" 7 | }, 8 | "dependencies": { 9 | "bootstrap": "github:twbs/bootstrap#v4-dev", 10 | "classnames": "^2.2.5", 11 | "normalize.css": "^4.2.0", 12 | "react-dom": "^15.4.1", 13 | "react-router": "^2.8.1", 14 | "react": "^15.4.1", 15 | "@neverbland/react-scripts": "latest" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test --env=jsdom", 21 | "lint:js": "eslint src/js/**/*.js", 22 | "lint:scss": "sass-lint 'src/css/**/*.scss' -v -q", 23 | "svg:pretty": "find src/images -name '*.svg' -type f -exec svgo --pretty --indent=2 '{}' \\;" 24 | }, 25 | "eslintConfig": { 26 | "extends": "react-app" 27 | }, 28 | "sasslintConfig": "./node_modules/@neverbland/react-scripts/config/sasslint.yml" 29 | } 30 | -------------------------------------------------------------------------------- /src/css/app.scss: -------------------------------------------------------------------------------- 1 | // External Libraries 2 | // ======== 3 | // http://v4-alpha.getbootstrap.com/layout/grid/ 4 | // $enable-flex: true; 5 | // @import '~bootstrap/scss/bootstrap-grid'; 6 | 7 | // https://necolas.github.io/normalize.css/ 8 | @import "~normalize.css/normalize"; 9 | 10 | // Optional addons 11 | // ======== 12 | // @import '_addons/clearfix'; 13 | // @import '_addons/colour-manager'; 14 | // @import '_addons/family'; 15 | // @import '_addons/font-face'; 16 | // @import '_addons/link-colors'; 17 | // @import '_addons/px-to-em'; 18 | // @import '_addons/px-to-rem'; 19 | 20 | // Base styles 21 | // ======== 22 | @import '_base/colours'; 23 | @import '_base/easings'; 24 | @import '_base/type'; 25 | @import '_base/forms'; 26 | @import '_base/base'; 27 | 28 | // Components 29 | // ======== 30 | // Put your components here. There should be one file 31 | // for each corresponding component, following the 32 | // BEM methodology https://en.bem.info/methodology/. 33 | -------------------------------------------------------------------------------- /src/css/_base/_easings.scss: -------------------------------------------------------------------------------- 1 | $ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550); 2 | $ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860); 3 | $ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000); 4 | $ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950); 5 | $ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000); 6 | $ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000); 7 | $ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000); 8 | $ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955); 9 | $ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275); 10 | $ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000); 11 | $ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000); 12 | $ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000); 13 | $ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000); 14 | $ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000); 15 | $ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000); 16 | $ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940); 17 | $ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045); 18 | $ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335); 19 | $ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035); 20 | $ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715); 21 | $ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060); 22 | $ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220); 23 | $ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190); 24 | $ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530); 25 | 26 | // Custom easings 27 | $slick-ease: cubic-bezier(0.2, 0.3, 0, 1); 28 | $bouncy: cubic-bezier(0.34, 1.61, 0.7, 1); 29 | -------------------------------------------------------------------------------- /src/css/_base/_type.scss: -------------------------------------------------------------------------------- 1 | // Type variables 2 | $base-font: sans-serif !default; 3 | $alt-font: sans-serif !default; 4 | 5 | // Type styles 6 | %h1, 7 | %h2, 8 | %h3, 9 | %h4, 10 | %h5, 11 | %h6, 12 | .h1, 13 | .h2, 14 | .h3, 15 | .h4, 16 | .h5, 17 | .h6, 18 | h1, 19 | h2, 20 | h3, 21 | h4, 22 | h5, 23 | h6 { 24 | margin: 14px 0; 25 | font-family: $alt-font; 26 | font-style: normal; 27 | color: $heading-colour; 28 | text-rendering: optimizeLegibility; 29 | } 30 | 31 | %h1, 32 | .h1, 33 | h1 { 34 | font-size: rem(44); 35 | line-height: 48.4px; 36 | } 37 | 38 | %h2, 39 | .h2, 40 | h2 { 41 | font-size: rem(37); 42 | line-height: 40.7px; 43 | } 44 | 45 | %h3, 46 | .h3, 47 | h3 { 48 | font-size: rem(27); 49 | line-height: 29.7px; 50 | } 51 | 52 | %h4, 53 | .h4, 54 | h4 { 55 | font-size: rem(23); 56 | line-height: 25.3px; 57 | } 58 | 59 | %h5, 60 | .h5, 61 | h5 { 62 | font-size: rem(17); 63 | line-height: 18.7px; 64 | } 65 | 66 | %h6, 67 | .h6, 68 | h6 { 69 | font-size: rem(14); 70 | line-height: 15.8px; 71 | } 72 | 73 | a { 74 | color: $link-colour; 75 | text-decoration: none; 76 | } 77 | 78 | p { 79 | margin-bottom: 17px; 80 | font-family: inherit; 81 | font-weight: normal; 82 | } 83 | 84 | hr { 85 | margin: 22px 0 21px; 86 | height: 0; 87 | border: solid $hr-colour; 88 | border-width: 1px 0 0; 89 | clear: both; 90 | } 91 | 92 | em, 93 | i { 94 | font-style: italic; 95 | line-height: inherit; 96 | } 97 | 98 | b, 99 | strong { 100 | font-weight: bold; 101 | line-height: inherit; 102 | } 103 | 104 | small { 105 | font-size: 60%; 106 | line-height: inherit; 107 | } 108 | -------------------------------------------------------------------------------- /src/images/sprite/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | Neverbland 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | Neverbuild React App 23 | 24 | 25 | 26 | 29 |
30 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Neverbuild 2 | 3 | ### :warning: Warning! Breaking change with SVG Sprite Loader, read this! 4 | To use an SVG sprite, you should now do like the following: 5 | https://github.com/Neverbland/neverbuild/blob/master/src/components/header.js#L9 6 | This is due to a [change on SVG Sprite Loader](https://github.com/kisenka/svg-sprite-loader/blob/master/2.0.md#client-runtime). 7 | 8 | Kickstarts a new React app 9 | 10 | ### The Webpack configuration sits in [our Create React App fork](https://github.com/Neverbland/create-react-app/tree/master/packages/react-scripts) for easier maintainability. 11 | This repository is intended to replace the `/template` folder of Create React App. 12 | 13 | This package includes scripts and configuration used by [Create React App](https://github.com/facebookincubator/create-react-app).
14 | Please refer to its documentation: 15 | 16 | * [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md) – How to develop apps bootstrapped with Create React App. 17 | 18 | 19 | ## Features 20 | 21 | * [Every Create React App features](https://github.com/facebookincubator/create-react-app#whats-inside) 22 | * React Router 23 | * SCSS 24 | * SVG sprites 25 | * Assets optimisation (png, jpg, svg, ...) 26 | * Automatic polyfilling (using Polyfill.io) 27 | 28 | ## Getting started 29 | 30 | ### `npm install` or `yarn start` 31 | Install the project. 32 | 33 | ### `npm start` or `yarn start` 34 | 35 | Runs the app in development mode.
36 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 37 | 38 | ### `npm run build` or `yarn build` 39 | 40 | Builds the app for production to the `build` folder.
41 | It correctly bundles React in production mode and optimizes the build for the best performance. 42 | 43 | The build is minified and the filenames include the hashes.
44 | By default, it also [includes a service worker](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#making-a-progressive-web-app) so that your app loads from local cache on future visits. 45 | 46 | ## Writing JS 47 | 48 | We use [EditorConfig](http://editorconfig.org/) for code consistency. Please see below to add support to your editor. 49 | 50 | ## Writing CSS 51 | 52 | We use [BEM](https://en.bem.info/) across our projects. 53 | 54 | ## Testing 55 | 56 | - Lint SCSS: `npm run lint:scss` 57 | 58 | ## Polyfills 59 | 60 | We use [Polyfill.io](https://polyfill.io/v2/docs/) to polyfill missing Javascript functionality. Simply add any missing functionality by appending the polyfill.io url in `src/public/index.html` with the feature you need. 61 | 62 | ## Recommended Tools 63 | 64 | - ESLint ([Atom Plugin](https://atom.io/packages/linter-eslint)/[Sublime Plugin](https://github.com/roadhump/SublimeLinter-eslint)) 65 | - SASS Lint ([Atom Plugin](https://atom.io/packages/linter-sass-lint)/[Sublime Plugin](https://github.com/skovhus/SublimeLinter-contrib-sass-lint)) 66 | - EditorConfig ([Atom Plugin](https://atom.io/packages/editorconfig)/[Sublime Plugin](https://github.com/sindresorhus/editorconfig-sublime)) 67 | - Beautifier ([Atom Plugin](https://atom.io/packages/atom-beautify)) 68 | 69 | ## License 70 | 71 | [MIT license](http://opensource.org/licenses/MIT) 72 | -------------------------------------------------------------------------------- /src/utils/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register() { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 34 | 35 | if (!isLocalhost) { 36 | // Is not local host. Just register service worker 37 | registerValidSW(swUrl); 38 | } else { 39 | // This is running on localhost. Lets check if a service worker still exists or not. 40 | checkValidServiceWorker(swUrl); 41 | } 42 | }); 43 | } 44 | } 45 | 46 | function registerValidSW(swUrl) { 47 | navigator.serviceWorker 48 | .register(swUrl) 49 | .then(registration => { 50 | registration.onupdatefound = () => { 51 | const installingWorker = registration.installing; 52 | installingWorker.onstatechange = () => { 53 | if (installingWorker.state === 'installed') { 54 | if (navigator.serviceWorker.controller) { 55 | // At this point, the old content will have been purged and 56 | // the fresh content will have been added to the cache. 57 | // It's the perfect time to display a "New content is 58 | // available; please refresh." message in your web app. 59 | console.log('New content is available; please refresh.'); 60 | } else { 61 | // At this point, everything has been precached. 62 | // It's the perfect time to display a 63 | // "Content is cached for offline use." message. 64 | console.log('Content is cached for offline use.'); 65 | } 66 | } 67 | }; 68 | }; 69 | }) 70 | .catch(error => { 71 | console.error('Error during service worker registration:', error); 72 | }); 73 | } 74 | 75 | function checkValidServiceWorker(swUrl) { 76 | // Check if the service worker can be found. If it can't reload the page. 77 | fetch(swUrl) 78 | .then(response => { 79 | // Ensure service worker exists, and that we really are getting a JS file. 80 | if ( 81 | response.status === 404 || 82 | response.headers.get('content-type').indexOf('javascript') === -1 83 | ) { 84 | // No service worker found. Probably a different app. Reload the page. 85 | navigator.serviceWorker.ready.then(registration => { 86 | registration.unregister().then(() => { 87 | window.location.reload(); 88 | }); 89 | }); 90 | } else { 91 | // Service worker found. Proceed as normal. 92 | registerValidSW(swUrl); 93 | } 94 | }) 95 | .catch(() => { 96 | console.log( 97 | 'No internet connection found. App is running in offline mode.' 98 | ); 99 | }); 100 | } 101 | 102 | export function unregister() { 103 | if ('serviceWorker' in navigator) { 104 | navigator.serviceWorker.ready.then(registration => { 105 | registration.unregister(); 106 | }); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/css/_addons/_family.scss: -------------------------------------------------------------------------------- 1 | // Select all children from the first to `$num`. 2 | // @group with-arguments 3 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 4 | // @param {number} $num - id of the child 5 | @mixin first($num) { 6 | &:nth-child(-n + #{$num}) { 7 | @content; 8 | } 9 | } 10 | 11 | // Select all children from the last to `$num`. 12 | // @group with-arguments 13 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 14 | // @param {number} $num - id of the child 15 | @mixin last($num) { 16 | &:nth-last-child(-n + #{$num}) { 17 | @content; 18 | } 19 | } 20 | 21 | // Select all children after the first to `$num`. 22 | // @group with-arguments 23 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 24 | // @param {number} $num - id of the child 25 | @mixin after-first($num) { 26 | &:nth-child(n + #{$num + 1}) { 27 | @content; 28 | } 29 | } 30 | 31 | // Select all children before `$num` from the last. 32 | // @group with-arguments 33 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 34 | // @param {number} $num - id of the child 35 | @mixin from-end($num) { 36 | &:nth-last-child(#{$num}) { 37 | @content; 38 | } 39 | } 40 | 41 | // Select all children between `$first` and `$last`. 42 | // @group with-arguments 43 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 44 | @mixin between($first, $last) { 45 | &:nth-child(n + #{$first}):nth-child(-n + #{$last}) { 46 | @content; 47 | } 48 | } 49 | 50 | // Select all even children between `$first` and `$last`. 51 | // @group with-arguments 52 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 53 | @mixin pair-between($first, $last) { 54 | &:nth-child(even):nth-child(n + #{$first}):nth-child(-n + #{$last}) { 55 | @content; 56 | } 57 | } 58 | 59 | // Select all odd children between `$first` and `$last`. 60 | // @group with-arguments 61 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 62 | @mixin impair-between($first, $last) { 63 | &:nth-child(odd):nth-child(n + #{$first}):nth-child(-n + #{$last}) { 64 | @content; 65 | } 66 | } 67 | 68 | // Select all `$num` children between `$first` and `$last`. 69 | // @group with-arguments 70 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 71 | @mixin n-between($num, $first, $last) { 72 | &:nth-child(#{$num}n):nth-child(n + #{$first}):nth-child(-n + #{$last}) { 73 | @content; 74 | } 75 | } 76 | 77 | // Select all children but `$num`. 78 | // @group with-arguments 79 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 80 | // @param {number} $num - id of the child 81 | @mixin all-but($num) { 82 | &:not(:nth-child(#{$num})) { 83 | @content; 84 | } 85 | } 86 | 87 | // Select children each `$num`. 88 | // @group with-arguments 89 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 90 | // @param {number} $num - id of the child 91 | // @alias every 92 | @mixin each($num) { 93 | &:nth-child(#{$num}n) { 94 | @content; 95 | } 96 | } 97 | 98 | // Select children each `$num`. 99 | // @group with-arguments 100 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 101 | // @param {number} $num - id of the child 102 | @mixin every($num) { 103 | &:nth-child(#{$num}n) { 104 | @content; 105 | } 106 | } 107 | 108 | // Select the `$num` child from the start and the `$num` child from the last. 109 | // @group with-arguments 110 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 111 | // @param {number} $num - id of the child 112 | @mixin from-first-last($num) { 113 | &:nth-child(#{$num}), 114 | &:nth-last-child(#{$num}) { 115 | @content; 116 | } 117 | } 118 | 119 | // Select the item in the middle of `$num` child. Only works with odd number 120 | // chain. 121 | // @group with-arguments 122 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 123 | // @param {number} $num - id of the child 124 | @mixin middle($num) { 125 | &:nth-child(#{round($num / 2)}) { 126 | @content; 127 | } 128 | } 129 | 130 | // Select all children between the `$num` first and the `$num` last. 131 | // @group with-arguments 132 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 133 | // @param {number} $num - id of the child 134 | @mixin all-but-first-last($num) { 135 | &:nth-child(n + #{$num}):nth-last-child(n + #{$num}) { 136 | @content; 137 | } 138 | } 139 | 140 | // This I/O mixin will only select the first of `$limit` items. It will not 141 | // work if there is not as much as item as you set in `$limit`. 142 | // @group io 143 | // @param {number} $limit 144 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 145 | @mixin first-of($limit) { 146 | &:nth-last-child(#{$limit}):first-child { 147 | @content; 148 | } 149 | } 150 | 151 | // This I/O mixin will only select the last of `$limit` items. It will not 152 | // if there is not as much as item as you set in `$limit`. 153 | // @group io 154 | // @param {number} $limit 155 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 156 | @mixin last-of($limit) { 157 | &:nth-of-type(#{$limit}):nth-last-of-type(1) { 158 | @content; 159 | } 160 | } 161 | 162 | // Select all even children. 163 | // @group no-arguments 164 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 165 | // @alias even 166 | @mixin pair() { 167 | &:nth-child(even) { 168 | @content; 169 | } 170 | } 171 | 172 | // Select all even children. 173 | // @group no-arguments 174 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 175 | @mixin even() { 176 | &:nth-child(even) { 177 | @content; 178 | } 179 | } 180 | 181 | // Select all odd children. 182 | // @group no-arguments 183 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 184 | // @alias odd 185 | @mixin impair() { 186 | &:nth-child(odd) { 187 | @content; 188 | } 189 | } 190 | 191 | // Select all odd children. 192 | // @group no-arguments 193 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 194 | @mixin odd() { 195 | &:nth-child(odd) { 196 | @content; 197 | } 198 | } 199 | 200 | // Select only the first and last child. 201 | // @group no-arguments 202 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 203 | @mixin first-last() { 204 | &:first-child, 205 | &:last-child { 206 | @content; 207 | } 208 | } 209 | 210 | // Will only select the child if it’s unique. 211 | // @group no-arguments 212 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 213 | @mixin only() { 214 | &:only-child { 215 | @content; 216 | } 217 | } 218 | 219 | // Will only select children if they are not unique. Meaning if there is at 220 | // least 2 children, the style is applied. 221 | // @group no-arguments 222 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 223 | @mixin not-unique() { 224 | &:not(:only-child) { 225 | @content; 226 | } 227 | } 228 | 229 | // This mixin is used to automatically sort z-index in numerical order. But it 230 | // can also sort them in anti-numerical order, depending the parameters you use. 231 | // @group using functions 232 | // @content [Write the style you want to apply to the children, and it will be added within the @content directive] 233 | // @param {number} $num - Number of children 234 | // @param {string} $direction [forward] - Direction of the sort 235 | // @param {number} $index [0] - Index of the sorting 236 | @mixin child-index($num, $direction: 'forward', $index: 0) { 237 | @for $i from 1 through $num { 238 | @if ($direction == 'forward') { 239 | &:nth-child(#{$i}) { 240 | z-index: order-index($i, $index); 241 | @content; 242 | } 243 | } @else if ($direction == 'backward') { 244 | &:nth-last-child(#{$i}) { 245 | z-index: order-index($i, $index); 246 | @content; 247 | } 248 | } 249 | } 250 | } 251 | 252 | // Used by the child-index mixin. It will returned the proper sorted numbers 253 | // depending on the `$index` value. 254 | // @access private 255 | // @param {number} $num - Number of children 256 | // @param {number} $index - Index of the sorting 257 | @function order-index($i, $index) { 258 | @return ($index + $i); 259 | } 260 | --------------------------------------------------------------------------------