├── .babelrc
├── src
├── modules
│ ├── store.js
│ ├── generateTodo.js
│ ├── Todo.js
│ ├── updateStatus.js
│ ├── TodosContainer.js
│ └── UI.js
├── index.html
├── index.js
├── style.css
└── todolist.test.js
├── .hintrc
├── webpack.config.js
├── .eslintrc.json
├── .stylelintrc.json
├── LICENSE
├── dist
├── index.html
└── main.js
├── package.json
├── .gitignore
├── .github
└── workflows
│ └── linter.yml
└── README.md
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "test": {
4 | "plugins": ["@babel/plugin-transform-modules-commonjs"]
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/src/modules/store.js:
--------------------------------------------------------------------------------
1 | export const getTodos = () => JSON.parse(localStorage.getItem('todos'));
2 | export const setTodos = (obj) => {
3 | localStorage.setItem('todos', JSON.stringify(obj));
4 | };
--------------------------------------------------------------------------------
/src/modules/generateTodo.js:
--------------------------------------------------------------------------------
1 | import UI from './UI.js';
2 |
3 | export default function populateTodos(data) {
4 | data.forEach((element) => {
5 | UI.add(element.id, element.description, element.completed);
6 | });
7 | }
--------------------------------------------------------------------------------
/src/modules/Todo.js:
--------------------------------------------------------------------------------
1 | export default class Todo {
2 | constructor(id, description, completed, index) {
3 | this.id = id;
4 | this.description = description;
5 | this.completed = completed;
6 | this.index = index;
7 | }
8 | }
--------------------------------------------------------------------------------
/.hintrc:
--------------------------------------------------------------------------------
1 | {
2 | "connector": {
3 | "name": "local",
4 | "options": {
5 | "pattern": ["**", "!.git/**", "!node_modules/**"]
6 | }
7 | },
8 | "extends": ["development"],
9 | "formatters": ["stylish"],
10 | "hints": [
11 | "button-type",
12 | "disown-opener",
13 | "html-checker",
14 | "meta-charset-utf-8",
15 | "meta-viewport",
16 | "no-inline-styles:error"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved:0 */
2 | const path = require('path');
3 | const HtmlWebpackPlugin = require('html-webpack-plugin');
4 |
5 | module.exports = {
6 | module: {
7 | rules: [
8 | {
9 | test: /\.css$/,
10 | use: ['style-loader', 'css-loader'],
11 | },
12 | ],
13 | },
14 | plugins: [
15 | new HtmlWebpackPlugin({
16 | template: path.resolve(__dirname, 'src', 'index.html'),
17 | }),
18 | ],
19 | };
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "jest": true
6 | },
7 | "parser": "babel-eslint",
8 | "parserOptions": {
9 | "ecmaVersion": 2018,
10 | "sourceType": "module"
11 | },
12 | "extends": ["airbnb-base"],
13 | "rules": {
14 | "no-shadow": "off",
15 | "no-param-reassign": "off",
16 | "eol-last": "off",
17 | "import/extensions": [
18 | 1,
19 | {
20 | "js": "always",
21 | "json": "always"
22 | }
23 | ]
24 | },
25 | "ignorePatterns": ["dist/", "build/"]
26 | }
27 |
--------------------------------------------------------------------------------
/src/modules/updateStatus.js:
--------------------------------------------------------------------------------
1 | import { getTodos, setTodos } from './store.js';
2 | import UI from './UI.js';
3 |
4 | export const updateStatus = (id) => {
5 | const [statusId] = id.match(/\d+/);
6 | const todos = getTodos().map((todo) => {
7 | if (todo.id === statusId) {
8 | return { ...todo, completed: !todo.completed };
9 | }
10 | return todo;
11 | });
12 | setTodos(todos);
13 | UI.updateStatusUI(statusId);
14 | };
15 | export const clearTodoList = () => {
16 | const listToNotClear = getTodos()
17 | .filter((todo) => todo.completed === false)
18 | .map((todo, index) => ({ ...todo, index: index + 1 }));
19 | const listToClear = getTodos().filter((todo) => todo.completed === true);
20 |
21 | listToClear.forEach((todo) => {
22 | UI.remove(todo.id);
23 | });
24 | setTodos(listToNotClear);
25 | };
26 |
--------------------------------------------------------------------------------
/.stylelintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["stylelint-config-standard"],
3 | "plugins": ["stylelint-scss", "stylelint-csstree-validator"],
4 | "rules": {
5 | "at-rule-no-unknown": [
6 | true,
7 | {
8 | "ignoreAtRules": [
9 | "tailwind",
10 | "apply",
11 | "variants",
12 | "responsive",
13 | "screen"
14 | ]
15 | }
16 | ],
17 | "scss/at-rule-no-unknown": [
18 | true,
19 | {
20 | "ignoreAtRules": [
21 | "tailwind",
22 | "apply",
23 | "variants",
24 | "responsive",
25 | "screen"
26 | ]
27 | }
28 | ],
29 | "csstree/validator": true
30 | },
31 | "ignoreFiles": [
32 | "build/**",
33 | "dist/**",
34 | "**/reset*.css",
35 | "**/bootstrap*.css",
36 | "**/*.js",
37 | "**/*.jsx"
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Nahom_zd
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 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | To do list
12 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
26 |
27 |
28 |
29 | Clear all completed
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | To do list
12 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
26 |
27 |
28 |
29 | Clear all completed
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/modules/TodosContainer.js:
--------------------------------------------------------------------------------
1 | import Todo from './Todo.js';
2 | import { getTodos, setTodos } from './store.js';
3 | import UI from './UI.js';
4 |
5 | export default class TodosContainer {
6 | addTodo = (description) => {
7 | this.todos = getTodos() || [];
8 | if (description.trim().length !== 0) {
9 | const id = Math.floor(Math.random() * 100000).toString();
10 | const index = this.todos.length + 1;
11 | const todo = new Todo(id, description, false, index);
12 | this.todos.push(todo);
13 | setTodos(this.todos);
14 | UI.add(id, description, false);
15 | }
16 | };
17 |
18 | removeTodo = (id) => {
19 | this.todos = getTodos() || [];
20 | this.todos = this.todos
21 | .filter((todo) => todo.id !== id)
22 | .map((todo, index) => ({ ...todo, index: index + 1 }));
23 | setTodos(this.todos);
24 | UI.remove(id);
25 | };
26 |
27 | updateDescription = (id, description) => {
28 | this.todos = getTodos() || [];
29 | const [updateId] = id.match(/\d+/);
30 |
31 | if (description.trim().length !== 0) {
32 | this.todos = this.todos.map((todo) => {
33 | if (todo.id === updateId) {
34 | return { ...todo, description };
35 | }
36 | return todo;
37 | });
38 | setTodos(this.todos);
39 | UI.updateTodo(id, description);
40 | } else {
41 | this.removeTodo(updateId);
42 | }
43 | };
44 | }
45 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "to-do-list",
3 | "version": "1.0.0",
4 | "description": "To do list app using javascript ,html and css.",
5 | "main": "index.js",
6 | "scripts": {
7 | "deploy": "gh-pages -d dist",
8 | "build": "webpack --mode development",
9 | "start": "webpack serve --mode development --open",
10 | "test": "jest --coverage --env=jsdom",
11 | "watch": "jest --watchAll *.js"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/zdnahom/to-do-list.git"
16 | },
17 | "keywords": [],
18 | "author": "",
19 | "license": "ISC",
20 | "bugs": {
21 | "url": "https://github.com/zdnahom/to-do-list/issues"
22 | },
23 | "homepage": "https://github.com/zdnahom/to-do-list",
24 | "devDependencies": {
25 | "@babel/plugin-transform-modules-commonjs": "^7.21.2",
26 | "babel-eslint": "^10.1.0",
27 | "css-loader": "^6.7.3",
28 | "eslint": "^7.32.0",
29 | "eslint-config-airbnb-base": "^14.2.1",
30 | "eslint-plugin-import": "^2.27.5",
31 | "html-webpack-plugin": "^5.5.0",
32 | "jest": "^29.4.3",
33 | "jest-environment-jsdom": "^29.4.3",
34 | "style-loader": "^3.3.1",
35 | "stylelint": "^13.13.1",
36 | "stylelint-config-standard": "^21.0.0",
37 | "stylelint-csstree-validator": "^1.9.0",
38 | "stylelint-scss": "^3.21.0",
39 | "webpack": "^5.75.0",
40 | "webpack-cli": "^5.0.1",
41 | "webpack-dev-server": "^4.11.1"
42 | },
43 | "dependencies": {
44 | "gh-pages": "^5.0.0"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import './style.css';
2 | import { getTodos } from './modules/store.js';
3 | import populateTodos from './modules/generateTodo.js';
4 | import TodosContainer from './modules/TodosContainer.js';
5 | import { updateStatus, clearTodoList } from './modules/updateStatus.js';
6 |
7 | const todoLists = getTodos() || [];
8 | const container = new TodosContainer();
9 |
10 | const todoElements = document.querySelector('.tasks');
11 | const form = document.querySelector('.task-adder');
12 | const { task } = form.elements;
13 | const clearButton = document.querySelector('.button-wrapper button');
14 |
15 | form.addEventListener('submit', (event) => {
16 | event.preventDefault();
17 | container.addTodo(task.value);
18 | task.value = '';
19 | });
20 |
21 | todoElements.addEventListener('click', (event) => {
22 | const { target } = event;
23 | if (parseInt(target.id, 10)) {
24 | container.removeTodo(event.target.id);
25 | } else if (target.id.includes('description')) {
26 | target.parentNode.parentNode.style.backgroundColor = 'rgb(253, 238, 213)';
27 | target.addEventListener('blur', () => {
28 | target.parentNode.parentNode.style.backgroundColor = 'white';
29 | container.updateDescription(target.id, target.value);
30 | });
31 | target.addEventListener('keypress', (event) => {
32 | if (event.key === 'Enter') {
33 | target.blur();
34 | }
35 | });
36 | }
37 | });
38 |
39 | todoElements.addEventListener('change', (event) => {
40 | if (event.target.id.includes('checkbox')) {
41 | updateStatus(event.target.id);
42 | }
43 | });
44 |
45 | clearButton.addEventListener('click', () => {
46 | clearTodoList();
47 | });
48 |
49 | window.addEventListener('DOMContentLoaded', () => {
50 | populateTodos(todoLists);
51 | });
52 |
--------------------------------------------------------------------------------
/src/modules/UI.js:
--------------------------------------------------------------------------------
1 | export default class UI {
2 | static remove = (id) => {
3 | const element = document.getElementById(id);
4 | const parentToRemove = element.parentNode.parentNode;
5 | parentToRemove.remove();
6 | };
7 |
8 | static add = (id, description, status) => {
9 | const li = document.createElement('li');
10 | li.className = 'todo';
11 | li.innerHTML = `
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | `;
20 |
21 | document.querySelector('.tasks').appendChild(li);
22 | document.querySelector(`#checkbox-${id}`).checked = status;
23 | if (document.querySelector(`#checkbox-${id}`).checked) {
24 | document.querySelector(`#description-${id}`).style.color = 'gray';
25 | document.querySelector(`#description-${id}`).style.textDecoration = 'line-through';
26 | } else {
27 | document.querySelector(`#description-${id}`).style.color = 'black';
28 | document.querySelector(`#description-${id}`).style.textDecoration = 'none';
29 | }
30 | };
31 |
32 | static updateTodo=(id, description) => {
33 | const updateTaskElement = document.querySelector(`#${id}`);
34 | updateTaskElement.value = description;
35 | }
36 |
37 | static updateStatusUI=(id) => {
38 | const checkbox = document.querySelector(`#checkbox-${id}`);
39 | const descriptionElement = document.querySelector(`#description-${id}`);
40 | if (checkbox.checked) {
41 | descriptionElement.style.color = 'gray';
42 | descriptionElement.style.textDecoration = 'line-through';
43 | } else {
44 | descriptionElement.style.color = 'black';
45 | descriptionElement.style.textDecoration = 'none';
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 |
84 | # Gatsby files
85 | .cache/
86 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
87 | # https://nextjs.org/blog/next-9-1#public-directory-support
88 | # public
89 |
90 | # vuepress build output
91 | .vuepress/dist
92 |
93 | # Serverless directories
94 | .serverless/
95 |
96 | # FuseBox cache
97 | .fusebox/
98 |
99 | # DynamoDB Local files
100 | .dynamodb/
101 |
102 | # TernJS port file
103 | .tern-port
104 |
--------------------------------------------------------------------------------
/.github/workflows/linter.yml:
--------------------------------------------------------------------------------
1 | name: Linters
2 |
3 | on: pull_request
4 |
5 | env:
6 | FORCE_COLOR: 1
7 |
8 | jobs:
9 | lighthouse:
10 | name: Lighthouse
11 | runs-on: ubuntu-22.04
12 | steps:
13 | - uses: actions/checkout@v2
14 | - uses: actions/setup-node@v1
15 | with:
16 | node-version: "12.x"
17 | - name: Setup Lighthouse
18 | run: npm install -g @lhci/cli@0.7.x
19 | - name: Lighthouse Report
20 | run: lhci autorun --upload.target=temporary-public-storage --collect.staticDistDir=.
21 | webhint:
22 | name: Webhint
23 | runs-on: ubuntu-22.04
24 | steps:
25 | - uses: actions/checkout@v2
26 | - uses: actions/setup-node@v1
27 | with:
28 | node-version: "12.x"
29 | - name: Setup Webhint
30 | run: |
31 | npm install --save-dev hint@7.x
32 | [ -f .hintrc ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.hintrc
33 | - name: Webhint Report
34 | run: npx hint .
35 | stylelint:
36 | name: Stylelint
37 | runs-on: ubuntu-22.04
38 | steps:
39 | - uses: actions/checkout@v2
40 | - uses: actions/setup-node@v1
41 | with:
42 | node-version: "12.x"
43 | - name: Setup Stylelint
44 | run: |
45 | npm install --save-dev stylelint@13.x stylelint-scss@3.x stylelint-config-standard@21.x stylelint-csstree-validator@1.x
46 | [ -f .stylelintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.stylelintrc.json
47 | - name: Stylelint Report
48 | run: npx stylelint "**/*.{css,scss}"
49 | eslint:
50 | name: ESLint
51 | runs-on: ubuntu-22.04
52 | steps:
53 | - uses: actions/checkout@v2
54 | - uses: actions/setup-node@v1
55 | with:
56 | node-version: "12.x"
57 | - name: Setup ESLint
58 | run: |
59 | npm install --save-dev eslint@7.x eslint-config-airbnb-base@14.x eslint-plugin-import@2.x babel-eslint@10.x
60 | [ -f .eslintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.eslintrc.json
61 | - name: ESLint Report
62 | run: npx eslint .
63 | nodechecker:
64 | name: node_modules checker
65 | runs-on: ubuntu-22.04
66 | steps:
67 | - uses: actions/checkout@v2
68 | - name: Check node_modules existence
69 | run: |
70 | if [ -d "node_modules/" ]; then echo -e "\e[1;31mThe node_modules/ folder was pushed to the repo. Please remove it from the GitHub repository and try again."; echo -e "\e[1;32mYou can set up a .gitignore file with this folder included on it to prevent this from happening in the future." && exit 1; fi
71 |
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | body {
8 | background-color: #d2d2d2;
9 | }
10 |
11 | .tasks-wrapper {
12 | width: 40%;
13 | background-color: white;
14 | margin: 100px auto;
15 | }
16 |
17 | .tasks-wrapper i {
18 | color: gray;
19 | }
20 |
21 | .tasks-header {
22 | display: flex;
23 | justify-content: space-between;
24 | align-items: center;
25 | padding: 3%;
26 | border-bottom: 1px solid #d2d2d2;
27 | }
28 |
29 | .tasks-header h3 {
30 | font-size: 1em;
31 | font-weight: 400;
32 | color: #6b6262;
33 | }
34 |
35 | .tasks-header i {
36 | font-size: 0.8em;
37 | }
38 |
39 | .task-adder {
40 | display: flex;
41 | justify-content: space-between;
42 | align-items: center;
43 | border-bottom: 1px solid #d2d2d2;
44 | padding: 3%;
45 | }
46 |
47 | .task-adder input {
48 | width: 100%;
49 | border: none;
50 | outline: none;
51 | font-size: 1em;
52 | color: #6b6262;
53 | }
54 |
55 | .task-adder button {
56 | background-color: inherit;
57 | border: none;
58 | font-size: 0.8em;
59 | }
60 |
61 | .tasks li {
62 | display: flex;
63 | justify-content: space-between;
64 | align-items: center;
65 | padding: 3%;
66 | border-bottom: 1px solid #d2d2d2;
67 | }
68 |
69 | .tasks div {
70 | display: flex;
71 | align-items: center;
72 | gap: 0.8em;
73 | width: 100%;
74 | }
75 |
76 | .tasks input[type='checkbox'] {
77 | width: 22px !important;
78 | height: 22px !important;
79 | display: flex;
80 | align-items: center;
81 | justify-content: center;
82 | margin: 5px;
83 | -webkit-appearance: none;
84 | -moz-appearance: none;
85 | -o-appearance: none;
86 | appearance: none;
87 | outline: 1px solid rgb(226, 219, 219);
88 | box-shadow: none;
89 | text-align: center;
90 | line-height: 1em;
91 | background: white;
92 | }
93 |
94 | .tasks input[type='checkbox']:checked::after {
95 | content: '✔';
96 | color: green;
97 | font-size: 1.4em;
98 | font-weight: 900;
99 | }
100 |
101 | .tasks input[type='text'] {
102 | width: 100%;
103 | font-size: 1em;
104 | border: none;
105 | background-color: inherit;
106 | outline: none;
107 | }
108 |
109 | .tasks button {
110 | background-color: inherit;
111 | border: none;
112 | cursor: pointer;
113 | }
114 |
115 | .tasks button i:hover {
116 | color: red;
117 | }
118 |
119 | .button-wrapper {
120 | display: flex;
121 | justify-content: center;
122 | background-color: #f7f2f2;
123 | }
124 |
125 | .button-wrapper button {
126 | background-color: inherit;
127 | border: none;
128 | padding: 3%;
129 | cursor: pointer;
130 | font-size: 1em;
131 | color: #6b6262;
132 | }
133 |
134 | .button-wrapper button:hover {
135 | color: black;
136 | text-decoration: underline;
137 | }
138 |
--------------------------------------------------------------------------------
/src/todolist.test.js:
--------------------------------------------------------------------------------
1 | import TodosContainer from './modules/TodosContainer.js';
2 | import { getTodos } from './modules/store.js';
3 | import { updateStatus, clearTodoList } from './modules/updateStatus.js';
4 |
5 | // Set up our document body
6 | document.body.innerHTML = `
7 |
9 | `;
10 |
11 | describe('Test Add todo', () => {
12 | it('Add a valid todo', () => {
13 | // arrange
14 | const container = new TodosContainer();
15 |
16 | // act
17 | container.addTodo('read books');
18 | container.addTodo('dance');
19 | container.addTodo('code for 1 hour');
20 | container.addTodo('Eat salad');
21 | const tasks = document.querySelectorAll('.tasks li');
22 |
23 | // assert
24 | expect(tasks).toHaveLength(4);
25 | });
26 |
27 | it('Add empty todo', () => {
28 | // arrange
29 | const container = new TodosContainer();
30 |
31 | // act
32 | container.addTodo(' ');
33 | const tasks = document.querySelectorAll('.tasks li');
34 |
35 | // assert
36 | expect(tasks).toHaveLength(4);
37 | });
38 | });
39 |
40 | describe('Test Remove todo', () => {
41 | it('Remove a todo with id=1', () => {
42 | // arrange
43 | const container = new TodosContainer();
44 | let tasks = document.querySelectorAll('.tasks li');
45 | const task = tasks[0].querySelector('i');
46 |
47 | // act
48 | container.removeTodo(task.id);
49 | tasks = document.querySelectorAll('.tasks li');
50 |
51 | // assert
52 | expect(tasks).toHaveLength(3);
53 | });
54 | });
55 |
56 | describe('Test Update todo', () => {
57 | it('Update todo item description', () => {
58 | // arrange
59 | const container = new TodosContainer();
60 | const tasks = document.querySelectorAll('.tasks li');
61 | const task = tasks[0].querySelector('input[type="text"]');
62 |
63 | // act
64 | container.updateDescription(task.id, 'Read more books');
65 |
66 | // assert
67 | expect(task.value).toEqual('Read more books');
68 | });
69 |
70 | it('Update todo item description with empty string', () => {
71 | // arrange
72 | const container = new TodosContainer();
73 | let tasks = document.querySelectorAll('.tasks li');
74 | const task = tasks[0].querySelector('input[type="text"]');
75 |
76 | // act
77 | container.updateDescription(task.id, '');
78 | tasks = document.querySelectorAll('.tasks li');
79 |
80 | // assert
81 | expect(tasks).toHaveLength(2);
82 | });
83 | });
84 |
85 | describe('Test for completed status', () => {
86 | it('change todo list status to true', () => {
87 | // arrange
88 | const tasks = document.querySelectorAll('.tasks li');
89 | const task1 = tasks[0].querySelector('input[type="checkbox"]');
90 | const task2 = tasks[1].querySelector('input[type="checkbox"]');
91 |
92 | // act
93 | updateStatus(task1.id);
94 | updateStatus(task2.id);
95 |
96 | // assert
97 | expect(getTodos()[0].completed).toBe(true);
98 | });
99 | it('change todo list status to false', () => {
100 | // arrange
101 | const tasks = document.querySelectorAll('.tasks li');
102 | const task = tasks[0].querySelector('input[type="checkbox"]');
103 |
104 | // act
105 | updateStatus(task.id);
106 |
107 | // assert
108 | expect(getTodos()[0].completed).toBe(false);
109 | });
110 | });
111 |
112 | describe('Test for Clear completed', () => {
113 | it('clear completed tasks', () => {
114 | // arrange
115 | let tasks = document.querySelectorAll('.tasks li');
116 |
117 | // act
118 | clearTodoList();
119 | tasks = document.querySelectorAll('.tasks li');
120 |
121 | // assert
122 | expect(tasks).toHaveLength(1);
123 | });
124 | });
125 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 📗 Table of Contents
4 |
5 | - [📗 Table of Contents](#-table-of-contents)
6 | - [📖 To do list](#-to-do-list)
7 | - [🛠 Built With ](#-built-with-)
8 | - [Tech Stack ](#tech-stack-)
9 | - [Key Features ](#key-features-)
10 | - [🚀 Live Demo ](#-live-demo-)
11 | - [💻 Getting Started ](#-getting-started-)
12 | - [Prerequisites](#prerequisites)
13 | - [Setup](#setup)
14 | - [Install](#install)
15 | - [Usage](#usage)
16 | - [Run tests](#run-tests)
17 | - [👥 Authors ](#-authors-)
18 | - [🔭 Future Features ](#-future-features-)
19 | - [🤝 Contributing ](#-contributing-)
20 | - [⭐️ Show your support ](#️-show-your-support-)
21 | - [🙏 Acknowledgments ](#-acknowledgments-)
22 | - [❓ FAQ (OPTIONAL) ](#-faq-optional-)
23 | - [📝 License ](#-license-)
24 |
25 |
26 |
27 | # 📖 To do list
28 | >
29 | To do list is a task management project built using pure javascript(ES6) , HTML, CSS, and Webpack.
30 |
31 | ## 🛠 Built With
32 |
33 | ### Tech Stack
34 |
35 |
36 | Client
37 |
42 |
43 |
44 | Server
45 |
49 |
50 |
51 |
52 |
53 |
54 | ### Key Features
55 |
56 | - **Display todo lists**
57 | - **Add new todo list**
58 | - **Remove todo list**
59 | - **Update todo list**
60 | - **Clear all completed todo lists**
61 |
62 |
63 |
64 |
65 | (back to top )
66 |
67 |
68 |
69 | ## 🚀 Live Demo
70 |
71 | - [Live Demo](https://zdnahom.github.io/to-do-list/)
72 |
73 | (back to top )
74 |
75 |
76 | ## 💻 Getting Started
77 |
78 |
79 | ### Prerequisites
80 |
81 | In order to run this project you need: Configure your code editor with HTML , CSS & JS and some other important extensions
82 |
83 |
84 |
85 | ### Setup
86 |
87 | git clone git@github.com:zdnahom/to-do-list.git
88 |
89 |
90 |
91 | ### Install
92 |
93 | Install this project with:
94 |
95 | git clone git@github.com:zdnahom/to-do-list.git
96 |
97 |
98 | ### Usage
99 |
100 | To run the project, execute the following command:
101 | - cd to-do-list
102 | - npm install
103 | - npm start
104 |
105 | ### Run tests
106 |
107 | To run tests, run the following command: No test module for now.But it will be added in the near future
108 |
109 |
110 |
111 |
112 | ## 👥 Authors
113 |
114 | 👤 **Nahom Zerihun Demissie 💻**
115 | - GitHub: [@zdnahom](https://github.com/zdnahom/)
116 |
117 |
118 | (back to top )
119 |
120 |
121 |
122 | ## 🔭 Future Features
123 |
124 | - **Add drag and drop functionality**
125 | - **Add cool animations**
126 |
127 |
128 |
129 |
130 | (back to top )
131 |
132 |
133 |
134 | ## 🤝 Contributing
135 |
136 | Contributions, issues, and feature requests are welcome!
137 |
138 | Feel free to check the [issues page](../../issues/).
139 |
140 | (back to top )
141 |
142 |
143 |
144 | ## ⭐️ Show your support
145 |
146 | If you like this project , please clone it and try it . I know you're going to love it
147 |
148 | (back to top )
149 |
150 |
151 |
152 | ## 🙏 Acknowledgments
153 | I would like to thank Microverse(staffs , mentors , reviewers) giving me the knowledge to build an amazing project like this.
154 |
155 | (back to top )
156 |
157 |
158 |
159 | ## ❓ FAQ (OPTIONAL)
160 |
161 | - **Can I fork the project and make a contribution?**
162 |
163 | Of course you can! First fork it and contribute to it.
164 |
165 | - **How should I ask a pull request**
166 |
167 | - Step 1 : Click on the pull request button
168 | - Step 2 : create pull request
169 |
170 | (back to top )
171 |
172 |
173 |
174 | ## 📝 License
175 |
176 | This project is [MIT](./LICENSE) licensed.
177 |
178 | _NOTE: we recommend using the [MIT license](https://choosealicense.com/licenses/mit/) - you can set it up quickly by [using templates available on GitHub](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository). You can also use [any other license](https://choosealicense.com/licenses/) if you wish._
179 |
180 | (back to top )
181 |
--------------------------------------------------------------------------------
/dist/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
3 | * This devtool is neither made for production nor for readable output files.
4 | * It uses "eval()" calls to create a separate source file in the browser devtools.
5 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
6 | * or disable the default devtool with "devtool: false".
7 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
8 | */
9 | /******/ (() => { // webpackBootstrap
10 | /******/ "use strict";
11 | /******/ var __webpack_modules__ = ({
12 |
13 | /***/ "./node_modules/css-loader/dist/cjs.js!./src/style.css":
14 | /*!*************************************************************!*\
15 | !*** ./node_modules/css-loader/dist/cjs.js!./src/style.css ***!
16 | \*************************************************************/
17 | /***/ ((module, __webpack_exports__, __webpack_require__) => {
18 |
19 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"* {\\r\\n box-sizing: border-box;\\r\\n margin: 0;\\r\\n padding: 0;\\r\\n}\\r\\n\\r\\nbody {\\r\\n background-color: #d2d2d2;\\r\\n}\\r\\n\\r\\n.tasks-wrapper {\\r\\n width: 40%;\\r\\n background-color: white;\\r\\n margin: 100px auto;\\r\\n}\\r\\n\\r\\n.tasks-wrapper i {\\r\\n color: gray;\\r\\n}\\r\\n\\r\\n.tasks-header {\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n align-items: center;\\r\\n padding: 3%;\\r\\n border-bottom: 1px solid #d2d2d2;\\r\\n}\\r\\n\\r\\n.tasks-header h3 {\\r\\n font-size: 1em;\\r\\n font-weight: 400;\\r\\n color: #6b6262;\\r\\n}\\r\\n\\r\\n.tasks-header i {\\r\\n font-size: 0.8em;\\r\\n}\\r\\n\\r\\n.task-adder {\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n align-items: center;\\r\\n border-bottom: 1px solid #d2d2d2;\\r\\n padding: 3%;\\r\\n}\\r\\n\\r\\n.task-adder input {\\r\\n width: 100%;\\r\\n border: none;\\r\\n outline: none;\\r\\n font-size: 1em;\\r\\n color: #6b6262;\\r\\n}\\r\\n\\r\\n.task-adder button {\\r\\n background-color: inherit;\\r\\n border: none;\\r\\n font-size: 0.8em;\\r\\n}\\r\\n\\r\\n.tasks li {\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n align-items: center;\\r\\n padding: 3%;\\r\\n border-bottom: 1px solid #d2d2d2;\\r\\n}\\r\\n\\r\\n.tasks div {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 0.8em;\\r\\n width: 100%;\\r\\n}\\r\\n\\r\\n.tasks input[type='checkbox'] {\\r\\n width: 22px !important;\\r\\n height: 22px !important;\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n margin: 5px;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n -o-appearance: none;\\r\\n appearance: none;\\r\\n outline: 1px solid rgb(226, 219, 219);\\r\\n box-shadow: none;\\r\\n text-align: center;\\r\\n line-height: 1em;\\r\\n background: white;\\r\\n}\\r\\n\\r\\n.tasks input[type='checkbox']:checked::after {\\r\\n content: '✔';\\r\\n color: green;\\r\\n font-size: 1.4em;\\r\\n font-weight: 900;\\r\\n}\\r\\n\\r\\n.tasks input[type='text'] {\\r\\n width: 100%;\\r\\n font-size: 1em;\\r\\n border: none;\\r\\n background-color: inherit;\\r\\n outline: none;\\r\\n}\\r\\n\\r\\n.tasks button {\\r\\n background-color: inherit;\\r\\n border: none;\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n.tasks button i:hover {\\r\\n color: red;\\r\\n}\\r\\n\\r\\n.button-wrapper {\\r\\n display: flex;\\r\\n justify-content: center;\\r\\n background-color: #f7f2f2;\\r\\n}\\r\\n\\r\\n.button-wrapper button {\\r\\n background-color: inherit;\\r\\n border: none;\\r\\n padding: 3%;\\r\\n cursor: pointer;\\r\\n font-size: 1em;\\r\\n color: #6b6262;\\r\\n}\\r\\n\\r\\n.button-wrapper button:hover {\\r\\n color: black;\\r\\n text-decoration: underline;\\r\\n}\\r\\n\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://to-do-list/./src/style.css?./node_modules/css-loader/dist/cjs.js");
20 |
21 | /***/ }),
22 |
23 | /***/ "./node_modules/css-loader/dist/runtime/api.js":
24 | /*!*****************************************************!*\
25 | !*** ./node_modules/css-loader/dist/runtime/api.js ***!
26 | \*****************************************************/
27 | /***/ ((module) => {
28 |
29 | eval("\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};\n\n//# sourceURL=webpack://to-do-list/./node_modules/css-loader/dist/runtime/api.js?");
30 |
31 | /***/ }),
32 |
33 | /***/ "./node_modules/css-loader/dist/runtime/noSourceMaps.js":
34 | /*!**************************************************************!*\
35 | !*** ./node_modules/css-loader/dist/runtime/noSourceMaps.js ***!
36 | \**************************************************************/
37 | /***/ ((module) => {
38 |
39 | eval("\n\nmodule.exports = function (i) {\n return i[1];\n};\n\n//# sourceURL=webpack://to-do-list/./node_modules/css-loader/dist/runtime/noSourceMaps.js?");
40 |
41 | /***/ }),
42 |
43 | /***/ "./src/style.css":
44 | /*!***********************!*\
45 | !*** ./src/style.css ***!
46 | \***********************/
47 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
48 |
49 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleDomAPI.js */ \"./node_modules/style-loader/dist/runtime/styleDomAPI.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertBySelector.js */ \"./node_modules/style-loader/dist/runtime/insertBySelector.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js */ \"./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertStyleElement.js */ \"./node_modules/style-loader/dist/runtime/insertStyleElement.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleTagTransform.js */ \"./node_modules/style-loader/dist/runtime/styleTagTransform.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../node_modules/css-loader/dist/cjs.js!./style.css */ \"./node_modules/css-loader/dist/cjs.js!./src/style.css\");\n\n \n \n \n \n \n \n \n \n \n\nvar options = {};\n\noptions.styleTagTransform = (_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());\noptions.setAttributes = (_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());\n\n options.insert = _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, \"head\");\n \noptions.domAPI = (_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());\noptions.insertStyleElement = (_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());\n\nvar update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"], options);\n\n\n\n\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"] && _node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"].locals ? _node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"].locals : undefined);\n\n\n//# sourceURL=webpack://to-do-list/./src/style.css?");
50 |
51 | /***/ }),
52 |
53 | /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js":
54 | /*!****************************************************************************!*\
55 | !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
56 | \****************************************************************************/
57 | /***/ ((module) => {
58 |
59 | eval("\n\nvar stylesInDOM = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n\n return updater;\n}\n\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n\n var newLastIdentifiers = modulesToDom(newList, options);\n\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n\n var _index = getIndexByIdentifier(_identifier);\n\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n\n stylesInDOM.splice(_index, 1);\n }\n }\n\n lastIdentifiers = newLastIdentifiers;\n };\n};\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?");
60 |
61 | /***/ }),
62 |
63 | /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js":
64 | /*!********************************************************************!*\
65 | !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
66 | \********************************************************************/
67 | /***/ ((module) => {
68 |
69 | eval("\n\nvar memo = {};\n/* istanbul ignore next */\n\nfunction getTarget(target) {\n if (typeof memo[target] === \"undefined\") {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n}\n/* istanbul ignore next */\n\n\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n}\n\nmodule.exports = insertBySelector;\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/insertBySelector.js?");
70 |
71 | /***/ }),
72 |
73 | /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js":
74 | /*!**********************************************************************!*\
75 | !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
76 | \**********************************************************************/
77 | /***/ ((module) => {
78 |
79 | eval("\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement(\"style\");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\n\nmodule.exports = insertStyleElement;\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/insertStyleElement.js?");
80 |
81 | /***/ }),
82 |
83 | /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js":
84 | /*!**********************************************************************************!*\
85 | !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
86 | \**********************************************************************************/
87 | /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
88 |
89 | eval("\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = true ? __webpack_require__.nc : 0;\n\n if (nonce) {\n styleElement.setAttribute(\"nonce\", nonce);\n }\n}\n\nmodule.exports = setAttributesWithoutAttributes;\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js?");
90 |
91 | /***/ }),
92 |
93 | /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js":
94 | /*!***************************************************************!*\
95 | !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
96 | \***************************************************************/
97 | /***/ ((module) => {
98 |
99 | eval("\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = \"\";\n\n if (obj.supports) {\n css += \"@supports (\".concat(obj.supports, \") {\");\n }\n\n if (obj.media) {\n css += \"@media \".concat(obj.media, \" {\");\n }\n\n var needLayer = typeof obj.layer !== \"undefined\";\n\n if (needLayer) {\n css += \"@layer\".concat(obj.layer.length > 0 ? \" \".concat(obj.layer) : \"\", \" {\");\n }\n\n css += obj.css;\n\n if (needLayer) {\n css += \"}\";\n }\n\n if (obj.media) {\n css += \"}\";\n }\n\n if (obj.supports) {\n css += \"}\";\n }\n\n var sourceMap = obj.sourceMap;\n\n if (sourceMap && typeof btoa !== \"undefined\") {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n options.styleTagTransform(css, styleElement, options.options);\n}\n\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n\n styleElement.parentNode.removeChild(styleElement);\n}\n/* istanbul ignore next */\n\n\nfunction domAPI(options) {\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\n\nmodule.exports = domAPI;\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/styleDomAPI.js?");
100 |
101 | /***/ }),
102 |
103 | /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js":
104 | /*!*********************************************************************!*\
105 | !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
106 | \*********************************************************************/
107 | /***/ ((module) => {
108 |
109 | eval("\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n\n styleElement.appendChild(document.createTextNode(css));\n }\n}\n\nmodule.exports = styleTagTransform;\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/styleTagTransform.js?");
110 |
111 | /***/ }),
112 |
113 | /***/ "./src/index.js":
114 | /*!**********************!*\
115 | !*** ./src/index.js ***!
116 | \**********************/
117 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
118 |
119 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./style.css */ \"./src/style.css\");\n/* harmony import */ var _modules_store_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modules/store.js */ \"./src/modules/store.js\");\n/* harmony import */ var _modules_TodosContainer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modules/TodosContainer.js */ \"./src/modules/TodosContainer.js\");\n/* harmony import */ var _modules_updateStatus_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modules/updateStatus.js */ \"./src/modules/updateStatus.js\");\n/* harmony import */ var _modules_UI_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./modules/UI.js */ \"./src/modules/UI.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst todoLists = (0,_modules_store_js__WEBPACK_IMPORTED_MODULE_1__.getTodos)() || [];\r\nconst container = new _modules_TodosContainer_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"]();\r\n\r\nconst form = document.querySelector('.task-adder');\r\nconst todoElements = document.querySelector('.tasks');\r\nconst { task } = form.elements;\r\nconst clearButton = document.querySelector('.button-wrapper button');\r\nfunction populateTodos(data) {\r\n data.forEach((element) => {\r\n _modules_UI_js__WEBPACK_IMPORTED_MODULE_4__[\"default\"].add(element.id, element.description, element.completed);\r\n });\r\n}\r\nform.addEventListener('submit', (event) => {\r\n event.preventDefault();\r\n container.addTodo(task.value);\r\n task.value = '';\r\n});\r\ntodoElements.addEventListener('click', (event) => {\r\n const { target } = event;\r\n if (parseInt(target.id, 10)) {\r\n container.removeTodo(event.target.id);\r\n } else if (target.id.includes('description')) {\r\n target.parentNode.parentNode.style.backgroundColor = 'rgb(253, 238, 213)';\r\n target.addEventListener('blur', () => {\r\n target.parentNode.parentNode.style.backgroundColor = 'white';\r\n container.updateDescription(target.id, target.value);\r\n });\r\n target.addEventListener('keypress', (event) => {\r\n if (event.key === 'Enter') {\r\n target.blur();\r\n }\r\n });\r\n }\r\n});\r\ntodoElements.addEventListener('change', (event) => {\r\n if (event.target.id.includes('checkbox')) {\r\n (0,_modules_updateStatus_js__WEBPACK_IMPORTED_MODULE_3__.updateStatus)(event.target.id);\r\n const [statusId] = event.target.id.match(/\\d+/);\r\n const descriptionElement = document.querySelector(`#description-${statusId}`);\r\n if (event.target.checked) {\r\n descriptionElement.style.color = 'gray';\r\n descriptionElement.style.textDecoration = 'line-through';\r\n } else {\r\n descriptionElement.style.color = 'black';\r\n descriptionElement.style.textDecoration = 'none';\r\n }\r\n }\r\n});\r\nclearButton.addEventListener('click', () => {\r\n (0,_modules_updateStatus_js__WEBPACK_IMPORTED_MODULE_3__.clearTodoList)();\r\n});\r\nwindow.addEventListener('DOMContentLoaded', () => {\r\n populateTodos(todoLists);\r\n});\r\n\n\n//# sourceURL=webpack://to-do-list/./src/index.js?");
120 |
121 | /***/ }),
122 |
123 | /***/ "./src/modules/Todo.js":
124 | /*!*****************************!*\
125 | !*** ./src/modules/Todo.js ***!
126 | \*****************************/
127 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
128 |
129 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ Todo)\n/* harmony export */ });\nclass Todo {\r\n constructor(id, description, completed, index) {\r\n this.id = id;\r\n this.description = description;\r\n this.completed = completed;\r\n this.index = index;\r\n }\r\n}\n\n//# sourceURL=webpack://to-do-list/./src/modules/Todo.js?");
130 |
131 | /***/ }),
132 |
133 | /***/ "./src/modules/TodosContainer.js":
134 | /*!***************************************!*\
135 | !*** ./src/modules/TodosContainer.js ***!
136 | \***************************************/
137 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
138 |
139 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ TodosContainer)\n/* harmony export */ });\n/* harmony import */ var _Todo_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Todo.js */ \"./src/modules/Todo.js\");\n/* harmony import */ var _store_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./store.js */ \"./src/modules/store.js\");\n/* harmony import */ var _UI_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./UI.js */ \"./src/modules/UI.js\");\n\r\n\r\n\r\n\r\nclass TodosContainer {\r\n addTodo = (description) => {\r\n this.todos = (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.getTodos)() || [];\r\n if (description.trim().length !== 0) {\r\n const id = (Math.floor(Math.random() * 100000)).toString();\r\n const index = this.todos.length + 1;\r\n const todo = new _Todo_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"](id, description, false, index);\r\n this.todos.push(todo);\r\n (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.setTodos)(this.todos);\r\n _UI_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].add(id, description, false);\r\n }\r\n };\r\n\r\n removeTodo = (id) => {\r\n this.todos = (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.getTodos)() || [];\r\n this.todos = this.todos\r\n .filter((todo) => todo.id !== id)\r\n .map((todo, index) => ({ ...todo, index: index + 1 }));\r\n (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.setTodos)(this.todos);\r\n _UI_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].remove(id);\r\n };\r\n\r\n updateDescription=(id, description) => {\r\n this.todos = (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.getTodos)() || [];\r\n const [updateId] = id.match(/\\d+/);\r\n const updateDes = description.match(/\\w+/g) ? description.match(/\\w+/g).join(' ') : '';\r\n if (updateDes.length > 0) {\r\n this.todos = this.todos.map((todo) => {\r\n if (todo.id === updateId) {\r\n return { ...todo, description: updateDes };\r\n }\r\n return todo;\r\n });\r\n (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.setTodos)(this.todos);\r\n } else {\r\n this.removeTodo(updateId);\r\n }\r\n }\r\n}\r\n\n\n//# sourceURL=webpack://to-do-list/./src/modules/TodosContainer.js?");
140 |
141 | /***/ }),
142 |
143 | /***/ "./src/modules/UI.js":
144 | /*!***************************!*\
145 | !*** ./src/modules/UI.js ***!
146 | \***************************/
147 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
148 |
149 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ UI)\n/* harmony export */ });\nclass UI {\r\n static remove = (id) => {\r\n const element = document.getElementById(id);\r\n const parentToRemove = element.parentNode.parentNode;\r\n parentToRemove.remove();\r\n };\r\n\r\n static add = (id, description, status) => {\r\n const li = document.createElement('li');\r\n li.innerHTML = `\r\n \r\n \r\n \r\n
\r\n \r\n \r\n \r\n `;\r\n\r\n document.querySelector('.tasks').appendChild(li);\r\n document.querySelector(`#checkbox-${id}`).checked = status;\r\n if (document.querySelector(`#checkbox-${id}`).checked) {\r\n document.querySelector(`#description-${id}`).style.color = 'gray';\r\n document.querySelector(`#description-${id}`).style.textDecoration = 'line-through';\r\n } else {\r\n document.querySelector(`#description-${id}`).style.color = 'black';\r\n document.querySelector(`#description-${id}`).style.textDecoration = 'none';\r\n }\r\n };\r\n}\r\n\n\n//# sourceURL=webpack://to-do-list/./src/modules/UI.js?");
150 |
151 | /***/ }),
152 |
153 | /***/ "./src/modules/store.js":
154 | /*!******************************!*\
155 | !*** ./src/modules/store.js ***!
156 | \******************************/
157 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
158 |
159 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"getTodos\": () => (/* binding */ getTodos),\n/* harmony export */ \"setTodos\": () => (/* binding */ setTodos)\n/* harmony export */ });\nconst getTodos = () => JSON.parse(localStorage.getItem('todos'));\r\nconst setTodos = (obj) => {\r\n localStorage.setItem('todos', JSON.stringify(obj));\r\n};\n\n//# sourceURL=webpack://to-do-list/./src/modules/store.js?");
160 |
161 | /***/ }),
162 |
163 | /***/ "./src/modules/updateStatus.js":
164 | /*!*************************************!*\
165 | !*** ./src/modules/updateStatus.js ***!
166 | \*************************************/
167 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
168 |
169 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"clearTodoList\": () => (/* binding */ clearTodoList),\n/* harmony export */ \"updateStatus\": () => (/* binding */ updateStatus)\n/* harmony export */ });\n/* harmony import */ var _store_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./store.js */ \"./src/modules/store.js\");\n/* harmony import */ var _UI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./UI.js */ \"./src/modules/UI.js\");\n\r\n\r\n\r\nconst updateStatus = (id) => {\r\n const [statusId] = id.match(/\\d+/);\r\n const todos = (0,_store_js__WEBPACK_IMPORTED_MODULE_0__.getTodos)().map((todo) => {\r\n if (todo.id === statusId) {\r\n return { ...todo, completed: !todo.completed };\r\n }\r\n return todo;\r\n });\r\n (0,_store_js__WEBPACK_IMPORTED_MODULE_0__.setTodos)(todos);\r\n};\r\nconst clearTodoList = () => {\r\n const listToNotClear = (0,_store_js__WEBPACK_IMPORTED_MODULE_0__.getTodos)()\r\n .filter((todo) => todo.completed === false)\r\n .map((todo, index) => ({ ...todo, index: index + 1 }));\r\n const listToClear = (0,_store_js__WEBPACK_IMPORTED_MODULE_0__.getTodos)().filter((todo) => todo.completed === true);\r\n\r\n listToClear.forEach((todo) => {\r\n _UI_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"].remove(todo.id);\r\n });\r\n (0,_store_js__WEBPACK_IMPORTED_MODULE_0__.setTodos)(listToNotClear);\r\n};\r\n\n\n//# sourceURL=webpack://to-do-list/./src/modules/updateStatus.js?");
170 |
171 | /***/ })
172 |
173 | /******/ });
174 | /************************************************************************/
175 | /******/ // The module cache
176 | /******/ var __webpack_module_cache__ = {};
177 | /******/
178 | /******/ // The require function
179 | /******/ function __webpack_require__(moduleId) {
180 | /******/ // Check if module is in cache
181 | /******/ var cachedModule = __webpack_module_cache__[moduleId];
182 | /******/ if (cachedModule !== undefined) {
183 | /******/ return cachedModule.exports;
184 | /******/ }
185 | /******/ // Create a new module (and put it into the cache)
186 | /******/ var module = __webpack_module_cache__[moduleId] = {
187 | /******/ id: moduleId,
188 | /******/ // no module.loaded needed
189 | /******/ exports: {}
190 | /******/ };
191 | /******/
192 | /******/ // Execute the module function
193 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
194 | /******/
195 | /******/ // Return the exports of the module
196 | /******/ return module.exports;
197 | /******/ }
198 | /******/
199 | /************************************************************************/
200 | /******/ /* webpack/runtime/compat get default export */
201 | /******/ (() => {
202 | /******/ // getDefaultExport function for compatibility with non-harmony modules
203 | /******/ __webpack_require__.n = (module) => {
204 | /******/ var getter = module && module.__esModule ?
205 | /******/ () => (module['default']) :
206 | /******/ () => (module);
207 | /******/ __webpack_require__.d(getter, { a: getter });
208 | /******/ return getter;
209 | /******/ };
210 | /******/ })();
211 | /******/
212 | /******/ /* webpack/runtime/define property getters */
213 | /******/ (() => {
214 | /******/ // define getter functions for harmony exports
215 | /******/ __webpack_require__.d = (exports, definition) => {
216 | /******/ for(var key in definition) {
217 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
218 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
219 | /******/ }
220 | /******/ }
221 | /******/ };
222 | /******/ })();
223 | /******/
224 | /******/ /* webpack/runtime/hasOwnProperty shorthand */
225 | /******/ (() => {
226 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
227 | /******/ })();
228 | /******/
229 | /******/ /* webpack/runtime/make namespace object */
230 | /******/ (() => {
231 | /******/ // define __esModule on exports
232 | /******/ __webpack_require__.r = (exports) => {
233 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
234 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
235 | /******/ }
236 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
237 | /******/ };
238 | /******/ })();
239 | /******/
240 | /******/ /* webpack/runtime/nonce */
241 | /******/ (() => {
242 | /******/ __webpack_require__.nc = undefined;
243 | /******/ })();
244 | /******/
245 | /************************************************************************/
246 | /******/
247 | /******/ // startup
248 | /******/ // Load entry module and return exports
249 | /******/ // This entry module can't be inlined because the eval devtool is used.
250 | /******/ var __webpack_exports__ = __webpack_require__("./src/index.js");
251 | /******/
252 | /******/ })()
253 | ;
--------------------------------------------------------------------------------