From a711653417bedd422486238b51888ba4c2ca954b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=94=84=EB=A1=9C=EA=B7=B8=EB=9E=98=EB=A8=B8=EC=8A=A4=20?= =?UTF-8?q?=EA=B5=90=EC=9C=A1=ED=8C=80?= Date: Tue, 19 Sep 2023 04:29:19 +0900 Subject: [PATCH 01/49] Initial commit --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..2069c94 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# FEDC5-3_VanillaJS_1 \ No newline at end of file From 568585dd06f4483c9c30a7201cc8e07b2788dd16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=94=84=EB=A1=9C=EA=B7=B8=EB=9E=98=EB=A8=B8=EC=8A=A4=20?= =?UTF-8?q?=EA=B5=90=EC=9C=A1=ED=8C=80?= Date: Tue, 19 Sep 2023 04:30:28 +0900 Subject: [PATCH 02/49] Update README.md --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2069c94..8dbe885 100644 --- a/README.md +++ b/README.md @@ -1 +1,27 @@ -# FEDC5-3_VanillaJS_1 \ No newline at end of file +# ๐Ÿ“Œ 3์ฃผ์ฐจ ๊ณผ์ œ[Mission3] + +## ํ•„์ˆ˜ ๊ณผ์ œ +- ๊ณผ์ œ ๊ธฐํ•œ + - ๊ณผ์ œ ์ˆ˜ํ–‰ ๊ธฐ๊ฐ„ : 2023๋…„ 10์›” 6์ผ(๊ธˆ) ~ 2023๋…„ 10์›” 11์ผ(์ˆ˜) + - ๋ฉ˜ํ‹ฐ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๊ธฐ๊ฐ„ : 2023๋…„ 10์›” 12์ผ(๋ชฉ) ~ 2023๋…„ 10์›” 13์ผ(๊ธˆ) + - ๋ฉ˜ํ†  ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๊ธฐ๊ฐ„ : 2023๋…„ 10์›” 12์ผ(๋ชฉ) ~ 2023๋…„ 10์›” 17์ผ(ํ™”) + - ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋ฐ˜์˜ ๊ธฐ๊ฐ„ : 2023๋…„ 10์›” 18์ผ(์ˆ˜) ~ 2023๋…„ 10์›” 19์ผ(๋ชฉ) +- ๋‚ด์šฉ + - ์ง€๊ธˆ๊นŒ์ง€ ๋งŒ๋“  **Simple List Todo ์•ฑ์„ ๊ฐ•ํ™”**ํ•ฉ๋‹ˆ๋‹ค. + - ์•„๋ž˜์˜ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋งŒ์กฑํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์˜ฌ๋ ค์ฃผ์„ธ์š”. + - ์•„๋ž˜์˜ ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ PR ์‹œ ํ™œ์šฉํ•ด๋„ ์ข‹์Šต๋‹ˆ๋‹ค! + +### ๊ณตํ†ต +- [ ] ์ปดํฌ๋„ŒํŠธ์— new๋ฅผ ๋ถ™์ด์ง€ ์•Š๊ณ  ์“ธ ๊ฒฝ์šฐ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋„๋ก ๋ฐฉ์–ด์ฝ”๋“œ๋ฅผ ๋„ฃ์–ด์ฃผ์„ธ์š”. + - ์ปดํฌ๋„ŒํŠธ๋ฅผ class ํ˜•ํƒœ๋กœ ๊ตฌํ˜„ํ•œ ๊ฒฝ์šฐ ์ด ์š”๊ตฌ์‚ฌํ•ญ์€ ๋ฌด์‹œํ•˜์…”๋„ ๋ฉ๋‹ˆ๋‹ค. +- [ ] state๋ฅผ ๊ฐ–๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฝ์šฐ, initialState๋ฅผ ๋ฐ›๋Š” ๋ถ€๋ถ„๊ณผ setState ํ•จ์ˆ˜์—์„œ nextState๋ฅผ ๋ฐ›๋Š” ๋ถ€๋ถ„์—์„œ state์— ๋Œ€ํ•œ validation์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์„ธ์š”. +- [ ] ๊ฐ€๊ธ‰์  ๋ณ€์ˆ˜๋Š” const๋กœ ์„ ์–ธํ•˜๋ฉฐ, ๋ถ€๋“์ดํ•œ ๊ฒฝ์šฐ์—๋งŒ let์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. + +### TodoList +- [ ] To do์˜ ๊ฐ’์— isCompleted๋ผ๋Š” ๊ฐ’์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  TodoList์˜ Todo๋ฅผ ํด๋ฆญํ•˜๋ฉด ํ•ด๋‹น ๊ฐ’์ด ํ† ๊ธ€ ๋˜๋„๋ก ๋งŒ๋“ญ๋‹ˆ๋‹ค. + - isCompleted๊ฐ€ true์ธ ๊ฒฝ์šฐ text์— ์‚ญ์„ ์ด ๊ทธ์–ด์ง€๋„๋ก ํ•ด์ฃผ์„ธ์š”. false๋กœ ๋ฐ”๋€Œ๋ฉด ์‚ญ์„ ์„ ์—†์• ์ฃผ์„ธ์š”. +- [ ] Todo text ์˜†์— ์‚ญ์ œ button์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋ˆ„๋ฅด๋ฉด ์‚ญ์ œ ๋˜๋„๋ก ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. + +### TodoCount +- [ ] TodoCount ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.์ด ์ปดํฌ๋„ŒํŠธ๋Š” TodoList ์•„๋ž˜์— ๋ Œ๋”๋ง ๋˜์–ด์•ผ ํ•˜๋ฉฐ, ์™„๋ฃŒ๋œ Todo์˜ ๊ฐฏ์ˆ˜ / ์ „์ œ Todo ๊ฐฏ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. + - ์ด๋•Œ TodoCount์—์„œ TodoList์— ์ง์ ‘ ์ ‘๊ทผํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. From 39ddbc55c2531108518aa00ac3f421f59f2c3d27 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:40:40 +0900 Subject: [PATCH 03/49] Initial code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๊ฐ•์˜ ๋“ค์œผ๋ฉฐ ๋”ฐ๋ผ ์นœ ์ฝ”๋“œ ์ž…๋‹ˆ๋‹ค. --- index.html | 20 ++++++++++++++++++++ src/App.js | 23 +++++++++++++++++++++++ src/Header.js | 10 ++++++++++ src/TodoForm.js | 28 ++++++++++++++++++++++++++++ src/TodoList.js | 23 +++++++++++++++++++++++ src/main.js | 7 +++++++ src/storage.js | 25 +++++++++++++++++++++++++ 7 files changed, 136 insertions(+) create mode 100644 index.html create mode 100644 src/App.js create mode 100644 src/Header.js create mode 100644 src/TodoForm.js create mode 100644 src/TodoList.js create mode 100644 src/main.js create mode 100644 src/storage.js diff --git a/index.html b/index.html new file mode 100644 index 0000000..3f69562 --- /dev/null +++ b/index.html @@ -0,0 +1,20 @@ + + + + + + + Todo List + + + +
+ + + + + + + + + \ No newline at end of file diff --git a/src/App.js b/src/App.js new file mode 100644 index 0000000..c71b0e1 --- /dev/null +++ b/src/App.js @@ -0,0 +1,23 @@ +function App({ $target, initialState }) { + new Header({ + $target, + text: 'Todo List' + }); + + new TodoForm({ + $target, + onSubmit: text => { + const nextState = [ + ...todoList.state, + { text } + ]; + todoList.setState(nextState); + storage.setItem('todo', JSON.stringify(nextState)); + } + }); + + const todoList = new TodoList({ + $target, + initialState + }); +} \ No newline at end of file diff --git a/src/Header.js b/src/Header.js new file mode 100644 index 0000000..0548a70 --- /dev/null +++ b/src/Header.js @@ -0,0 +1,10 @@ +function Header({ $target, text }) { + const $header = document.createElement('h1'); + $target.appendChild($header); + + this.render = () => { + $header.textContent = text; + } + + this.render(); +} \ No newline at end of file diff --git a/src/TodoForm.js b/src/TodoForm.js new file mode 100644 index 0000000..17b1c83 --- /dev/null +++ b/src/TodoForm.js @@ -0,0 +1,28 @@ +function TodoForm({ $target, onSubmit }) { + const $form = document.createElement('form'); + $target.appendChild($form); + + let isInit = false; + + this.render = () => { + $form.innerHTML = ` + + + `; + + if (!isInit) { + $form.addEventListener('submit', e => { + e.preventDefault(); // ํƒœ๊ทธ๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ณ ์œ  ๊ธฐ๋Šฅ ๋ง‰๊ธฐ(form ํƒœ๊ทธ์˜ ์ƒˆ๋กœ๊ณ ์นจ ๋ง‰๊ธฐ) + + const $todo = $form.querySelector('input[name=todo]'); + const text = $todo.value; + if (text.length > 1) { + $todo.value = ''; + onSubmit(text); + } + }); + } + } + + this.render(); +} \ No newline at end of file diff --git a/src/TodoList.js b/src/TodoList.js new file mode 100644 index 0000000..19cc259 --- /dev/null +++ b/src/TodoList.js @@ -0,0 +1,23 @@ +// params.$target - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋  DOM ์•จ๋ฆฌ๋จผํŠธ +// params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ +function TodoList({ $target, initialState }) { + const $todoList = document.createElement('div'); + $target.appendChild($todoList); + + this.state = initialState; + + this.setState = nextState => { + this.state = nextState; + this.render(); + } + + this.render = () => { + $todoList.innerHTML = ` + + `; + } + + this.render(); +} \ No newline at end of file diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..bf86e23 --- /dev/null +++ b/src/main.js @@ -0,0 +1,7 @@ +const initialState = storage.getItem("todo", []); +const $app = document.querySelector("#app"); + +new App({ + $target: $app, + initialState +}); \ No newline at end of file diff --git a/src/storage.js b/src/storage.js new file mode 100644 index 0000000..f2d9f5a --- /dev/null +++ b/src/storage.js @@ -0,0 +1,25 @@ +const storage = (function (storage) { + const setItem = (key, value) => { + try { + storage.setItem(key, value); + } catch (error) { + console.log(error); + } + } + + const getItem = (key, defaultValue) => { + try { + const data = storage.getItem(key); + if (data) return JSON.parse(data); + return defaultValue; + } catch (error) { + console.log(error); + return defaultValue; + } + } + + return { + setItem, + getItem + } +})(window.localStorage); \ No newline at end of file From a24eea88f7d7c0357ec8229966b451210f86f4f4 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sun, 8 Oct 2023 11:17:34 +0900 Subject: [PATCH 04/49] =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=EC=97=90=20new=EB=A5=BC=20=EB=B6=99=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EA=B3=A0=20=EC=93=B8=20=EA=B2=BD=EC=9A=B0=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Header.js | 4 ++++ src/TodoForm.js | 4 ++++ src/TodoList.js | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/Header.js b/src/Header.js index 0548a70..ab7b2a4 100644 --- a/src/Header.js +++ b/src/Header.js @@ -1,4 +1,8 @@ function Header({ $target, text }) { + if (!new.target) { + throw new Error('You must use new with Header'); + } + const $header = document.createElement('h1'); $target.appendChild($header); diff --git a/src/TodoForm.js b/src/TodoForm.js index 17b1c83..6573ba0 100644 --- a/src/TodoForm.js +++ b/src/TodoForm.js @@ -1,4 +1,8 @@ function TodoForm({ $target, onSubmit }) { + if (!new.target) { + throw new Error('You must use new with TodoForm'); + } + const $form = document.createElement('form'); $target.appendChild($form); diff --git a/src/TodoList.js b/src/TodoList.js index 19cc259..0ad8b88 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -1,6 +1,10 @@ // params.$target - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋  DOM ์•จ๋ฆฌ๋จผํŠธ // params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ function TodoList({ $target, initialState }) { + if (!new.target) { + throw new Error('You must use new with TodoList'); + } + const $todoList = document.createElement('div'); $target.appendChild($todoList); From 879cc343cc8718ddd47682a3a689133d63f85a52 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Mon, 9 Oct 2023 13:58:33 +0900 Subject: [PATCH 05/49] =?UTF-8?q?script=20=ED=8C=8C=EC=9D=BC=20module=20?= =?UTF-8?q?=EC=86=8D=EC=84=B1=EC=9C=BC=EB=A1=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 7 +------ src/App.js | 9 +++++++-- src/Header.js | 2 +- src/TodoForm.js | 2 +- src/TodoList.js | 2 +- src/main.js | 5 ++++- src/storage.js | 37 ++++++++++++++++--------------------- 7 files changed, 31 insertions(+), 33 deletions(-) diff --git a/index.html b/index.html index 3f69562..6cd79af 100644 --- a/index.html +++ b/index.html @@ -9,12 +9,7 @@
- - - - - - + \ No newline at end of file diff --git a/src/App.js b/src/App.js index c71b0e1..2e7e4e5 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,9 @@ -function App({ $target, initialState }) { +import Header from "./Header.js"; +import TodoForm from "./TodoForm.js"; +import TodoList from "./TodoList.js"; +import { setItem } from "./storage.js"; + +export default function App({ $target, initialState }) { new Header({ $target, text: 'Todo List' @@ -12,7 +17,7 @@ function App({ $target, initialState }) { { text } ]; todoList.setState(nextState); - storage.setItem('todo', JSON.stringify(nextState)); + setItem('todo', JSON.stringify(nextState)); } }); diff --git a/src/Header.js b/src/Header.js index ab7b2a4..8a62bb5 100644 --- a/src/Header.js +++ b/src/Header.js @@ -1,4 +1,4 @@ -function Header({ $target, text }) { +export default function Header({ $target, text }) { if (!new.target) { throw new Error('You must use new with Header'); } diff --git a/src/TodoForm.js b/src/TodoForm.js index 6573ba0..8479344 100644 --- a/src/TodoForm.js +++ b/src/TodoForm.js @@ -1,4 +1,4 @@ -function TodoForm({ $target, onSubmit }) { +export default function TodoForm({ $target, onSubmit }) { if (!new.target) { throw new Error('You must use new with TodoForm'); } diff --git a/src/TodoList.js b/src/TodoList.js index 0ad8b88..2cbbb13 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -1,6 +1,6 @@ // params.$target - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋  DOM ์•จ๋ฆฌ๋จผํŠธ // params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ -function TodoList({ $target, initialState }) { +export default function TodoList({ $target, initialState }) { if (!new.target) { throw new Error('You must use new with TodoList'); } diff --git a/src/main.js b/src/main.js index bf86e23..820dcac 100644 --- a/src/main.js +++ b/src/main.js @@ -1,4 +1,7 @@ -const initialState = storage.getItem("todo", []); +import App from "./App.js"; +import { getItem } from "./storage.js"; + +const initialState = getItem("todo", []); const $app = document.querySelector("#app"); new App({ diff --git a/src/storage.js b/src/storage.js index f2d9f5a..3250345 100644 --- a/src/storage.js +++ b/src/storage.js @@ -1,25 +1,20 @@ -const storage = (function (storage) { - const setItem = (key, value) => { - try { - storage.setItem(key, value); - } catch (error) { - console.log(error); - } - } +const storage = window.localStorage; - const getItem = (key, defaultValue) => { - try { - const data = storage.getItem(key); - if (data) return JSON.parse(data); - return defaultValue; - } catch (error) { - console.log(error); - return defaultValue; - } +export const setItem = (key, value) => { + try { + storage.setItem(key, value); + } catch (error) { + console.log(error); } +} - return { - setItem, - getItem +export const getItem = (key, defaultValue) => { + try { + const data = storage.getItem(key); + if (data) return JSON.parse(data); + return defaultValue; + } catch (error) { + console.log(error); + return defaultValue; } -})(window.localStorage); \ No newline at end of file +} \ No newline at end of file From da761ccaf78af2bc177ebf3be64c2479f61039f9 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 10 Oct 2023 13:58:17 +0900 Subject: [PATCH 06/49] =?UTF-8?q?TodoList=EC=97=90=20isCompleted=20?= =?UTF-8?q?=EA=B0=92,=20=ED=86=A0=EA=B8=80=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 1 + src/App.js | 2 +- src/TodoList.js | 43 ++++++++++++++++++++++++++++++++++++++++--- style.css | 12 ++++++++++++ 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 style.css diff --git a/index.html b/index.html index 6cd79af..552acda 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,7 @@ Todo List + diff --git a/src/App.js b/src/App.js index 2e7e4e5..aa702f2 100644 --- a/src/App.js +++ b/src/App.js @@ -14,7 +14,7 @@ export default function App({ $target, initialState }) { onSubmit: text => { const nextState = [ ...todoList.state, - { text } + { text, isCompleted: false } ]; todoList.setState(nextState); setItem('todo', JSON.stringify(nextState)); diff --git a/src/TodoList.js b/src/TodoList.js index 2cbbb13..820d78f 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -1,3 +1,5 @@ +import { setItem } from "./storage.js"; + // params.$target - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋  DOM ์•จ๋ฆฌ๋จผํŠธ // params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ export default function TodoList({ $target, initialState }) { @@ -18,10 +20,45 @@ export default function TodoList({ $target, initialState }) { this.render = () => { $todoList.innerHTML = ` `; - } + + const liList = $todoList.querySelectorAll("li"); + liList.forEach(($li, index) => { + $li.addEventListener("click", (e) => { + const checkbox = e.currentTarget.children[0]; + if (e.target.tagName !== "INPUT") { + // checkbox๊ฐ€ ์•„๋‹Œ ๋ถ€๋ถ„์„ ํด๋ฆญํ–ˆ์„ ๋•Œ checked ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝ + checkbox.checked = !checkbox.checked; + } + + const isCompleted = checkbox.checked; + if (isCompleted) { + e.currentTarget.classList.add("completed"); + } else { + e.currentTarget.classList.remove("completed"); + } + + const newState = [...this.state]; + newState[index] = { + ...newState[index], + isCompleted, + }; + this.setState(newState); + setItem("todo", JSON.stringify(newState)); + }); + }); + }; this.render(); -} \ No newline at end of file +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..c2d2118 --- /dev/null +++ b/style.css @@ -0,0 +1,12 @@ +ul { + list-style: none; + padding: 0; +} + +li { + cursor: pointer; +} + +.completed { + text-decoration: line-through; +} \ No newline at end of file From 8494326995ea25f7d71bbf0ccafeac3454728ebe Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:20:48 +0900 Subject: [PATCH 07/49] =?UTF-8?q?TodoList=20text=20=EC=98=86=EC=97=90=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EB=B2=84=ED=8A=BC=20=EB=B0=8F=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/TodoList.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/TodoList.js b/src/TodoList.js index 820d78f..0eef37f 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -25,7 +25,8 @@ export default function TodoList({ $target, initialState }) { ({ text, isCompleted }) => `
  • - ${text} + ${text} +
  • ` ) @@ -33,6 +34,19 @@ export default function TodoList({ $target, initialState }) { `; + const deleteButtonAll = $todoList.querySelectorAll(".deleteBtn"); + deleteButtonAll.forEach(($deleteBtn, index) => { + $deleteBtn.addEventListener("click", (e) => { + // list์˜ li ํ˜น์€ checkbox๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•จ + e.stopPropagation(); + + const newState = [...this.state]; + newState.splice(index, 1); + this.setState(newState); + setItem("todo", JSON.stringify(newState)); + }); + }); + const liList = $todoList.querySelectorAll("li"); liList.forEach(($li, index) => { $li.addEventListener("click", (e) => { From 7be0d9e478bdcf1a0facc389390970df191313a6 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 10 Oct 2023 15:02:30 +0900 Subject: [PATCH 08/49] =?UTF-8?q?TodoCount=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EA=B0=9C=EC=88=98?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=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 | 27 ++++++++++++++++++++++----- src/TodoCount.js | 21 +++++++++++++++++++++ src/TodoList.js | 4 +++- src/main.js | 6 ++++-- 4 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 src/TodoCount.js diff --git a/src/App.js b/src/App.js index aa702f2..cb2e8d1 100644 --- a/src/App.js +++ b/src/App.js @@ -1,9 +1,10 @@ import Header from "./Header.js"; import TodoForm from "./TodoForm.js"; import TodoList from "./TodoList.js"; +import TodoCount from "./TodoCount.js"; import { setItem } from "./storage.js"; -export default function App({ $target, initialState }) { +export default function App({ $target, initialState, initialCount }) { new Header({ $target, text: 'Todo List' @@ -17,12 +18,28 @@ export default function App({ $target, initialState }) { { text, isCompleted: false } ]; todoList.setState(nextState); - setItem('todo', JSON.stringify(nextState)); - } + setItem("todo", JSON.stringify(nextState)); + + const done = nextState.filter((todo) => todo.isCompleted).length; + const count = { total: nextState.length, done }; + todoCount.setState(count); + setItem("count", JSON.stringify(count)); + }, }); const todoList = new TodoList({ $target, - initialState + initialState, + updateCount: () => { + const done = todoList.state.filter((todo) => todo.isCompleted).length; + const nextState = { total: todoList.state.length, done }; + todoCount.setState(nextState); + setItem("count", JSON.stringify(nextState)); + }, + }); + + const todoCount = new TodoCount({ + $target, + initialCount, }); -} \ No newline at end of file +} diff --git a/src/TodoCount.js b/src/TodoCount.js new file mode 100644 index 0000000..0d638e3 --- /dev/null +++ b/src/TodoCount.js @@ -0,0 +1,21 @@ +export default function TodoCount({ $target, initialCount }) { + if (!new.target) { + throw new Error("You must use new with TodoCount"); + } + + const $container = document.createElement("div"); + $target.appendChild($container); + + this.state = initialCount; + + this.setState = (nextState) => { + this.state = nextState; + this.render(); + }; + + this.render = () => { + $container.textContent = `์™„๋ฃŒ ${this.state.done}๊ฐœ / ์ด ${this.state.total}๊ฐœ`; + }; + + this.render(); +} diff --git a/src/TodoList.js b/src/TodoList.js index 0eef37f..1855e79 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -2,7 +2,7 @@ import { setItem } from "./storage.js"; // params.$target - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋  DOM ์•จ๋ฆฌ๋จผํŠธ // params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ -export default function TodoList({ $target, initialState }) { +export default function TodoList({ $target, initialState, updateCount }) { if (!new.target) { throw new Error('You must use new with TodoList'); } @@ -44,6 +44,7 @@ export default function TodoList({ $target, initialState }) { newState.splice(index, 1); this.setState(newState); setItem("todo", JSON.stringify(newState)); + updateCount(); }); }); @@ -70,6 +71,7 @@ export default function TodoList({ $target, initialState }) { }; this.setState(newState); setItem("todo", JSON.stringify(newState)); + updateCount(); }); }); }; diff --git a/src/main.js b/src/main.js index 820dcac..baaf076 100644 --- a/src/main.js +++ b/src/main.js @@ -2,9 +2,11 @@ import App from "./App.js"; import { getItem } from "./storage.js"; const initialState = getItem("todo", []); +const initialCount = getItem("count", { total: 0, done: 0 }); const $app = document.querySelector("#app"); new App({ $target: $app, - initialState -}); \ No newline at end of file + initialState, + initialCount, +}); From 31729f4ddc067de02ab4d9898567c6b7323a5a8f Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 10 Oct 2023 15:03:47 +0900 Subject: [PATCH 09/49] =?UTF-8?q?=EB=A6=B0=ED=8A=B8=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 | 9 +++------ src/Header.js | 8 ++++---- src/TodoForm.js | 14 +++++++------- src/TodoList.js | 8 ++++---- src/storage.js | 4 ++-- 5 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/App.js b/src/App.js index cb2e8d1..527f5a9 100644 --- a/src/App.js +++ b/src/App.js @@ -7,16 +7,13 @@ import { setItem } from "./storage.js"; export default function App({ $target, initialState, initialCount }) { new Header({ $target, - text: 'Todo List' + text: "Todo List", }); new TodoForm({ $target, - onSubmit: text => { - const nextState = [ - ...todoList.state, - { text, isCompleted: false } - ]; + onSubmit: (text) => { + const nextState = [...todoList.state, { text, isCompleted: false }]; todoList.setState(nextState); setItem("todo", JSON.stringify(nextState)); diff --git a/src/Header.js b/src/Header.js index 8a62bb5..488333d 100644 --- a/src/Header.js +++ b/src/Header.js @@ -1,14 +1,14 @@ export default function Header({ $target, text }) { if (!new.target) { - throw new Error('You must use new with Header'); + throw new Error("You must use new with Header"); } - const $header = document.createElement('h1'); + const $header = document.createElement("h1"); $target.appendChild($header); this.render = () => { $header.textContent = text; - } + }; this.render(); -} \ No newline at end of file +} diff --git a/src/TodoForm.js b/src/TodoForm.js index 8479344..c7b209f 100644 --- a/src/TodoForm.js +++ b/src/TodoForm.js @@ -1,9 +1,9 @@ export default function TodoForm({ $target, onSubmit }) { if (!new.target) { - throw new Error('You must use new with TodoForm'); + throw new Error("You must use new with TodoForm"); } - const $form = document.createElement('form'); + const $form = document.createElement("form"); $target.appendChild($form); let isInit = false; @@ -15,18 +15,18 @@ export default function TodoForm({ $target, onSubmit }) { `; if (!isInit) { - $form.addEventListener('submit', e => { + $form.addEventListener("submit", (e) => { e.preventDefault(); // ํƒœ๊ทธ๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ณ ์œ  ๊ธฐ๋Šฅ ๋ง‰๊ธฐ(form ํƒœ๊ทธ์˜ ์ƒˆ๋กœ๊ณ ์นจ ๋ง‰๊ธฐ) - const $todo = $form.querySelector('input[name=todo]'); + const $todo = $form.querySelector("input[name=todo]"); const text = $todo.value; if (text.length > 1) { - $todo.value = ''; + $todo.value = ""; onSubmit(text); } }); } - } + }; this.render(); -} \ No newline at end of file +} diff --git a/src/TodoList.js b/src/TodoList.js index 1855e79..3d18ecf 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -4,18 +4,18 @@ import { setItem } from "./storage.js"; // params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ export default function TodoList({ $target, initialState, updateCount }) { if (!new.target) { - throw new Error('You must use new with TodoList'); + throw new Error("You must use new with TodoList"); } - const $todoList = document.createElement('div'); + const $todoList = document.createElement("div"); $target.appendChild($todoList); this.state = initialState; - this.setState = nextState => { + this.setState = (nextState) => { this.state = nextState; this.render(); - } + }; this.render = () => { $todoList.innerHTML = ` diff --git a/src/storage.js b/src/storage.js index 3250345..7119153 100644 --- a/src/storage.js +++ b/src/storage.js @@ -6,7 +6,7 @@ export const setItem = (key, value) => { } catch (error) { console.log(error); } -} +}; export const getItem = (key, defaultValue) => { try { @@ -17,4 +17,4 @@ export const getItem = (key, defaultValue) => { console.log(error); return defaultValue; } -} \ No newline at end of file +}; From 26433a47b6fb138f742325ec2f716fd336dde177 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 10 Oct 2023 15:36:15 +0900 Subject: [PATCH 10/49] =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=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 --- style.css | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/style.css b/style.css index c2d2118..855a621 100644 --- a/style.css +++ b/style.css @@ -5,6 +5,29 @@ ul { li { cursor: pointer; + margin: 10px; +} + +input { + padding: 4px 8px; + border-radius: 4px; + border: 1px solid #2e2f35; + outline: none; +} + +button { + cursor: pointer; + border-radius: 4px; + border: 1px solid #2e2f35; + margin-left: 5px; + padding-top: 3px; + background-color: transparent; + color: #2e2f35; +} + +button:hover { + background-color: #2e2f35; + color: #fff; } .completed { From 0f5b5a82ad28bc6c9b93278aacf9e04deca47662 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Wed, 11 Oct 2023 13:57:24 +0900 Subject: [PATCH 11/49] =?UTF-8?q?=EB=91=90=20=EA=B8=80=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EC=83=81=20=EB=AF=B8=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=EC=B0=BD=20=ED=8C=9D=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/TodoForm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TodoForm.js b/src/TodoForm.js index c7b209f..a4472f3 100644 --- a/src/TodoForm.js +++ b/src/TodoForm.js @@ -23,7 +23,7 @@ export default function TodoForm({ $target, onSubmit }) { if (text.length > 1) { $todo.value = ""; onSubmit(text); - } + } else alert("๋‘ ๊ธ€์ž ์ด์ƒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); }); } }; From 71703beb5398bece6c7093286dccd685b90ab8a3 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Wed, 11 Oct 2023 13:57:48 +0900 Subject: [PATCH 12/49] =?UTF-8?q?=EB=B0=98=EB=B3=B5=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=95=A8=EC=88=98=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 | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/App.js b/src/App.js index 527f5a9..9448380 100644 --- a/src/App.js +++ b/src/App.js @@ -15,28 +15,27 @@ export default function App({ $target, initialState, initialCount }) { onSubmit: (text) => { const nextState = [...todoList.state, { text, isCompleted: false }]; todoList.setState(nextState); + updateCount(nextState); setItem("todo", JSON.stringify(nextState)); - - const done = nextState.filter((todo) => todo.isCompleted).length; - const count = { total: nextState.length, done }; - todoCount.setState(count); - setItem("count", JSON.stringify(count)); }, }); const todoList = new TodoList({ $target, initialState, - updateCount: () => { - const done = todoList.state.filter((todo) => todo.isCompleted).length; - const nextState = { total: todoList.state.length, done }; - todoCount.setState(nextState); - setItem("count", JSON.stringify(nextState)); - }, + updateCount: () => updateCount(todoList.state), }); const todoCount = new TodoCount({ $target, initialCount, }); + + // ์นด์šดํŠธ ์—…๋ฐ์ดํŠธ + const updateCount = (todoList) => { + const done = todoList.filter((todo) => todo.isCompleted).length; + const nextState = { total: todoList.length, done }; + todoCount.setState(nextState); + setItem("count", JSON.stringify(nextState)); + }; } From ca37ecda72f946d6d19c213e48bfbcc53d9da0e2 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 12 Oct 2023 15:36:30 +0900 Subject: [PATCH 13/49] =?UTF-8?q?=EC=B4=88=EA=B8=B0=EA=B0=92=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/TodoCount.js | 4 +++- src/TodoList.js | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/TodoCount.js b/src/TodoCount.js index 0d638e3..4db26ae 100644 --- a/src/TodoCount.js +++ b/src/TodoCount.js @@ -6,7 +6,9 @@ export default function TodoCount({ $target, initialCount }) { const $container = document.createElement("div"); $target.appendChild($container); - this.state = initialCount; + if (initialCount.total && initialCount.done) { + this.state = initialCount; + } else this.state = { total: 0, done: 0 }; this.setState = (nextState) => { this.state = nextState; diff --git a/src/TodoList.js b/src/TodoList.js index 3d18ecf..7f09e3f 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -10,7 +10,8 @@ export default function TodoList({ $target, initialState, updateCount }) { const $todoList = document.createElement("div"); $target.appendChild($todoList); - this.state = initialState; + if (Array.isArray(initialState)) this.state = initialState; + else this.state = []; this.setState = (nextState) => { this.state = nextState; From e337536e9051079d802a9a8ff5a5116bc54b5916 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 19 Oct 2023 01:48:46 +0900 Subject: [PATCH 14/49] =?UTF-8?q?new.target=20=EC=9C=A0=ED=9A=A8=EC=84=B1?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Header.js | 6 +++--- src/TodoCount.js | 6 +++--- src/TodoForm.js | 6 +++--- src/TodoList.js | 5 ++--- src/util/validation.js | 9 +++++++++ 5 files changed, 20 insertions(+), 12 deletions(-) create mode 100644 src/util/validation.js diff --git a/src/Header.js b/src/Header.js index 488333d..4e67a16 100644 --- a/src/Header.js +++ b/src/Header.js @@ -1,7 +1,7 @@ +import validation from "./util/validation.js"; + export default function Header({ $target, text }) { - if (!new.target) { - throw new Error("You must use new with Header"); - } + validation.newTarget(new.target); const $header = document.createElement("h1"); $target.appendChild($header); diff --git a/src/TodoCount.js b/src/TodoCount.js index 4db26ae..18f7731 100644 --- a/src/TodoCount.js +++ b/src/TodoCount.js @@ -1,7 +1,7 @@ +import validation from "./util/validation.js"; + export default function TodoCount({ $target, initialCount }) { - if (!new.target) { - throw new Error("You must use new with TodoCount"); - } + validation.newTarget(new.target); const $container = document.createElement("div"); $target.appendChild($container); diff --git a/src/TodoForm.js b/src/TodoForm.js index a4472f3..955c400 100644 --- a/src/TodoForm.js +++ b/src/TodoForm.js @@ -1,7 +1,7 @@ +import validation from "./util/validation.js"; + export default function TodoForm({ $target, onSubmit }) { - if (!new.target) { - throw new Error("You must use new with TodoForm"); - } + validation.newTarget(new.target); const $form = document.createElement("form"); $target.appendChild($form); diff --git a/src/TodoList.js b/src/TodoList.js index 7f09e3f..1ed3eb9 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -1,11 +1,10 @@ import { setItem } from "./storage.js"; +import validation from "./util/validation.js"; // params.$target - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋  DOM ์•จ๋ฆฌ๋จผํŠธ // params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ export default function TodoList({ $target, initialState, updateCount }) { - if (!new.target) { - throw new Error("You must use new with TodoList"); - } + validation.newTarget(new.target); const $todoList = document.createElement("div"); $target.appendChild($todoList); diff --git a/src/util/validation.js b/src/util/validation.js new file mode 100644 index 0000000..fd30d81 --- /dev/null +++ b/src/util/validation.js @@ -0,0 +1,9 @@ +const validation = { + newTarget(target) { + if (!target) { + throw new Error("You must use new keyword"); + } + }, +}; + +export default validation; From 12d4512b58bb9b83cb6ce2b2638bbcb152e672ff Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 19 Oct 2023 01:50:08 +0900 Subject: [PATCH 15/49] =?UTF-8?q?=ED=88=AC=EB=91=90=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=83=81=ED=83=9C=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/TodoList.js | 5 ++++- src/util/validation.js | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/TodoList.js b/src/TodoList.js index 1ed3eb9..2a512a6 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -13,7 +13,10 @@ export default function TodoList({ $target, initialState, updateCount }) { else this.state = []; this.setState = (nextState) => { - this.state = nextState; + const newState = validation.state(nextState); + this.state = newState; + setItem("todo", JSON.stringify(newState)); + updateCount(newState); this.render(); }; diff --git a/src/util/validation.js b/src/util/validation.js index fd30d81..722bbd4 100644 --- a/src/util/validation.js +++ b/src/util/validation.js @@ -4,6 +4,12 @@ const validation = { throw new Error("You must use new keyword"); } }, + state(todoList) { + return todoList.filter( + (todo) => + typeof todo?.text === "string" && typeof todo?.isCompleted === "boolean" + ); + }, }; export default validation; From 20050fd0391a6289695c644e57d24bc20f6fb5e7 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 19 Oct 2023 01:50:27 +0900 Subject: [PATCH 16/49] =?UTF-8?q?=ED=88=AC=EB=91=90=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B9=B4=EC=9A=B4=ED=8A=B8=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=EA=B0=92=20=ED=95=A0=EB=8B=B9=20=EC=A1=B0=EA=B1=B4=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/TodoCount.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TodoCount.js b/src/TodoCount.js index 18f7731..810ef12 100644 --- a/src/TodoCount.js +++ b/src/TodoCount.js @@ -6,7 +6,7 @@ export default function TodoCount({ $target, initialCount }) { const $container = document.createElement("div"); $target.appendChild($container); - if (initialCount.total && initialCount.done) { + if (initialCount.total) { this.state = initialCount; } else this.state = { total: 0, done: 0 }; From 1d84f5d218e9f99a06b5085392b8d0c6def33ec8 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 19 Oct 2023 01:51:06 +0900 Subject: [PATCH 17/49] =?UTF-8?q?=EB=B0=98=EB=B3=B5=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20setState=EC=97=90=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 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/App.js b/src/App.js index 9448380..3125ca8 100644 --- a/src/App.js +++ b/src/App.js @@ -15,15 +15,13 @@ export default function App({ $target, initialState, initialCount }) { onSubmit: (text) => { const nextState = [...todoList.state, { text, isCompleted: false }]; todoList.setState(nextState); - updateCount(nextState); - setItem("todo", JSON.stringify(nextState)); }, }); const todoList = new TodoList({ $target, initialState, - updateCount: () => updateCount(todoList.state), + updateCount: (state) => updateCount(state), }); const todoCount = new TodoCount({ From ab66e5f11514155008318d36e0316bd14c19cd42 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 19 Oct 2023 01:51:27 +0900 Subject: [PATCH 18/49] =?UTF-8?q?=ED=88=AC=EB=91=90=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=82=AD=EC=84=A0/=EC=82=AD=EC=A0=9C=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/TodoList.js | 58 +++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/src/TodoList.js b/src/TodoList.js index 2a512a6..2676bc8 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -25,10 +25,11 @@ export default function TodoList({ $target, initialState, updateCount }) { `; + }; + + $todoList.addEventListener("click", (e) => { + const { target } = e; + const $li = target.closest("li"); - const deleteButtonAll = $todoList.querySelectorAll(".deleteBtn"); - deleteButtonAll.forEach(($deleteBtn, index) => { - $deleteBtn.addEventListener("click", (e) => { - // list์˜ li ํ˜น์€ checkbox๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•จ - e.stopPropagation(); + if ($li) { + const newState = [...this.state]; + const { index } = $li.dataset; - const newState = [...this.state]; + if (target.className === "deleteBtn") { newState.splice(index, 1); this.setState(newState); - setItem("todo", JSON.stringify(newState)); - updateCount(); - }); - }); + } else if (target.className.includes("todoList")) { + const isCompleted = target.className.includes("completed"); - const liList = $todoList.querySelectorAll("li"); - liList.forEach(($li, index) => { - $li.addEventListener("click", (e) => { - const checkbox = e.currentTarget.children[0]; - if (e.target.tagName !== "INPUT") { - // checkbox๊ฐ€ ์•„๋‹Œ ๋ถ€๋ถ„์„ ํด๋ฆญํ–ˆ์„ ๋•Œ checked ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝ - checkbox.checked = !checkbox.checked; - } + if (isCompleted) target.classList.remove("completed"); + else target.classList.add("completed"); - const isCompleted = checkbox.checked; - if (isCompleted) { - e.currentTarget.classList.add("completed"); - } else { - e.currentTarget.classList.remove("completed"); - } - - const newState = [...this.state]; newState[index] = { ...newState[index], - isCompleted, + isCompleted: !isCompleted, }; this.setState(newState); - setItem("todo", JSON.stringify(newState)); - updateCount(); - }); - }); - }; + } + } + }); this.render(); } From 565fcd4137a9a665b85396fb48b83e6c192822e7 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 15:42:46 +0900 Subject: [PATCH 19/49] =?UTF-8?q?rename:=20=ED=8F=B4=EB=8D=94=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 10 +++++----- src/{ => components}/Header.js | 2 +- src/{ => components}/TodoCount.js | 2 +- src/{ => components}/TodoForm.js | 2 +- src/{ => components}/TodoList.js | 8 ++++---- src/main.js | 2 +- src/{ => utils}/storage.js | 0 src/{util => utils}/validation.js | 0 8 files changed, 13 insertions(+), 13 deletions(-) rename src/{ => components}/Header.js (83%) rename src/{ => components}/TodoCount.js (91%) rename src/{ => components}/TodoForm.js (94%) rename src/{ => components}/TodoList.js (91%) rename src/{ => utils}/storage.js (100%) rename src/{util => utils}/validation.js (100%) diff --git a/src/App.js b/src/App.js index 3125ca8..fdcae15 100644 --- a/src/App.js +++ b/src/App.js @@ -1,8 +1,8 @@ -import Header from "./Header.js"; -import TodoForm from "./TodoForm.js"; -import TodoList from "./TodoList.js"; -import TodoCount from "./TodoCount.js"; -import { setItem } from "./storage.js"; +import Header from "./components/Header.js"; +import TodoForm from "./components/TodoForm.js"; +import TodoList from "./components/TodoList.js"; +import TodoCount from "./components/TodoCount.js"; +import { setItem } from "./utils/storage.js"; export default function App({ $target, initialState, initialCount }) { new Header({ diff --git a/src/Header.js b/src/components/Header.js similarity index 83% rename from src/Header.js rename to src/components/Header.js index 4e67a16..74ebc35 100644 --- a/src/Header.js +++ b/src/components/Header.js @@ -1,4 +1,4 @@ -import validation from "./util/validation.js"; +import validation from "../utils/validation.js"; export default function Header({ $target, text }) { validation.newTarget(new.target); diff --git a/src/TodoCount.js b/src/components/TodoCount.js similarity index 91% rename from src/TodoCount.js rename to src/components/TodoCount.js index 810ef12..fe35e7a 100644 --- a/src/TodoCount.js +++ b/src/components/TodoCount.js @@ -1,4 +1,4 @@ -import validation from "./util/validation.js"; +import validation from "../utils/validation.js"; export default function TodoCount({ $target, initialCount }) { validation.newTarget(new.target); diff --git a/src/TodoForm.js b/src/components/TodoForm.js similarity index 94% rename from src/TodoForm.js rename to src/components/TodoForm.js index 955c400..4ff29be 100644 --- a/src/TodoForm.js +++ b/src/components/TodoForm.js @@ -1,4 +1,4 @@ -import validation from "./util/validation.js"; +import validation from "../utils/validation.js"; export default function TodoForm({ $target, onSubmit }) { validation.newTarget(new.target); diff --git a/src/TodoList.js b/src/components/TodoList.js similarity index 91% rename from src/TodoList.js rename to src/components/TodoList.js index 2676bc8..c6b6aad 100644 --- a/src/TodoList.js +++ b/src/components/TodoList.js @@ -1,5 +1,5 @@ -import { setItem } from "./storage.js"; -import validation from "./util/validation.js"; +import { setItem } from "../utils/storage.js"; +import validation from "../utils/validation.js"; // params.$target - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋  DOM ์•จ๋ฆฌ๋จผํŠธ // params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ @@ -27,8 +27,8 @@ export default function TodoList({ $target, initialState, updateCount }) { .map( ({ text, isCompleted }, index) => `
  • + isCompleted ? "completed" : "" + }"> ${text}
  • diff --git a/src/main.js b/src/main.js index baaf076..296bb82 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,5 @@ import App from "./App.js"; -import { getItem } from "./storage.js"; +import { getItem } from "./utils/storage.js"; const initialState = getItem("todo", []); const initialCount = getItem("count", { total: 0, done: 0 }); diff --git a/src/storage.js b/src/utils/storage.js similarity index 100% rename from src/storage.js rename to src/utils/storage.js diff --git a/src/util/validation.js b/src/utils/validation.js similarity index 100% rename from src/util/validation.js rename to src/utils/validation.js From 93fde36bbe6d4d092b3bbda8b1ca1a35e3d91454 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 15:44:37 +0900 Subject: [PATCH 20/49] =?UTF-8?q?rename:=20.js=20>=20.ts=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/{App.js => App.ts} | 10 +++++----- .../Header.js => component/Header.ts} | 2 +- .../TodoCount.js => component/TodoCount.ts} | 2 +- .../TodoForm.js => component/TodoForm.ts} | 2 +- .../TodoList.js => component/TodoList.ts} | 17 ++++++++--------- src/{main.js => main.ts} | 2 +- src/{utils/storage.js => util/storage.ts} | 0 src/{utils/validation.js => util/validation.ts} | 0 8 files changed, 17 insertions(+), 18 deletions(-) rename src/{App.js => App.ts} (76%) rename src/{components/Header.js => component/Header.ts} (83%) rename src/{components/TodoCount.js => component/TodoCount.ts} (91%) rename src/{components/TodoForm.js => component/TodoForm.ts} (94%) rename src/{components/TodoList.js => component/TodoList.ts} (83%) rename src/{main.js => main.ts} (84%) rename src/{utils/storage.js => util/storage.ts} (100%) rename src/{utils/validation.js => util/validation.ts} (100%) diff --git a/src/App.js b/src/App.ts similarity index 76% rename from src/App.js rename to src/App.ts index fdcae15..add5541 100644 --- a/src/App.js +++ b/src/App.ts @@ -1,8 +1,8 @@ -import Header from "./components/Header.js"; -import TodoForm from "./components/TodoForm.js"; -import TodoList from "./components/TodoList.js"; -import TodoCount from "./components/TodoCount.js"; -import { setItem } from "./utils/storage.js"; +import Header from "./component/Header.js"; +import TodoForm from "./component/TodoForm.js"; +import TodoList from "./component/TodoList.js"; +import TodoCount from "./component/TodoCount.js"; +import { setItem } from "./util/storage.js"; export default function App({ $target, initialState, initialCount }) { new Header({ diff --git a/src/components/Header.js b/src/component/Header.ts similarity index 83% rename from src/components/Header.js rename to src/component/Header.ts index 74ebc35..633f6dc 100644 --- a/src/components/Header.js +++ b/src/component/Header.ts @@ -1,4 +1,4 @@ -import validation from "../utils/validation.js"; +import validation from "../util/validation.js"; export default function Header({ $target, text }) { validation.newTarget(new.target); diff --git a/src/components/TodoCount.js b/src/component/TodoCount.ts similarity index 91% rename from src/components/TodoCount.js rename to src/component/TodoCount.ts index fe35e7a..8cf870c 100644 --- a/src/components/TodoCount.js +++ b/src/component/TodoCount.ts @@ -1,4 +1,4 @@ -import validation from "../utils/validation.js"; +import validation from "../util/validation.js"; export default function TodoCount({ $target, initialCount }) { validation.newTarget(new.target); diff --git a/src/components/TodoForm.js b/src/component/TodoForm.ts similarity index 94% rename from src/components/TodoForm.js rename to src/component/TodoForm.ts index 4ff29be..e09a633 100644 --- a/src/components/TodoForm.js +++ b/src/component/TodoForm.ts @@ -1,4 +1,4 @@ -import validation from "../utils/validation.js"; +import validation from "../util/validation.js"; export default function TodoForm({ $target, onSubmit }) { validation.newTarget(new.target); diff --git a/src/components/TodoList.js b/src/component/TodoList.ts similarity index 83% rename from src/components/TodoList.js rename to src/component/TodoList.ts index c6b6aad..f83a98c 100644 --- a/src/components/TodoList.js +++ b/src/component/TodoList.ts @@ -1,5 +1,5 @@ -import { setItem } from "../utils/storage.js"; -import validation from "../utils/validation.js"; +import { setItem } from "../util/storage.js"; +import validation from "../util/validation.js"; // params.$target - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋  DOM ์•จ๋ฆฌ๋จผํŠธ // params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ @@ -24,17 +24,16 @@ export default function TodoList({ $target, initialState, updateCount }) { $todoList.innerHTML = ` `; }; diff --git a/src/main.js b/src/main.ts similarity index 84% rename from src/main.js rename to src/main.ts index 296bb82..3e40f13 100644 --- a/src/main.js +++ b/src/main.ts @@ -1,5 +1,5 @@ import App from "./App.js"; -import { getItem } from "./utils/storage.js"; +import { getItem } from "./util/storage.js"; const initialState = getItem("todo", []); const initialCount = getItem("count", { total: 0, done: 0 }); diff --git a/src/utils/storage.js b/src/util/storage.ts similarity index 100% rename from src/utils/storage.js rename to src/util/storage.ts diff --git a/src/utils/validation.js b/src/util/validation.ts similarity index 100% rename from src/utils/validation.js rename to src/util/validation.ts From 616d1d3cfbdb9c088b9fcbba55bda7fe9a27bd94 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 19:27:45 +0900 Subject: [PATCH 21/49] =?UTF-8?q?chore:=20typescript=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=20=EC=85=8B=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + index.html | 26 ++- package-lock.json | 455 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 12 ++ tsconfig.json | 9 + tslint.json | 9 + 6 files changed, 499 insertions(+), 14 deletions(-) create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 tsconfig.json create mode 100644 tslint.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b2d59d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/dist \ No newline at end of file diff --git a/index.html b/index.html index 552acda..d4ca147 100644 --- a/index.html +++ b/index.html @@ -1,16 +1,14 @@ - + + + + + Todo List + + - - - - Todo List - - - - -
    - - - - \ No newline at end of file + +
    + + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..05cc57f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,455 @@ +{ + "name": "todo-list", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "todo-list", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "tslint": "^6.1.3", + "typescript": "^5.3.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" + } + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c439659 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "todo-list", + "version": "1.0.0", + "main": "main.js", + "scripts": { + "start": "npx serve" + }, + "devDependencies": { + "tslint": "^6.1.3", + "typescript": "^5.3.3" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6303ad8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "ES2015", + "module": "ES2015", + "strict": true, + "outDir": "dist", + "sourceMap": true + } +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..32fa6e5 --- /dev/null +++ b/tslint.json @@ -0,0 +1,9 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:recommended" + ], + "jsRules": {}, + "rules": {}, + "rulesDirectory": [] +} \ No newline at end of file From 28224b1984c6e7f3c8770ec246705486330f9d9a Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 19:31:12 +0900 Subject: [PATCH 22/49] =?UTF-8?q?rename:=20=ED=8F=B4=EB=8D=94=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 11 ++++++----- src/component/Header.ts | 14 -------------- src/{component => components}/TodoCount.ts | 2 +- src/{component => components}/TodoForm.ts | 2 +- src/{component => components}/TodoList.ts | 4 ++-- src/main.ts | 2 +- src/{util => utils}/storage.ts | 0 src/{util => utils}/validation.ts | 0 8 files changed, 11 insertions(+), 24 deletions(-) delete mode 100644 src/component/Header.ts rename src/{component => components}/TodoCount.ts (91%) rename src/{component => components}/TodoForm.ts (94%) rename src/{component => components}/TodoList.ts (94%) rename src/{util => utils}/storage.ts (100%) rename src/{util => utils}/validation.ts (100%) diff --git a/src/App.ts b/src/App.ts index add5541..58efb7e 100644 --- a/src/App.ts +++ b/src/App.ts @@ -1,8 +1,9 @@ -import Header from "./component/Header.js"; -import TodoForm from "./component/TodoForm.js"; -import TodoList from "./component/TodoList.js"; -import TodoCount from "./component/TodoCount.js"; -import { setItem } from "./util/storage.js"; +import Header from "./components/Header.js"; +import TodoForm from "./components/TodoForm.js"; +import TodoList from "./components/TodoList.js"; +import TodoCount from "./components/TodoCount.js"; +import { setItem } from "./utils/storage.js"; +import { TodoCount as TodoCnt, TodoItem } from "./types/todo.js"; export default function App({ $target, initialState, initialCount }) { new Header({ diff --git a/src/component/Header.ts b/src/component/Header.ts deleted file mode 100644 index 633f6dc..0000000 --- a/src/component/Header.ts +++ /dev/null @@ -1,14 +0,0 @@ -import validation from "../util/validation.js"; - -export default function Header({ $target, text }) { - validation.newTarget(new.target); - - const $header = document.createElement("h1"); - $target.appendChild($header); - - this.render = () => { - $header.textContent = text; - }; - - this.render(); -} diff --git a/src/component/TodoCount.ts b/src/components/TodoCount.ts similarity index 91% rename from src/component/TodoCount.ts rename to src/components/TodoCount.ts index 8cf870c..fe35e7a 100644 --- a/src/component/TodoCount.ts +++ b/src/components/TodoCount.ts @@ -1,4 +1,4 @@ -import validation from "../util/validation.js"; +import validation from "../utils/validation.js"; export default function TodoCount({ $target, initialCount }) { validation.newTarget(new.target); diff --git a/src/component/TodoForm.ts b/src/components/TodoForm.ts similarity index 94% rename from src/component/TodoForm.ts rename to src/components/TodoForm.ts index e09a633..4ff29be 100644 --- a/src/component/TodoForm.ts +++ b/src/components/TodoForm.ts @@ -1,4 +1,4 @@ -import validation from "../util/validation.js"; +import validation from "../utils/validation.js"; export default function TodoForm({ $target, onSubmit }) { validation.newTarget(new.target); diff --git a/src/component/TodoList.ts b/src/components/TodoList.ts similarity index 94% rename from src/component/TodoList.ts rename to src/components/TodoList.ts index f83a98c..65759a7 100644 --- a/src/component/TodoList.ts +++ b/src/components/TodoList.ts @@ -1,5 +1,5 @@ -import { setItem } from "../util/storage.js"; -import validation from "../util/validation.js"; +import { setItem } from "../utils/storage.js"; +import validation from "../utils/validation.js"; // params.$target - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋  DOM ์•จ๋ฆฌ๋จผํŠธ // params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ diff --git a/src/main.ts b/src/main.ts index 3e40f13..296bb82 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ import App from "./App.js"; -import { getItem } from "./util/storage.js"; +import { getItem } from "./utils/storage.js"; const initialState = getItem("todo", []); const initialCount = getItem("count", { total: 0, done: 0 }); diff --git a/src/util/storage.ts b/src/utils/storage.ts similarity index 100% rename from src/util/storage.ts rename to src/utils/storage.ts diff --git a/src/util/validation.ts b/src/utils/validation.ts similarity index 100% rename from src/util/validation.ts rename to src/utils/validation.ts From 2d8a1b3d1115f650ab95fa1db2195e0735bb3fd1 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 19:32:43 +0900 Subject: [PATCH 23/49] =?UTF-8?q?feat:=20main.ts=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 296bb82..301c03d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,7 +3,7 @@ import { getItem } from "./utils/storage.js"; const initialState = getItem("todo", []); const initialCount = getItem("count", { total: 0, done: 0 }); -const $app = document.querySelector("#app"); +const $app = document.querySelector("#app") as HTMLElement; new App({ $target: $app, From 3201d20c1a48dd8ed1c695843b5ac10f18f6d72a Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 19:34:10 +0900 Subject: [PATCH 24/49] =?UTF-8?q?feat:=20App=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=ED=81=B4=EB=9E=98=EC=8A=A4=20+=20ts=20=EB=B3=80?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 59 +++++++++++++++++++++++++---------------------- src/main.ts | 6 +---- src/types/todo.ts | 9 ++++++++ 3 files changed, 42 insertions(+), 32 deletions(-) create mode 100644 src/types/todo.ts diff --git a/src/App.ts b/src/App.ts index 58efb7e..90bc729 100644 --- a/src/App.ts +++ b/src/App.ts @@ -5,36 +5,41 @@ import TodoCount from "./components/TodoCount.js"; import { setItem } from "./utils/storage.js"; import { TodoCount as TodoCnt, TodoItem } from "./types/todo.js"; -export default function App({ $target, initialState, initialCount }) { - new Header({ - $target, - text: "Todo List", - }); +export default class App { + // todoList: TodoList; + // todoCount: TodoCount; - new TodoForm({ - $target, - onSubmit: (text) => { - const nextState = [...todoList.state, { text, isCompleted: false }]; - todoList.setState(nextState); - }, - }); + constructor( + protected readonly $target: HTMLElement, + protected readonly initialState: TodoItem[], + protected readonly initialCount: TodoCnt + ) { - const todoList = new TodoList({ - $target, - initialState, - updateCount: (state) => updateCount(state), - }); + // new TodoForm({ + // $target: this.$target, + // onSubmit: (text: string) => { + // const nextState = [...this.todoList.state, { text, isCompleted: false }]; + // this.todoList.setState(nextState); + // }, + // }); - const todoCount = new TodoCount({ - $target, - initialCount, - }); + // this.todoList = new TodoList({ + // $target: this.$target, + // initialState: this.initialState, + // updateCount: (state: TodoItem[]) => this.updateCount(state), + // }); + + // this.todoCount = new TodoCount({ + // $target: this.$target, + // initialCount: this.initialCount, + // }); + } // ์นด์šดํŠธ ์—…๋ฐ์ดํŠธ - const updateCount = (todoList) => { - const done = todoList.filter((todo) => todo.isCompleted).length; - const nextState = { total: todoList.length, done }; - todoCount.setState(nextState); - setItem("count", JSON.stringify(nextState)); - }; + // updateCount(todoList: TodoItem[]) { + // const done = todoList.filter((todo) => todo.isCompleted).length; + // const nextState = { total: todoList.length, done }; + // this.todoCount.setState(nextState); + // setItem("count", JSON.stringify(nextState)); + // }; } diff --git a/src/main.ts b/src/main.ts index 301c03d..4206790 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,8 +5,4 @@ const initialState = getItem("todo", []); const initialCount = getItem("count", { total: 0, done: 0 }); const $app = document.querySelector("#app") as HTMLElement; -new App({ - $target: $app, - initialState, - initialCount, -}); +new App($app, initialState, initialCount); diff --git a/src/types/todo.ts b/src/types/todo.ts new file mode 100644 index 0000000..4e06d91 --- /dev/null +++ b/src/types/todo.ts @@ -0,0 +1,9 @@ +export interface TodoItem { + text: string; + isCompleted: boolean; +} + +export interface TodoCount { + total: number; + done: number; +} \ No newline at end of file From ebc2683b1588443676c62eab2304ab22c53d5233 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 19:34:19 +0900 Subject: [PATCH 25/49] =?UTF-8?q?feat:=20Header=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=ED=81=B4=EB=9E=98=EC=8A=A4=20+=20ts=20?= =?UTF-8?q?=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 1 + src/components/Header.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 src/components/Header.ts diff --git a/src/App.ts b/src/App.ts index 90bc729..36bdb7c 100644 --- a/src/App.ts +++ b/src/App.ts @@ -14,6 +14,7 @@ export default class App { protected readonly initialState: TodoItem[], protected readonly initialCount: TodoCnt ) { + new Header(this.$target, "Todo List"); // new TodoForm({ // $target: this.$target, diff --git a/src/components/Header.ts b/src/components/Header.ts new file mode 100644 index 0000000..77eee52 --- /dev/null +++ b/src/components/Header.ts @@ -0,0 +1,15 @@ +export default class Header { + $header = document.createElement("h1"); + + constructor( + private readonly $target: HTMLElement, + private readonly text: string + ) { + this.$target.appendChild(this.$header); + this.render(); + }; + + render() { + this.$header.textContent = this.text; + } +}; From 90adc4b34f23073cad3d32fa4d7c1a9a7abf8351 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 20:05:52 +0900 Subject: [PATCH 26/49] =?UTF-8?q?feat:=20TodoList=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=ED=81=B4=EB=9E=98=EC=8A=A4=20+=20ts=20?= =?UTF-8?q?=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 24 +++++------ src/components/TodoList.ts | 83 ++++++++++++++++++++------------------ src/utils/validation.ts | 4 +- 3 files changed, 58 insertions(+), 53 deletions(-) diff --git a/src/App.ts b/src/App.ts index 36bdb7c..baa10e0 100644 --- a/src/App.ts +++ b/src/App.ts @@ -6,7 +6,7 @@ import { setItem } from "./utils/storage.js"; import { TodoCount as TodoCnt, TodoItem } from "./types/todo.js"; export default class App { - // todoList: TodoList; + todoList: TodoList; // todoCount: TodoCount; constructor( @@ -24,11 +24,11 @@ export default class App { // }, // }); - // this.todoList = new TodoList({ - // $target: this.$target, - // initialState: this.initialState, - // updateCount: (state: TodoItem[]) => this.updateCount(state), - // }); + this.todoList = new TodoList( + this.$target, + this.initialState, + (state: TodoItem[]) => this.updateCount(state) + ); // this.todoCount = new TodoCount({ // $target: this.$target, @@ -37,10 +37,10 @@ export default class App { } // ์นด์šดํŠธ ์—…๋ฐ์ดํŠธ - // updateCount(todoList: TodoItem[]) { - // const done = todoList.filter((todo) => todo.isCompleted).length; - // const nextState = { total: todoList.length, done }; - // this.todoCount.setState(nextState); - // setItem("count", JSON.stringify(nextState)); - // }; + updateCount(todoList: TodoItem[]) { + // const done = todoList.filter((todo) => todo.isCompleted).length; + // const nextState = { total: todoList.length, done }; + // this.todoCount.setState(nextState); + // setItem("count", JSON.stringify(nextState)); + }; } diff --git a/src/components/TodoList.ts b/src/components/TodoList.ts index 65759a7..a83e748 100644 --- a/src/components/TodoList.ts +++ b/src/components/TodoList.ts @@ -1,27 +1,58 @@ import { setItem } from "../utils/storage.js"; import validation from "../utils/validation.js"; +import { TodoItem } from "../types/todo.js"; -// params.$target - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋  DOM ์•จ๋ฆฌ๋จผํŠธ -// params.initialState - ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํƒœ -export default function TodoList({ $target, initialState, updateCount }) { - validation.newTarget(new.target); +export default class TodoList { + state: TodoItem[] = []; + $todoList = document.createElement("div"); - const $todoList = document.createElement("div"); - $target.appendChild($todoList); + constructor( + private readonly $target: HTMLElement, + private readonly initialState: TodoItem[], + private readonly updateCount: (state: TodoItem[]) => void + ) { + this.$target.appendChild(this.$todoList); - if (Array.isArray(initialState)) this.state = initialState; - else this.state = []; + if (Array.isArray(this.initialState)) this.state = this.initialState; + else this.state = []; - this.setState = (nextState) => { + this.render(); + + this.$todoList.addEventListener("click", (e) => { + const target = e.target as HTMLLIElement; + const $li = target.closest("li"); + + if ($li) { + const newState = [...this.state]; + const index = +($li.dataset.index as string); + + if (target.className === "deleteBtn") { + newState.splice(index, 1); + this.setState(newState); + } else if (target.className.includes("todoList")) { + const isCompleted = target.className.includes("completed"); + if (isCompleted) target.classList.remove("completed"); + else target.classList.add("completed"); + newState[index] = { + ...newState[index], + isCompleted: !isCompleted, + }; + this.setState(newState); + } + } + }); + } + + setState(nextState: TodoItem[]) { const newState = validation.state(nextState); this.state = newState; setItem("todo", JSON.stringify(newState)); - updateCount(newState); + this.updateCount(newState); this.render(); }; - this.render = () => { - $todoList.innerHTML = ` + render() { + this.$todoList.innerHTML = ` `; }; - - $todoList.addEventListener("click", (e) => { - const { target } = e; - const $li = target.closest("li"); - - if ($li) { - const newState = [...this.state]; - const { index } = $li.dataset; - - if (target.className === "deleteBtn") { - newState.splice(index, 1); - this.setState(newState); - } else if (target.className.includes("todoList")) { - const isCompleted = target.className.includes("completed"); - - if (isCompleted) target.classList.remove("completed"); - else target.classList.add("completed"); - - newState[index] = { - ...newState[index], - isCompleted: !isCompleted, - }; - this.setState(newState); - } - } - }); - - this.render(); } diff --git a/src/utils/validation.ts b/src/utils/validation.ts index 722bbd4..76a28f9 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -1,10 +1,12 @@ +import { TodoItem } from "../types/todo.js"; + const validation = { newTarget(target) { if (!target) { throw new Error("You must use new keyword"); } }, - state(todoList) { + state(todoList: TodoItem[]) { return todoList.filter( (todo) => typeof todo?.text === "string" && typeof todo?.isCompleted === "boolean" From adb0435169381054f3d91505fcaeadb99c9cddc7 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 20:55:05 +0900 Subject: [PATCH 27/49] =?UTF-8?q?feat:=20TodoForm=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=ED=81=B4=EB=9E=98=EC=8A=A4=20+=20ts=20?= =?UTF-8?q?=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 14 +++++++------- src/components/TodoForm.ts | 34 +++++++++++++++++----------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/App.ts b/src/App.ts index baa10e0..2872271 100644 --- a/src/App.ts +++ b/src/App.ts @@ -16,13 +16,13 @@ export default class App { ) { new Header(this.$target, "Todo List"); - // new TodoForm({ - // $target: this.$target, - // onSubmit: (text: string) => { - // const nextState = [...this.todoList.state, { text, isCompleted: false }]; - // this.todoList.setState(nextState); - // }, - // }); + new TodoForm( + this.$target, + (text: string) => { + const nextState = [...this.todoList.state, { text, isCompleted: false }]; + this.todoList.setState(nextState); + }, + ); this.todoList = new TodoList( this.$target, diff --git a/src/components/TodoForm.ts b/src/components/TodoForm.ts index 4ff29be..b75c527 100644 --- a/src/components/TodoForm.ts +++ b/src/components/TodoForm.ts @@ -1,32 +1,32 @@ -import validation from "../utils/validation.js"; -export default function TodoForm({ $target, onSubmit }) { - validation.newTarget(new.target); +export default class TodoForm { + $form = document.createElement("form"); + isInit = false; - const $form = document.createElement("form"); - $target.appendChild($form); + constructor( + private readonly $target: HTMLElement, + private readonly onSubmit: (text: string) => void + ) { + this.$target.appendChild(this.$form); + this.render(); + } - let isInit = false; - - this.render = () => { - $form.innerHTML = ` + render() { + this.$form.innerHTML = ` `; - if (!isInit) { - $form.addEventListener("submit", (e) => { - e.preventDefault(); // ํƒœ๊ทธ๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ณ ์œ  ๊ธฐ๋Šฅ ๋ง‰๊ธฐ(form ํƒœ๊ทธ์˜ ์ƒˆ๋กœ๊ณ ์นจ ๋ง‰๊ธฐ) - - const $todo = $form.querySelector("input[name=todo]"); + if (!this.isInit) { + this.$form.addEventListener("submit", (e) => { + e.preventDefault(); + const $todo = this.$form.querySelector("input[name=todo]") as HTMLInputElement; const text = $todo.value; if (text.length > 1) { $todo.value = ""; - onSubmit(text); + this.onSubmit(text); } else alert("๋‘ ๊ธ€์ž ์ด์ƒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); }); } }; - - this.render(); } From 46bfbbcfe044df501b72d48c7aaf899d10dcb6ee Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 20:56:30 +0900 Subject: [PATCH 28/49] =?UTF-8?q?remove:=20class=EB=A1=9C=20=EB=B0=94?= =?UTF-8?q?=EA=BE=B8=EB=A9=B4=EC=84=9C=20new=20=EC=97=B0=EC=82=B0=EC=9E=90?= =?UTF-8?q?=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/validation.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/utils/validation.ts b/src/utils/validation.ts index 76a28f9..4ee9d74 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -1,11 +1,6 @@ import { TodoItem } from "../types/todo.js"; const validation = { - newTarget(target) { - if (!target) { - throw new Error("You must use new keyword"); - } - }, state(todoList: TodoItem[]) { return todoList.filter( (todo) => From 634a9936b67d9964ba568eb540c167d9ac7aee96 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 20:49:32 +0900 Subject: [PATCH 29/49] =?UTF-8?q?feat:=20TodoCount=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=ED=81=B4=EB=9E=98=EC=8A=A4=20+=20ts=20?= =?UTF-8?q?=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 7 ++----- src/components/TodoCount.ts | 31 ++++++++++++++++++------------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/App.ts b/src/App.ts index 2872271..b124343 100644 --- a/src/App.ts +++ b/src/App.ts @@ -7,7 +7,7 @@ import { TodoCount as TodoCnt, TodoItem } from "./types/todo.js"; export default class App { todoList: TodoList; - // todoCount: TodoCount; + todoCount: TodoCount; constructor( protected readonly $target: HTMLElement, @@ -30,10 +30,7 @@ export default class App { (state: TodoItem[]) => this.updateCount(state) ); - // this.todoCount = new TodoCount({ - // $target: this.$target, - // initialCount: this.initialCount, - // }); + this.todoCount = new TodoCount(this.$target, this.initialCount); } // ์นด์šดํŠธ ์—…๋ฐ์ดํŠธ diff --git a/src/components/TodoCount.ts b/src/components/TodoCount.ts index fe35e7a..48efa10 100644 --- a/src/components/TodoCount.ts +++ b/src/components/TodoCount.ts @@ -1,23 +1,28 @@ -import validation from "../utils/validation.js"; +import { TodoCount as TodoCnt } from "../types/todo.js"; -export default function TodoCount({ $target, initialCount }) { - validation.newTarget(new.target); +export default class TodoCount { + $container = document.createElement("div"); + state: TodoCnt; - const $container = document.createElement("div"); - $target.appendChild($container); + constructor( + private readonly $target: HTMLElement, + private readonly initialCount: TodoCnt + ) { + this.$target.appendChild(this.$container); - if (initialCount.total) { - this.state = initialCount; - } else this.state = { total: 0, done: 0 }; + if (this.initialCount.total) { + this.state = this.initialCount; + } else this.state = { total: 0, done: 0 }; - this.setState = (nextState) => { + this.render(); + } + + setState(nextState: TodoCnt) { this.state = nextState; this.render(); }; - this.render = () => { - $container.textContent = `์™„๋ฃŒ ${this.state.done}๊ฐœ / ์ด ${this.state.total}๊ฐœ`; + render() { + this.$container.textContent = `์™„๋ฃŒ ${this.state.done}๊ฐœ / ์ด ${this.state.total}๊ฐœ`; }; - - this.render(); } From d7ad87b2fb6f13e4c3804efe9cc18a3c88448ef7 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 21:04:19 +0900 Subject: [PATCH 30/49] =?UTF-8?q?comment:=20updateCount=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/App.ts b/src/App.ts index b124343..c341bfa 100644 --- a/src/App.ts +++ b/src/App.ts @@ -35,9 +35,9 @@ export default class App { // ์นด์šดํŠธ ์—…๋ฐ์ดํŠธ updateCount(todoList: TodoItem[]) { - // const done = todoList.filter((todo) => todo.isCompleted).length; - // const nextState = { total: todoList.length, done }; - // this.todoCount.setState(nextState); - // setItem("count", JSON.stringify(nextState)); + const done = todoList.filter((todo) => todo.isCompleted).length; + const nextState = { total: todoList.length, done }; + this.todoCount.setState(nextState); + setItem("count", JSON.stringify(nextState)); }; } From 7a412578a059260c51ea2fdea60954325af6b12e Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 21:05:29 +0900 Subject: [PATCH 31/49] =?UTF-8?q?feat:=20storage=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=ED=83=80=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/storage.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/storage.ts b/src/utils/storage.ts index 7119153..ea219fa 100644 --- a/src/utils/storage.ts +++ b/src/utils/storage.ts @@ -1,6 +1,6 @@ const storage = window.localStorage; -export const setItem = (key, value) => { +export const setItem = (key: string, value: string) => { try { storage.setItem(key, value); } catch (error) { @@ -8,7 +8,7 @@ export const setItem = (key, value) => { } }; -export const getItem = (key, defaultValue) => { +export const getItem = (key: string, defaultValue: T): T => { try { const data = storage.getItem(key); if (data) return JSON.parse(data); From a891ce3d9ac986777bd67de84d0d22590bceb2ba Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 21:45:36 +0900 Subject: [PATCH 32/49] =?UTF-8?q?feat:=20=EC=A0=91=EA=B7=BC=EC=A0=9C?= =?UTF-8?q?=ED=95=9C=EC=9E=90=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 14 +++++++------- src/components/Header.ts | 4 ++-- src/components/TodoCount.ts | 6 +++--- src/components/TodoForm.ts | 6 +++--- src/components/TodoList.ts | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/App.ts b/src/App.ts index c341bfa..481ccc5 100644 --- a/src/App.ts +++ b/src/App.ts @@ -6,13 +6,13 @@ import { setItem } from "./utils/storage.js"; import { TodoCount as TodoCnt, TodoItem } from "./types/todo.js"; export default class App { - todoList: TodoList; - todoCount: TodoCount; + private readonly todoList: TodoList; + private readonly todoCount: TodoCount; constructor( - protected readonly $target: HTMLElement, - protected readonly initialState: TodoItem[], - protected readonly initialCount: TodoCnt + private readonly $target: HTMLElement, + private readonly initialState: TodoItem[], + private readonly initialCount: TodoCnt ) { new Header(this.$target, "Todo List"); @@ -27,14 +27,14 @@ export default class App { this.todoList = new TodoList( this.$target, this.initialState, - (state: TodoItem[]) => this.updateCount(state) + (state: TodoItem[]) => this.#updateCount(state) ); this.todoCount = new TodoCount(this.$target, this.initialCount); } // ์นด์šดํŠธ ์—…๋ฐ์ดํŠธ - updateCount(todoList: TodoItem[]) { + #updateCount(todoList: TodoItem[]) { const done = todoList.filter((todo) => todo.isCompleted).length; const nextState = { total: todoList.length, done }; this.todoCount.setState(nextState); diff --git a/src/components/Header.ts b/src/components/Header.ts index 77eee52..e842bf1 100644 --- a/src/components/Header.ts +++ b/src/components/Header.ts @@ -1,5 +1,5 @@ export default class Header { - $header = document.createElement("h1"); + private readonly $header = document.createElement("h1"); constructor( private readonly $target: HTMLElement, @@ -9,7 +9,7 @@ export default class Header { this.render(); }; - render() { + private render() { this.$header.textContent = this.text; } }; diff --git a/src/components/TodoCount.ts b/src/components/TodoCount.ts index 48efa10..b83f9de 100644 --- a/src/components/TodoCount.ts +++ b/src/components/TodoCount.ts @@ -1,8 +1,8 @@ import { TodoCount as TodoCnt } from "../types/todo.js"; export default class TodoCount { - $container = document.createElement("div"); - state: TodoCnt; + private readonly $container = document.createElement("div"); + private state: TodoCnt; constructor( private readonly $target: HTMLElement, @@ -22,7 +22,7 @@ export default class TodoCount { this.render(); }; - render() { + private render() { this.$container.textContent = `์™„๋ฃŒ ${this.state.done}๊ฐœ / ์ด ${this.state.total}๊ฐœ`; }; } diff --git a/src/components/TodoForm.ts b/src/components/TodoForm.ts index b75c527..acdacc9 100644 --- a/src/components/TodoForm.ts +++ b/src/components/TodoForm.ts @@ -1,7 +1,7 @@ export default class TodoForm { - $form = document.createElement("form"); - isInit = false; + private readonly $form = document.createElement("form"); + private isInit = false; constructor( private readonly $target: HTMLElement, @@ -11,7 +11,7 @@ export default class TodoForm { this.render(); } - render() { + private render() { this.$form.innerHTML = ` diff --git a/src/components/TodoList.ts b/src/components/TodoList.ts index a83e748..857b127 100644 --- a/src/components/TodoList.ts +++ b/src/components/TodoList.ts @@ -4,7 +4,7 @@ import { TodoItem } from "../types/todo.js"; export default class TodoList { state: TodoItem[] = []; - $todoList = document.createElement("div"); + private readonly $todoList = document.createElement("div"); constructor( private readonly $target: HTMLElement, @@ -51,7 +51,7 @@ export default class TodoList { this.render(); }; - render() { + private render() { this.$todoList.innerHTML = `
      ${this.state From 0e4f9da3d21913b0a2e62056733a7d05e700f383 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Sat, 9 Dec 2023 21:47:22 +0900 Subject: [PATCH 33/49] =?UTF-8?q?chore:=20scripts=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c439659..54b8863 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "main": "main.js", "scripts": { - "start": "npx serve" + "start": "tsc && npx serve" }, "devDependencies": { "tslint": "^6.1.3", From 663c37a40a67493f6e93dbe4bb13b1b639a24dac Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:42:23 +0900 Subject: [PATCH 34/49] =?UTF-8?q?refactor:=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EB=8B=A8=EC=96=B8=EC=97=90=EC=84=9C=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EA=B0=80=EB=93=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TodoForm.ts | 3 ++- src/components/TodoList.ts | 3 ++- src/main.ts | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/TodoForm.ts b/src/components/TodoForm.ts index acdacc9..4312e85 100644 --- a/src/components/TodoForm.ts +++ b/src/components/TodoForm.ts @@ -20,7 +20,8 @@ export default class TodoForm { if (!this.isInit) { this.$form.addEventListener("submit", (e) => { e.preventDefault(); - const $todo = this.$form.querySelector("input[name=todo]") as HTMLInputElement; + const $todo = this.$form.querySelector("input[name=todo]"); + if (!$todo) return; const text = $todo.value; if (text.length > 1) { $todo.value = ""; diff --git a/src/components/TodoList.ts b/src/components/TodoList.ts index 857b127..f951cf3 100644 --- a/src/components/TodoList.ts +++ b/src/components/TodoList.ts @@ -24,7 +24,8 @@ export default class TodoList { if ($li) { const newState = [...this.state]; - const index = +($li.dataset.index as string); + if (typeof $li.dataset.index !== "string") return; + const index = +$li.dataset.index; if (target.className === "deleteBtn") { newState.splice(index, 1); diff --git a/src/main.ts b/src/main.ts index 4206790..60b666d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,6 +3,6 @@ import { getItem } from "./utils/storage.js"; const initialState = getItem("todo", []); const initialCount = getItem("count", { total: 0, done: 0 }); -const $app = document.querySelector("#app") as HTMLElement; +const $app = document.querySelector("#app"); -new App($app, initialState, initialCount); +$app && new App($app, initialState, initialCount); From e249e6aefd4b71791dbb5c2e88c885d828fe1378 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:42:39 +0900 Subject: [PATCH 35/49] =?UTF-8?q?refactor:=20=EC=B4=88=EA=B8=B0=EA=B0=92?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TodoList.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/TodoList.ts b/src/components/TodoList.ts index f951cf3..e793caf 100644 --- a/src/components/TodoList.ts +++ b/src/components/TodoList.ts @@ -3,7 +3,7 @@ import validation from "../utils/validation.js"; import { TodoItem } from "../types/todo.js"; export default class TodoList { - state: TodoItem[] = []; + state: TodoItem[]; private readonly $todoList = document.createElement("div"); constructor( From 4fa5d9f7d4ff43f7810adbb7a8a0dbda0f5d1be3 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 14 Dec 2023 00:17:32 +0900 Subject: [PATCH 36/49] =?UTF-8?q?refactor:=20constructor=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=20=EC=83=81=ED=83=9C=EA=B0=92=20this=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=EC=9E=90=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 15 +++++++++------ src/components/Header.ts | 2 +- src/components/TodoCount.ts | 7 +++---- src/components/TodoForm.ts | 2 +- src/components/TodoList.ts | 4 ++-- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/App.ts b/src/App.ts index 481ccc5..d61f3e1 100644 --- a/src/App.ts +++ b/src/App.ts @@ -14,23 +14,26 @@ export default class App { private readonly initialState: TodoItem[], private readonly initialCount: TodoCnt ) { - new Header(this.$target, "Todo List"); + new Header($target, "Todo List"); new TodoForm( - this.$target, + $target, (text: string) => { - const nextState = [...this.todoList.state, { text, isCompleted: false }]; + const nextState = [ + ...this.todoList.state, + { text, isCompleted: false } + ]; this.todoList.setState(nextState); }, ); this.todoList = new TodoList( - this.$target, - this.initialState, (state: TodoItem[]) => this.#updateCount(state) + $target, + initialState, ); - this.todoCount = new TodoCount(this.$target, this.initialCount); + this.todoCount = new TodoCount($target, initialCount); } // ์นด์šดํŠธ ์—…๋ฐ์ดํŠธ diff --git a/src/components/Header.ts b/src/components/Header.ts index e842bf1..39f2429 100644 --- a/src/components/Header.ts +++ b/src/components/Header.ts @@ -5,7 +5,7 @@ export default class Header { private readonly $target: HTMLElement, private readonly text: string ) { - this.$target.appendChild(this.$header); + $target.appendChild(this.$header); this.render(); }; diff --git a/src/components/TodoCount.ts b/src/components/TodoCount.ts index b83f9de..bcb2bda 100644 --- a/src/components/TodoCount.ts +++ b/src/components/TodoCount.ts @@ -8,11 +8,10 @@ export default class TodoCount { private readonly $target: HTMLElement, private readonly initialCount: TodoCnt ) { - this.$target.appendChild(this.$container); + $target.appendChild(this.$container); - if (this.initialCount.total) { - this.state = this.initialCount; - } else this.state = { total: 0, done: 0 }; + if (initialCount.total) this.state = initialCount; + else this.state = { total: 0, done: 0 }; this.render(); } diff --git a/src/components/TodoForm.ts b/src/components/TodoForm.ts index 4312e85..c6845b9 100644 --- a/src/components/TodoForm.ts +++ b/src/components/TodoForm.ts @@ -7,7 +7,7 @@ export default class TodoForm { private readonly $target: HTMLElement, private readonly onSubmit: (text: string) => void ) { - this.$target.appendChild(this.$form); + $target.appendChild(this.$form); this.render(); } diff --git a/src/components/TodoList.ts b/src/components/TodoList.ts index e793caf..92ad9f6 100644 --- a/src/components/TodoList.ts +++ b/src/components/TodoList.ts @@ -11,9 +11,9 @@ export default class TodoList { private readonly initialState: TodoItem[], private readonly updateCount: (state: TodoItem[]) => void ) { - this.$target.appendChild(this.$todoList); + $target.appendChild(this.$todoList); - if (Array.isArray(this.initialState)) this.state = this.initialState; + if (Array.isArray(initialState)) this.state = initialState; else this.state = []; this.render(); From 2802b9fa94252ec89ffb9491138ce11b1e005e96 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 14 Dec 2023 00:17:57 +0900 Subject: [PATCH 37/49] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/storage.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/utils/storage.ts b/src/utils/storage.ts index ea219fa..f3867e7 100644 --- a/src/utils/storage.ts +++ b/src/utils/storage.ts @@ -3,8 +3,9 @@ const storage = window.localStorage; export const setItem = (key: string, value: string) => { try { storage.setItem(key, value); - } catch (error) { - console.log(error); + } + catch (error: unknown) { + if (error instanceof Error) console.log(error); } }; @@ -14,7 +15,7 @@ export const getItem = (key: string, defaultValue: T): T => { if (data) return JSON.parse(data); return defaultValue; } catch (error) { - console.log(error); + if (error instanceof Error) console.log(error); return defaultValue; } }; From ec5b624082744d6bb226d72e55108f81e54c9577 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 14 Dec 2023 00:18:31 +0900 Subject: [PATCH 38/49] =?UTF-8?q?refactor:=20early=20return=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TodoForm.ts | 24 ++++++++++++------------ src/components/TodoList.ts | 34 +++++++++++++++++----------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/components/TodoForm.ts b/src/components/TodoForm.ts index c6845b9..2271a8b 100644 --- a/src/components/TodoForm.ts +++ b/src/components/TodoForm.ts @@ -17,17 +17,17 @@ export default class TodoForm { `; - if (!this.isInit) { - this.$form.addEventListener("submit", (e) => { - e.preventDefault(); - const $todo = this.$form.querySelector("input[name=todo]"); - if (!$todo) return; - const text = $todo.value; - if (text.length > 1) { - $todo.value = ""; - this.onSubmit(text); - } else alert("๋‘ ๊ธ€์ž ์ด์ƒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); - }); - } + if (this.isInit) return; + + this.$form.addEventListener("submit", (e) => { + e.preventDefault(); + const $todo = this.$form.querySelector("input[name=todo]"); + if (!$todo) return; + const text = $todo.value; + if (text.length > 1) { + $todo.value = ""; + this.onSubmit(text); + } else alert("๋‘ ๊ธ€์ž ์ด์ƒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); + }); }; } diff --git a/src/components/TodoList.ts b/src/components/TodoList.ts index 92ad9f6..94cfbaa 100644 --- a/src/components/TodoList.ts +++ b/src/components/TodoList.ts @@ -22,24 +22,24 @@ export default class TodoList { const target = e.target as HTMLLIElement; const $li = target.closest("li"); - if ($li) { - const newState = [...this.state]; - if (typeof $li.dataset.index !== "string") return; - const index = +$li.dataset.index; + if (!$li) return; - if (target.className === "deleteBtn") { - newState.splice(index, 1); - this.setState(newState); - } else if (target.className.includes("todoList")) { - const isCompleted = target.className.includes("completed"); - if (isCompleted) target.classList.remove("completed"); - else target.classList.add("completed"); - newState[index] = { - ...newState[index], - isCompleted: !isCompleted, - }; - this.setState(newState); - } + const newState = [...this.state]; + if (typeof $li.dataset.index !== "string") return; + const index = +$li.dataset.index; + + if (target.className === "deleteBtn") { + newState.splice(index, 1); + this.setState(newState); + } else if (target.className.includes("todoList")) { + const isCompleted = target.className.includes("completed"); + if (isCompleted) target.classList.remove("completed"); + else target.classList.add("completed"); + newState[index] = { + ...newState[index], + isCompleted: !isCompleted, + }; + this.setState(newState); } }); } From 9c19859a003ea957d6cc360096beb5688aba005a Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 14 Dec 2023 00:19:01 +0900 Subject: [PATCH 39/49] =?UTF-8?q?feat:=20storage=20key=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/todo.ts | 2 ++ src/utils/storage.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/types/todo.ts b/src/types/todo.ts index 4e06d91..c7a0412 100644 --- a/src/types/todo.ts +++ b/src/types/todo.ts @@ -1,4 +1,6 @@ export interface TodoItem { +export type StorageKey = "todo" | "count"; + text: string; isCompleted: boolean; } diff --git a/src/utils/storage.ts b/src/utils/storage.ts index f3867e7..371c6b9 100644 --- a/src/utils/storage.ts +++ b/src/utils/storage.ts @@ -1,3 +1,5 @@ +import { StorageKey } from "../types/todo"; + const storage = window.localStorage; export const setItem = (key: string, value: string) => { @@ -9,7 +11,7 @@ export const setItem = (key: string, value: string) => { } }; -export const getItem = (key: string, defaultValue: T): T => { +export const getItem = (key: StorageKey, defaultValue: T): T => { try { const data = storage.getItem(key); if (data) return JSON.parse(data); From 30c340451f967b2ff2b40b8b73af6696b5304ab4 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Thu, 14 Dec 2023 00:19:41 +0900 Subject: [PATCH 40/49] =?UTF-8?q?refactor:=20todo=20list=20=EB=B0=B0?= =?UTF-8?q?=EC=97=B4=20=ED=83=80=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 8 ++++---- src/components/TodoList.ts | 10 +++++----- src/types/todo.ts | 6 ++++-- src/utils/validation.ts | 4 ++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/App.ts b/src/App.ts index d61f3e1..0abbe90 100644 --- a/src/App.ts +++ b/src/App.ts @@ -3,7 +3,7 @@ import TodoForm from "./components/TodoForm.js"; import TodoList from "./components/TodoList.js"; import TodoCount from "./components/TodoCount.js"; import { setItem } from "./utils/storage.js"; -import { TodoCount as TodoCnt, TodoItem } from "./types/todo.js"; +import { TodoCount as TodoCnt, TodoList as TodoLi } from "./types/todo.js"; export default class App { private readonly todoList: TodoList; @@ -11,7 +11,7 @@ export default class App { constructor( private readonly $target: HTMLElement, - private readonly initialState: TodoItem[], + private readonly initialState: TodoLi, private readonly initialCount: TodoCnt ) { new Header($target, "Todo List"); @@ -28,16 +28,16 @@ export default class App { ); this.todoList = new TodoList( - (state: TodoItem[]) => this.#updateCount(state) $target, initialState, + (state: TodoLi) => this.#updateCount(state) ); this.todoCount = new TodoCount($target, initialCount); } // ์นด์šดํŠธ ์—…๋ฐ์ดํŠธ - #updateCount(todoList: TodoItem[]) { + #updateCount(todoList: TodoLi) { const done = todoList.filter((todo) => todo.isCompleted).length; const nextState = { total: todoList.length, done }; this.todoCount.setState(nextState); diff --git a/src/components/TodoList.ts b/src/components/TodoList.ts index 94cfbaa..3323419 100644 --- a/src/components/TodoList.ts +++ b/src/components/TodoList.ts @@ -1,15 +1,15 @@ import { setItem } from "../utils/storage.js"; import validation from "../utils/validation.js"; -import { TodoItem } from "../types/todo.js"; +import { TodoList as TodoLi } from "../types/todo.js"; export default class TodoList { - state: TodoItem[]; + state: TodoLi; private readonly $todoList = document.createElement("div"); constructor( private readonly $target: HTMLElement, - private readonly initialState: TodoItem[], - private readonly updateCount: (state: TodoItem[]) => void + private readonly initialState: TodoLi, + private readonly updateCount: (state: TodoLi) => void ) { $target.appendChild(this.$todoList); @@ -44,7 +44,7 @@ export default class TodoList { }); } - setState(nextState: TodoItem[]) { + setState(nextState: TodoLi) { const newState = validation.state(nextState); this.state = newState; setItem("todo", JSON.stringify(newState)); diff --git a/src/types/todo.ts b/src/types/todo.ts index c7a0412..0f9893c 100644 --- a/src/types/todo.ts +++ b/src/types/todo.ts @@ -1,6 +1,8 @@ -export interface TodoItem { export type StorageKey = "todo" | "count"; +export type TodoList = TodoItem[]; + +interface TodoItem { text: string; isCompleted: boolean; } @@ -8,4 +10,4 @@ export type StorageKey = "todo" | "count"; export interface TodoCount { total: number; done: number; -} \ No newline at end of file +} diff --git a/src/utils/validation.ts b/src/utils/validation.ts index 4ee9d74..1480f20 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -1,7 +1,7 @@ -import { TodoItem } from "../types/todo.js"; +import { TodoList } from "../types/todo.js"; const validation = { - state(todoList: TodoItem[]) { + state(todoList: TodoList) { return todoList.filter( (todo) => typeof todo?.text === "string" && typeof todo?.isCompleted === "boolean" From 1c062e514b7beccc1b58d6204e33f957f3aaab5a Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:16:28 +0900 Subject: [PATCH 41/49] =?UTF-8?q?refactor:=20=EC=A0=84=EC=97=AD=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20main=20>=20App=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.ts | 14 ++++++++------ src/main.ts | 7 +------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/App.ts b/src/App.ts index 0abbe90..fdeaf67 100644 --- a/src/App.ts +++ b/src/App.ts @@ -2,18 +2,20 @@ import Header from "./components/Header.js"; import TodoForm from "./components/TodoForm.js"; import TodoList from "./components/TodoList.js"; import TodoCount from "./components/TodoCount.js"; -import { setItem } from "./utils/storage.js"; +import { setItem, getItem } from "./utils/storage.js"; import { TodoCount as TodoCnt, TodoList as TodoLi } from "./types/todo.js"; - export default class App { private readonly todoList: TodoList; private readonly todoCount: TodoCount; + private readonly initialState: TodoLi; + private readonly initialCount: TodoCnt; constructor( private readonly $target: HTMLElement, - private readonly initialState: TodoLi, - private readonly initialCount: TodoCnt ) { + this.initialState = getItem("todo", []); + this.initialCount = getItem("count", { total: 0, done: 0 }); + new Header($target, "Todo List"); new TodoForm( @@ -29,11 +31,11 @@ export default class App { this.todoList = new TodoList( $target, - initialState, + this.initialState, (state: TodoLi) => this.#updateCount(state) ); - this.todoCount = new TodoCount($target, initialCount); + this.todoCount = new TodoCount($target, this.initialCount); } // ์นด์šดํŠธ ์—…๋ฐ์ดํŠธ diff --git a/src/main.ts b/src/main.ts index 60b666d..579bc6b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,3 @@ import App from "./App.js"; -import { getItem } from "./utils/storage.js"; - -const initialState = getItem("todo", []); -const initialCount = getItem("count", { total: 0, done: 0 }); const $app = document.querySelector("#app"); - -$app && new App($app, initialState, initialCount); +$app && new App($app); From 474710ea0bbcbe6c2a8d463e1c3a3d5ec73f9ebe Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:16:55 +0900 Subject: [PATCH 42/49] =?UTF-8?q?refactor:=20=EC=B5=9C=EC=86=8C=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=20=EA=B0=9C=EC=88=98=20HTML=20=EC=86=8D?= =?UTF-8?q?=EC=84=B1=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=99=84=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=ED=95=B4=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TodoForm.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/TodoForm.ts b/src/components/TodoForm.ts index 2271a8b..feaa826 100644 --- a/src/components/TodoForm.ts +++ b/src/components/TodoForm.ts @@ -13,7 +13,7 @@ export default class TodoForm { private render() { this.$form.innerHTML = ` - + `; @@ -24,10 +24,8 @@ export default class TodoForm { const $todo = this.$form.querySelector("input[name=todo]"); if (!$todo) return; const text = $todo.value; - if (text.length > 1) { - $todo.value = ""; - this.onSubmit(text); - } else alert("๋‘ ๊ธ€์ž ์ด์ƒ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"); + $todo.value = ""; + this.onSubmit(text); }); }; } From 4c198d149ad805cfe48b69747d3f54b153a99094 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:24:06 +0900 Subject: [PATCH 43/49] =?UTF-8?q?refactor:=20isInit=20=ED=94=8C=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=B3=80=EC=88=98=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TodoForm.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/TodoForm.ts b/src/components/TodoForm.ts index feaa826..fe858df 100644 --- a/src/components/TodoForm.ts +++ b/src/components/TodoForm.ts @@ -1,7 +1,6 @@ export default class TodoForm { private readonly $form = document.createElement("form"); - private isInit = false; constructor( private readonly $target: HTMLElement, @@ -17,8 +16,6 @@ export default class TodoForm { `; - if (this.isInit) return; - this.$form.addEventListener("submit", (e) => { e.preventDefault(); const $todo = this.$form.querySelector("input[name=todo]"); From d141abb145faed2dc2e82260e09afaacbf1c96dd Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:24:32 +0900 Subject: [PATCH 44/49] =?UTF-8?q?refactor:=20=EB=8F=94=20=EB=A0=8C?= =?UTF-8?q?=EB=8D=94=EC=99=80=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EB=B0=94?= =?UTF-8?q?=EC=9D=B8=EB=94=A9=20=ED=95=A8=EC=88=98=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TodoForm.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/TodoForm.ts b/src/components/TodoForm.ts index fe858df..3cd141f 100644 --- a/src/components/TodoForm.ts +++ b/src/components/TodoForm.ts @@ -8,6 +8,7 @@ export default class TodoForm { ) { $target.appendChild(this.$form); this.render(); + this.setEvent(); } private render() { @@ -15,7 +16,9 @@ export default class TodoForm { `; + }; + private setEvent() { this.$form.addEventListener("submit", (e) => { e.preventDefault(); const $todo = this.$form.querySelector("input[name=todo]"); @@ -24,5 +27,5 @@ export default class TodoForm { $todo.value = ""; this.onSubmit(text); }); - }; + } } From 088d7f5d4afa4cda93cf62138c12bb82ba73b52e Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:30:18 +0900 Subject: [PATCH 45/49] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TodoList.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/TodoList.ts b/src/components/TodoList.ts index 3323419..e174b2a 100644 --- a/src/components/TodoList.ts +++ b/src/components/TodoList.ts @@ -13,9 +13,7 @@ export default class TodoList { ) { $target.appendChild(this.$todoList); - if (Array.isArray(initialState)) this.state = initialState; - else this.state = []; - + this.state = initialState; this.render(); this.$todoList.addEventListener("click", (e) => { From 7199c763b667d329eac3c8a1d55d7b10b90de0b0 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:31:49 +0900 Subject: [PATCH 46/49] =?UTF-8?q?refactor:=20=EC=9D=B4=EB=B2=A4=ED=8A=B8?= =?UTF-8?q?=20=EB=B0=94=EC=9D=B8=EB=94=A9=20=ED=95=A8=EC=88=98=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TodoList.ts | 54 ++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/components/TodoList.ts b/src/components/TodoList.ts index e174b2a..6e8a124 100644 --- a/src/components/TodoList.ts +++ b/src/components/TodoList.ts @@ -12,34 +12,9 @@ export default class TodoList { private readonly updateCount: (state: TodoLi) => void ) { $target.appendChild(this.$todoList); - this.state = initialState; this.render(); - - this.$todoList.addEventListener("click", (e) => { - const target = e.target as HTMLLIElement; - const $li = target.closest("li"); - - if (!$li) return; - - const newState = [...this.state]; - if (typeof $li.dataset.index !== "string") return; - const index = +$li.dataset.index; - - if (target.className === "deleteBtn") { - newState.splice(index, 1); - this.setState(newState); - } else if (target.className.includes("todoList")) { - const isCompleted = target.className.includes("completed"); - if (isCompleted) target.classList.remove("completed"); - else target.classList.add("completed"); - newState[index] = { - ...newState[index], - isCompleted: !isCompleted, - }; - this.setState(newState); - } - }); + this.setEvent(); } setState(nextState: TodoLi) { @@ -67,4 +42,31 @@ export default class TodoList {
    `; }; + + private setEvent() { + this.$todoList.addEventListener("click", (e) => { + const target = e.target as HTMLLIElement; + const $li = target.closest("li"); + + if (!$li) return; + + const newState = [...this.state]; + if (typeof $li.dataset.index !== "string") return; + const index = +$li.dataset.index; + + if (target.className === "deleteBtn") { + newState.splice(index, 1); + this.setState(newState); + } else if (target.className.includes("todoList")) { + const isCompleted = target.className.includes("completed"); + if (isCompleted) target.classList.remove("completed"); + else target.classList.add("completed"); + newState[index] = { + ...newState[index], + isCompleted: !isCompleted, + }; + this.setState(newState); + } + }); + } } From 63c7448c2597905c663d7fe9eff7dbdd1c58a64e Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:40:44 +0900 Subject: [PATCH 47/49] =?UTF-8?q?refactor:=20=EC=9C=A0=ED=9A=A8=EC=84=B1?= =?UTF-8?q?=20=EA=B2=80=EC=82=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TodoList.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/TodoList.ts b/src/components/TodoList.ts index 6e8a124..89d6624 100644 --- a/src/components/TodoList.ts +++ b/src/components/TodoList.ts @@ -1,5 +1,4 @@ import { setItem } from "../utils/storage.js"; -import validation from "../utils/validation.js"; import { TodoList as TodoLi } from "../types/todo.js"; export default class TodoList { @@ -18,10 +17,9 @@ export default class TodoList { } setState(nextState: TodoLi) { - const newState = validation.state(nextState); - this.state = newState; - setItem("todo", JSON.stringify(newState)); - this.updateCount(newState); + this.state = nextState; + setItem("todo", JSON.stringify(nextState)); + this.updateCount(nextState); this.render(); }; From 775a2a49a9e870415f0205701d73d5389abc1c72 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:40:53 +0900 Subject: [PATCH 48/49] =?UTF-8?q?remove:=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/validation.ts | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 src/utils/validation.ts diff --git a/src/utils/validation.ts b/src/utils/validation.ts deleted file mode 100644 index 1480f20..0000000 --- a/src/utils/validation.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { TodoList } from "../types/todo.js"; - -const validation = { - state(todoList: TodoList) { - return todoList.filter( - (todo) => - typeof todo?.text === "string" && typeof todo?.isCompleted === "boolean" - ); - }, -}; - -export default validation; From 8a7e3ed5d58db59fc969a08eb9a7fdbe9e64aa61 Mon Sep 17 00:00:00 2001 From: Baeg <73841260+bgyoons@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:45:06 +0900 Subject: [PATCH 49/49] =?UTF-8?q?rename:=20TodoList=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=ED=8F=B4=EB=8D=94=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TodoList/.gitignore" | 0 .../TodoList/index.html" | 0 .../TodoList/package-lock.json" | 0 .../TodoList/package.json" | 0 .../TodoList/src/App.ts" | 0 .../TodoList/src/components/Header.ts" | 0 .../TodoList/src/components/TodoCount.ts" | 0 .../TodoList/src/components/TodoForm.ts" | 0 .../TodoList/src/components/TodoList.ts" | 0 .../TodoList/src/main.ts" | 0 .../TodoList/src/types/todo.ts" | 0 .../TodoList/src/utils/storage.ts" | 0 .../TodoList/style.css" | 0 .../TodoList/tsconfig.json" | 0 .../TodoList/tslint.json" | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename .gitignore => "\353\260\261\354\234\244\354\204\234/TodoList/.gitignore" (100%) rename index.html => "\353\260\261\354\234\244\354\204\234/TodoList/index.html" (100%) rename package-lock.json => "\353\260\261\354\234\244\354\204\234/TodoList/package-lock.json" (100%) rename package.json => "\353\260\261\354\234\244\354\204\234/TodoList/package.json" (100%) rename src/App.ts => "\353\260\261\354\234\244\354\204\234/TodoList/src/App.ts" (100%) rename src/components/Header.ts => "\353\260\261\354\234\244\354\204\234/TodoList/src/components/Header.ts" (100%) rename src/components/TodoCount.ts => "\353\260\261\354\234\244\354\204\234/TodoList/src/components/TodoCount.ts" (100%) rename src/components/TodoForm.ts => "\353\260\261\354\234\244\354\204\234/TodoList/src/components/TodoForm.ts" (100%) rename src/components/TodoList.ts => "\353\260\261\354\234\244\354\204\234/TodoList/src/components/TodoList.ts" (100%) rename src/main.ts => "\353\260\261\354\234\244\354\204\234/TodoList/src/main.ts" (100%) rename src/types/todo.ts => "\353\260\261\354\234\244\354\204\234/TodoList/src/types/todo.ts" (100%) rename src/utils/storage.ts => "\353\260\261\354\234\244\354\204\234/TodoList/src/utils/storage.ts" (100%) rename style.css => "\353\260\261\354\234\244\354\204\234/TodoList/style.css" (100%) rename tsconfig.json => "\353\260\261\354\234\244\354\204\234/TodoList/tsconfig.json" (100%) rename tslint.json => "\353\260\261\354\234\244\354\204\234/TodoList/tslint.json" (100%) diff --git a/.gitignore "b/\353\260\261\354\234\244\354\204\234/TodoList/.gitignore" similarity index 100% rename from .gitignore rename to "\353\260\261\354\234\244\354\204\234/TodoList/.gitignore" diff --git a/index.html "b/\353\260\261\354\234\244\354\204\234/TodoList/index.html" similarity index 100% rename from index.html rename to "\353\260\261\354\234\244\354\204\234/TodoList/index.html" diff --git a/package-lock.json "b/\353\260\261\354\234\244\354\204\234/TodoList/package-lock.json" similarity index 100% rename from package-lock.json rename to "\353\260\261\354\234\244\354\204\234/TodoList/package-lock.json" diff --git a/package.json "b/\353\260\261\354\234\244\354\204\234/TodoList/package.json" similarity index 100% rename from package.json rename to "\353\260\261\354\234\244\354\204\234/TodoList/package.json" diff --git a/src/App.ts "b/\353\260\261\354\234\244\354\204\234/TodoList/src/App.ts" similarity index 100% rename from src/App.ts rename to "\353\260\261\354\234\244\354\204\234/TodoList/src/App.ts" diff --git a/src/components/Header.ts "b/\353\260\261\354\234\244\354\204\234/TodoList/src/components/Header.ts" similarity index 100% rename from src/components/Header.ts rename to "\353\260\261\354\234\244\354\204\234/TodoList/src/components/Header.ts" diff --git a/src/components/TodoCount.ts "b/\353\260\261\354\234\244\354\204\234/TodoList/src/components/TodoCount.ts" similarity index 100% rename from src/components/TodoCount.ts rename to "\353\260\261\354\234\244\354\204\234/TodoList/src/components/TodoCount.ts" diff --git a/src/components/TodoForm.ts "b/\353\260\261\354\234\244\354\204\234/TodoList/src/components/TodoForm.ts" similarity index 100% rename from src/components/TodoForm.ts rename to "\353\260\261\354\234\244\354\204\234/TodoList/src/components/TodoForm.ts" diff --git a/src/components/TodoList.ts "b/\353\260\261\354\234\244\354\204\234/TodoList/src/components/TodoList.ts" similarity index 100% rename from src/components/TodoList.ts rename to "\353\260\261\354\234\244\354\204\234/TodoList/src/components/TodoList.ts" diff --git a/src/main.ts "b/\353\260\261\354\234\244\354\204\234/TodoList/src/main.ts" similarity index 100% rename from src/main.ts rename to "\353\260\261\354\234\244\354\204\234/TodoList/src/main.ts" diff --git a/src/types/todo.ts "b/\353\260\261\354\234\244\354\204\234/TodoList/src/types/todo.ts" similarity index 100% rename from src/types/todo.ts rename to "\353\260\261\354\234\244\354\204\234/TodoList/src/types/todo.ts" diff --git a/src/utils/storage.ts "b/\353\260\261\354\234\244\354\204\234/TodoList/src/utils/storage.ts" similarity index 100% rename from src/utils/storage.ts rename to "\353\260\261\354\234\244\354\204\234/TodoList/src/utils/storage.ts" diff --git a/style.css "b/\353\260\261\354\234\244\354\204\234/TodoList/style.css" similarity index 100% rename from style.css rename to "\353\260\261\354\234\244\354\204\234/TodoList/style.css" diff --git a/tsconfig.json "b/\353\260\261\354\234\244\354\204\234/TodoList/tsconfig.json" similarity index 100% rename from tsconfig.json rename to "\353\260\261\354\234\244\354\204\234/TodoList/tsconfig.json" diff --git a/tslint.json "b/\353\260\261\354\234\244\354\204\234/TodoList/tslint.json" similarity index 100% rename from tslint.json rename to "\353\260\261\354\234\244\354\204\234/TodoList/tslint.json"