├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .storybook ├── main.js └── preview.js ├── .stylelintignore ├── .stylelintrc.js ├── README.md ├── jsconfig.json ├── next.config.js ├── package.json ├── public ├── images │ └── js.jpg └── mario.ico ├── site.config.js ├── src ├── assets │ ├── fonts │ │ ├── FiraCode-Bold.ttf │ │ ├── FiraCode-Light.ttf │ │ ├── FiraCode-Medium.ttf │ │ ├── FiraCode-Regular.ttf │ │ └── FiraCode-SemiBold.ttf │ ├── icons │ │ ├── HobbitHome.js │ │ ├── ShopBag.js │ │ ├── Sunshine.js │ │ └── index.js │ └── stylesheets │ │ ├── app.scss │ │ ├── components │ │ ├── button.scss │ │ ├── footer.scss │ │ ├── header.scss │ │ └── image.scss │ │ ├── fonts.scss │ │ ├── global.scss │ │ ├── modules │ │ ├── colors.module.scss │ │ ├── fonts.module.scss │ │ └── sizes.module.scss │ │ ├── pages │ │ └── home.module.scss │ │ ├── reset.scss │ │ ├── utils.scss │ │ └── variables.scss ├── components │ ├── Button │ │ ├── index.js │ │ └── stories.js │ ├── Footer │ │ └── index.js │ ├── Head │ │ └── index.js │ ├── Header │ │ └── index.js │ ├── Icon │ │ ├── index.js │ │ └── stories.js │ ├── Image │ │ ├── index.js │ │ └── stories.js │ └── Page │ │ ├── index.js │ │ └── stories.js ├── guide │ ├── Icons │ │ └── stories.js │ └── colors │ │ └── stories.js ├── pages │ ├── _app.js │ ├── _document.js │ ├── api │ │ └── hello.js │ └── index.js └── utils │ ├── helper.js │ └── icons.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = false 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /public/ 2 | /out/ 3 | /.next/ 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'root': true, 3 | 'settings': { 4 | 'react': { 5 | 'version': 'detect' 6 | } 7 | }, 8 | 'env': { 9 | 'browser': true, 10 | 'es2021': true, 11 | 'node': true 12 | }, 13 | 'extends': [ 14 | 'eslint:recommended', 15 | 'plugin:react/recommended' 16 | ], 17 | 'parserOptions': { 18 | 'ecmaFeatures': { 19 | 'jsx': true 20 | }, 21 | 'ecmaVersion': 12, 22 | 'sourceType': 'module' 23 | }, 24 | 'plugins': [ 25 | 'react' 26 | ], 27 | 'rules': { 28 | 'no-useless-escape': 'off', 29 | 'no-debugger': 'off', 30 | 'space-before-function-paren': ['error', 'always'], 31 | 'react/prop-types': ['off'], 32 | 'indent': ['error', 2], 33 | 'linebreak-style': [ 34 | 'error', 35 | 'unix' 36 | ], 37 | 'quotes': [ 38 | 'error', 39 | 'single' 40 | ], 41 | 'semi': [ 42 | 'error', 43 | 'never' 44 | ], 45 | 'eol-last': [ 46 | 'error', 47 | 'always' 48 | ] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | const JsConfigPathsPlugin = require('jsconfig-paths-webpack-plugin'); 2 | const path = require('path'); 3 | 4 | let jsconfig = new JsConfigPathsPlugin() 5 | 6 | module.exports = { 7 | "stories": [ 8 | "../src/**/*.stories.mdx", 9 | "../src/**/**/stories.@(js|jsx|ts|tsx)" 10 | ], 11 | "addons": [ 12 | "@storybook/addon-links", 13 | "@storybook/addon-essentials" 14 | ], 15 | "compilerOptions": { 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"], 19 | "~@/*": ["./src/assets/stylesheets/*"] 20 | } 21 | }, 22 | webpackFinal: async (config, { configType }) => { 23 | // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION' 24 | // You can change the configuration based on that. 25 | // 'PRODUCTION' is used when building the static version of storybook. 26 | 27 | // Make whatever fine-grained changes you need 28 | config.module.rules.push({ 29 | test: /\.scss$/, 30 | use: ['style-loader', 'css-loader', 'sass-loader'], 31 | include: path.resolve(__dirname, '../'), 32 | }, 33 | { 34 | test: /\.(svg|png|jpe?g|gif)$/i, 35 | include: path.resolve(__dirname, './'), 36 | use: [ 37 | { 38 | loader: 'file-loader', 39 | }, 40 | ] 41 | }); 42 | 43 | 44 | config.resolve = { 45 | plugins: [ 46 | jsconfig 47 | ] 48 | } 49 | 50 | // Return the altered config 51 | return config; 52 | } 53 | } -------------------------------------------------------------------------------- /.storybook/preview.js: -------------------------------------------------------------------------------- 1 | import * as nextImage from 'next/image'; 2 | import '../src/assets/stylesheets/app.scss'; 3 | 4 | Object.defineProperty(nextImage, 'default', { 5 | configurable: true, 6 | value: (props) => { 7 | return ; 8 | }, 9 | }); 10 | 11 | export const parameters = { 12 | actions: { argTypesRegex: "^on[A-Z].*" }, 13 | } -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /public/ 3 | /out/ 4 | /.next/ -------------------------------------------------------------------------------- /.stylelintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "extends": "stylelint-config-sass-guidelines", 3 | "plugins": [ 4 | "stylelint-scss" 5 | ], 6 | rules: { 7 | "selector-class-pattern": "^(?:(?:o|c|u|t|s|is|has|_|js|qa)-)?[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*(?:__[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:--[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:\\[.+\\])?$", 8 | "max-nesting-depth": 5, 9 | "property-no-unknown": [true, { 10 | "ignoreSelectors": [/:export/] 11 | }], 12 | "declaration-property-value-disallowed-list": { 13 | "/^border/": [] 14 | }, 15 | "scss/at-import-partial-extension-blacklist": [''], 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | 15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. 16 | 17 | ## Storybook 18 | Storybook the run development server: 19 | ```bash 20 | npm run storybook 21 | # or 22 | yarn storybook 23 | ``` 24 | 25 | Open [http://localhost:6006](http://localhost:6006) with your browser to see the result. 26 | Then add stories.js file and add example to this file a component folder. 27 | 28 | ## Learn More 29 | 30 | To learn more about Next.js, take a look at the following resources: 31 | 32 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 33 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 34 | 35 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 36 | 37 | ## Deploy on Vercel 38 | 39 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/import?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 40 | 41 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 42 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["./src/*"], 6 | "~@/*": ["./src/assets/stylesheets/*"] 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | images: { 5 | loader: 'imgix' 6 | }, 7 | sassOptions: { 8 | includePaths: [path.join(__dirname, 'src/assets/stylesheets')], 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-boilerplate", 3 | "version": "0.1.0", 4 | "private": true, 5 | "author": "edisdev", 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "storybook": "start-storybook -s ./public,./static -p 6006", 11 | "build-storybook": "build-storybook", 12 | "export": "next build && next export", 13 | "lint": "yarn eslint ./ --ext .js", 14 | "stlint": "yarn stylelint ./src/**/*.scss --config=.stylelintrc.js", 15 | "stlint:fix": "yarn stlint --fix", 16 | "lint:fix": "yarn lint --fix", 17 | "precommit": "yarn lint --fix && yarn stlint --fix" 18 | }, 19 | "dependencies": { 20 | "jsconfig-paths-webpack-plugin": "^0.1.3", 21 | "next": "10.0.3", 22 | "normalize-scss": "^7.0.1", 23 | "react": "17.0.1", 24 | "react-dom": "17.0.1", 25 | "sass": "^1.30.0", 26 | "sass-loader": "^10.1.0", 27 | "style-loader": "^2.0.0" 28 | }, 29 | "devDependencies": { 30 | "@babel/core": "^7.12.10", 31 | "@storybook/addon-actions": "^6.1.11", 32 | "@storybook/addon-essentials": "^6.1.11", 33 | "@storybook/addon-links": "^6.1.11", 34 | "@storybook/react": "^6.1.11", 35 | "babel-loader": "^8.2.2", 36 | "eslint": "^7.16.0", 37 | "eslint-plugin-react": "^7.21.5", 38 | "husky": "^4.3.6", 39 | "stylelint": "^13.8.0", 40 | "stylelint-config-sass-guidelines": "^7.1.0", 41 | "stylelint-scss": "^3.18.0" 42 | }, 43 | "husky": { 44 | "hooks": { 45 | "pre-commit": "yarn precommit" 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /public/images/js.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edisdev/next-boilerplate/09dad8ca48deee618a6204d4c6e7677ac0aaab9f/public/images/js.jpg -------------------------------------------------------------------------------- /public/mario.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edisdev/next-boilerplate/09dad8ca48deee618a6204d4c6e7677ac0aaab9f/public/mario.ico -------------------------------------------------------------------------------- /site.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'Next Minimal Template', 3 | description: 'Next Template For React', 4 | siteUrl: '', 5 | googleAnalytic: '', 6 | author: { 7 | email: '', 8 | name: '' 9 | }, 10 | lang: 'en' 11 | } 12 | -------------------------------------------------------------------------------- /src/assets/fonts/FiraCode-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edisdev/next-boilerplate/09dad8ca48deee618a6204d4c6e7677ac0aaab9f/src/assets/fonts/FiraCode-Bold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/FiraCode-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edisdev/next-boilerplate/09dad8ca48deee618a6204d4c6e7677ac0aaab9f/src/assets/fonts/FiraCode-Light.ttf -------------------------------------------------------------------------------- /src/assets/fonts/FiraCode-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edisdev/next-boilerplate/09dad8ca48deee618a6204d4c6e7677ac0aaab9f/src/assets/fonts/FiraCode-Medium.ttf -------------------------------------------------------------------------------- /src/assets/fonts/FiraCode-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edisdev/next-boilerplate/09dad8ca48deee618a6204d4c6e7677ac0aaab9f/src/assets/fonts/FiraCode-Regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/FiraCode-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edisdev/next-boilerplate/09dad8ca48deee618a6204d4c6e7677ac0aaab9f/src/assets/fonts/FiraCode-SemiBold.ttf -------------------------------------------------------------------------------- /src/assets/icons/HobbitHome.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | import { config } from '@/utils/icons.js' 5 | 6 | const defaultColors = ['#D99E82', '#662113', '#C1694F', '#FFD983', '#FFAC33'] 7 | 8 | const HobbitHome = (options) => { 9 | const opts = config(options, defaultColors) 10 | let colors = opts.colors 11 | 12 | return 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | } 31 | 32 | HobbitHome.propTypes = { 33 | /** 34 | * Icon width size 35 | */ 36 | width: PropTypes.number, 37 | /** 38 | * Icon height size 39 | */ 40 | height: PropTypes.number, 41 | /** 42 | * Icon colors 43 | */ 44 | colors: PropTypes.array 45 | } 46 | 47 | export default HobbitHome 48 | -------------------------------------------------------------------------------- /src/assets/icons/ShopBag.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | import { config } from '@/utils/icons.js' 5 | 6 | const ShopBag = (options) => { 7 | const opts = config(options, ['#CCD6DD', '#66757F', '#E1E8ED', '#292F33']) 8 | let colors = opts.colors 9 | 10 | return 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | } 23 | 24 | ShopBag.propTypes = { 25 | /** 26 | * Icon width size 27 | */ 28 | width: PropTypes.number, 29 | /** 30 | * Icon height size 31 | */ 32 | height: PropTypes.number, 33 | /** 34 | * Icon colors 35 | */ 36 | colors: PropTypes.array 37 | } 38 | 39 | export default ShopBag 40 | -------------------------------------------------------------------------------- /src/assets/icons/Sunshine.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | import { config } from '@/utils/icons' 5 | 6 | const Sunshine = (options) => { 7 | const opts = config(options, ['#FFD983', '#66757F', '#FFCC4D', '#5B6876']) 8 | let colors = opts.colors 9 | 10 | return 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | } 28 | 29 | Sunshine.propTypes = { 30 | /** 31 | * Icon width size 32 | */ 33 | width: PropTypes.number, 34 | /** 35 | * Icon height size 36 | */ 37 | height: PropTypes.number, 38 | /** 39 | * Icon colors 40 | */ 41 | colors: PropTypes.array 42 | } 43 | 44 | export default Sunshine 45 | -------------------------------------------------------------------------------- /src/assets/icons/index.js: -------------------------------------------------------------------------------- 1 | const req = require.context('@/assets/icons/', true, /\.(js)$/i) 2 | const icons = {} 3 | 4 | export const files = req.keys() 5 | .filter(icon => !icon.match(/index/)) 6 | .map(icon => icon.replace(new RegExp('\./|(.js)', 'g'), '')) 7 | 8 | files.map(f => icons[f] = require(`./${f}.js`).default) 9 | export default icons 10 | -------------------------------------------------------------------------------- /src/assets/stylesheets/app.scss: -------------------------------------------------------------------------------- 1 | // 2 | @import 'normalize-scss'; 3 | @import 'reset.scss'; 4 | 5 | // config 6 | @import 'variables.scss'; 7 | @import 'fonts.scss'; 8 | @import 'utils.scss'; 9 | 10 | // components 11 | @import './components/button.scss'; 12 | @import './components/header.scss'; 13 | @import './components/footer.scss'; 14 | @import './components/image.scss'; 15 | 16 | // globals 17 | @import './global.scss'; 18 | -------------------------------------------------------------------------------- /src/assets/stylesheets/components/button.scss: -------------------------------------------------------------------------------- 1 | .button { 2 | border: 0; 3 | border-radius: 3em; 4 | cursor: pointer; 5 | display: inline-block; 6 | font-weight: 700; 7 | line-height: 1; 8 | 9 | &--primary { 10 | background-color: #1ea7fd; 11 | color: #fff; 12 | } 13 | 14 | &--secondary { 15 | background-color: transparent; 16 | box-shadow: rgba(0, 0, 0, 0.15) 0 0 0 1px inset; 17 | color: #333; 18 | } 19 | 20 | &--small { 21 | font-size: 12px; 22 | padding: 10px 16px; 23 | } 24 | 25 | &--medium { 26 | font-size: 14px; 27 | padding: 11px 20px; 28 | } 29 | 30 | &--large { 31 | font-size: 16px; 32 | padding: 12px 24px; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/assets/stylesheets/components/footer.scss: -------------------------------------------------------------------------------- 1 | .Footer { 2 | align-items: center; 3 | border-top: 1px solid #eaeaea; 4 | display: flex; 5 | height: 100px; 6 | justify-content: center; 7 | width: 100%; 8 | 9 | img { 10 | margin-left: 0.5rem; 11 | } 12 | 13 | a { 14 | align-items: center; 15 | display: flex; 16 | justify-content: center; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/assets/stylesheets/components/header.scss: -------------------------------------------------------------------------------- 1 | .Header { 2 | align-items: center; 3 | border-bottom: 1px solid #9deeee; 4 | display: flex; 5 | justify-content: center; 6 | padding: 20px; 7 | } 8 | -------------------------------------------------------------------------------- /src/assets/stylesheets/components/image.scss: -------------------------------------------------------------------------------- 1 | .Image { 2 | max-height: max-content; 3 | max-width: max-content; 4 | 5 | img { 6 | max-width: 100%; 7 | } 8 | 9 | &_Circle { 10 | img { 11 | border-radius: 100%; 12 | object-fit: cover; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/assets/stylesheets/fonts.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Fira Code'; 3 | font-style: normal; 4 | font-weight: 200; 5 | src: url('../fonts/FiraCode-Light.ttf') format('ttf'); 6 | } 7 | 8 | @font-face { 9 | font-family: 'Fira Code'; 10 | font-style: normal; 11 | font-weight: 400; 12 | src: url('../fonts/FiraCode-Medium.ttf') format('ttf'); 13 | } 14 | 15 | 16 | @font-face { 17 | font-family: 'Fira Code'; 18 | font-style: normal; 19 | font-weight: 500; 20 | src: url('../fonts/FiraCode-Regular.ttf') format('ttf'); 21 | } 22 | 23 | @font-face { 24 | font-family: 'Fira Code'; 25 | font-style: normal; 26 | font-weight: 600; 27 | src: url('../fonts/FiraCode-SemiBold.ttf') format('ttf'); 28 | } 29 | 30 | @font-face { 31 | font-family: 'Fira Code'; 32 | font-style: normal; 33 | font-weight: 900; 34 | src: url('../fonts/FiraCode-Bold.ttf') format('ttf'); 35 | } 36 | 37 | 38 | h1, 39 | h2, 40 | h3, 41 | h4, 42 | h5, 43 | h6, 44 | .h1, 45 | .h2, 46 | .h3, 47 | .h4, 48 | .h5, 49 | .h6 { 50 | font-weight: $font-wt-normal; 51 | line-height: 1.2; 52 | margin: 0 0 15px; 53 | } 54 | 55 | strong, 56 | b {font-weight: $font-wt-medium;} 57 | -------------------------------------------------------------------------------- /src/assets/stylesheets/global.scss: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 10px; 3 | } 4 | 5 | body { 6 | font-family: 'Fira Code'; 7 | font-size: $font-size; 8 | margin: 0; 9 | padding: 0; 10 | } 11 | 12 | .container { 13 | align-items: center; 14 | display: flex; 15 | flex-direction: column; 16 | justify-content: center; 17 | min-height: 100vh; 18 | padding: 0 0.5rem; 19 | } 20 | 21 | .main { 22 | align-items: center; 23 | display: flex; 24 | flex: 1; 25 | flex-direction: column; 26 | justify-content: center; 27 | padding: 5rem; 28 | } 29 | 30 | .code { 31 | background: #fafafa; 32 | border-radius: 5px; 33 | font-size: 1.1rem; 34 | padding: 0.75rem; 35 | } 36 | 37 | .grid { 38 | align-items: center; 39 | display: flex; 40 | flex-wrap: wrap; 41 | justify-content: center; 42 | margin-top: 3rem; 43 | max-width: 800px; 44 | } 45 | -------------------------------------------------------------------------------- /src/assets/stylesheets/modules/colors.module.scss: -------------------------------------------------------------------------------- 1 | $app: #111; 2 | $gray: #f0f1efee; 3 | $orange: rgb(255, 208, 0); 4 | 5 | :export { 6 | app: $app; 7 | gray: $gray; 8 | orange: $orange; 9 | } 10 | -------------------------------------------------------------------------------- /src/assets/stylesheets/modules/fonts.module.scss: -------------------------------------------------------------------------------- 1 | $font-size: 14px; 2 | $font-size-xs: 1.2em; 3 | $font-size-sm: 1.4em; 4 | $font-size-lg: 1.6em; 5 | $font-size-xl: 1.8em; 6 | $font-size-xxl: 2em; 7 | $font-size-xxxl: 2.4em; 8 | $font-wt-thin: 200; 9 | $font-wt-normal: 400; 10 | $font-wt-medium: 500; 11 | $font-wt-semi: 500; 12 | $font-wt-bold: 900; 13 | 14 | :export { 15 | font-size: $font-size; 16 | font-size-lg: $font-size-lg; 17 | font-size-sm: $font-size-sm; 18 | font-size-xl: $font-size-xl; 19 | font-size-xs: $font-size-xs; 20 | font-size-xxl: $font-size-xxl; 21 | font-size-xxxl: $font-size-xxxl; 22 | font-wt-bold: $font-wt-bold; 23 | font-wt-medium: $font-wt-medium; 24 | font-wt-normal: $font-wt-normal; 25 | font-wt-semi: $font-wt-semi; 26 | font-wt-thin: $font-wt-thin; 27 | } 28 | -------------------------------------------------------------------------------- /src/assets/stylesheets/modules/sizes.module.scss: -------------------------------------------------------------------------------- 1 | //border 2 | $border-radius: 6px; 3 | $border-radius-sm: 3px; 4 | 5 | // grid 6 | $padding: 20px; 7 | 8 | :export { 9 | border-radius: $border-radius; 10 | border-radius-sm: $border-radius-sm; 11 | padding: $padding; 12 | } 13 | -------------------------------------------------------------------------------- /src/assets/stylesheets/pages/home.module.scss: -------------------------------------------------------------------------------- 1 | // this file is creating create-next-app 2 | 3 | .section { 4 | align-items: center; 5 | display: flex; 6 | flex-direction: column; 7 | padding: 20px; 8 | width: 100%; 9 | } 10 | 11 | .section h1 { 12 | margin-bottom: 30px; 13 | } 14 | 15 | .card { 16 | border: 1px solid #eaeaea; 17 | border-radius: 10px; 18 | color: inherit; 19 | flex-basis: 45%; 20 | margin: 1rem; 21 | padding: 1.5rem; 22 | text-align: left; 23 | text-decoration: none; 24 | transition: color 0.15s ease, border-color 0.15s ease; 25 | } 26 | 27 | .card:hover, 28 | .card:focus, 29 | .card:active { 30 | border-color: #0070f3; 31 | color: #0070f3; 32 | } 33 | 34 | .card h3 { 35 | font-size: 1.5rem; 36 | margin: 0 0 1rem; 37 | } 38 | 39 | .card p { 40 | font-size: 1.25rem; 41 | line-height: 1.5; 42 | margin: 0; 43 | } 44 | 45 | .logo { 46 | height: 1em; 47 | } 48 | 49 | .title a { 50 | color: #0070f3; 51 | text-decoration: none; 52 | } 53 | 54 | .title a:hover, 55 | .title a:focus, 56 | .title a:active { 57 | text-decoration: underline; 58 | } 59 | 60 | .title { 61 | font-size: 4rem; 62 | line-height: 1.15; 63 | margin: 0; 64 | } 65 | 66 | .title, 67 | .description { 68 | text-align: center; 69 | } 70 | 71 | .description { 72 | font-size: 1.5rem; 73 | line-height: 1.5; 74 | } 75 | 76 | @media (max-width: 600px) { 77 | .grid { 78 | flex-direction: column; 79 | width: 100%; 80 | } 81 | } 82 | // custom 83 | .Buttons { 84 | height: max-content; 85 | padding: 10vh; 86 | } 87 | 88 | .ImageArea { 89 | max-height: 400px; 90 | width: 100%; 91 | } 92 | -------------------------------------------------------------------------------- /src/assets/stylesheets/reset.scss: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, 7 | body, 8 | div, 9 | span, 10 | applet, 11 | object, 12 | iframe, 13 | h1, 14 | h2, 15 | h3, 16 | h4, 17 | h5, 18 | h6, 19 | p, 20 | blockquote, 21 | pre, 22 | a, 23 | abbr, 24 | acronym, 25 | address, 26 | big, 27 | cite, 28 | code, 29 | del, 30 | dfn, 31 | em, 32 | img, 33 | ins, 34 | kbd, 35 | q, 36 | s, 37 | samp, 38 | small, 39 | strike, 40 | strong, 41 | sub, 42 | sup, 43 | tt, 44 | var, 45 | b, 46 | u, 47 | i, 48 | center, 49 | dl, 50 | dt, 51 | dd, 52 | ol, 53 | ul, 54 | li, 55 | fieldset, 56 | form, 57 | label, 58 | legend, 59 | table, 60 | caption, 61 | tbody, 62 | tfoot, 63 | thead, 64 | tr, 65 | th, 66 | td, 67 | article, 68 | aside, 69 | canvas, 70 | details, 71 | embed, 72 | figure, 73 | figcaption, 74 | footer, 75 | header, 76 | hgroup, 77 | menu, 78 | nav, 79 | output, 80 | ruby, 81 | section, 82 | summary, 83 | time, 84 | mark, 85 | audio, 86 | video { 87 | border: 0; 88 | font: inherit; 89 | font-size: 100%; 90 | margin: 0; 91 | padding: 0; 92 | vertical-align: baseline; 93 | } 94 | 95 | /* HTML5 display-role reset for older browsers */ 96 | 97 | article, 98 | aside, 99 | details, 100 | figcaption, 101 | figure, 102 | footer, 103 | header, 104 | hgroup, 105 | menu, 106 | nav, 107 | section { 108 | display: block; 109 | } 110 | 111 | body { 112 | line-height: 1; 113 | } 114 | 115 | ol, 116 | ul { 117 | list-style: none; 118 | } 119 | 120 | blockquote, 121 | q { 122 | quotes: none; 123 | } 124 | 125 | blockquote { 126 | &::before, 127 | &::after { 128 | content: ''; 129 | } 130 | } 131 | 132 | q { 133 | &::before, 134 | &::after { 135 | content: ''; 136 | } 137 | } 138 | 139 | table { 140 | border-collapse: collapse; 141 | border-spacing: 0; 142 | } 143 | -------------------------------------------------------------------------------- /src/assets/stylesheets/utils.scss: -------------------------------------------------------------------------------- 1 | .flex { 2 | display: flex !important; 3 | 4 | &-inline {display: inline-flex !important;} 5 | 6 | &-top {margin-bottom: auto;} 7 | &-left {margin-right: auto;} 8 | &-bottom {margin-top: auto;} 9 | &-right {margin-left: auto;} 10 | 11 | &-align { 12 | &-start {align-items: start;} 13 | &-center {align-items: center;} 14 | &-end {align-items: flex-end;} 15 | &-stretch {align-items: stretch !important;} 16 | &-baseline { align-items: baseline; } 17 | } 18 | 19 | &-align-self { 20 | &-start {align-self: start;} 21 | &-center {align-self: center;} 22 | &-end {align-self: flex-end;} 23 | &-stretch {align-self: stretch !important;} 24 | &-baseline { align-self: baseline; } 25 | } 26 | 27 | &-justify { 28 | &-start {justify-content: start !important;} 29 | &-center {justify-content: center !important;} 30 | &-end {justify-content: flex-end !important;} 31 | &-stretch {justify-content: stretch !important;} 32 | &-space-between {justify-content: space-between !important;} 33 | } 34 | 35 | &-dir { 36 | &-col { flex-direction: column; } 37 | &-row { flex-direction: row; } 38 | } 39 | 40 | &-primary {flex: 1;} 41 | &-nowrap {flex-wrap: nowrap !important;} 42 | } 43 | 44 | .d { 45 | &-block {display: block !important;} 46 | &-inline-block {display: inline-block !important;} 47 | &-grid {display: grid !important;} 48 | } 49 | 50 | .nowrap {white-space: nowrap !important;} 51 | .textWrap {white-space: normal !important;} 52 | 53 | .text { 54 | &-right {text-align: right !important;} 55 | &-center {text-align: center !important;} 56 | &-left {text-align: left !important;} 57 | 58 | &-underline { 59 | text-decoration: underline !important; 60 | 61 | &-hover { 62 | &:hover {text-decoration: underline !important;} 63 | 64 | &-none { 65 | &:hover {text-decoration: none !important;} 66 | } 67 | } 68 | &-none {text-decoration: none !important;} 69 | } 70 | 71 | &-linethrough { 72 | text-decoration: line-through; 73 | } 74 | } 75 | 76 | .font { 77 | &-xxl {font-size: $font-size-xxl;} 78 | &-xl {font-size: $font-size-xl;} 79 | &-lg {font-size: $font-size-lg;} 80 | &-sm {font-size: $font-size-sm;} 81 | &-xs {font-size: $font-size-xs;} 82 | &-thin {font-weight: $font-wt-thin !important;} 83 | &-normal {font-weight: $font-wt-normal !important;} 84 | &-medium {font-weight: $font-wt-medium !important;} 85 | &-semi {font-weight: $font-wt-semi !important;} 86 | &-bold {font-weight: $font-wt-bold !important;} 87 | &-italic {font-style: italic !important;} 88 | @for $i from 10 through 20 { 89 | &-#{$i} {font-size: #{$i}px;} 90 | } 91 | } 92 | 93 | .m { 94 | @each $val in (0, 2, 5, 10, 15, 20, 25, 30) { 95 | &-#{$val} {margin: #{$val}px !important;} 96 | 97 | &-h-#{$val} { 98 | margin-left: #{$val}px !important; 99 | margin-right: #{$val}px !important; 100 | } 101 | &-v-#{$val} { 102 | margin-bottom: #{$val}px !important; 103 | margin-top: #{$val}px !important; 104 | } 105 | 106 | @each $dir in (top, left, bottom, right) { 107 | &-#{$dir} { 108 | &-#{$val} { 109 | margin-#{$dir}: #{$val}px !important; 110 | } 111 | } 112 | } 113 | } 114 | } 115 | 116 | .p { 117 | @each $val in (0, 2, 5, 10, 15, 20, 25, 30) { 118 | &-#{$val} {padding: #{$val}px !important;} 119 | 120 | &-h-#{$val} { 121 | padding-left: #{$val}px !important; 122 | padding-right: #{$val}px !important; 123 | } 124 | &-v-#{$val} { 125 | padding-bottom: #{$val}px !important; 126 | padding-top: #{$val}px !important; 127 | } 128 | 129 | @each $dir in (top, left, bottom, right) { 130 | &-#{$dir} { 131 | &-#{$val} { 132 | padding-#{$dir}: #{$val}px !important; 133 | } 134 | } 135 | } 136 | } 137 | } 138 | 139 | .b { 140 | &-all {border: 1px solid currentColor !important;} 141 | 142 | @each $dir in (top, left, bottom, right) { 143 | &-#{$dir} { 144 | border-#{$dir}: 1px solid currentColor !important; 145 | 146 | &-none {border-#{$dir}: none !important;} 147 | } 148 | } 149 | 150 | &-none {border: none !important;} 151 | 152 | &-radius { 153 | border-radius: $border-radius !important; 154 | 155 | &-sm {border-radius: $border-radius-sm !important;} 156 | 157 | &-no { 158 | border-radius: 0 !important; 159 | } 160 | } 161 | } 162 | 163 | 164 | .full { 165 | width: 100%; 166 | } 167 | 168 | .max-content { 169 | &-width { 170 | width: max-content; 171 | } 172 | 173 | &-height { 174 | height: max-content; 175 | } 176 | } 177 | 178 | .no-text-select { 179 | -webkit-touch-callout: none; /* iOS Safari */ 180 | user-select: none; /* Safari */ 181 | user-select: none; /* Konqueror HTML */ 182 | user-select: none; /* Firefox */ 183 | user-select: none; /* Internet Explorer/Edge */ 184 | user-select: none; 185 | } 186 | -------------------------------------------------------------------------------- /src/assets/stylesheets/variables.scss: -------------------------------------------------------------------------------- 1 | // colors 2 | @import './modules/colors.module.scss'; 3 | // fonts 4 | @import './modules/fonts.module.scss'; 5 | //sizes 6 | @import './modules/sizes.module.scss'; 7 | -------------------------------------------------------------------------------- /src/components/Button/index.js: -------------------------------------------------------------------------------- 1 | 2 | import React from 'react' 3 | 4 | import PropTypes from 'prop-types' 5 | /** 6 | * 7 | * Primary UI component for user interaction 8 | */ 9 | 10 | const Button = ({ primary, backgroundColor, size, children, ...props }) => { 11 | const mode = primary ? 'button--primary' : 'button--secondary' 12 | let customClass = props.className || '' 13 | delete props.className 14 | 15 | return ( 16 | 24 | ) 25 | } 26 | 27 | Button.propTypes = { 28 | /** 29 | * Is this the principal call to action on the page? 30 | */ 31 | primary: PropTypes.bool, 32 | /** 33 | * What background color to use 34 | */ 35 | backgroundColor: PropTypes.string, 36 | /** 37 | * How large should the button be? 38 | */ 39 | size: PropTypes.oneOf(['small', 'medium', 'large']), 40 | /** 41 | * Button contents 42 | */ 43 | /** 44 | * Optional click handler 45 | */ 46 | onClick: PropTypes.func, 47 | } 48 | 49 | Button.defaultProps = { 50 | backgroundColor: null, 51 | primary: false, 52 | size: 'medium', 53 | onClick: undefined, 54 | } 55 | 56 | 57 | export default Button 58 | -------------------------------------------------------------------------------- /src/components/Button/stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Button from './index' 3 | 4 | export default { 5 | title: 'Example/Button', 6 | component: Button, 7 | argTypes: { 8 | backgroundColor: { control: 'color' }, 9 | }, 10 | } 11 | 12 | const Template = (args) =>