From 035505032063da9dbe518992f3a5e61a83bcfdbc Mon Sep 17 00:00:00 2001 From: kimjanghu Date: Tue, 6 Jul 2021 21:34:50 +0900 Subject: [PATCH 01/14] =?UTF-8?q?feat:=20=EC=B4=88=EA=B8=B0=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 13 + .gitignore | 125 ++++++++ .prettierrc.js | 8 + index.html | 70 +++-- package.json | 25 ++ yarn.lock | 789 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 994 insertions(+), 36 deletions(-) create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 .prettierrc.js create mode 100644 package.json create mode 100644 yarn.lock diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..e9504fc6 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,13 @@ +module.exports = { + env: { + browser: true, + node: true, + es2021: true, + }, + plugins: ["prettier"], + extends: ["eslint:recommended", "plugin:prettier/recommended"], + parserOptions: { + ecmaVersion: 2021, + sourceType: "module", + }, +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..922166da --- /dev/null +++ b/.gitignore @@ -0,0 +1,125 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/node +# Edit at https://www.toptal.com/developers/gitignore?templates=node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-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/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# 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 +.env.production + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# 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 + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# End of https://www.toptal.com/developers/gitignore/api/node \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 00000000..6dd16f22 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,8 @@ +module.exports = { + singleQuote: true, + semi: true, + useTabs: false, + tabWidth: 2, + trailingComma: 'all', + printWidth: 120, +}; \ No newline at end of file diff --git a/index.html b/index.html index 13a02fdb..507e1b41 100644 --- a/index.html +++ b/index.html @@ -1,38 +1,36 @@ - - - - 이벤트 - TODOS - - - -
-

TODOS

- -
- -
    -
    - 0 - -
    -
    -
    - - + + + + + 이벤트 - TODOS + + + + +
    +

    TODOS

    + +
    + +
      +
      + 0 + +
      +
      +
      + + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..b265afa0 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "js-todo-list-step1", + "version": "1.0.0", + "description": "

      JS 투두리스트 스텝1

      자바스크립트로 구현 하는 투두리스트

      \"template

      ", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/kimjanghu/js-todo-list-step1.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/kimjanghu/js-todo-list-step1/issues" + }, + "homepage": "https://github.com/kimjanghu/js-todo-list-step1#readme", + "devDependencies": { + "eslint": "^7.30.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^3.4.0", + "prettier": "^2.3.2" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..ca72cfea --- /dev/null +++ b/yarn.lock @@ -0,0 +1,789 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/helper-validator-identifier@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" + integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== + +"@babel/highlight@^7.10.4": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" + integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@eslint/eslintrc@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179" + integrity sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" + integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + +acorn-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.6.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.1.tgz#ae65764bf1edde8cd861281cda5057852364a295" + integrity sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@^4.0.1, debug@^4.1.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-prettier@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" + integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== + +eslint-plugin-prettier@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz#cdbad3bf1dbd2b177e9825737fe63b476a08f0c7" + integrity sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint@^7.30.0: + version "7.30.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.30.0.tgz#6d34ab51aaa56112fd97166226c9a97f505474f8" + integrity sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.2" + "@humanwhocodes/config-array" "^0.5.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.1.2" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.0.tgz#da07fb8808050aba6fdeac2294542e5043583f05" + integrity sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.6.0, globals@^13.9.0: + version "13.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" + integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== + dependencies: + type-fest "^0.20.2" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" + integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +semver@^7.2.1: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +table@^6.0.9: + version "6.7.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" + integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== + dependencies: + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.0" + strip-ansi "^6.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== From 3fda74ccf7b0e3c58d57796177dc2c5ef8e8ecb4 Mon Sep 17 00:00:00 2001 From: kimjanghu Date: Tue, 6 Jul 2021 22:51:15 +0900 Subject: [PATCH 02/14] =?UTF-8?q?feat:=20entry=20point=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 3 ++- src/App.js | 5 +++++ src/index.js | 4 ++++ src/utils/utils.js | 4 ++++ 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/App.js create mode 100644 src/index.js create mode 100644 src/utils/utils.js diff --git a/index.html b/index.html index 507e1b41..88319e22 100644 --- a/index.html +++ b/index.html @@ -6,10 +6,11 @@ 이벤트 - TODOS + -
      +

      TODOS

      diff --git a/src/App.js b/src/App.js new file mode 100644 index 00000000..bd80931d --- /dev/null +++ b/src/App.js @@ -0,0 +1,5 @@ +export default class App { + constructor($target) { + console.log($target); + } +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..d3b567cd --- /dev/null +++ b/src/index.js @@ -0,0 +1,4 @@ +import App from './App.js'; +import { $ } from './utils/utils.js'; + +document.addEventListener('DOMContentLoaded', () => new App($('#app'))); diff --git a/src/utils/utils.js b/src/utils/utils.js new file mode 100644 index 00000000..79ec734d --- /dev/null +++ b/src/utils/utils.js @@ -0,0 +1,4 @@ +const $ = (selector) => document.querySelector(selector); +const $$ = (selector) => document.querySelectorAll(selector); + +export { $, $$ }; From 0fb7a7944ceddd62153601b57a521e613351a6e1 Mon Sep 17 00:00:00 2001 From: janghu Date: Wed, 7 Jul 2021 11:40:14 +0900 Subject: [PATCH 03/14] =?UTF-8?q?feat:=20core=20component=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/Component.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/core/Component.js diff --git a/src/core/Component.js b/src/core/Component.js new file mode 100644 index 00000000..979cc8c5 --- /dev/null +++ b/src/core/Component.js @@ -0,0 +1,16 @@ +export default class Component { + $target; + props; + + constructor($target, props) { + this.$target = $target; + this.props = props; + this.setState(); + this.render(); + this.bindEvents(); + } + + setState() {} + render() {} + bindEvents() {} +} From 7c73ad44e68db5dcb638522aa233cb833bbc3aaa Mon Sep 17 00:00:00 2001 From: janghu Date: Wed, 7 Jul 2021 11:40:25 +0900 Subject: [PATCH 04/14] =?UTF-8?q?feat:=20core=20state=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/State.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/core/State.js diff --git a/src/core/State.js b/src/core/State.js new file mode 100644 index 00000000..e589da1b --- /dev/null +++ b/src/core/State.js @@ -0,0 +1,13 @@ +export default class State { + constructor(state) { + this.state = state; + } + + get() { + return this.state; + } + + set(newState) { + this.state = newState; + } +} From 5da65a2242d0ecc76f41cbe79dd3cd500749f318 Mon Sep 17 00:00:00 2001 From: janghu Date: Wed, 7 Jul 2021 12:04:45 +0900 Subject: [PATCH 05/14] =?UTF-8?q?feat:=20todo=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 26 +++++++++++++++++++++++--- src/components/NewTodoInput.js | 20 ++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 src/components/NewTodoInput.js diff --git a/src/App.js b/src/App.js index bd80931d..20567bea 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,25 @@ -export default class App { - constructor($target) { - console.log($target); +import NewTodoInput from './components/NewTodoInput.js'; +import Component from './core/component.js'; +import State from './core/State.js'; +import { $ } from './utils/utils.js'; + +export default class App extends Component { + setState() { + this.todoList = new State([]); + } + + render() { + this.mountChildren(); + } + + mountChildren() { + new NewTodoInput($('#new-todo-title'), { + todoList: this.todoList, + onSubmitTodo: this.onSubmitTodo, + }); + } + + onSubmitTodo() { + console.log(this.todoList); } } diff --git a/src/components/NewTodoInput.js b/src/components/NewTodoInput.js new file mode 100644 index 00000000..9dca063d --- /dev/null +++ b/src/components/NewTodoInput.js @@ -0,0 +1,20 @@ +import Component from '../core/component.js'; + +export default class NewTodoInput extends Component { + render() {} + + bindEvents() { + this.$target.addEventListener('keyup', ({ key }) => { + if (key !== 'Enter') return; + this.addTodo(this.$target.value); + this.$target.value = ''; + this.props.onSubmitTodo(); + }); + } + + addTodo(todo) { + const todoList = this.props.todoList.get(); + todoList.push(todo); + this.props.todoList.set(todoList); + } +} From 1f04215780b1341c3aa8b540598cbe397f0bd664 Mon Sep 17 00:00:00 2001 From: janghu Date: Wed, 7 Jul 2021 15:19:33 +0900 Subject: [PATCH 06/14] =?UTF-8?q?feat:=20todo=20data=20=ED=98=95=EC=8B=9D?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/NewTodoInput.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/NewTodoInput.js b/src/components/NewTodoInput.js index 9dca063d..908ddb45 100644 --- a/src/components/NewTodoInput.js +++ b/src/components/NewTodoInput.js @@ -1,8 +1,6 @@ import Component from '../core/component.js'; export default class NewTodoInput extends Component { - render() {} - bindEvents() { this.$target.addEventListener('keyup', ({ key }) => { if (key !== 'Enter') return; @@ -14,7 +12,11 @@ export default class NewTodoInput extends Component { addTodo(todo) { const todoList = this.props.todoList.get(); - todoList.push(todo); + todoList.push({ + id: Date.now(), + todo, + checked: false, + }); this.props.todoList.set(todoList); } } From 86965d717480b147637ffb395db7ba3b69d2c17c Mon Sep 17 00:00:00 2001 From: janghu Date: Wed, 7 Jul 2021 17:19:13 +0900 Subject: [PATCH 07/14] =?UTF-8?q?feat:=20WIP=20todoList=20checkbox=20?= =?UTF-8?q?=EC=A7=84=ED=96=89=EC=A4=91..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 14 ++++++++++--- src/components/TodoList.js | 42 ++++++++++++++++++++++++++++++++++++++ src/utils/constants.js | 10 +++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 src/components/TodoList.js create mode 100644 src/utils/constants.js diff --git a/src/App.js b/src/App.js index 20567bea..1e87bf6c 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,5 @@ import NewTodoInput from './components/NewTodoInput.js'; +import TodoList from './components/TodoList.js'; import Component from './core/component.js'; import State from './core/State.js'; import { $ } from './utils/utils.js'; @@ -15,11 +16,18 @@ export default class App extends Component { mountChildren() { new NewTodoInput($('#new-todo-title'), { todoList: this.todoList, - onSubmitTodo: this.onSubmitTodo, + onSubmitTodo: this.mountTodoList.bind(this), }); } - onSubmitTodo() { - console.log(this.todoList); + mountTodoList() { + new TodoList($('#todo-list'), { + todoList: this.todoList, + deleteTodo: this.deleteTodo.bind(this), + }); + } + + deleteTodo(id) { + console.log(id); } } diff --git a/src/components/TodoList.js b/src/components/TodoList.js new file mode 100644 index 00000000..85f183f0 --- /dev/null +++ b/src/components/TodoList.js @@ -0,0 +1,42 @@ +import Component from '../core/component.js'; +import { $ } from '../utils/utils.js'; +import { todoButton } from '../utils/constants.js'; + +export default class TodoList extends Component { + render() { + const todoList = this.props.todoList + .get() + .reduce((html, { id, todo }) => (html += this.renderTodo({ id, todo })), ''); + this.$target.innerHTML = todoList; + } + + renderTodo({ id, todo }) { + return ` +
    • +
      + + + +
      + +
    • + `; + } + + bindEvents() { + this.$target.addEventListener('click', (e) => { + console.log(1); + if (e.target.classList.contains(todoButton.TOGGLE)) { + const checkId = e.target.id; + // this.$target.removeChild(target.closest('.todo')); + e.target.closest('.todo').classList.toggle('completed'); + return; + // console.log(target.closest('.todo')); + // this.props.deleteTodo(checkId); + } + e.stopPropagation(); + // if (target.classList.contains(todoButton.DESTROY)) { + // } + }); + } +} diff --git a/src/utils/constants.js b/src/utils/constants.js new file mode 100644 index 00000000..1ccc76bf --- /dev/null +++ b/src/utils/constants.js @@ -0,0 +1,10 @@ +const todoButton = { + TOGGLE: 'toggle', + LABEL: 'label', + DESTROY: 'destroy', + EDIT: 'edit', + EDITING: 'editing', + COMPLETED: 'completed', +}; + +export { todoButton }; From fabc69e4ac8af4548d09578fe5883692d92a3376 Mon Sep 17 00:00:00 2001 From: kimjanghu Date: Wed, 7 Jul 2021 22:43:22 +0900 Subject: [PATCH 08/14] feat: Add check todo --- src/App.js | 13 ++++++++++--- src/components/TodoList.js | 23 +++++++++-------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/App.js b/src/App.js index 1e87bf6c..0e1d7ec2 100644 --- a/src/App.js +++ b/src/App.js @@ -23,11 +23,18 @@ export default class App extends Component { mountTodoList() { new TodoList($('#todo-list'), { todoList: this.todoList, - deleteTodo: this.deleteTodo.bind(this), + checkTodo: this.checkTodo.bind(this), }); } - deleteTodo(id) { - console.log(id); + checkTodo(id) { + const todoList = this.todoList.get().map((todo) => { + if (todo.id === id) { + todo.checked = !todo.checked; + return todo; + } + return todo; + }); + this.todoList.set([...todoList]); } } diff --git a/src/components/TodoList.js b/src/components/TodoList.js index 85f183f0..b02e90de 100644 --- a/src/components/TodoList.js +++ b/src/components/TodoList.js @@ -1,5 +1,5 @@ import Component from '../core/component.js'; -import { $ } from '../utils/utils.js'; +import { $, $$ } from '../utils/utils.js'; import { todoButton } from '../utils/constants.js'; export default class TodoList extends Component { @@ -24,19 +24,14 @@ export default class TodoList extends Component { } bindEvents() { - this.$target.addEventListener('click', (e) => { - console.log(1); - if (e.target.classList.contains(todoButton.TOGGLE)) { - const checkId = e.target.id; - // this.$target.removeChild(target.closest('.todo')); - e.target.closest('.todo').classList.toggle('completed'); - return; - // console.log(target.closest('.todo')); - // this.props.deleteTodo(checkId); - } - e.stopPropagation(); - // if (target.classList.contains(todoButton.DESTROY)) { - // } + $$('.todo').forEach((item) => { + item.addEventListener('click', ({ target }) => { + if (target.classList.contains(todoButton.TOGGLE)) { + const checkId = Number(target.id); + target.closest('.todo').classList.toggle('completed'); + this.props.checkTodo(checkId); + } + }); }); } } From 58bb0861577c75478ffaaebe250d54c51a4c2bcf Mon Sep 17 00:00:00 2001 From: kimjanghu Date: Wed, 7 Jul 2021 23:13:03 +0900 Subject: [PATCH 09/14] =?UTF-8?q?chore:=20constants=20name=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/constants.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/constants.js b/src/utils/constants.js index 1ccc76bf..68a4311c 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -1,4 +1,4 @@ -const todoButton = { +const TODO_BUTTONS = { TOGGLE: 'toggle', LABEL: 'label', DESTROY: 'destroy', @@ -7,4 +7,4 @@ const todoButton = { COMPLETED: 'completed', }; -export { todoButton }; +export { TODO_BUTTONS }; From 442933a8bba33e57079f365a096caba1d7fbeeac Mon Sep 17 00:00:00 2001 From: kimjanghu Date: Wed, 7 Jul 2021 23:13:31 +0900 Subject: [PATCH 10/14] =?UTF-8?q?feat:=20todo=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 7 +++++++ src/components/TodoList.js | 13 ++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/App.js b/src/App.js index 0e1d7ec2..39bd84b0 100644 --- a/src/App.js +++ b/src/App.js @@ -24,6 +24,7 @@ export default class App extends Component { new TodoList($('#todo-list'), { todoList: this.todoList, checkTodo: this.checkTodo.bind(this), + deleteTodo: this.deleteTodo.bind(this), }); } @@ -37,4 +38,10 @@ export default class App extends Component { }); this.todoList.set([...todoList]); } + + deleteTodo(id) { + const todoList = this.todoList.get().filter((todo) => todo.id !== id); + this.todoList.set([...todoList]); + console.log(this.todoList); + } } diff --git a/src/components/TodoList.js b/src/components/TodoList.js index b02e90de..8a916cb7 100644 --- a/src/components/TodoList.js +++ b/src/components/TodoList.js @@ -1,6 +1,6 @@ import Component from '../core/component.js'; import { $, $$ } from '../utils/utils.js'; -import { todoButton } from '../utils/constants.js'; +import { TODO_BUTTONS } from '../utils/constants.js'; export default class TodoList extends Component { render() { @@ -26,11 +26,18 @@ export default class TodoList extends Component { bindEvents() { $$('.todo').forEach((item) => { item.addEventListener('click', ({ target }) => { - if (target.classList.contains(todoButton.TOGGLE)) { - const checkId = Number(target.id); + const classList = target.classList; + const checkId = Number(target.id); + if (classList.contains(TODO_BUTTONS.TOGGLE)) { target.closest('.todo').classList.toggle('completed'); this.props.checkTodo(checkId); } + + if (classList.contains(TODO_BUTTONS.DESTROY)) { + const removeTarget = target.closest('.todo'); + this.$target.removeChild(removeTarget); + this.props.deleteTodo(checkId); + } }); }); } From 57aea54cf5e08868480ddd4dc5c3aa7646370ce7 Mon Sep 17 00:00:00 2001 From: kimjanghu Date: Fri, 9 Jul 2021 23:49:23 +0900 Subject: [PATCH 11/14] =?UTF-8?q?feat:=20=EC=B4=9D=20todo=20=EA=B0=AF?= =?UTF-8?q?=EC=88=98=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 15 +-------------- src/components/TodoCount.js | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 14 deletions(-) create mode 100644 src/components/TodoCount.js diff --git a/index.html b/index.html index 88319e22..07ea3ad5 100644 --- a/index.html +++ b/index.html @@ -16,20 +16,7 @@

      TODOS

        -
        - 0 - -
        +
        diff --git a/src/components/TodoCount.js b/src/components/TodoCount.js new file mode 100644 index 00000000..91d0ed58 --- /dev/null +++ b/src/components/TodoCount.js @@ -0,0 +1,20 @@ +import Component from '../core/component.js'; + +export default class TodoCount extends Component { + render() { + this.$target.innerHTML = ` + ${this.props.todoList.get().length} + + `; + } +} From 12a311c1b835cc32ee764352413fb257fb5dec46 Mon Sep 17 00:00:00 2001 From: kimjanghu Date: Fri, 9 Jul 2021 23:50:04 +0900 Subject: [PATCH 12/14] =?UTF-8?q?feat:=20todo=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TodoList.js | 39 +++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/components/TodoList.js b/src/components/TodoList.js index 8a916cb7..19eabbcb 100644 --- a/src/components/TodoList.js +++ b/src/components/TodoList.js @@ -12,13 +12,13 @@ export default class TodoList extends Component { renderTodo({ id, todo }) { return ` -
      • +
      • - + - +
        - +
      • `; } @@ -27,16 +27,41 @@ export default class TodoList extends Component { $$('.todo').forEach((item) => { item.addEventListener('click', ({ target }) => { const classList = target.classList; - const checkId = Number(target.id); + const targetId = Number(target.dataset.id); if (classList.contains(TODO_BUTTONS.TOGGLE)) { target.closest('.todo').classList.toggle('completed'); - this.props.checkTodo(checkId); + this.props.checkTodo(targetId); } if (classList.contains(TODO_BUTTONS.DESTROY)) { const removeTarget = target.closest('.todo'); this.$target.removeChild(removeTarget); - this.props.deleteTodo(checkId); + this.props.deleteTodo(targetId); + } + }); + + item.addEventListener('dblclick', ({ target }) => { + const classList = target.classList; + if (classList.contains(TODO_BUTTONS.LABEL)) { + target.closest('.todo').classList.add('editing'); + target.closest('.todo').querySelector('.edit').focus(); + } + }); + + item.addEventListener('keyup', ({ target, key }) => { + const targetId = Number(target.dataset.id); + const editTarget = target.closest('.todo'); + if (key === 'Enter') { + editTarget.classList.add('view'); + editTarget.classList.remove('editing'); + this.props.editTodo(targetId, target.value); + return; + } + + if (key === 'Escape') { + editTarget.classList.add('view'); + editTarget.classList.remove('editing'); + return; } }); }); From d69a1504f2ab60db40798e9d014cec5451b4dd67 Mon Sep 17 00:00:00 2001 From: kimjanghu Date: Fri, 9 Jul 2021 23:50:30 +0900 Subject: [PATCH 13/14] =?UTF-8?q?feat:=20todo=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EC=B4=9D=20=EA=B0=AF=EC=88=98=20=ED=91=9C=EC=8B=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/App.js b/src/App.js index 39bd84b0..bbb13e4f 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,5 @@ import NewTodoInput from './components/NewTodoInput.js'; +import TodoCount from './components/TodoCount.js'; import TodoList from './components/TodoList.js'; import Component from './core/component.js'; import State from './core/State.js'; @@ -18,14 +19,20 @@ export default class App extends Component { todoList: this.todoList, onSubmitTodo: this.mountTodoList.bind(this), }); + + this.todoCountView = new TodoCount($('.count-container'), { + todoList: this.todoList, + }); } mountTodoList() { - new TodoList($('#todo-list'), { + this.todoListView = new TodoList($('#todo-list'), { todoList: this.todoList, checkTodo: this.checkTodo.bind(this), deleteTodo: this.deleteTodo.bind(this), + editTodo: this.editTodo.bind(this), }); + this.todoCountView.render(); } checkTodo(id) { @@ -42,6 +49,17 @@ export default class App extends Component { deleteTodo(id) { const todoList = this.todoList.get().filter((todo) => todo.id !== id); this.todoList.set([...todoList]); - console.log(this.todoList); + this.todoCountView.render(); + } + + editTodo(id, value) { + this.todoList.get().map((todo) => { + if (todo.id === id) { + todo.todo = value; + return todo; + } + return todo; + }); + this.todoListView.render(); } } From b4592f1b28e3558710146fdc4a3f9e7f888b5705 Mon Sep 17 00:00:00 2001 From: kimjanghu Date: Mon, 12 Jul 2021 08:58:50 +0900 Subject: [PATCH 14/14] =?UTF-8?q?feat:=20todo=20filter=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 15 ++++++++- src/App.js | 61 +++++++++++++++++++++++++++++----- src/components/NewTodoInput.js | 3 ++ src/components/TodoCount.js | 47 ++++++++++++++++++-------- src/components/TodoList.js | 26 +++++++++++---- src/utils/constants.js | 17 ++++++++-- src/utils/utils.js | 11 ++++-- 7 files changed, 144 insertions(+), 36 deletions(-) diff --git a/index.html b/index.html index 07ea3ad5..71f3f62c 100644 --- a/index.html +++ b/index.html @@ -16,7 +16,20 @@

        TODOS

          -
          +
          + + +
          diff --git a/src/App.js b/src/App.js index bbb13e4f..92ebc26c 100644 --- a/src/App.js +++ b/src/App.js @@ -3,15 +3,53 @@ import TodoCount from './components/TodoCount.js'; import TodoList from './components/TodoList.js'; import Component from './core/component.js'; import State from './core/State.js'; -import { $ } from './utils/utils.js'; +import { FILTER_TYPES, STORAGE_KEY } from './utils/constants.js'; +import { $, setLocalStorageItem, getLocalStorageItem } from './utils/utils.js'; export default class App extends Component { setState() { - this.todoList = new State([]); + this.todoList = new State(getLocalStorageItem(STORAGE_KEY.TODO) || []); + this.filteredTodoList = new State(null); + this.filterState = new State('all'); } render() { this.mountChildren(); + this.mountTodoList(); + } + + setFilteredTodoList() { + const filterTodo = Object.freeze({ + [FILTER_TYPES.ALL]: this.viewAllTodo.bind(this), + [FILTER_TYPES.ACTIVE]: this.viewActiveTodo.bind(this), + [FILTER_TYPES.COMPLETED]: this.viewCompletedTodo.bind(this), + }); + filterTodo[this.filterState.get()](); + // this.todoListView.setState(this.filteredTodoList.get()); + // this.todoListView.render(); + this.renderComponent(this.todoListView); + this.renderComponent(this.todoCountView); + this.todoCountView.setState(this.filteredTodoList.get()); + this.todoCountView.render(); + } + + renderComponent(view) { + view.setState(this.filteredTodoList.get()); + view.render(); + } + + viewAllTodo() { + this.filteredTodoList.set(this.todoList.get()); + } + + viewActiveTodo() { + const activeTodo = this.todoList.get().filter((todo) => todo.checked === false); + this.filteredTodoList.set(activeTodo); + } + + viewCompletedTodo() { + const completedTodo = this.todoList.get().filter((todo) => todo.checked === true); + this.filteredTodoList.set(completedTodo); } mountChildren() { @@ -19,20 +57,21 @@ export default class App extends Component { todoList: this.todoList, onSubmitTodo: this.mountTodoList.bind(this), }); - - this.todoCountView = new TodoCount($('.count-container'), { - todoList: this.todoList, - }); } mountTodoList() { this.todoListView = new TodoList($('#todo-list'), { - todoList: this.todoList, + todoList: this.filteredTodoList.get() === null ? this.todoList.get() : this.filteredTodoList.get(), checkTodo: this.checkTodo.bind(this), deleteTodo: this.deleteTodo.bind(this), editTodo: this.editTodo.bind(this), }); - this.todoCountView.render(); + + this.todoCountView = new TodoCount($('.count-container'), { + todoList: this.filteredTodoList.get() === null ? this.todoList.get() : this.filteredTodoList.get(), + filterState: this.filterState, + onClickTodoRender: this.setFilteredTodoList.bind(this), + }); } checkTodo(id) { @@ -44,22 +83,26 @@ export default class App extends Component { return todo; }); this.todoList.set([...todoList]); + setLocalStorageItem(STORAGE_KEY, todoList); } deleteTodo(id) { const todoList = this.todoList.get().filter((todo) => todo.id !== id); + setLocalStorageItem(STORAGE_KEY.TODO, todoList); this.todoList.set([...todoList]); this.todoCountView.render(); } editTodo(id, value) { - this.todoList.get().map((todo) => { + const todoList = this.todoList.get().map((todo) => { if (todo.id === id) { todo.todo = value; return todo; } return todo; }); + setLocalStorageItem(STORAGE_KEY.TODO, todoList); + this.todoList.set([...todoList]); this.todoListView.render(); } } diff --git a/src/components/NewTodoInput.js b/src/components/NewTodoInput.js index 908ddb45..cba5c120 100644 --- a/src/components/NewTodoInput.js +++ b/src/components/NewTodoInput.js @@ -1,4 +1,6 @@ import Component from '../core/component.js'; +import { STORAGE_KEY } from '../utils/constants.js'; +import { setLocalStorageItem } from '../utils/utils.js'; export default class NewTodoInput extends Component { bindEvents() { @@ -18,5 +20,6 @@ export default class NewTodoInput extends Component { checked: false, }); this.props.todoList.set(todoList); + setLocalStorageItem(STORAGE_KEY.TODO, todoList); } } diff --git a/src/components/TodoCount.js b/src/components/TodoCount.js index 91d0ed58..15e97384 100644 --- a/src/components/TodoCount.js +++ b/src/components/TodoCount.js @@ -1,20 +1,39 @@ import Component from '../core/component.js'; +import { FILTER_TYPES, TODO_BUTTONS } from '../utils/constants.js'; +import { $, $$ } from '../utils/utils.js'; export default class TodoCount extends Component { + setState(newState) { + this.todoList = newState || this.props.todoList; + } + render() { - this.$target.innerHTML = ` - ${this.props.todoList.get().length} - - `; + $('.todo-count').innerHTML = `총 ${this.todoList.length} 개`; + } + + bindEvents() { + $('.filters').addEventListener('click', ({ target }) => { + if (target.classList.contains(FILTER_TYPES.ALL)) { + this.props.filterState.set(FILTER_TYPES.ALL); + this.selectFilterTypeBtn(FILTER_TYPES.ALL); + } + if (target.classList.contains(FILTER_TYPES.ACTIVE)) { + this.props.filterState.set(FILTER_TYPES.ACTIVE); + this.selectFilterTypeBtn(FILTER_TYPES.ACTIVE); + } + if (target.classList.contains(FILTER_TYPES.COMPLETED)) { + this.props.filterState.set(FILTER_TYPES.COMPLETED); + this.selectFilterTypeBtn(FILTER_TYPES.COMPLETED); + } + this.props.onClickTodoRender(); + }); + } + + selectFilterTypeBtn(type) { + $$('a', $('.filters')).forEach((tag) => { + tag.classList.remove(TODO_BUTTONS.SELECTED); + }); + + $(`.${type}`, $('.filters')).classList.add(TODO_BUTTONS.SELECTED); } } diff --git a/src/components/TodoList.js b/src/components/TodoList.js index 19eabbcb..319c6305 100644 --- a/src/components/TodoList.js +++ b/src/components/TodoList.js @@ -3,18 +3,25 @@ import { $, $$ } from '../utils/utils.js'; import { TODO_BUTTONS } from '../utils/constants.js'; export default class TodoList extends Component { + setState(newState) { + this.todoList = newState || this.props.todoList; + } + render() { - const todoList = this.props.todoList - .get() - .reduce((html, { id, todo }) => (html += this.renderTodo({ id, todo })), ''); + console.log(this.todoList); + const todoList = this.todoList.reduce( + (html, { id, todo, checked }) => (html += this.renderTodo({ id, todo, checked })), + '', + ); this.$target.innerHTML = todoList; } - renderTodo({ id, todo }) { + renderTodo({ id, todo, checked }) { + const checkTodo = checked ? 'completed' : ''; return ` -
        • +
        • - + ${this.checkCheckbox(id, checked)}
          @@ -23,6 +30,12 @@ export default class TodoList extends Component { `; } + checkCheckbox(id, checked) { + return checked + ? `` + : ``; + } + bindEvents() { $$('.todo').forEach((item) => { item.addEventListener('click', ({ target }) => { @@ -31,6 +44,7 @@ export default class TodoList extends Component { if (classList.contains(TODO_BUTTONS.TOGGLE)) { target.closest('.todo').classList.toggle('completed'); this.props.checkTodo(targetId); + console.log(targetId); } if (classList.contains(TODO_BUTTONS.DESTROY)) { diff --git a/src/utils/constants.js b/src/utils/constants.js index 68a4311c..ed91d93c 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -1,10 +1,21 @@ -const TODO_BUTTONS = { +const TODO_BUTTONS = Object.freeze({ TOGGLE: 'toggle', LABEL: 'label', DESTROY: 'destroy', EDIT: 'edit', EDITING: 'editing', COMPLETED: 'completed', -}; + SELECTED: 'selected', +}); -export { TODO_BUTTONS }; +const FILTER_TYPES = Object.freeze({ + ALL: 'all', + ACTIVE: 'active', + COMPLETED: 'completed', +}); + +const STORAGE_KEY = Object.freeze({ + TODO: 'todoList', +}); + +export { TODO_BUTTONS, FILTER_TYPES, STORAGE_KEY }; diff --git a/src/utils/utils.js b/src/utils/utils.js index 79ec734d..86233246 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -1,4 +1,9 @@ -const $ = (selector) => document.querySelector(selector); -const $$ = (selector) => document.querySelectorAll(selector); +const $ = (selector, tag = document) => tag.querySelector(selector); +const $$ = (selector, tag = document) => tag.querySelectorAll(selector); +const setLocalStorageItem = (key, value) => localStorage.setItem(key, JSON.stringify(value)); +const getLocalStorageItem = (key) => { + const todoList = localStorage.getItem(key); + return JSON.parse(todoList); +}; -export { $, $$ }; +export { $, $$, setLocalStorageItem, getLocalStorageItem };