├── .gitignore
├── LICENSE
├── index.html
├── package-lock.json
├── package.json
├── src
├── App.jsx
├── NewTodoForm.jsx
├── TodoItem.jsx
├── TodoList.jsx
├── main.jsx
└── styles.css
└── vite.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 WebDevSimplified
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-todo-list",
3 | "version": "0.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "react-todo-list",
9 | "version": "0.0.0",
10 | "dependencies": {
11 | "react": "^18.2.0",
12 | "react-dom": "^18.2.0"
13 | },
14 | "devDependencies": {
15 | "@types/react": "^18.0.28",
16 | "@types/react-dom": "^18.0.11",
17 | "@vitejs/plugin-react-swc": "^3.0.0",
18 | "vite": "^4.2.0"
19 | }
20 | },
21 | "node_modules/@esbuild/android-arm": {
22 | "version": "0.17.15",
23 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.15.tgz",
24 | "integrity": "sha512-sRSOVlLawAktpMvDyJIkdLI/c/kdRTOqo8t6ImVxg8yT7LQDUYV5Rp2FKeEosLr6ZCja9UjYAzyRSxGteSJPYg==",
25 | "cpu": [
26 | "arm"
27 | ],
28 | "dev": true,
29 | "optional": true,
30 | "os": [
31 | "android"
32 | ],
33 | "engines": {
34 | "node": ">=12"
35 | }
36 | },
37 | "node_modules/@esbuild/android-arm64": {
38 | "version": "0.17.15",
39 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.15.tgz",
40 | "integrity": "sha512-0kOB6Y7Br3KDVgHeg8PRcvfLkq+AccreK///B4Z6fNZGr/tNHX0z2VywCc7PTeWp+bPvjA5WMvNXltHw5QjAIA==",
41 | "cpu": [
42 | "arm64"
43 | ],
44 | "dev": true,
45 | "optional": true,
46 | "os": [
47 | "android"
48 | ],
49 | "engines": {
50 | "node": ">=12"
51 | }
52 | },
53 | "node_modules/@esbuild/android-x64": {
54 | "version": "0.17.15",
55 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.15.tgz",
56 | "integrity": "sha512-MzDqnNajQZ63YkaUWVl9uuhcWyEyh69HGpMIrf+acR4otMkfLJ4sUCxqwbCyPGicE9dVlrysI3lMcDBjGiBBcQ==",
57 | "cpu": [
58 | "x64"
59 | ],
60 | "dev": true,
61 | "optional": true,
62 | "os": [
63 | "android"
64 | ],
65 | "engines": {
66 | "node": ">=12"
67 | }
68 | },
69 | "node_modules/@esbuild/darwin-arm64": {
70 | "version": "0.17.15",
71 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.15.tgz",
72 | "integrity": "sha512-7siLjBc88Z4+6qkMDxPT2juf2e8SJxmsbNVKFY2ifWCDT72v5YJz9arlvBw5oB4W/e61H1+HDB/jnu8nNg0rLA==",
73 | "cpu": [
74 | "arm64"
75 | ],
76 | "dev": true,
77 | "optional": true,
78 | "os": [
79 | "darwin"
80 | ],
81 | "engines": {
82 | "node": ">=12"
83 | }
84 | },
85 | "node_modules/@esbuild/darwin-x64": {
86 | "version": "0.17.15",
87 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.15.tgz",
88 | "integrity": "sha512-NbImBas2rXwYI52BOKTW342Tm3LTeVlaOQ4QPZ7XuWNKiO226DisFk/RyPk3T0CKZkKMuU69yOvlapJEmax7cg==",
89 | "cpu": [
90 | "x64"
91 | ],
92 | "dev": true,
93 | "optional": true,
94 | "os": [
95 | "darwin"
96 | ],
97 | "engines": {
98 | "node": ">=12"
99 | }
100 | },
101 | "node_modules/@esbuild/freebsd-arm64": {
102 | "version": "0.17.15",
103 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.15.tgz",
104 | "integrity": "sha512-Xk9xMDjBVG6CfgoqlVczHAdJnCs0/oeFOspFap5NkYAmRCT2qTn1vJWA2f419iMtsHSLm+O8B6SLV/HlY5cYKg==",
105 | "cpu": [
106 | "arm64"
107 | ],
108 | "dev": true,
109 | "optional": true,
110 | "os": [
111 | "freebsd"
112 | ],
113 | "engines": {
114 | "node": ">=12"
115 | }
116 | },
117 | "node_modules/@esbuild/freebsd-x64": {
118 | "version": "0.17.15",
119 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.15.tgz",
120 | "integrity": "sha512-3TWAnnEOdclvb2pnfsTWtdwthPfOz7qAfcwDLcfZyGJwm1SRZIMOeB5FODVhnM93mFSPsHB9b/PmxNNbSnd0RQ==",
121 | "cpu": [
122 | "x64"
123 | ],
124 | "dev": true,
125 | "optional": true,
126 | "os": [
127 | "freebsd"
128 | ],
129 | "engines": {
130 | "node": ">=12"
131 | }
132 | },
133 | "node_modules/@esbuild/linux-arm": {
134 | "version": "0.17.15",
135 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.15.tgz",
136 | "integrity": "sha512-MLTgiXWEMAMr8nmS9Gigx43zPRmEfeBfGCwxFQEMgJ5MC53QKajaclW6XDPjwJvhbebv+RzK05TQjvH3/aM4Xw==",
137 | "cpu": [
138 | "arm"
139 | ],
140 | "dev": true,
141 | "optional": true,
142 | "os": [
143 | "linux"
144 | ],
145 | "engines": {
146 | "node": ">=12"
147 | }
148 | },
149 | "node_modules/@esbuild/linux-arm64": {
150 | "version": "0.17.15",
151 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.15.tgz",
152 | "integrity": "sha512-T0MVnYw9KT6b83/SqyznTs/3Jg2ODWrZfNccg11XjDehIved2oQfrX/wVuev9N936BpMRaTR9I1J0tdGgUgpJA==",
153 | "cpu": [
154 | "arm64"
155 | ],
156 | "dev": true,
157 | "optional": true,
158 | "os": [
159 | "linux"
160 | ],
161 | "engines": {
162 | "node": ">=12"
163 | }
164 | },
165 | "node_modules/@esbuild/linux-ia32": {
166 | "version": "0.17.15",
167 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.15.tgz",
168 | "integrity": "sha512-wp02sHs015T23zsQtU4Cj57WiteiuASHlD7rXjKUyAGYzlOKDAjqK6bk5dMi2QEl/KVOcsjwL36kD+WW7vJt8Q==",
169 | "cpu": [
170 | "ia32"
171 | ],
172 | "dev": true,
173 | "optional": true,
174 | "os": [
175 | "linux"
176 | ],
177 | "engines": {
178 | "node": ">=12"
179 | }
180 | },
181 | "node_modules/@esbuild/linux-loong64": {
182 | "version": "0.17.15",
183 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.15.tgz",
184 | "integrity": "sha512-k7FsUJjGGSxwnBmMh8d7IbObWu+sF/qbwc+xKZkBe/lTAF16RqxRCnNHA7QTd3oS2AfGBAnHlXL67shV5bBThQ==",
185 | "cpu": [
186 | "loong64"
187 | ],
188 | "dev": true,
189 | "optional": true,
190 | "os": [
191 | "linux"
192 | ],
193 | "engines": {
194 | "node": ">=12"
195 | }
196 | },
197 | "node_modules/@esbuild/linux-mips64el": {
198 | "version": "0.17.15",
199 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.15.tgz",
200 | "integrity": "sha512-ZLWk6czDdog+Q9kE/Jfbilu24vEe/iW/Sj2d8EVsmiixQ1rM2RKH2n36qfxK4e8tVcaXkvuV3mU5zTZviE+NVQ==",
201 | "cpu": [
202 | "mips64el"
203 | ],
204 | "dev": true,
205 | "optional": true,
206 | "os": [
207 | "linux"
208 | ],
209 | "engines": {
210 | "node": ">=12"
211 | }
212 | },
213 | "node_modules/@esbuild/linux-ppc64": {
214 | "version": "0.17.15",
215 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.15.tgz",
216 | "integrity": "sha512-mY6dPkIRAiFHRsGfOYZC8Q9rmr8vOBZBme0/j15zFUKM99d4ILY4WpOC7i/LqoY+RE7KaMaSfvY8CqjJtuO4xg==",
217 | "cpu": [
218 | "ppc64"
219 | ],
220 | "dev": true,
221 | "optional": true,
222 | "os": [
223 | "linux"
224 | ],
225 | "engines": {
226 | "node": ">=12"
227 | }
228 | },
229 | "node_modules/@esbuild/linux-riscv64": {
230 | "version": "0.17.15",
231 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.15.tgz",
232 | "integrity": "sha512-EcyUtxffdDtWjjwIH8sKzpDRLcVtqANooMNASO59y+xmqqRYBBM7xVLQhqF7nksIbm2yHABptoioS9RAbVMWVA==",
233 | "cpu": [
234 | "riscv64"
235 | ],
236 | "dev": true,
237 | "optional": true,
238 | "os": [
239 | "linux"
240 | ],
241 | "engines": {
242 | "node": ">=12"
243 | }
244 | },
245 | "node_modules/@esbuild/linux-s390x": {
246 | "version": "0.17.15",
247 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.15.tgz",
248 | "integrity": "sha512-BuS6Jx/ezxFuHxgsfvz7T4g4YlVrmCmg7UAwboeyNNg0OzNzKsIZXpr3Sb/ZREDXWgt48RO4UQRDBxJN3B9Rbg==",
249 | "cpu": [
250 | "s390x"
251 | ],
252 | "dev": true,
253 | "optional": true,
254 | "os": [
255 | "linux"
256 | ],
257 | "engines": {
258 | "node": ">=12"
259 | }
260 | },
261 | "node_modules/@esbuild/linux-x64": {
262 | "version": "0.17.15",
263 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.15.tgz",
264 | "integrity": "sha512-JsdS0EgEViwuKsw5tiJQo9UdQdUJYuB+Mf6HxtJSPN35vez1hlrNb1KajvKWF5Sa35j17+rW1ECEO9iNrIXbNg==",
265 | "cpu": [
266 | "x64"
267 | ],
268 | "dev": true,
269 | "optional": true,
270 | "os": [
271 | "linux"
272 | ],
273 | "engines": {
274 | "node": ">=12"
275 | }
276 | },
277 | "node_modules/@esbuild/netbsd-x64": {
278 | "version": "0.17.15",
279 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.15.tgz",
280 | "integrity": "sha512-R6fKjtUysYGym6uXf6qyNephVUQAGtf3n2RCsOST/neIwPqRWcnc3ogcielOd6pT+J0RDR1RGcy0ZY7d3uHVLA==",
281 | "cpu": [
282 | "x64"
283 | ],
284 | "dev": true,
285 | "optional": true,
286 | "os": [
287 | "netbsd"
288 | ],
289 | "engines": {
290 | "node": ">=12"
291 | }
292 | },
293 | "node_modules/@esbuild/openbsd-x64": {
294 | "version": "0.17.15",
295 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.15.tgz",
296 | "integrity": "sha512-mVD4PGc26b8PI60QaPUltYKeSX0wxuy0AltC+WCTFwvKCq2+OgLP4+fFd+hZXzO2xW1HPKcytZBdjqL6FQFa7w==",
297 | "cpu": [
298 | "x64"
299 | ],
300 | "dev": true,
301 | "optional": true,
302 | "os": [
303 | "openbsd"
304 | ],
305 | "engines": {
306 | "node": ">=12"
307 | }
308 | },
309 | "node_modules/@esbuild/sunos-x64": {
310 | "version": "0.17.15",
311 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.15.tgz",
312 | "integrity": "sha512-U6tYPovOkw3459t2CBwGcFYfFRjivcJJc1WC8Q3funIwX8x4fP+R6xL/QuTPNGOblbq/EUDxj9GU+dWKX0oWlQ==",
313 | "cpu": [
314 | "x64"
315 | ],
316 | "dev": true,
317 | "optional": true,
318 | "os": [
319 | "sunos"
320 | ],
321 | "engines": {
322 | "node": ">=12"
323 | }
324 | },
325 | "node_modules/@esbuild/win32-arm64": {
326 | "version": "0.17.15",
327 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.15.tgz",
328 | "integrity": "sha512-W+Z5F++wgKAleDABemiyXVnzXgvRFs+GVKThSI+mGgleLWluv0D7Diz4oQpgdpNzh4i2nNDzQtWbjJiqutRp6Q==",
329 | "cpu": [
330 | "arm64"
331 | ],
332 | "dev": true,
333 | "optional": true,
334 | "os": [
335 | "win32"
336 | ],
337 | "engines": {
338 | "node": ">=12"
339 | }
340 | },
341 | "node_modules/@esbuild/win32-ia32": {
342 | "version": "0.17.15",
343 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.15.tgz",
344 | "integrity": "sha512-Muz/+uGgheShKGqSVS1KsHtCyEzcdOn/W/Xbh6H91Etm+wiIfwZaBn1W58MeGtfI8WA961YMHFYTthBdQs4t+w==",
345 | "cpu": [
346 | "ia32"
347 | ],
348 | "dev": true,
349 | "optional": true,
350 | "os": [
351 | "win32"
352 | ],
353 | "engines": {
354 | "node": ">=12"
355 | }
356 | },
357 | "node_modules/@esbuild/win32-x64": {
358 | "version": "0.17.15",
359 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.15.tgz",
360 | "integrity": "sha512-DjDa9ywLUUmjhV2Y9wUTIF+1XsmuFGvZoCmOWkli1XcNAh5t25cc7fgsCx4Zi/Uurep3TTLyDiKATgGEg61pkA==",
361 | "cpu": [
362 | "x64"
363 | ],
364 | "dev": true,
365 | "optional": true,
366 | "os": [
367 | "win32"
368 | ],
369 | "engines": {
370 | "node": ">=12"
371 | }
372 | },
373 | "node_modules/@swc/core": {
374 | "version": "1.3.46",
375 | "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.46.tgz",
376 | "integrity": "sha512-WxzgJMWUBVJ95HsvEqlWzM3Qxp2FQrPa4QdAkQQuuvCMnfdctGUbhX/c3LiSRlWrl2LIkYAi4bLansTOol4QcQ==",
377 | "dev": true,
378 | "hasInstallScript": true,
379 | "engines": {
380 | "node": ">=10"
381 | },
382 | "funding": {
383 | "type": "opencollective",
384 | "url": "https://opencollective.com/swc"
385 | },
386 | "optionalDependencies": {
387 | "@swc/core-darwin-arm64": "1.3.46",
388 | "@swc/core-darwin-x64": "1.3.46",
389 | "@swc/core-linux-arm-gnueabihf": "1.3.46",
390 | "@swc/core-linux-arm64-gnu": "1.3.46",
391 | "@swc/core-linux-arm64-musl": "1.3.46",
392 | "@swc/core-linux-x64-gnu": "1.3.46",
393 | "@swc/core-linux-x64-musl": "1.3.46",
394 | "@swc/core-win32-arm64-msvc": "1.3.46",
395 | "@swc/core-win32-ia32-msvc": "1.3.46",
396 | "@swc/core-win32-x64-msvc": "1.3.46"
397 | },
398 | "peerDependencies": {
399 | "@swc/helpers": "^0.5.0"
400 | }
401 | },
402 | "node_modules/@swc/core-darwin-arm64": {
403 | "version": "1.3.46",
404 | "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.46.tgz",
405 | "integrity": "sha512-kY4ASe7SsntDw2B1T70H9K1CFmK8POi+LyIpeCyC96EB9wbH2Sax+ploBB/wZALbYzr/dMJzOCU8QXzdmVS4Rg==",
406 | "cpu": [
407 | "arm64"
408 | ],
409 | "dev": true,
410 | "optional": true,
411 | "os": [
412 | "darwin"
413 | ],
414 | "engines": {
415 | "node": ">=10"
416 | }
417 | },
418 | "node_modules/@swc/core-darwin-x64": {
419 | "version": "1.3.46",
420 | "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.46.tgz",
421 | "integrity": "sha512-kE3PMk8xW+2BZ3oZiTxxsUU/GzrGwM+qS4frOBz9TYHZe+W1dTtj4F9vBit4PFJ+tv4O6DPt9neGobzdq0UmRw==",
422 | "cpu": [
423 | "x64"
424 | ],
425 | "dev": true,
426 | "optional": true,
427 | "os": [
428 | "darwin"
429 | ],
430 | "engines": {
431 | "node": ">=10"
432 | }
433 | },
434 | "node_modules/@swc/core-linux-arm-gnueabihf": {
435 | "version": "1.3.46",
436 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.46.tgz",
437 | "integrity": "sha512-7TbiUr9MYxT+mC7sVrayag/isFoaZUG/ogkEK8B/ouA1pnIYqWh3N5ifqCzfcSRiOURt+vVqPyoO1puSiNzVuQ==",
438 | "cpu": [
439 | "arm"
440 | ],
441 | "dev": true,
442 | "optional": true,
443 | "os": [
444 | "linux"
445 | ],
446 | "engines": {
447 | "node": ">=10"
448 | }
449 | },
450 | "node_modules/@swc/core-linux-arm64-gnu": {
451 | "version": "1.3.46",
452 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.46.tgz",
453 | "integrity": "sha512-Ycw4LU/wsUK9R+Y/2qFOPQseZDfM5D5gbWGrrYj5RoTm57FbnUsSsO26QeZxUNvams1oAQDkZDuerCc9qBRzIQ==",
454 | "cpu": [
455 | "arm64"
456 | ],
457 | "dev": true,
458 | "optional": true,
459 | "os": [
460 | "linux"
461 | ],
462 | "engines": {
463 | "node": ">=10"
464 | }
465 | },
466 | "node_modules/@swc/core-linux-arm64-musl": {
467 | "version": "1.3.46",
468 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.46.tgz",
469 | "integrity": "sha512-cBclyr6IW1PBr8l9D4FkebgbqlkiIYnSJCbY84J/6PfTzQlD6w9a1TAoYxdGZpJ7SGHdmB0oDiZS1rhxCSCV/Q==",
470 | "cpu": [
471 | "arm64"
472 | ],
473 | "dev": true,
474 | "optional": true,
475 | "os": [
476 | "linux"
477 | ],
478 | "engines": {
479 | "node": ">=10"
480 | }
481 | },
482 | "node_modules/@swc/core-linux-x64-gnu": {
483 | "version": "1.3.46",
484 | "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.46.tgz",
485 | "integrity": "sha512-amqMhTA2CXB6t11hVAZSSPKq4DZ9/sWbW3wYYQHxzqrMJML0726OJs4pt0XnlU7FzdP/9M9j2B/gWCRaCMxXVA==",
486 | "cpu": [
487 | "x64"
488 | ],
489 | "dev": true,
490 | "optional": true,
491 | "os": [
492 | "linux"
493 | ],
494 | "engines": {
495 | "node": ">=10"
496 | }
497 | },
498 | "node_modules/@swc/core-linux-x64-musl": {
499 | "version": "1.3.46",
500 | "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.46.tgz",
501 | "integrity": "sha512-WOQZTIkJ9khIj5Z2unf6OTrWV9k8br+HZ93RvnamEmJBlLPUuT9IjB+agNhjaDgOpz9/ZldSGqV7vzl5FGQl1Q==",
502 | "cpu": [
503 | "x64"
504 | ],
505 | "dev": true,
506 | "optional": true,
507 | "os": [
508 | "linux"
509 | ],
510 | "engines": {
511 | "node": ">=10"
512 | }
513 | },
514 | "node_modules/@swc/core-win32-arm64-msvc": {
515 | "version": "1.3.46",
516 | "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.46.tgz",
517 | "integrity": "sha512-4JSREbqaTRQ6QO0EeoiB6G5vuFT8zI8aTOLu5At7Cvlw+X7bOGNO+wJ3Tqw7O+68OL+0bPHzHGTXKL9kUccY1A==",
518 | "cpu": [
519 | "arm64"
520 | ],
521 | "dev": true,
522 | "optional": true,
523 | "os": [
524 | "win32"
525 | ],
526 | "engines": {
527 | "node": ">=10"
528 | }
529 | },
530 | "node_modules/@swc/core-win32-ia32-msvc": {
531 | "version": "1.3.46",
532 | "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.46.tgz",
533 | "integrity": "sha512-kC8dIDzcArm1e85yHJsEZFxcNq5NztLkrqkP1nVOQ+9QXD9DKhjbZtWy2gnpclinii6KEGng8SieWiJiOA0CBQ==",
534 | "cpu": [
535 | "ia32"
536 | ],
537 | "dev": true,
538 | "optional": true,
539 | "os": [
540 | "win32"
541 | ],
542 | "engines": {
543 | "node": ">=10"
544 | }
545 | },
546 | "node_modules/@swc/core-win32-x64-msvc": {
547 | "version": "1.3.46",
548 | "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.46.tgz",
549 | "integrity": "sha512-rrSAfq+DvpJioBxUsnuH+sKl0eXid1DwkwNzkVGHEreN9GoP7GospWtFq7VDcO6DrS/s3HtR4/TzoIYFEBCRIg==",
550 | "cpu": [
551 | "x64"
552 | ],
553 | "dev": true,
554 | "optional": true,
555 | "os": [
556 | "win32"
557 | ],
558 | "engines": {
559 | "node": ">=10"
560 | }
561 | },
562 | "node_modules/@swc/helpers": {
563 | "version": "0.5.0",
564 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.0.tgz",
565 | "integrity": "sha512-SjY/p4MmECVVEWspzSRpQEM3sjR17sP8PbGxELWrT+YZMBfiUyt1MRUNjMV23zohwlG2HYtCQOsCwsTHguXkyg==",
566 | "dev": true,
567 | "peer": true,
568 | "dependencies": {
569 | "tslib": "^2.4.0"
570 | }
571 | },
572 | "node_modules/@types/prop-types": {
573 | "version": "15.7.5",
574 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
575 | "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
576 | "dev": true
577 | },
578 | "node_modules/@types/react": {
579 | "version": "18.0.33",
580 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.33.tgz",
581 | "integrity": "sha512-sHxzVxeanvQyQ1lr8NSHaj0kDzcNiGpILEVt69g9S31/7PfMvNCKLKcsHw4lYKjs3cGNJjXSP4mYzX43QlnjNA==",
582 | "dev": true,
583 | "dependencies": {
584 | "@types/prop-types": "*",
585 | "@types/scheduler": "*",
586 | "csstype": "^3.0.2"
587 | }
588 | },
589 | "node_modules/@types/react-dom": {
590 | "version": "18.0.11",
591 | "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz",
592 | "integrity": "sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==",
593 | "dev": true,
594 | "dependencies": {
595 | "@types/react": "*"
596 | }
597 | },
598 | "node_modules/@types/scheduler": {
599 | "version": "0.16.3",
600 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
601 | "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
602 | "dev": true
603 | },
604 | "node_modules/@vitejs/plugin-react-swc": {
605 | "version": "3.2.0",
606 | "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.2.0.tgz",
607 | "integrity": "sha512-IcBoXL/mcH7JdQr/nfDlDwTdIaH8Rg7LpfQDF4nAht+juHWIuv6WhpKPCSfY4+zztAaB07qdBoFz1XCZsgo3pQ==",
608 | "dev": true,
609 | "dependencies": {
610 | "@swc/core": "^1.3.35"
611 | },
612 | "peerDependencies": {
613 | "vite": "^4"
614 | }
615 | },
616 | "node_modules/csstype": {
617 | "version": "3.1.2",
618 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
619 | "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
620 | "dev": true
621 | },
622 | "node_modules/esbuild": {
623 | "version": "0.17.15",
624 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.15.tgz",
625 | "integrity": "sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw==",
626 | "dev": true,
627 | "hasInstallScript": true,
628 | "bin": {
629 | "esbuild": "bin/esbuild"
630 | },
631 | "engines": {
632 | "node": ">=12"
633 | },
634 | "optionalDependencies": {
635 | "@esbuild/android-arm": "0.17.15",
636 | "@esbuild/android-arm64": "0.17.15",
637 | "@esbuild/android-x64": "0.17.15",
638 | "@esbuild/darwin-arm64": "0.17.15",
639 | "@esbuild/darwin-x64": "0.17.15",
640 | "@esbuild/freebsd-arm64": "0.17.15",
641 | "@esbuild/freebsd-x64": "0.17.15",
642 | "@esbuild/linux-arm": "0.17.15",
643 | "@esbuild/linux-arm64": "0.17.15",
644 | "@esbuild/linux-ia32": "0.17.15",
645 | "@esbuild/linux-loong64": "0.17.15",
646 | "@esbuild/linux-mips64el": "0.17.15",
647 | "@esbuild/linux-ppc64": "0.17.15",
648 | "@esbuild/linux-riscv64": "0.17.15",
649 | "@esbuild/linux-s390x": "0.17.15",
650 | "@esbuild/linux-x64": "0.17.15",
651 | "@esbuild/netbsd-x64": "0.17.15",
652 | "@esbuild/openbsd-x64": "0.17.15",
653 | "@esbuild/sunos-x64": "0.17.15",
654 | "@esbuild/win32-arm64": "0.17.15",
655 | "@esbuild/win32-ia32": "0.17.15",
656 | "@esbuild/win32-x64": "0.17.15"
657 | }
658 | },
659 | "node_modules/fsevents": {
660 | "version": "2.3.2",
661 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
662 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
663 | "dev": true,
664 | "hasInstallScript": true,
665 | "optional": true,
666 | "os": [
667 | "darwin"
668 | ],
669 | "engines": {
670 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
671 | }
672 | },
673 | "node_modules/function-bind": {
674 | "version": "1.1.1",
675 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
676 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
677 | "dev": true
678 | },
679 | "node_modules/has": {
680 | "version": "1.0.3",
681 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
682 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
683 | "dev": true,
684 | "dependencies": {
685 | "function-bind": "^1.1.1"
686 | },
687 | "engines": {
688 | "node": ">= 0.4.0"
689 | }
690 | },
691 | "node_modules/is-core-module": {
692 | "version": "2.11.0",
693 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
694 | "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
695 | "dev": true,
696 | "dependencies": {
697 | "has": "^1.0.3"
698 | },
699 | "funding": {
700 | "url": "https://github.com/sponsors/ljharb"
701 | }
702 | },
703 | "node_modules/js-tokens": {
704 | "version": "4.0.0",
705 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
706 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
707 | },
708 | "node_modules/loose-envify": {
709 | "version": "1.4.0",
710 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
711 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
712 | "dependencies": {
713 | "js-tokens": "^3.0.0 || ^4.0.0"
714 | },
715 | "bin": {
716 | "loose-envify": "cli.js"
717 | }
718 | },
719 | "node_modules/nanoid": {
720 | "version": "3.3.6",
721 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
722 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
723 | "dev": true,
724 | "funding": [
725 | {
726 | "type": "github",
727 | "url": "https://github.com/sponsors/ai"
728 | }
729 | ],
730 | "bin": {
731 | "nanoid": "bin/nanoid.cjs"
732 | },
733 | "engines": {
734 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
735 | }
736 | },
737 | "node_modules/path-parse": {
738 | "version": "1.0.7",
739 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
740 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
741 | "dev": true
742 | },
743 | "node_modules/picocolors": {
744 | "version": "1.0.0",
745 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
746 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
747 | "dev": true
748 | },
749 | "node_modules/postcss": {
750 | "version": "8.4.21",
751 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
752 | "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
753 | "dev": true,
754 | "funding": [
755 | {
756 | "type": "opencollective",
757 | "url": "https://opencollective.com/postcss/"
758 | },
759 | {
760 | "type": "tidelift",
761 | "url": "https://tidelift.com/funding/github/npm/postcss"
762 | }
763 | ],
764 | "dependencies": {
765 | "nanoid": "^3.3.4",
766 | "picocolors": "^1.0.0",
767 | "source-map-js": "^1.0.2"
768 | },
769 | "engines": {
770 | "node": "^10 || ^12 || >=14"
771 | }
772 | },
773 | "node_modules/react": {
774 | "version": "18.2.0",
775 | "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
776 | "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
777 | "dependencies": {
778 | "loose-envify": "^1.1.0"
779 | },
780 | "engines": {
781 | "node": ">=0.10.0"
782 | }
783 | },
784 | "node_modules/react-dom": {
785 | "version": "18.2.0",
786 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
787 | "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
788 | "dependencies": {
789 | "loose-envify": "^1.1.0",
790 | "scheduler": "^0.23.0"
791 | },
792 | "peerDependencies": {
793 | "react": "^18.2.0"
794 | }
795 | },
796 | "node_modules/resolve": {
797 | "version": "1.22.1",
798 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
799 | "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
800 | "dev": true,
801 | "dependencies": {
802 | "is-core-module": "^2.9.0",
803 | "path-parse": "^1.0.7",
804 | "supports-preserve-symlinks-flag": "^1.0.0"
805 | },
806 | "bin": {
807 | "resolve": "bin/resolve"
808 | },
809 | "funding": {
810 | "url": "https://github.com/sponsors/ljharb"
811 | }
812 | },
813 | "node_modules/rollup": {
814 | "version": "3.20.2",
815 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz",
816 | "integrity": "sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==",
817 | "dev": true,
818 | "bin": {
819 | "rollup": "dist/bin/rollup"
820 | },
821 | "engines": {
822 | "node": ">=14.18.0",
823 | "npm": ">=8.0.0"
824 | },
825 | "optionalDependencies": {
826 | "fsevents": "~2.3.2"
827 | }
828 | },
829 | "node_modules/scheduler": {
830 | "version": "0.23.0",
831 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
832 | "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
833 | "dependencies": {
834 | "loose-envify": "^1.1.0"
835 | }
836 | },
837 | "node_modules/source-map-js": {
838 | "version": "1.0.2",
839 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
840 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
841 | "dev": true,
842 | "engines": {
843 | "node": ">=0.10.0"
844 | }
845 | },
846 | "node_modules/supports-preserve-symlinks-flag": {
847 | "version": "1.0.0",
848 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
849 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
850 | "dev": true,
851 | "engines": {
852 | "node": ">= 0.4"
853 | },
854 | "funding": {
855 | "url": "https://github.com/sponsors/ljharb"
856 | }
857 | },
858 | "node_modules/tslib": {
859 | "version": "2.5.0",
860 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
861 | "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==",
862 | "dev": true,
863 | "peer": true
864 | },
865 | "node_modules/vite": {
866 | "version": "4.2.1",
867 | "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz",
868 | "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==",
869 | "dev": true,
870 | "dependencies": {
871 | "esbuild": "^0.17.5",
872 | "postcss": "^8.4.21",
873 | "resolve": "^1.22.1",
874 | "rollup": "^3.18.0"
875 | },
876 | "bin": {
877 | "vite": "bin/vite.js"
878 | },
879 | "engines": {
880 | "node": "^14.18.0 || >=16.0.0"
881 | },
882 | "optionalDependencies": {
883 | "fsevents": "~2.3.2"
884 | },
885 | "peerDependencies": {
886 | "@types/node": ">= 14",
887 | "less": "*",
888 | "sass": "*",
889 | "stylus": "*",
890 | "sugarss": "*",
891 | "terser": "^5.4.0"
892 | },
893 | "peerDependenciesMeta": {
894 | "@types/node": {
895 | "optional": true
896 | },
897 | "less": {
898 | "optional": true
899 | },
900 | "sass": {
901 | "optional": true
902 | },
903 | "stylus": {
904 | "optional": true
905 | },
906 | "sugarss": {
907 | "optional": true
908 | },
909 | "terser": {
910 | "optional": true
911 | }
912 | }
913 | }
914 | }
915 | }
916 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-todo-list",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "react": "^18.2.0",
13 | "react-dom": "^18.2.0"
14 | },
15 | "devDependencies": {
16 | "@types/react": "^18.0.28",
17 | "@types/react-dom": "^18.0.11",
18 | "@vitejs/plugin-react-swc": "^3.0.0",
19 | "vite": "^4.2.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react"
2 | import { NewTodoForm } from "./NewTodoForm"
3 | import "./styles.css"
4 | import { TodoList } from "./TodoList"
5 |
6 | export default function App() {
7 | const [todos, setTodos] = useState(() => {
8 | const localValue = localStorage.getItem("ITEMS")
9 | if (localValue == null) return []
10 |
11 | return JSON.parse(localValue)
12 | })
13 |
14 | useEffect(() => {
15 | localStorage.setItem("ITEMS", JSON.stringify(todos))
16 | }, [todos])
17 |
18 | function addTodo(title) {
19 | setTodos(currentTodos => {
20 | return [
21 | ...currentTodos,
22 | { id: crypto.randomUUID(), title, completed: false },
23 | ]
24 | })
25 | }
26 |
27 | function toggleTodo(id, completed) {
28 | setTodos(currentTodos => {
29 | return currentTodos.map(todo => {
30 | if (todo.id === id) {
31 | return { ...todo, completed }
32 | }
33 |
34 | return todo
35 | })
36 | })
37 | }
38 |
39 | function deleteTodo(id) {
40 | setTodos(currentTodos => {
41 | return currentTodos.filter(todo => todo.id !== id)
42 | })
43 | }
44 |
45 | return (
46 | <>
47 |
48 | Todo List
49 |
50 | >
51 | )
52 | }
53 |
--------------------------------------------------------------------------------
/src/NewTodoForm.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 |
3 | export function NewTodoForm({ onSubmit }) {
4 | const [newItem, setNewItem] = useState("")
5 |
6 | function handleSubmit(e) {
7 | e.preventDefault()
8 | if (newItem === "") return
9 |
10 | onSubmit(newItem)
11 |
12 | setNewItem("")
13 | }
14 |
15 | return (
16 |
28 | )
29 | }
30 |
--------------------------------------------------------------------------------
/src/TodoItem.jsx:
--------------------------------------------------------------------------------
1 | export function TodoItem({ completed, id, title, toggleTodo, deleteTodo }) {
2 | return (
3 |
4 |
5 | toggleTodo(id, e.target.checked)}
9 | />
10 | {title}
11 |
12 | deleteTodo(id)} className="btn btn-danger">
13 | Delete
14 |
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/src/TodoList.jsx:
--------------------------------------------------------------------------------
1 | import { TodoItem } from "./TodoItem"
2 |
3 | export function TodoList({ todos, toggleTodo, deleteTodo }) {
4 | return (
5 |
6 | {todos.length === 0 && "No Todos"}
7 | {todos.map(todo => {
8 | return (
9 |
15 | )
16 | })}
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import ReactDOM from "react-dom/client"
3 | import App from "./App"
4 |
5 | ReactDOM.createRoot(document.getElementById("root")).render(
6 |
7 |
8 |
9 | )
10 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | * {
2 | font-family: Arial, Helvetica, sans-serif;
3 | box-sizing: border-box;
4 | }
5 |
6 | body {
7 | background: #333;
8 | color: hsl(200, 100%, 90%);
9 | max-width: 400px;
10 | padding: 1rem;
11 | margin: 0 auto;
12 | }
13 |
14 | .new-item-form {
15 | display: flex;
16 | flex-direction: column;
17 | gap: 0.5rem;
18 | }
19 |
20 | .form-row {
21 | display: flex;
22 | flex-direction: column;
23 | gap: 0.1rem;
24 | }
25 |
26 | .btn {
27 | background: hsl(200, 100%, 50%, 0.1);
28 | border: 1px solid hsl(200, 100%, 50%);
29 | color: hsl(200, 100%, 50%);
30 | padding: 0.25em 0.5em;
31 | border-radius: 0.25em;
32 | cursor: pointer;
33 | outline: none;
34 | }
35 |
36 | .btn:hover,
37 | .btn:focus-visible {
38 | background: hsl(200, 100%, 50%, 0.2);
39 | }
40 |
41 | .btn.btn-danger {
42 | background: hsl(0, 100%, 40%, 0.1);
43 | border: 1px solid hsl(0, 100%, 40%);
44 | color: hsl(0, 100%, 40%);
45 | }
46 |
47 | .btn.btn-danger:hover,
48 | .btn.btn-danger:focus-visible {
49 | background: hsl(0, 100%, 40%, 0.2);
50 | }
51 |
52 | .new-item-form input {
53 | outline: none;
54 | border: 1px solid hsl(200, 100%, 40%);
55 | background: hsl(200, 100%, 30%);
56 | border-radius: 0.25em;
57 | padding: 0.25em 0.5em;
58 | color: hsl(200, 100%, 90%);
59 | }
60 |
61 | .new-item-form input:focus {
62 | border: 1px solid hsl(200, 100%, 70%);
63 | }
64 |
65 | .header {
66 | font-size: 1.5rem;
67 | margin-top: 1.5rem;
68 | margin-bottom: 0.5rem;
69 | }
70 |
71 | .list {
72 | margin: 0;
73 | padding: 0;
74 | margin-left: 1rem;
75 | list-style: none;
76 | }
77 |
78 | .list li:has(input:checked) label {
79 | color: hsl(200, 20%, 40%);
80 | }
81 |
82 | .list {
83 | display: flex;
84 | flex-direction: column;
85 | gap: 0.3rem;
86 | }
87 |
88 | .list li {
89 | display: flex;
90 | gap: 0.5rem;
91 | align-items: center;
92 | }
93 |
94 | .list li label {
95 | display: flex;
96 | gap: 0.25rem;
97 | cursor: pointer;
98 | align-items: center;
99 | }
100 |
101 | .list li:has(input:focus-visible) label {
102 | outline: 1px solid hsl(200, 100%, 50%);
103 | }
104 |
105 | .list li input {
106 | outline: none;
107 | width: 0;
108 | height: 0;
109 | appearance: none;
110 | pointer-events: none;
111 | position: absolute;
112 | }
113 |
114 | .list li label::before {
115 | content: "";
116 | display: block;
117 | width: 0.9rem;
118 | height: 0.9rem;
119 | background: hsl(200, 100%, 90%);
120 | border-radius: 0.25em;
121 | display: flex;
122 | justify-content: center;
123 | align-items: center;
124 | }
125 |
126 | .list li label:hover::before {
127 | background: hsl(200, 100%, 80%);
128 | }
129 |
130 | .list li:has(input:checked) label::before {
131 | content: "✔";
132 | background: hsl(200, 100%, 40%);
133 | color: hsl(200, 100%, 90%);
134 | font-size: 0.75rem;
135 | font-weight: bold;
136 | }
137 |
138 | .list li:has(input:checked) label:hover::before {
139 | background: hsl(200, 100%, 30%);
140 | }
141 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react-swc'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------