11import { setItem } from "../utils/storage.js" ;
22import validation from "../utils/validation.js" ;
3+ import { TodoItem } from "../types/todo.js" ;
34
4- // params.$target - 해당 컴포넌트가 추가될 DOM 앨리먼트
5- // params.initialState - 해당 컴포넌트의 초기 상태
6- export default function TodoList ( { $target, initialState, updateCount } ) {
7- validation . newTarget ( new . target ) ;
5+ export default class TodoList {
6+ state : TodoItem [ ] = [ ] ;
7+ $todoList = document . createElement ( "div" ) ;
88
9- const $todoList = document . createElement ( "div" ) ;
10- $target . appendChild ( $todoList ) ;
9+ constructor (
10+ private readonly $target : HTMLElement ,
11+ private readonly initialState : TodoItem [ ] ,
12+ private readonly updateCount : ( state : TodoItem [ ] ) => void
13+ ) {
14+ this . $target . appendChild ( this . $todoList ) ;
1115
12- if ( Array . isArray ( initialState ) ) this . state = initialState ;
13- else this . state = [ ] ;
16+ if ( Array . isArray ( this . initialState ) ) this . state = this . initialState ;
17+ else this . state = [ ] ;
1418
15- this . setState = ( nextState ) => {
19+ this . render ( ) ;
20+
21+ this . $todoList . addEventListener ( "click" , ( e ) => {
22+ const target = e . target as HTMLLIElement ;
23+ const $li = target . closest ( "li" ) ;
24+
25+ if ( $li ) {
26+ const newState = [ ...this . state ] ;
27+ const index = + ( $li . dataset . index as string ) ;
28+
29+ if ( target . className === "deleteBtn" ) {
30+ newState . splice ( index , 1 ) ;
31+ this . setState ( newState ) ;
32+ } else if ( target . className . includes ( "todoList" ) ) {
33+ const isCompleted = target . className . includes ( "completed" ) ;
34+ if ( isCompleted ) target . classList . remove ( "completed" ) ;
35+ else target . classList . add ( "completed" ) ;
36+ newState [ index ] = {
37+ ...newState [ index ] ,
38+ isCompleted : ! isCompleted ,
39+ } ;
40+ this . setState ( newState ) ;
41+ }
42+ }
43+ } ) ;
44+ }
45+
46+ setState ( nextState : TodoItem [ ] ) {
1647 const newState = validation . state ( nextState ) ;
1748 this . state = newState ;
1849 setItem ( "todo" , JSON . stringify ( newState ) ) ;
19- updateCount ( newState ) ;
50+ this . updateCount ( newState ) ;
2051 this . render ( ) ;
2152 } ;
2253
23- this . render = ( ) => {
24- $todoList . innerHTML = `
54+ render ( ) {
55+ this . $todoList . innerHTML = `
2556 <ul>
2657 ${ this . state
2758 . map (
@@ -37,32 +68,4 @@ export default function TodoList({ $target, initialState, updateCount }) {
3768 </ul>
3869 ` ;
3970 } ;
40-
41- $todoList . addEventListener ( "click" , ( e ) => {
42- const { target } = e ;
43- const $li = target . closest ( "li" ) ;
44-
45- if ( $li ) {
46- const newState = [ ...this . state ] ;
47- const { index } = $li . dataset ;
48-
49- if ( target . className === "deleteBtn" ) {
50- newState . splice ( index , 1 ) ;
51- this . setState ( newState ) ;
52- } else if ( target . className . includes ( "todoList" ) ) {
53- const isCompleted = target . className . includes ( "completed" ) ;
54-
55- if ( isCompleted ) target . classList . remove ( "completed" ) ;
56- else target . classList . add ( "completed" ) ;
57-
58- newState [ index ] = {
59- ...newState [ index ] ,
60- isCompleted : ! isCompleted ,
61- } ;
62- this . setState ( newState ) ;
63- }
64- }
65- } ) ;
66-
67- this . render ( ) ;
6871}
0 commit comments