├── .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 |
19 | 20 | 21 |
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 | --------------------------------------------------------------------------------