├── .gitignore
├── LICENSE
├── README.md
├── package-lock.json
├── package.json
├── public
├── index.html
└── robots.txt
├── snowpack.config.mjs
├── src
└── index.ts
├── tsconfig.json
└── types
└── static.d.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | .snowpack
2 | build
3 | node_modules
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # New Project
2 |
3 | > ✨ Bootstrapped with Create Snowpack App (CSA).
4 |
5 | ## Available Scripts
6 |
7 | ### npm start
8 |
9 | Runs the app in the development mode.
10 | Open http://localhost:8080 to view it in the browser.
11 |
12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console.
14 |
15 | ### npm run build
16 |
17 | Builds a static copy of your site to the `build/` folder.
18 | Your app is ready to be deployed!
19 |
20 | **For the best production performance:** Add a build bundler plugin like [@snowpack/plugin-webpack](https://github.com/snowpackjs/snowpack/tree/main/plugins/plugin-webpack) or [snowpack-plugin-rollup-bundle](https://github.com/ParamagicDev/snowpack-plugin-rollup-bundle) to your `snowpack.config.mjs` config file.
21 |
22 | ### Q: What about Eject?
23 |
24 | No eject needed! Snowpack guarantees zero lock-in, and CSA strives for the same.
25 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "start": "snowpack dev",
4 | "build": "snowpack build"
5 | },
6 | "dependencies": {
7 | "canvas-confetti": "^1.2.0",
8 | "uuid": "^8.3.2"
9 | },
10 | "devDependencies": {
11 | "@snowpack/plugin-typescript": "^1.2.1",
12 | "@types/canvas-confetti": "^1.0.0",
13 | "@types/snowpack-env": "^2.3.3",
14 | "@types/uuid": "^8.3.4",
15 | "prettier": "^2.2.1",
16 | "snowpack": "^3.3.7",
17 | "typescript": "^4.2.4"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Document
9 |
15 |
16 |
17 |
18 |
22 |
23 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/snowpack.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import("snowpack").SnowpackUserConfig } */
2 | export default {
3 | mount: {
4 | public: { url: '/', static: true },
5 | src: { url: '/dist' },
6 | },
7 | plugins: [
8 | [
9 | '@snowpack/plugin-typescript',
10 | {
11 | /* Yarn PnP workaround: see https://www.npmjs.com/package/@snowpack/plugin-typescript */
12 | ...(process.versions.pnp ? { tsc: 'yarn pnpify tsc' } : {}),
13 | },
14 | ],
15 | ],
16 | routes: [
17 | /* Enable an SPA Fallback in development: */
18 | // {"match": "routes", "src": ".*", "dest": "/index.html"},
19 | ],
20 | optimize: {
21 | /* Example: Bundle your final build: */
22 | // "bundle": true,
23 | },
24 | packageOptions: {
25 | /* ... */
26 | },
27 | devOptions: {
28 | /* ... */
29 | },
30 | buildOptions: {
31 | /* ... */
32 | },
33 | };
34 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { v4 as uuidV4 } from "uuid"
2 |
3 | type Task = {
4 | id: string
5 | title: string
6 | completed: boolean
7 | createdAt: Date
8 | }
9 |
10 | const list = document.querySelector("#list")
11 | const form = document.getElementById("new-task-form") as HTMLFormElement | null
12 | const input = document.querySelector("#new-task-title")
13 | const tasks: Task[] = loadTasks()
14 | tasks.forEach(addListItem)
15 |
16 | form?.addEventListener("submit", e => {
17 | e.preventDefault()
18 |
19 | if (input?.value == "" || input?.value == null) return
20 |
21 | const newTask: Task = {
22 | id: uuidV4(),
23 | title: input.value,
24 | completed: false,
25 | createdAt: new Date(),
26 | }
27 | tasks.push(newTask)
28 | saveTasks()
29 |
30 | addListItem(newTask)
31 | input.value = ""
32 | })
33 |
34 | function addListItem(task: Task) {
35 | const item = document.createElement("li")
36 | const label = document.createElement("label")
37 | const checkbox = document.createElement("input")
38 | checkbox.addEventListener("change", () => {
39 | task.completed = checkbox.checked
40 | saveTasks()
41 | })
42 | checkbox.type = "checkbox"
43 | checkbox.checked = task.completed
44 | label.append(checkbox, task.title)
45 | item.append(label)
46 | list?.append(item)
47 | }
48 |
49 | function saveTasks() {
50 | localStorage.setItem("TASKS", JSON.stringify(tasks))
51 | }
52 |
53 | function loadTasks(): Task[] {
54 | const taskJSON = localStorage.getItem("TASKS")
55 | if (taskJSON == null) return []
56 | return JSON.parse(taskJSON)
57 | }
58 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src", "types"],
3 | "compilerOptions": {
4 | "module": "esnext",
5 | "target": "esnext",
6 | "moduleResolution": "node",
7 | "jsx": "preserve",
8 | "baseUrl": "./",
9 | /* paths - import rewriting/resolving */
10 | "paths": {
11 | // If you configured any Snowpack aliases, add them here.
12 | // Add this line to get types for streaming imports (packageOptions.source="remote"):
13 | // "*": [".snowpack/types/*"]
14 | // More info: https://www.snowpack.dev/guides/streaming-imports
15 | },
16 | "allowSyntheticDefaultImports": true,
17 | "importsNotUsedAsValues": "error",
18 | /* more strict checking for errors that per-file transpilers like `esbuild` would crash */
19 | "isolatedModules": true,
20 | /* noEmit - We only use TypeScript for type checking. */
21 | "noEmit": true,
22 | /* Additional Options */
23 | "strict": true,
24 | "skipLibCheck": true,
25 | "forceConsistentCasingInFileNames": true,
26 | "resolveJsonModule": true,
27 | "useDefineForClassFields": true
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/types/static.d.ts:
--------------------------------------------------------------------------------
1 | /* Use this file to declare any custom file extensions for importing */
2 | /* Use this folder to also add/extend a package d.ts file, if needed. */
3 |
4 | /* CSS MODULES */
5 | declare module '*.module.css' {
6 | const classes: { [key: string]: string };
7 | export default classes;
8 | }
9 | declare module '*.module.scss' {
10 | const classes: { [key: string]: string };
11 | export default classes;
12 | }
13 | declare module '*.module.sass' {
14 | const classes: { [key: string]: string };
15 | export default classes;
16 | }
17 | declare module '*.module.less' {
18 | const classes: { [key: string]: string };
19 | export default classes;
20 | }
21 | declare module '*.module.styl' {
22 | const classes: { [key: string]: string };
23 | export default classes;
24 | }
25 |
26 | /* CSS */
27 | declare module '*.css';
28 | declare module '*.scss';
29 | declare module '*.sass';
30 | declare module '*.less';
31 | declare module '*.styl';
32 |
33 | /* IMAGES */
34 | declare module '*.svg' {
35 | const ref: string;
36 | export default ref;
37 | }
38 | declare module '*.bmp' {
39 | const ref: string;
40 | export default ref;
41 | }
42 | declare module '*.gif' {
43 | const ref: string;
44 | export default ref;
45 | }
46 | declare module '*.jpg' {
47 | const ref: string;
48 | export default ref;
49 | }
50 | declare module '*.jpeg' {
51 | const ref: string;
52 | export default ref;
53 | }
54 | declare module '*.png' {
55 | const ref: string;
56 | export default ref;
57 | }
58 |
59 | /* CUSTOM: ADD YOUR OWN HERE */
60 |
--------------------------------------------------------------------------------