diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4b48d59 --- /dev/null +++ b/.gitignore @@ -0,0 +1,112 @@ +# MACBOOK Default File +.DS_Store + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# others +node_modules +yarn.lock +   \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..138f45f --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,10 @@ +{ + "printWidth": 100, + "tabWidth": 2, + "singleQuote": true, + "trailingComma": "all", + "bracketSpacing": true, + "semi": false, + "useTabs": false, + "endOfLine": "lf" +} diff --git a/1-Colors/index.html b/1-Colors/index.html new file mode 100644 index 0000000..1022c2c --- /dev/null +++ b/1-Colors/index.html @@ -0,0 +1,19 @@ + + + + + + + Random Color Change + + + + + + +
+ + + + + \ No newline at end of file diff --git a/1-Colors/src/css/style.css b/1-Colors/src/css/style.css new file mode 100644 index 0000000..97f38c1 --- /dev/null +++ b/1-Colors/src/css/style.css @@ -0,0 +1,29 @@ +html, +body { + width: 100%; + height: 100vh; + overflow: hidden; +} + +#app { + width: 100%; + height: 100vh; + display: flex; + justify-content: center; + align-items: center; +} + +.color-btn { + background-color: transparent; + border: 3.5px solid; + border-radius: 8px; + color: gray; + outline: none; + width: 80px; + height: 30px; + font-size: 15px; +} + +.color-btn:hover { + background-color: #e6e6e6; +} diff --git a/1-Colors/src/js/App.js b/1-Colors/src/js/App.js new file mode 100644 index 0000000..78f8dcb --- /dev/null +++ b/1-Colors/src/js/App.js @@ -0,0 +1,17 @@ +export default function App({ $target }) { + const $background = document.getElementById('app') + const $button = document.createElement('button') + $button.className = 'color-btn' + $button.innerText = 'Click me' + $target.appendChild($button) + + $button.addEventListener('click', () => { + onColorChange() + }) + + function onColorChange() { + const colors = ['#FC5C7D', '#6A82FB', '#38ef7d', '#fffbd5', 'eee8aa', '#ffdab9', '#fffaf0'] + let num = Math.floor(Math.random() * colors.length) + $background.style.backgroundColor = colors[num] + } +} diff --git a/1-Colors/src/main.js b/1-Colors/src/main.js new file mode 100644 index 0000000..7c7b3a8 --- /dev/null +++ b/1-Colors/src/main.js @@ -0,0 +1,7 @@ +import App from './js/App.js' + +const $app = document.querySelector('#app') + +new App({ + $target: $app, +}) diff --git a/2-Hex_Color/index.html b/2-Hex_Color/index.html new file mode 100644 index 0000000..9df0995 --- /dev/null +++ b/2-Hex_Color/index.html @@ -0,0 +1,20 @@ + + + + + + + Hex Colors gradient + + + + + + +
+ + + + + + diff --git a/2-Hex_Color/src/css/reset.css b/2-Hex_Color/src/css/reset.css new file mode 100644 index 0000000..5bca465 --- /dev/null +++ b/2-Hex_Color/src/css/reset.css @@ -0,0 +1,129 @@ +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +input:focus { + outline: none; +} +a { + color: inherit; + text-decoration: none; +} diff --git a/2-Hex_Color/src/css/style.css b/2-Hex_Color/src/css/style.css new file mode 100644 index 0000000..7f515a4 --- /dev/null +++ b/2-Hex_Color/src/css/style.css @@ -0,0 +1,75 @@ +@import 'reset.css'; + +:root { + --left: white; + --right: white; + --font: black; + --direction: to left; +} + +html, +body { + width: 100%; + height: 100vh; + overflow: hidden; +} + +#app { + width: 100%; + height: 100vh; + display: flex; + justify-content: center; + align-items: center; + background: linear-gradient(var(--direction), var(--left), var(--right)); + -webkit-animation: colorchange 8s linear infinite alternate; +} + +@-webkit-keyframes colorchange { + 0% { + color: white; + } + 30% { + color: gray; + } + 60% { + color: darkgray; + } + 100% { + color: black; + } +} + +.description { + width: 900px; + font-size: 45px; + font-weight: bold; + margin-left: 3%; +} + +.subDescription { + width: 800px; + font-size: 45px; + font-weight: bold; + margin-left: 7.5%; +} + +.gradient { + width: 900px; + font-size: 35px; + font-weight: bold; + margin: 7% 0% 0% 7%; +} + +.color_btn { + margin: 3% 0% 0% 43%; + width: 90px; + height: 50px; + font-weight: bold; + background: transparent; + border: 4px solid black; + border-radius: 4px; +} + +.color_btn:hover { + background-color: var(--left); +} diff --git a/2-Hex_Color/src/js/App.js b/2-Hex_Color/src/js/App.js new file mode 100644 index 0000000..e2f0623 --- /dev/null +++ b/2-Hex_Color/src/js/App.js @@ -0,0 +1,62 @@ +import { leftOption, rightOption, directOption } from '../utils/Constant.js' +import Background from './Background.js' +import Description from './Description.js' + +export default function App({ $target }) { + this.state = { + left: 'white', + right: 'white', + direction: 'to right', + } + + const { left, right, direction } = this.state + + const description = new Description({ + $target, + initialState: { + left, + right, + direction, + }, + onChangeColor: () => { + const colorRandomNum = Math.floor(Math.random() * leftOption.length) + const direcRandomNum = Math.floor(Math.random() * directOption.length) + + const selectedLeft = leftOption[colorRandomNum] + const selectedRight = rightOption[colorRandomNum] + const selectedDirection = directOption[direcRandomNum] + + this.setState({ + left: selectedLeft, + right: selectedRight, + direction: selectedDirection, + }) + }, + }) + + const background = new Background({ + $target, + initialState: { + left, + right, + direction, + }, + }) + + this.setState = (nextState) => { + this.state = nextState + + const { left, right, direction } = this.state + description.setState({ + left, + right, + direction, + }) + + background.setState({ + left, + right, + direction, + }) + } +} diff --git a/2-Hex_Color/src/js/Background.js b/2-Hex_Color/src/js/Background.js new file mode 100644 index 0000000..0dc603b --- /dev/null +++ b/2-Hex_Color/src/js/Background.js @@ -0,0 +1,16 @@ +import { $setProperty } from '../utils/document.js' + +export default function Background({ $target, initialState }) { + this.state = initialState + + this.setState = (nextState) => { + this.state = nextState + this.render() + } + + this.render = () => { + $setProperty($target, '--left', this.state.left) + $setProperty($target, '--right', this.state.right) + $setProperty($target, '--direction', this.state.direction) + } +} diff --git a/2-Hex_Color/src/js/Description.js b/2-Hex_Color/src/js/Description.js new file mode 100644 index 0000000..16773af --- /dev/null +++ b/2-Hex_Color/src/js/Description.js @@ -0,0 +1,32 @@ +export default function Description({ $target, initialState, onChangeColor }) { + const $itemDiv = document.createElement('div') + $target.appendChild($itemDiv) + + this.state = initialState + + this.setState = (nextState) => { + this.state = nextState + this.render() + } + + this.render = () => { + const { left, right, direction } = this.state + + $itemDiv.innerHTML = ` +

CLICK THE BUTTON BELLOW TO GENERATE

+

A RANDOM HEX COLOR COMBINATION

+

background liner-gradient(${direction}, ${left}, ${right})

+ + ` + } + + this.render() + + $itemDiv.addEventListener('click', (e) => { + const { className } = e.target + + if (className === 'color_btn') { + onChangeColor() + } + }) +} diff --git a/2-Hex_Color/src/main.js b/2-Hex_Color/src/main.js new file mode 100644 index 0000000..7c7b3a8 --- /dev/null +++ b/2-Hex_Color/src/main.js @@ -0,0 +1,7 @@ +import App from './js/App.js' + +const $app = document.querySelector('#app') + +new App({ + $target: $app, +}) diff --git a/2-Hex_Color/src/utils/Constant.js b/2-Hex_Color/src/utils/Constant.js new file mode 100644 index 0000000..ce99761 --- /dev/null +++ b/2-Hex_Color/src/utils/Constant.js @@ -0,0 +1,29 @@ +export const leftOption = [ + '#2193b0', + '#bdc3c7', + '#12c2e9', + '#1f4037', + '#8360c3', + '#E94057', + '#007991', +] +export const rightOption = [ + '#6dd5ed', + '#2c3e50', + '#f64f59', + '#99f2c8', + '#2ebf91', + '#F27121', + '#78ffd6', +] +export const directOption = [ + 'to right', + 'to left', + 'to top', + 'to bottom', + '45deg', + '90deg', + '75deg', + '15deg', + '60deg', +] diff --git a/2-Hex_Color/src/utils/document.js b/2-Hex_Color/src/utils/document.js new file mode 100644 index 0000000..c0c2ded --- /dev/null +++ b/2-Hex_Color/src/utils/document.js @@ -0,0 +1,2 @@ +export const $setProperty = ($target, startPoint, color) => + $target.style.setProperty(startPoint, color) diff --git a/3-Quote/index.html b/3-Quote/index.html new file mode 100644 index 0000000..d447afc --- /dev/null +++ b/3-Quote/index.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + +
+
+

+

+
+ +
+ + + + + + diff --git a/3-Quote/src/css/reset.css b/3-Quote/src/css/reset.css new file mode 100644 index 0000000..5bca465 --- /dev/null +++ b/3-Quote/src/css/reset.css @@ -0,0 +1,129 @@ +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +input:focus { + outline: none; +} +a { + color: inherit; + text-decoration: none; +} diff --git a/3-Quote/src/css/style.css b/3-Quote/src/css/style.css new file mode 100644 index 0000000..579767e --- /dev/null +++ b/3-Quote/src/css/style.css @@ -0,0 +1,59 @@ +@import 'reset.css'; + +html, +body { + width: 100%; + height: 100vh; + overflow: hidden; +} + +.app { + width: 100%; + height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + background: linear-gradient(to right, #5d52a2, #3683b0, #5d52a2); +} + +.quote_wrapper { + width: 60%; + height: 42%; + display: flex; + flex-direction: column; + align-items: center; + border: 10px solid #06bdc1; + border-radius: 4px; + background-color: #f4edea; +} + +.quote_text { + width: 750px; + margin-top: 12%; + margin-left: 5%; + font-size: 26px; + line-height: 150%; + text-align: center; +} + +.quote_author { + margin-top: 5%; + font-size: 25px; +} + +button { + width: 140px; + height: 40px; + font-size: 16px; + margin-top: 3%; + color: white; + border: none; + border-radius: 4px; + background-color: #17a2b8; + outline: none; +} + +button:hover { + background-color: #138799; +} diff --git a/3-Quote/src/js/App.js b/3-Quote/src/js/App.js new file mode 100644 index 0000000..ea1852c --- /dev/null +++ b/3-Quote/src/js/App.js @@ -0,0 +1,15 @@ +import { request } from '../service/api.js' + +export default function App({ $target }) { + const $app = document.querySelector('.app') + const $text = document.querySelector('.quote_text') + const $author = document.querySelector('.quote_author') + const $button = document.querySelector('button') + + $button.addEventListener('click', async (e) => { + const { quote, author } = await request() + $text.innerText = '"' + quote + '"' + + $author.innerText = author ? '- ' + author : 'anonymous' + }) +} diff --git a/3-Quote/src/main.js b/3-Quote/src/main.js new file mode 100644 index 0000000..7c7b3a8 --- /dev/null +++ b/3-Quote/src/main.js @@ -0,0 +1,7 @@ +import App from './js/App.js' + +const $app = document.querySelector('#app') + +new App({ + $target: $app, +}) diff --git a/3-Quote/src/service/api.js b/3-Quote/src/service/api.js new file mode 100644 index 0000000..833839a --- /dev/null +++ b/3-Quote/src/service/api.js @@ -0,0 +1,13 @@ +export const request = async () => { + try { + const res = await fetch('https://free-quotes-api.herokuapp.com/') + + if (!res.ok) { + throw new Error('Fail to fetch API data') + } + + return await res.json() + } catch (e) { + alert(e.message) + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2c3a1b3 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "scripts": { + "start": "node main.js", + "lint": "eslint *.js", + "lint:fix": "eslint --fix *.js" + }, + "devDependencies": { + "eslint": "^7.32.0", + "eslint-config-airbnb-base": "^14.2.1", + "eslint-config-google": "^0.14.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-import": "^2.24.0", + "eslint-plugin-prettier": "^3.4.0", + "prettier": "^2.3.2" + } +}