diff --git a/.eslintrc.js b/.eslintrc.js
index 91f0a228..465c2470 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,84 +1,84 @@
-module.exports = {
- env: {
- browser: true,
- es2021: true,
- jest: true,
- "jest/globals": true,
- },
- extends: [
- "airbnb",
- "eslint:recommended",
- "plugin:react/recommended",
- "plugin:import/errors",
- "plugin:import/warnings",
- "plugin:jsx-a11y/recommended",
- "prettier",
- "plugin:cypress/recommended",
- ],
- parser: "@babel/eslint-parser",
- parserOptions: {
- ecmaVersion: 12,
- sourceType: "module",
- requireConfigFile: "false",
- jsx: true,
- },
- plugins: [
- "html",
- "react",
- "react-hooks",
- "jsx-a11y",
- "markdown",
- "react-hooks",
- "import",
- "prettier",
- ],
- settings: {
- react: {
- version: "detect",
- },
- jest: {
- version: 26,
- },
- },
- overrides: [
- {
- files: ["*.html"],
- parser: "@html-eslint/parser",
- extends: ["plugin:@html-eslint/recommended"],
- },
- {
- files: ["src/**/*.test.js"],
- plugins: ["jest"],
- rules: {
- "jest/expect-expect": "error",
- },
- extends: ["plugin:jest/recommended"],
- },
- ],
- rules: {
- "prettier/prettier": [
- "error",
- {
- endOfLine: "auto",
- },
- ],
- "react/jsx-filename-extension": "off",
- "import/prefer-default-export": "off",
- "prefer-destructuring": "off",
- "object-shorthand": "off",
- "react/jsx-props-no-spreading": "off",
- "arrow-body-style": "off",
- "no-underscore-dangle": "off",
- "react/forbid-prop-types": "off",
- "react/prop-types": "off",
- "no-unused-expressions": "off",
- "jsx-a11y/label-has-for": [
- "error",
- {
- required: {
- some: ["nesting", "id"],
- },
- },
- ],
- },
-};
+// module.exports = {
+// env: {
+// browser: true,
+// es2021: true,
+// jest: true,
+// "jest/globals": true,
+// },
+// extends: [
+// "airbnb",
+// "eslint:recommended",
+// "plugin:react/recommended",
+// "plugin:import/errors",
+// "plugin:import/warnings",
+// "plugin:jsx-a11y/recommended",
+// "prettier",
+// "plugin:cypress/recommended",
+// ],
+// parser: "@babel/eslint-parser",
+// parserOptions: {
+// ecmaVersion: 12,
+// sourceType: "module",
+// requireConfigFile: "false",
+// jsx: true,
+// },
+// plugins: [
+// "html",
+// "react",
+// "react-hooks",
+// "jsx-a11y",
+// "markdown",
+// "react-hooks",
+// "import",
+// "prettier",
+// ],
+// settings: {
+// react: {
+// version: "detect",
+// },
+// jest: {
+// version: 26,
+// },
+// },
+// overrides: [
+// {
+// files: ["*.html"],
+// parser: "@html-eslint/parser",
+// extends: ["plugin:@html-eslint/recommended"],
+// },
+// {
+// files: ["src/**/*.test.js"],
+// plugins: ["jest"],
+// rules: {
+// "jest/expect-expect": "error",
+// },
+// extends: ["plugin:jest/recommended"],
+// },
+// ],
+// rules: {
+// "prettier/prettier": [
+// "error",
+// {
+// endOfLine: "auto",
+// },
+// ],
+// "react/jsx-filename-extension": "off",
+// "import/prefer-default-export": "off",
+// "prefer-destructuring": "off",
+// "object-shorthand": "off",
+// "react/jsx-props-no-spreading": "off",
+// "arrow-body-style": "off",
+// "no-underscore-dangle": "off",
+// "react/forbid-prop-types": "off",
+// "react/prop-types": "off",
+// "no-unused-expressions": "off",
+// "jsx-a11y/label-has-for": [
+// "error",
+// {
+// required: {
+// some: ["nesting", "id"],
+// },
+// },
+// ],
+// },
+// };
diff --git a/.husky/.gitignore b/.husky/.gitignore
new file mode 100644
index 00000000..31354ec1
--- /dev/null
+++ b/.husky/.gitignore
@@ -0,0 +1 @@
+_
diff --git a/.prettierrc b/.prettierrc
index 8c4b2fa1..20c9dbad 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,19 +1,19 @@
-{
- "arrowParens": "always",
- "bracketSpacing": true,
- "embeddedLanguageFormatting": "auto",
- "htmlWhitespaceSensitivity": "css",
- "insertPragma": false,
- "jsxBracketSameLine": false,
- "jsxSingleQuote": false,
- "printWidth": 80,
- "proseWrap": "always",
- "quoteProps": "as-needed",
- "requirePragma": false,
- "semi": true,
- "singleQuote": false,
- "tabWidth": 2,
- "trailingComma": "all",
- "useTabs": false,
- "endOfLine": "lf"
-}
+// {
+// "arrowParens": "always",
+// "bracketSpacing": true,
+// "embeddedLanguageFormatting": "auto",
+// "htmlWhitespaceSensitivity": "css",
+// "insertPragma": false,
+// "jsxBracketSameLine": false,
+// "jsxSingleQuote": false,
+// "printWidth": 160,
+// "proseWrap": "always",
+// "quoteProps": "as-needed",
+// "requirePragma": false,
+// "semi": true,
+// "singleQuote": false,
+// "tabWidth": 2,
+// "trailingComma": "all",
+// "useTabs": false,
+// "endOfLine": "lf"
+// }
diff --git a/package-lock.json b/package-lock.json
index 5a546dc7..b92db76a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1420,6 +1420,29 @@
}
}
},
+ "@emotion/is-prop-valid": {
+ "version": "0.8.8",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
+ "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
+ "requires": {
+ "@emotion/memoize": "0.7.4"
+ }
+ },
+ "@emotion/memoize": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
+ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
+ },
+ "@emotion/stylis": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
+ "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
+ },
+ "@emotion/unitless": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
+ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
+ },
"@eslint/eslintrc": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz",
@@ -1448,6 +1471,11 @@
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
}
}
},
@@ -1636,6 +1664,11 @@
"read-pkg": "^5.2.0",
"type-fest": "^0.8.1"
}
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
}
}
},
@@ -1756,6 +1789,11 @@
"read-pkg": "^5.2.0",
"type-fest": "^0.8.1"
}
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
}
}
},
@@ -2315,6 +2353,15 @@
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.169.tgz",
"integrity": "sha512-DvmZHoHTFJ8zhVYwCLWbQ7uAbYQEk52Ev2/ZiQ7Y7gQGeV9pjBqjnQpECMHfKS1rCYAhMI7LHVxwyZLZinJgdw=="
},
+ "@types/mdast": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz",
+ "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "*"
+ }
+ },
"@types/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz",
@@ -2425,6 +2472,12 @@
"source-map": "^0.6.1"
}
},
+ "@types/unist": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
+ "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==",
+ "dev": true
+ },
"@types/webpack": {
"version": "4.41.28",
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.28.tgz",
@@ -3296,6 +3349,22 @@
"@babel/helper-define-polyfill-provider": "^0.2.0"
}
},
+ "babel-plugin-styled-components": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.2.tgz",
+ "integrity": "sha512-Vb1R3d4g+MUfPQPVDMCGjm3cDocJEUTR7Xq7QS95JWWeksN1wdFRYpD2kulDgI3Huuaf1CZd+NK4KQmqUFh5dA==",
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.0.0",
+ "@babel/helper-module-imports": "^7.0.0",
+ "babel-plugin-syntax-jsx": "^6.18.0",
+ "lodash": "^4.17.11"
+ }
+ },
+ "babel-plugin-syntax-jsx": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+ "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
+ },
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
@@ -3566,12 +3635,6 @@
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
"integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
},
- "bail": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
- "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==",
- "dev": true
- },
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -4038,6 +4101,11 @@
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
"integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg=="
},
+ "camelize": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
+ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
+ },
"caniuse-api": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@@ -4312,12 +4380,6 @@
}
}
},
- "collapse-white-space": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz",
- "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==",
- "dev": true
- },
"collect-v8-coverage": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
@@ -4801,6 +4863,19 @@
"postcss": "^7.0.5"
}
},
+ "css-box-model": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
+ "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
+ "requires": {
+ "tiny-invariant": "^1.0.6"
+ }
+ },
+ "css-color-keywords": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+ "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU="
+ },
"css-color-names": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
@@ -4884,6 +4959,16 @@
"resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
"integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w=="
},
+ "css-to-react-native": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz",
+ "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==",
+ "requires": {
+ "camelize": "^1.0.0",
+ "css-color-keywords": "^1.0.0",
+ "postcss-value-parser": "^4.0.2"
+ }
+ },
"css-tree": {
"version": "1.0.0-alpha.37",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
@@ -5574,9 +5659,9 @@
"integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0="
},
"dns-packet": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
- "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz",
+ "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==",
"requires": {
"ip": "^1.1.0",
"safe-buffer": "^5.0.1"
@@ -6538,13 +6623,12 @@
}
},
"eslint-plugin-markdown": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-2.1.0.tgz",
- "integrity": "sha512-Rqw7tosArdlzXcR/xJGW3Er9gRiF7iE+QEMEm7hZZ/feZjUf8xCaGQJgB1nzs9yVhJnUeiAcj5TXLLfKMbp3DQ==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-2.2.1.tgz",
+ "integrity": "sha512-FgWp4iyYvTFxPwfbxofTvXxgzPsDuSKHQy2S+a8Ve6savbujey+lgrFFbXQA0HPygISpRYWYBjooPzhYSF81iA==",
"dev": true,
"requires": {
- "remark-parse": "^7.0.0",
- "unified": "^6.1.2"
+ "mdast-util-from-markdown": "^0.8.5"
}
},
"eslint-plugin-node": {
@@ -8856,23 +8940,11 @@
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="
},
- "is-whitespace-character": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz",
- "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==",
- "dev": true
- },
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
},
- "is-word-character": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz",
- "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==",
- "dev": true
- },
"is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
@@ -9209,6 +9281,11 @@
"read-pkg": "^5.2.0",
"type-fest": "^0.8.1"
}
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
}
}
},
@@ -9482,6 +9559,11 @@
"read-pkg": "^5.2.0",
"type-fest": "^0.8.1"
}
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
}
}
},
@@ -9573,6 +9655,11 @@
"read-pkg": "^5.2.0",
"type-fest": "^0.8.1"
}
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
}
}
},
@@ -9666,6 +9753,11 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w=="
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
}
}
},
@@ -9752,6 +9844,11 @@
"read-pkg": "^5.2.0",
"type-fest": "^0.8.1"
}
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
}
}
},
@@ -10493,12 +10590,6 @@
"object-visit": "^1.0.0"
}
},
- "markdown-escapes": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz",
- "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==",
- "dev": true
- },
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -10509,6 +10600,25 @@
"safe-buffer": "^5.1.2"
}
},
+ "mdast-util-from-markdown": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz",
+ "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==",
+ "dev": true,
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-to-string": "^2.0.0",
+ "micromark": "~2.11.0",
+ "parse-entities": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0"
+ }
+ },
+ "mdast-util-to-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz",
+ "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==",
+ "dev": true
+ },
"mdn-data": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
@@ -10519,6 +10629,11 @@
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
+ "memoize-one": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
+ "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
+ },
"memory-fs": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
@@ -10582,6 +10697,16 @@
"resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz",
"integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g=="
},
+ "micromark": {
+ "version": "2.11.4",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz",
+ "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.0.0",
+ "parse-entities": "^2.0.0"
+ }
+ },
"micromatch": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
@@ -10846,6 +10971,11 @@
"resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz",
"integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA=="
},
+ "nanocolors": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.10.tgz",
+ "integrity": "sha512-i+EDWGsJClQwR/bhLIG/CObZZwaYaS5qt+yjxZbfV+77QiNHNzE9nj4d9Ut1TGZ0R0eSwPcQWzReASzXuw/7oA=="
+ },
"nanoid": {
"version": "3.1.23",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
@@ -11447,9 +11577,9 @@
}
},
"parse-entities": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz",
- "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
+ "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
"dev": true,
"requires": {
"character-entities": "^1.0.0",
@@ -11533,9 +11663,9 @@
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
},
"path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"path-starts-with": {
"version": "1.0.0",
@@ -11766,69 +11896,12 @@
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
},
"postcss": {
- "version": "7.0.35",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
- "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+ "version": "7.0.38",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.38.tgz",
+ "integrity": "sha512-wNrSHWjHDQJR/IZL5IKGxRtFgrYNaAA/UrkW2WqbtZO6uxSLMxMN+s2iqUMwnAWm3fMROlDYZB41dr0Mt7vBwQ==",
"requires": {
- "chalk": "^2.4.2",
- "source-map": "^0.6.1",
- "supports-color": "^6.1.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "requires": {
- "color-convert": "^1.9.0"
- }
- },
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "dependencies": {
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "requires": {
- "has-flag": "^3.0.0"
- }
- }
- }
- },
- "color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "requires": {
- "color-name": "1.1.3"
- }
- },
- "color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
- },
- "supports-color": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
- "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
- "requires": {
- "has-flag": "^3.0.0"
- }
- }
+ "nanocolors": "^0.2.2",
+ "source-map": "^0.6.1"
}
},
"postcss-attribute-case-insensitive": {
@@ -13033,6 +13106,11 @@
"performance-now": "^2.1.0"
}
},
+ "raf-schd": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz",
+ "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ=="
+ },
"ramda": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz",
@@ -13100,6 +13178,20 @@
"whatwg-fetch": "^3.4.1"
}
},
+ "react-beautiful-dnd": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.0.tgz",
+ "integrity": "sha512-aGvblPZTJowOWUNiwd6tNfEpgkX5OxmpqxHKNW/4VmvZTNTbeiq7bA3bn5T+QSF2uibXB0D1DmJsb1aC/+3cUA==",
+ "requires": {
+ "@babel/runtime": "^7.9.2",
+ "css-box-model": "^1.2.0",
+ "memoize-one": "^5.1.1",
+ "raf-schd": "^4.0.2",
+ "react-redux": "^7.2.0",
+ "redux": "^4.0.4",
+ "use-memo-one": "^1.1.1"
+ }
+ },
"react-dev-utils": {
"version": "11.0.4",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
@@ -13760,29 +13852,6 @@
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
"integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk="
},
- "remark-parse": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-7.0.2.tgz",
- "integrity": "sha512-9+my0lQS80IQkYXsMA8Sg6m9QfXYJBnXjWYN5U+kFc5/n69t+XZVXU/ZBYr3cYH8FheEGf1v87rkFDhJ8bVgMA==",
- "dev": true,
- "requires": {
- "collapse-white-space": "^1.0.2",
- "is-alphabetical": "^1.0.0",
- "is-decimal": "^1.0.0",
- "is-whitespace-character": "^1.0.0",
- "is-word-character": "^1.0.0",
- "markdown-escapes": "^1.0.0",
- "parse-entities": "^1.1.0",
- "repeat-string": "^1.5.4",
- "state-toggle": "^1.0.0",
- "trim": "0.0.1",
- "trim-trailing-lines": "^1.0.0",
- "unherit": "^1.0.4",
- "unist-util-remove-position": "^1.0.0",
- "vfile-location": "^2.0.0",
- "xtend": "^4.0.1"
- }
- },
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -13825,12 +13894,6 @@
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
},
- "replace-ext": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
- "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
- "dev": true
- },
"request": {
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
@@ -13971,9 +14034,9 @@
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
},
"resolve-url-loader": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.3.tgz",
- "integrity": "sha512-WbDSNFiKPPLem1ln+EVTE+bFUBdTTytfQZWbmghroaFNFaAVmGq0Saqw6F/306CwgPXsGwXVxbODE+3xAo/YbA==",
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz",
+ "integrity": "sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg==",
"requires": {
"adjust-sourcemap-loader": "3.0.0",
"camelcase": "5.3.1",
@@ -13981,7 +14044,7 @@
"convert-source-map": "1.7.0",
"es6-iterator": "2.0.3",
"loader-utils": "1.2.3",
- "postcss": "7.0.21",
+ "postcss": "7.0.36",
"rework": "1.0.1",
"rework-visit": "1.0.0",
"source-map": "0.6.1"
@@ -14062,9 +14125,9 @@
}
},
"postcss": {
- "version": "7.0.21",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz",
- "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==",
+ "version": "7.0.36",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
+ "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@@ -14680,6 +14743,11 @@
"safe-buffer": "^5.0.1"
}
},
+ "shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
+ },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -15193,12 +15261,6 @@
}
}
},
- "state-toggle": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz",
- "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==",
- "dev": true
- },
"static-extend": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
@@ -15483,6 +15545,38 @@
"schema-utils": "^2.7.0"
}
},
+ "styled-components": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.1.tgz",
+ "integrity": "sha512-JThv2JRzyH0NOIURrk9iskdxMSAAtCfj/b2Sf1WJaCUsloQkblepy1jaCLX/bYE+mhYo3unmwVSI9I5d9ncSiQ==",
+ "requires": {
+ "@babel/helper-module-imports": "^7.0.0",
+ "@babel/traverse": "^7.4.5",
+ "@emotion/is-prop-valid": "^0.8.8",
+ "@emotion/stylis": "^0.8.4",
+ "@emotion/unitless": "^0.7.4",
+ "babel-plugin-styled-components": ">= 1.12.0",
+ "css-to-react-native": "^3.0.0",
+ "hoist-non-react-statics": "^3.0.0",
+ "shallowequal": "^1.1.0",
+ "supports-color": "^5.5.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
"stylehacks": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",
@@ -15635,9 +15729,9 @@
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
},
"tar": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
- "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
+ "version": "6.1.11",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
+ "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"requires": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
@@ -15982,24 +16076,6 @@
"punycode": "^2.1.1"
}
},
- "trim": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
- "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=",
- "dev": true
- },
- "trim-trailing-lines": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz",
- "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==",
- "dev": true
- },
- "trough": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz",
- "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==",
- "dev": true
- },
"tryer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz",
@@ -16080,11 +16156,6 @@
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="
},
- "type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
- },
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -16124,16 +16195,6 @@
"which-boxed-primitive": "^1.0.2"
}
},
- "unherit": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz",
- "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.0",
- "xtend": "^4.0.0"
- }
- },
"unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
@@ -16158,20 +16219,6 @@
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
"integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg=="
},
- "unified": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz",
- "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==",
- "dev": true,
- "requires": {
- "bail": "^1.0.0",
- "extend": "^3.0.0",
- "is-plain-obj": "^1.1.0",
- "trough": "^1.0.0",
- "vfile": "^2.0.0",
- "x-is-string": "^0.1.0"
- }
- },
"union-value": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
@@ -16217,43 +16264,13 @@
"crypto-random-string": "^1.0.0"
}
},
- "unist-util-is": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz",
- "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==",
- "dev": true
- },
- "unist-util-remove-position": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz",
- "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==",
- "dev": true,
- "requires": {
- "unist-util-visit": "^1.1.0"
- }
- },
"unist-util-stringify-position": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz",
- "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==",
- "dev": true
- },
- "unist-util-visit": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
- "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
- "dev": true,
- "requires": {
- "unist-util-visit-parents": "^2.0.0"
- }
- },
- "unist-util-visit-parents": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
- "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
+ "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
"dev": true,
"requires": {
- "unist-util-is": "^3.0.0"
+ "@types/unist": "^2.0.2"
}
},
"universalify": {
@@ -16379,9 +16396,9 @@
}
},
"url-parse": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
- "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
+ "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
"requires": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
@@ -16392,6 +16409,11 @@
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
},
+ "use-memo-one": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.2.tgz",
+ "integrity": "sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ=="
+ },
"util": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
@@ -16494,33 +16516,6 @@
"extsprintf": "^1.2.0"
}
},
- "vfile": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz",
- "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.4",
- "replace-ext": "1.0.0",
- "unist-util-stringify-position": "^1.0.0",
- "vfile-message": "^1.0.0"
- }
- },
- "vfile-location": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz",
- "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==",
- "dev": true
- },
- "vfile-message": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz",
- "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==",
- "dev": true,
- "requires": {
- "unist-util-stringify-position": "^1.1.1"
- }
- },
"vm-browserify": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
@@ -17569,9 +17564,9 @@
}
},
"ws": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
- "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
+ "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
"requires": {
"async-limiter": "~1.0.0"
}
@@ -17983,15 +17978,9 @@
}
},
"ws": {
- "version": "7.4.5",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz",
- "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g=="
- },
- "x-is-string": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz",
- "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=",
- "dev": true
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz",
+ "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w=="
},
"xml-name-validator": {
"version": "3.0.0",
diff --git a/package.json b/package.json
index 18a1117b..77a7a26b 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"formik": "^2.2.6",
"prop-types": "^15.7.2",
"react": "^17.0.2",
+ "react-beautiful-dnd": "^13.1.0",
"react-dom": "^17.0.2",
"react-redux": "^7.2.3",
"react-router-dom": "^5.2.0",
@@ -29,6 +30,7 @@
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"sass": "^1.32.11",
+ "styled-components": "^5.3.1",
"uuid": "^8.3.2",
"web-vitals": "^1.1.1",
"yup": "^0.32.9"
diff --git a/src/App.js b/src/App.js
index de524524..821f0d54 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,15 +1,209 @@
-import React from "react";
-
-function App() {
- return (
-
-
-
- );
+import React, { Component } from "react";
+import { BrowserRouter as Router } from "react-router-dom";
+import { Route } from "react-router";
+import { readLocalStorage, writeLocalStorage } from "./api";
+import { ThemeProvider } from "styled-components";
+import { v4 as uuid } from "uuid";
+import { AppMain, AppMainWrapper, AppContainer } from "./App.styled";
+import { dark, GlobalStyle, light } from "./themes";
+import Header from "./components/Header";
+import FormAddTodo from "./components/FormAddTodo";
+import TodoList from "./components/TodoList";
+import Footer from "./components/Footer";
+import NoTodos from "./components/NoTodos";
+import { Checkbox } from "./components/Checkbox";
+
+const LOCAL_STORAGE_KEY = "react-todos";
+
+class App extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ todos: [],
+ isLoading: false,
+ isDarkMode: false,
+ };
+
+ this.moveTodo = this.moveTodo.bind(this);
+ this.addTodo = this.addTodo.bind(this);
+ this.deleteTodo = this.deleteTodo.bind(this);
+ this.setTextTodo = this.setTextTodo.bind(this);
+ this.setDoneTodo = this.setDoneTodo.bind(this);
+ this.isEditingTodo = this.isEditingTodo.bind(this);
+ this.clearDoneTodos = this.clearDoneTodos.bind(this);
+ this.getTodos = this.getTodos.bind(this);
+ this.toggleDarkMode = this.toggleDarkMode.bind(this);
+ }
+
+ componentDidMount() {
+ setTimeout(() => {
+ const todos = readLocalStorage(LOCAL_STORAGE_KEY);
+
+ if (todos) {
+ this.setState((prevState) => ({
+ ...prevState,
+ todos,
+ isLoading: false,
+ }));
+ }
+ }, 1500);
+ }
+
+ componentDidUpdate() {
+ const { todos } = this.state;
+
+ writeLocalStorage(LOCAL_STORAGE_KEY, todos);
+ }
+
+ addTodo(data) {
+ const newTodo = {
+ ...data,
+ id: uuid(),
+ done: false,
+ isEditing: false,
+ };
+
+ this.setState((prevState) => ({
+ ...prevState,
+ todos: [...prevState.todos, newTodo],
+ }));
+ }
+
+ moveTodo(srcIndex, dstIndex) {
+ const { todos } = this.state;
+
+ const draggedTodo = todos[srcIndex];
+ todos.splice(srcIndex, 1);
+ todos.splice(dstIndex, 0, draggedTodo);
+
+ this.setState((prevState) => ({
+ ...prevState,
+ todos,
+ }));
+ }
+
+ deleteTodo(id) {
+ const { todos } = this.state;
+
+ const newTodos = todos.filter((item) => item.id !== id);
+
+ this.setState((prevState) => ({
+ ...prevState,
+ todos: newTodos,
+ }));
+ }
+
+ setTextTodo(id, text) {
+ const { todos } = this.state;
+
+ const newTodos = todos.map((item) => {
+ if (item.id === id) item.text = text;
+
+ return item;
+ });
+
+ this.setState((prevState) => ({
+ ...prevState,
+ todos: newTodos,
+ }));
+ }
+
+ setDoneTodo(id) {
+ const { todos } = this.state;
+
+ const newTodos = todos.map((item) => {
+ if (item.id === id) item.done = !item.done;
+
+ return item;
+ });
+
+ this.setState((prevState) => ({
+ ...prevState,
+ todos: newTodos,
+ }));
+ }
+
+ clearDoneTodos() {
+ const { todos } = this.state;
+
+ const newTodos = todos.filter((item) => {
+ return !item.done;
+ });
+
+ this.setState((prevState) => ({
+ ...prevState,
+ todos: newTodos,
+ }));
+ }
+
+ isEditingTodo(id) {
+ const { todos } = this.state;
+
+ const newTodos = todos.map((item) => {
+ item.isEditing = item.id === id;
+
+ return item;
+ });
+
+ this.setState((prevState) => ({
+ ...prevState,
+ todos: newTodos,
+ }));
+ }
+
+ getTodos(pathname) {
+ const { todos } = this.state;
+
+ if (pathname === "/active") return todos.filter((item) => !item.done);
+ if (pathname === "/completed") return todos.filter((item) => item.done);
+
+ return todos;
+ }
+
+ toggleDarkMode() {
+ this.setState((prevState) => ({
+ ...prevState,
+ isDarkMode: !prevState.isDarkMode,
+ }));
+ }
+
+ render() {
+ const theme = this.state.isDarkMode ? dark : light;
+ const pathname = this.props.location.pathname;
+
+ const todos = this.getTodos(pathname);
+ const dndDisabled = pathname !== "/";
+
+ return (
+
+
+
+
+
+
+
+ {
+ todos.length > 0 ? (
+
+ ) : (
+
+ )
+ }
+
+
+
+
+
+ );
+ }
}
export default App;
diff --git a/src/App.styled.js b/src/App.styled.js
new file mode 100644
index 00000000..c9c95b88
--- /dev/null
+++ b/src/App.styled.js
@@ -0,0 +1,43 @@
+import styled from "styled-components";
+
+const AppMain = styled.main`
+ background-image: url(${({ theme }) => theme.background.image});
+ background-size: cover;
+ background-repeat: no-repeat;
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ height: 100vh;
+
+ transition: background 0.25s ease-in-out;
+`;
+
+const AppMainWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+ padding: 1rem;
+
+ width: 100%;
+
+ @media (min-width: 480px) {
+ width: 480px;
+ }
+
+ @media (min-width: 768px) {
+ width: 768px;
+ }
+`;
+
+const AppContainer = styled.div`
+ background: ${({ theme }) => theme.background.color.default};
+ box-shadow: ${({ theme }) => theme.shadow.default};
+ border-radius: 0.25rem;
+ overflow: hidden;
+
+ transition: background 0.25s ease-in-out;
+`;
+
+export {AppMain, AppMainWrapper, AppContainer};
\ No newline at end of file
diff --git a/src/api/index.js b/src/api/index.js
new file mode 100644
index 00000000..b4c8dfb4
--- /dev/null
+++ b/src/api/index.js
@@ -0,0 +1 @@
+export { readLocalStorage, writeLocalStorage } from "./localStorage";
diff --git a/src/api/localStorage.js b/src/api/localStorage.js
new file mode 100644
index 00000000..97df0fd4
--- /dev/null
+++ b/src/api/localStorage.js
@@ -0,0 +1,20 @@
+export function readLocalStorage(key) {
+ try {
+ const raw = localStorage.getItem(key);
+ const data = JSON.parse(raw);
+
+ return data;
+ } catch (err) {
+ console.error(err);
+ return null;
+ }
+}
+
+export function writeLocalStorage(key, data) {
+ try {
+ const raw = JSON.stringify(data);
+ localStorage.setItem(key, raw);
+ } catch (err) {
+ console.error(err);
+ }
+}
diff --git a/src/components/CheckBox/Checkbox.styled.js b/src/components/CheckBox/Checkbox.styled.js
new file mode 100644
index 00000000..ac81d820
--- /dev/null
+++ b/src/components/CheckBox/Checkbox.styled.js
@@ -0,0 +1,41 @@
+import styled from "styled-components";
+
+const Checkbox = styled.input.attrs({ type: "checkbox" })`
+ appearance: none;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ width: 2rem;
+ height: 2rem;
+ min-width: 2rem;
+
+ cursor: pointer;
+ user-select: none;
+
+ background: white;
+ border-radius: 50%;
+ box-shadow: 0 0 4px rgba(0,0,0,0.25);
+
+ &::after {
+ content: '\u{2713}';
+ font-size: 1.5rem;
+ color: white;
+ display: none;
+ }
+
+ &:hover {
+ background: linear-gradient(135deg, rgba(62,141,180,0.25) 0%, rgba(236,41,251,0.25) 100%);
+ }
+
+ &:checked {
+ background: linear-gradient(135deg, rgba(62,141,180,1) 0%, rgba(236,41,251,1) 100%);
+ }
+
+ &:checked::after {
+ display: block;
+ }
+`;
+
+export { Checkbox };
+
diff --git a/src/components/CheckBox/index.js b/src/components/CheckBox/index.js
new file mode 100644
index 00000000..ec4a10a4
--- /dev/null
+++ b/src/components/CheckBox/index.js
@@ -0,0 +1 @@
+export { Checkbox } from "./Checkbox.styled";
diff --git a/src/components/CheckButton/CheckButton.js b/src/components/CheckButton/CheckButton.js
new file mode 100644
index 00000000..e39270a3
--- /dev/null
+++ b/src/components/CheckButton/CheckButton.js
@@ -0,0 +1,19 @@
+import { Component } from "react";
+import { CheckButtonStyled, Icon } from "./CheckButton.styled";
+
+export default class CheckButton extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ return (
+
+
+
+
+
+
+ )
+ }
+}
\ No newline at end of file
diff --git a/src/components/CheckButton/CheckButton.styled.js b/src/components/CheckButton/CheckButton.styled.js
new file mode 100644
index 00000000..90b886b4
--- /dev/null
+++ b/src/components/CheckButton/CheckButton.styled.js
@@ -0,0 +1,44 @@
+import styled, { css } from "styled-components";
+import RoundButton from "../RoundButton";
+
+const CheckButtonStyled = styled(RoundButton)`
+ color: transparent;
+
+ &:hover {
+ background: ${({ theme }) => theme.background.color.roundButton.hover};
+ color: rgba(255,255,255,0.75);
+ }
+
+ &:active {
+ background: ${({ theme }) => theme.background.color.roundButton.active};
+ color: #FFFFFF;
+ }
+
+ ${
+ ({ isEnabled }) => isEnabled && css`
+ background: ${({ theme }) => theme.background.color.roundButton.active} !important;
+ color: white !important;
+
+ border: 1px solid green;
+ `
+ }
+`;
+
+const Icon = styled.svg`
+ display: block;
+ height: 1rem;
+ width: 1rem;
+
+ ${CheckButtonStyled}:hover & {
+ fill: #FFFFFF;
+ }
+`;
+
+const CheckButton = styled(CheckButtonStyled)`
+ &::before {
+ content: '\u{2713}';
+ }
+`
+
+export { CheckButtonStyled, Icon };
+export default CheckButton;
\ No newline at end of file
diff --git a/src/components/CheckButton/index.js b/src/components/CheckButton/index.js
new file mode 100644
index 00000000..31635548
--- /dev/null
+++ b/src/components/CheckButton/index.js
@@ -0,0 +1 @@
+export { default } from "./CheckButton.styled";
diff --git a/src/components/Counter/Counter.js b/src/components/Counter/Counter.js
new file mode 100644
index 00000000..10c9b523
--- /dev/null
+++ b/src/components/Counter/Counter.js
@@ -0,0 +1,13 @@
+import { Component } from "react";
+
+export default class Counter extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const { count } = this.props;
+
+ return {count} Items left;
+ }
+}
diff --git a/src/components/Counter/index.js b/src/components/Counter/index.js
new file mode 100644
index 00000000..e09713ba
--- /dev/null
+++ b/src/components/Counter/index.js
@@ -0,0 +1 @@
+export { default } from "./Counter";
diff --git a/src/components/DeleteButton/DeleteButton.js b/src/components/DeleteButton/DeleteButton.js
new file mode 100644
index 00000000..395f496b
--- /dev/null
+++ b/src/components/DeleteButton/DeleteButton.js
@@ -0,0 +1,19 @@
+import { Component } from "react";
+import { DeleteButtonStyled, Icon } from "./DeleteButton.styled";
+
+export default class DeleteButon extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ return (
+
+
+
+
+
+
+ )
+ }
+}
\ No newline at end of file
diff --git a/src/components/DeleteButton/DeleteButton.styled.js b/src/components/DeleteButton/DeleteButton.styled.js
new file mode 100644
index 00000000..1298d011
--- /dev/null
+++ b/src/components/DeleteButton/DeleteButton.styled.js
@@ -0,0 +1,28 @@
+import styled from "styled-components";
+import RoundButton from "../RoundButton";
+
+const DeleteButtonStyled = styled(RoundButton)`
+ &:hover {
+ background: ${({ theme }) => theme.background.color.roundButton.hover};
+ color: rgba(255,255,255,0.75);
+ }
+`;
+
+const Icon = styled.svg`
+ display: block;
+ height: 1rem;
+ width: 1rem;
+
+ ${DeleteButtonStyled}:hover & {
+ fill: #FFFFFF;
+ }
+`;
+
+const DeleteButton = styled(DeleteButtonStyled)`
+ &::before {
+ content: '\u{00d7}';
+ }
+`;
+
+export { DeleteButtonStyled, Icon };
+export default DeleteButton;
\ No newline at end of file
diff --git a/src/components/DeleteButton/index.js b/src/components/DeleteButton/index.js
new file mode 100644
index 00000000..fb7bf9f9
--- /dev/null
+++ b/src/components/DeleteButton/index.js
@@ -0,0 +1 @@
+export { default } from "./DeleteButton.styled";
diff --git a/src/components/ErrorMessage/ErrorMessage.js b/src/components/ErrorMessage/ErrorMessage.js
new file mode 100644
index 00000000..f9a4dddc
--- /dev/null
+++ b/src/components/ErrorMessage/ErrorMessage.js
@@ -0,0 +1,7 @@
+import { ErrorMessageStyled } from "./ErrorMessage.styled";
+
+export default function ErrorMessage(props) {
+ const { children, dataTestId } = props;
+
+ return {children};
+}
diff --git a/src/components/ErrorMessage/ErrorMessage.styled.js b/src/components/ErrorMessage/ErrorMessage.styled.js
new file mode 100644
index 00000000..2237b0b5
--- /dev/null
+++ b/src/components/ErrorMessage/ErrorMessage.styled.js
@@ -0,0 +1,12 @@
+import styled from "styled-components";
+
+const ErrorMessageStyled = styled.div`
+ padding: 0.5rem;
+ margin: 0;
+
+ border-radius: 0.25rem;
+ color: #FFFFFF;
+ background: rgba(255, 0, 0, 0.35);
+`;
+
+export { ErrorMessageStyled };
\ No newline at end of file
diff --git a/src/components/ErrorMessage/index.js b/src/components/ErrorMessage/index.js
new file mode 100644
index 00000000..3b2ac0c7
--- /dev/null
+++ b/src/components/ErrorMessage/index.js
@@ -0,0 +1 @@
+export { default } from "./ErrorMessage";
diff --git a/src/components/Filter/Filter.js b/src/components/Filter/Filter.js
new file mode 100644
index 00000000..795f7dcb
--- /dev/null
+++ b/src/components/Filter/Filter.js
@@ -0,0 +1,21 @@
+import { Component } from "react";
+
+import { FilterLink, FilterStyled } from "./Filter.styled.js";
+
+export default class TodoFilter extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const activeStyle = { fontWeight: 600, color: "#4094C0" };
+
+ return (
+
+ All
+ Active
+ Completed
+
+ );
+ }
+}
diff --git a/src/components/Filter/Filter.styled.js b/src/components/Filter/Filter.styled.js
new file mode 100644
index 00000000..0fb7f80d
--- /dev/null
+++ b/src/components/Filter/Filter.styled.js
@@ -0,0 +1,16 @@
+import { NavLink } from "react-router-dom";
+import styled from "styled-components";
+
+const FilterStyled = styled.nav`
+ display: flex;
+ justify-content: center;
+ gap: 1rem;
+`;
+
+const FilterLink = styled(NavLink)`
+ &:hover {
+ color: #4094C0;
+ }
+`;
+
+export { FilterStyled, FilterLink };
\ No newline at end of file
diff --git a/src/components/Filter/index.js b/src/components/Filter/index.js
new file mode 100644
index 00000000..84ae2e87
--- /dev/null
+++ b/src/components/Filter/index.js
@@ -0,0 +1 @@
+export { default } from "./Filter";
diff --git a/src/components/Footer/Footer.js b/src/components/Footer/Footer.js
new file mode 100644
index 00000000..3993657f
--- /dev/null
+++ b/src/components/Footer/Footer.js
@@ -0,0 +1,23 @@
+import { Component } from "react";
+
+import { FooterButton, FooterStyled } from "./Footer.styled.js";
+import Counter from "../Counter";
+import Filter from "../Filter";
+
+export default class Footer extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const { count, handleClear } = this.props;
+
+ return (
+
+
+
+ Clear Completed
+
+ );
+ }
+}
diff --git a/src/components/Footer/Footer.styled.js b/src/components/Footer/Footer.styled.js
new file mode 100644
index 00000000..c78451df
--- /dev/null
+++ b/src/components/Footer/Footer.styled.js
@@ -0,0 +1,31 @@
+import styled from "styled-components";
+
+const FooterStyled = styled.footer`
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+
+ padding: 1.25rem;
+ font-size: 0.9rem;
+
+ box-shadow: 0 0 4px rgba(0,0,0,0.25);
+ border-radius: 0.25rem;
+ color: ${({ theme }) => theme.text.color.default };
+
+ transition: background 0.25s ease-in-out, color 0.25s ease-in-out;
+`;
+
+const FooterButton = styled.button`
+ color: inherit;
+ background: none;
+ border: none;
+ outline: none;
+
+ cursor: pointer;
+
+ &:hover {
+ color: #4094C0;
+ }
+`;
+
+export { FooterStyled, FooterButton };
\ No newline at end of file
diff --git a/src/components/Footer/index.js b/src/components/Footer/index.js
new file mode 100644
index 00000000..3738288b
--- /dev/null
+++ b/src/components/Footer/index.js
@@ -0,0 +1 @@
+export { default } from "./Footer";
diff --git a/src/components/FormAddTodo/FormAddTodo.js b/src/components/FormAddTodo/FormAddTodo.js
new file mode 100644
index 00000000..0baf2327
--- /dev/null
+++ b/src/components/FormAddTodo/FormAddTodo.js
@@ -0,0 +1,57 @@
+import { Component } from "react";
+import { Formik } from "formik";
+import { todoSchema } from "../../schema";
+
+import { FormAddTodoStyled, Form } from "./FormAddTodo.styled";
+import Input from "../Input";
+import ErrorMessage from "../ErrorMessage";
+
+export default class FormAddTodo extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const { handleAddTodo } = this.props;
+
+ return (
+
+ {
+ actions.setSubmitting(true);
+
+ setTimeout(() => {
+ handleAddTodo(values);
+ actions.resetForm();
+ }, 500);
+ }}
+ >
+ {({ handleChange, handleSubmit, validateField, resetForm, errors, values }) => (
+
+ )}
+
+
+ );
+ }
+}
diff --git a/src/components/FormAddTodo/FormAddTodo.styled.js b/src/components/FormAddTodo/FormAddTodo.styled.js
new file mode 100644
index 00000000..c697571f
--- /dev/null
+++ b/src/components/FormAddTodo/FormAddTodo.styled.js
@@ -0,0 +1,22 @@
+import styled from "styled-components";
+
+const FormAddTodoStyled = styled.section`
+ padding: 0.75rem;
+
+ border-radius: 0.25rem;
+ box-shadow: ${({ theme }) => theme.shadow.default };
+ background: ${({ theme }) => theme.background.color.default };
+ color: ${({ theme }) => theme.text.color.default };
+
+ transition: background 0.25s ease-in-out, color 0.25s ease-in-out;
+`;
+
+const Form = styled.form`
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ justify-content: center;
+ gap: 0.5rem;
+`;
+
+export { Form, FormAddTodoStyled };
\ No newline at end of file
diff --git a/src/components/FormAddTodo/index.js b/src/components/FormAddTodo/index.js
new file mode 100644
index 00000000..6afd3b87
--- /dev/null
+++ b/src/components/FormAddTodo/index.js
@@ -0,0 +1 @@
+export { default } from "./FormAddTodo";
diff --git a/src/components/FormUpdateTodo/FormUpdateTodo.js b/src/components/FormUpdateTodo/FormUpdateTodo.js
new file mode 100644
index 00000000..6e82923c
--- /dev/null
+++ b/src/components/FormUpdateTodo/FormUpdateTodo.js
@@ -0,0 +1,59 @@
+import { Component } from "react";
+import { Formik } from "formik";
+import { todoSchema } from "../../schema";
+import Input from "../Input";
+import ErrorMessage from "../ErrorMessage";
+
+import { FormUpdateTodoStyled, Form } from "./FormUpdateTodo.styled";
+
+export default class FormUpdateTodo extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const { text, handleSetText, handleCloseForm } = this.props;
+
+ return (
+
+ {
+ setTimeout(() => {
+ handleSetText(values.text);
+ handleCloseForm();
+ actions.resetForm();
+ }, 500);
+ }}
+ >
+ {({ handleChange, handleSubmit, validateField, resetForm, errors, values }) => (
+
+ )}
+
+
+ );
+ }
+}
diff --git a/src/components/FormUpdateTodo/FormUpdateTodo.styled.js b/src/components/FormUpdateTodo/FormUpdateTodo.styled.js
new file mode 100644
index 00000000..8692a309
--- /dev/null
+++ b/src/components/FormUpdateTodo/FormUpdateTodo.styled.js
@@ -0,0 +1,15 @@
+import styled from "styled-components";
+
+const FormUpdateTodoStyled = styled.section`
+ width: 100%;
+`;
+
+const Form = styled.form`
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ justify-content: center;
+ gap: 0.5rem;
+`;
+
+export { FormUpdateTodoStyled, Form };
\ No newline at end of file
diff --git a/src/components/FormUpdateTodo/index.js b/src/components/FormUpdateTodo/index.js
new file mode 100644
index 00000000..932ff341
--- /dev/null
+++ b/src/components/FormUpdateTodo/index.js
@@ -0,0 +1 @@
+export { default } from "./FormUpdateTodo";
diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js
new file mode 100644
index 00000000..76d203b1
--- /dev/null
+++ b/src/components/Header/Header.js
@@ -0,0 +1,21 @@
+import { Component } from "react";
+
+import { HeaderStyled, Title } from "./Header.styled";
+import ThemeSwitch from "../ThemeSwitch";
+
+export default class Header extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const { handleTheme, isDarkMode } = this.props;
+
+ return (
+
+ TODO
+
+
+ );
+ }
+}
diff --git a/src/components/Header/Header.styled.js b/src/components/Header/Header.styled.js
new file mode 100644
index 00000000..8414d19e
--- /dev/null
+++ b/src/components/Header/Header.styled.js
@@ -0,0 +1,19 @@
+import styled from "styled-components";
+
+const HeaderStyled = styled.header`
+ display: flex;
+ flex-direction: row;
+ align-items: baseline;
+ justify-content: space-between;
+`;
+
+const Title = styled.h1`
+ margin: 0;
+
+ font-size: 3rem;
+ font-weight: 400;
+
+ color: white;
+`;
+
+export { HeaderStyled, Title };
\ No newline at end of file
diff --git a/src/components/Header/index.js b/src/components/Header/index.js
new file mode 100644
index 00000000..243d8ed9
--- /dev/null
+++ b/src/components/Header/index.js
@@ -0,0 +1 @@
+export { default } from "./Header";
\ No newline at end of file
diff --git a/src/components/Input/Input.js b/src/components/Input/Input.js
new file mode 100644
index 00000000..4724feef
--- /dev/null
+++ b/src/components/Input/Input.js
@@ -0,0 +1,38 @@
+import { Component } from "react";
+import { v4 as uuid } from "uuid";
+
+import { InputStyled } from "./input.styled";
+
+export default class Input extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const {
+ id = uuid(),
+ name = "name",
+ type = "text",
+ value = "",
+ placeholder = "",
+ onChange = () => {},
+ onBlur = () => {},
+ isWrong = false,
+ setAutoFocus = false,
+ } = this.props;
+
+ return (
+
+ );
+ }
+}
diff --git a/src/components/Input/index.js b/src/components/Input/index.js
new file mode 100644
index 00000000..a50d7d11
--- /dev/null
+++ b/src/components/Input/index.js
@@ -0,0 +1 @@
+export { default } from "./Input";
diff --git a/src/components/Input/input.styled.js b/src/components/Input/input.styled.js
new file mode 100644
index 00000000..85017f93
--- /dev/null
+++ b/src/components/Input/input.styled.js
@@ -0,0 +1,29 @@
+import styled, { css } from "styled-components";
+
+const InputStyled = styled.input`
+ appearance: none;
+
+ width: 100%;
+ padding: 0.5rem;
+
+ border-radius: 0.25rem;
+ border: none;
+ outline: none;
+
+ background: ${({ theme }) => theme.background.color.input.default};
+ color: ${({ theme }) => theme.text.color.default};
+
+ &::placeholder {
+ color: ${({ theme }) => theme.text.color.placeholder.default};
+ }
+
+ &:focus, &:hover {
+ box-shadow: ${({ theme }) => theme.shadow.input.hover};
+ }
+
+ ${({ isWrong }) => isWrong && css`
+ box-shadow: ${({ theme }) => theme.shadow.input.isWrong};
+ `}
+`;
+
+export { InputStyled };
\ No newline at end of file
diff --git a/src/components/NoTodos/NoTodos.js b/src/components/NoTodos/NoTodos.js
new file mode 100644
index 00000000..98cc4d74
--- /dev/null
+++ b/src/components/NoTodos/NoTodos.js
@@ -0,0 +1,26 @@
+import { Component } from "react";
+
+import { Image, NoTodosStyled, Title } from "./NoTodos.styled";
+
+export default class NoTodos extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const { pathname } = this.props;
+
+ const messages = {
+ "/": "There are no tasks. Get started and put some!",
+ "/active": "It seems there's nothing to do yet. We need to do something!",
+ "/completed": "There are no completed tasks. Come on, don't be lazy!",
+ };
+
+ return (
+
+
+ {messages[pathname]}
+
+ );
+ }
+}
diff --git a/src/components/NoTodos/NoTodos.styled.js b/src/components/NoTodos/NoTodos.styled.js
new file mode 100644
index 00000000..3bb08169
--- /dev/null
+++ b/src/components/NoTodos/NoTodos.styled.js
@@ -0,0 +1,30 @@
+import styled from "styled-components";
+import image from "../../img/undraw_wandering_mind_0mkm.svg";
+
+const NoTodosStyled = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 1.5rem;
+
+ height: 40vh;
+ padding: 2rem;
+
+ color: ${({ theme }) => theme.text.color.default };
+`;
+
+const Image = styled.img`
+ width: 240px;
+ content: url(${image});
+`;
+
+const Title = styled.h3`
+ margin: 0;
+
+ text-align: center;
+ font-size: 1.5rem;
+ font-weight: 400;
+`;
+
+export { NoTodosStyled, Image, Title };
\ No newline at end of file
diff --git a/src/components/NoTodos/index.js b/src/components/NoTodos/index.js
new file mode 100644
index 00000000..d9736b02
--- /dev/null
+++ b/src/components/NoTodos/index.js
@@ -0,0 +1 @@
+export { default } from "./NoTodos";
diff --git a/src/components/RoundButton/RoundButton.styled.js b/src/components/RoundButton/RoundButton.styled.js
new file mode 100644
index 00000000..f1097fba
--- /dev/null
+++ b/src/components/RoundButton/RoundButton.styled.js
@@ -0,0 +1,24 @@
+import styled from "styled-components";
+
+const RoundButton = styled.button`
+ appearance: none;
+ cursor: pointer;
+ user-select: none;
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ width: 2rem;
+ height: 2rem;
+ min-width: 2rem;
+
+ border: none;
+ outline: none;
+ border-radius: 50%;
+
+ box-shadow: inset 0 0 4px rgba(0,0,0,0.5);
+ background: white;
+`;
+
+export default RoundButton;
\ No newline at end of file
diff --git a/src/components/RoundButton/index.js b/src/components/RoundButton/index.js
new file mode 100644
index 00000000..8b3ef7a9
--- /dev/null
+++ b/src/components/RoundButton/index.js
@@ -0,0 +1 @@
+export { default } from "./RoundButton.styled";
\ No newline at end of file
diff --git a/src/components/ThemeSwitch/ThemeSwitch.js b/src/components/ThemeSwitch/ThemeSwitch.js
new file mode 100644
index 00000000..b3cf7975
--- /dev/null
+++ b/src/components/ThemeSwitch/ThemeSwitch.js
@@ -0,0 +1,22 @@
+import { Component } from "react";
+import { ThemeSwitchStyled, Icon } from "./ThemeSwitch.styled";
+import moonSVG from "../../img/moon-svgrepo-com.svg";
+import sunSVG from "../../img/sun-svgrepo-com.svg";
+
+export default class ThemeSwitch extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ const { onClick, isDarkMode } = this.props;
+
+ const image = isDarkMode ? moonSVG : sunSVG;
+
+ return (
+
+
+
+ );
+ }
+}
diff --git a/src/components/ThemeSwitch/ThemeSwitch.styled.js b/src/components/ThemeSwitch/ThemeSwitch.styled.js
new file mode 100644
index 00000000..33b86e12
--- /dev/null
+++ b/src/components/ThemeSwitch/ThemeSwitch.styled.js
@@ -0,0 +1,23 @@
+import styled from "styled-components";
+
+const ThemeSwitchStyled = styled.button`
+ height: 2rem;
+ width: 2rem;
+
+ background: none;
+ border: none;
+ outline: none;
+
+ border-radius: 50%;
+ padding: 0.25rem;
+
+ &:hover {
+ box-shadow: ${({ theme }) => theme.shadow.default}
+ }
+`;
+
+const Icon = styled.img`
+ display: block;
+`;
+
+export { ThemeSwitchStyled, Icon };
\ No newline at end of file
diff --git a/src/components/ThemeSwitch/index.js b/src/components/ThemeSwitch/index.js
new file mode 100644
index 00000000..c77e9b74
--- /dev/null
+++ b/src/components/ThemeSwitch/index.js
@@ -0,0 +1 @@
+export { default } from "./ThemeSwitch";
\ No newline at end of file
diff --git a/src/components/TodoItem/TodoItem.js b/src/components/TodoItem/TodoItem.js
new file mode 100644
index 00000000..ca259217
--- /dev/null
+++ b/src/components/TodoItem/TodoItem.js
@@ -0,0 +1,54 @@
+import { Component } from "react";
+
+import { TodoItemStyled, FieldButton } from "./TodoItem.styled";
+import FormUpdateTodo from "../FormUpdateTodo";
+import DeleteButton from "../DeleteButton";
+import CheckButton from "../CheckButton";
+
+export default class TodoItem extends Component {
+ constructor(props) {
+ super(props);
+
+ this.handleSetText = this.handleSetText.bind(this);
+ this.handleSetDone = this.handleSetDone.bind(this);
+ this.handleDelete = this.handleDelete.bind(this);
+ this.handleOpenForm = this.handleOpenForm.bind(this);
+ this.handleCloseForm = this.handleCloseForm.bind(this);
+ }
+
+ handleSetText(text) {
+ this.props.handleSetText(this.props.id, text);
+ }
+
+ handleSetDone() {
+ this.props.handleSetDone(this.props.id);
+ }
+
+ handleDelete() {
+ this.props.handleDelete(this.props.id);
+ }
+
+ handleOpenForm() {
+ this.props.handleIsEditing(this.props.id);
+ }
+
+ handleCloseForm() {
+ this.props.handleIsEditing(null);
+ }
+
+ render() {
+ const { text, isEditing, done } = this.props;
+
+ return (
+
+
+ {isEditing ? (
+
+ ) : (
+ {text}
+ )}
+
+
+ );
+ }
+}
diff --git a/src/components/TodoItem/TodoItem.styled.js b/src/components/TodoItem/TodoItem.styled.js
new file mode 100644
index 00000000..eee71d96
--- /dev/null
+++ b/src/components/TodoItem/TodoItem.styled.js
@@ -0,0 +1,50 @@
+import styled, { css } from "styled-components";
+
+const TodoItemStyled = styled.article`
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 2rem;
+
+ min-height: 8vh;
+ padding: 1rem;
+
+ border-radius: 0.25rem;
+
+ box-shadow: ${({ theme }) => theme.shadow.todoItem.default};
+ background: ${({ theme }) => theme.background.color.todoItem.default};
+ color: ${({ theme }) => theme.text.color.default};
+
+ transition: background 0.25s ease-in-out, color 0.25s ease-in-out;
+
+ ${({ isDone }) => isDone && css`
+ background: ${({ theme }) => theme.background.color.todoItem.isDone};
+ `}
+`;
+
+const FieldButton = styled.button`
+ width: 100%;
+ padding: 0.5rem;
+
+ cursor: pointer;
+ user-select: none;
+
+ text-align: left;
+
+ border-radius: 0.25rem;
+ border: none;
+ outline: none;
+ background: inherit;
+ color: ${({ theme }) => theme.text.color.default};
+
+ &:hover {
+ box-shadow: ${({ theme }) => theme.shadow.fieldButton.hover};
+ }
+
+ ${({ isDone }) => isDone && css`
+ color: ${({ theme }) => theme.text.color.fieldButton.isDone};
+ text-decoration: line-through;
+ `}
+`;
+
+export { TodoItemStyled, FieldButton };
diff --git a/src/components/TodoItem/index.js b/src/components/TodoItem/index.js
new file mode 100644
index 00000000..ca66afea
--- /dev/null
+++ b/src/components/TodoItem/index.js
@@ -0,0 +1 @@
+export { default } from "./TodoItem";
diff --git a/src/components/TodoList/TodoList.js b/src/components/TodoList/TodoList.js
new file mode 100644
index 00000000..c828110b
--- /dev/null
+++ b/src/components/TodoList/TodoList.js
@@ -0,0 +1,54 @@
+import { Component } from "react";
+import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
+
+import { TodoListStyled } from "./TodoList.styled.js";
+import TodoItem from "../TodoItem";
+
+export default class TodoList extends Component {
+ constructor(props) {
+ super(props);
+
+ this.handleDragEnd = this.handleDragEnd.bind(this);
+ }
+
+ handleDragEnd(result) {
+ if (!result.source || !result.destination) return;
+
+ const [srcIndex, dstIndex] = [result.source.index, result.destination.index];
+
+ this.props.handleMove(srcIndex, dstIndex);
+ }
+
+ render() {
+ const { dndDisabled, todos, handleDelete, handleSetDone, handleSetText, handleIsEditing } = this.props;
+
+ return (
+
+
+
+ {(provided) => (
+
+ {todos.map((item, index) => (
+
+ {(provided) => (
+ -
+
+
+ )}
+
+ ))}
+ {provided.placeholder}
+
+ )}
+
+
+
+ );
+ }
+}
diff --git a/src/components/TodoList/TodoList.styled.js b/src/components/TodoList/TodoList.styled.js
new file mode 100644
index 00000000..5b378b1f
--- /dev/null
+++ b/src/components/TodoList/TodoList.styled.js
@@ -0,0 +1,8 @@
+import styled from "styled-components";
+
+const TodoListStyled = styled.div`
+ height: 40vh;
+ overflow-y: scroll;
+`;
+
+export { TodoListStyled };
\ No newline at end of file
diff --git a/src/components/TodoList/index.js b/src/components/TodoList/index.js
new file mode 100644
index 00000000..8d439448
--- /dev/null
+++ b/src/components/TodoList/index.js
@@ -0,0 +1 @@
+export { default } from "./TodoList";
diff --git a/src/img/app-view.jpg b/src/img/app-view.jpg
deleted file mode 100644
index 35376b2a..00000000
Binary files a/src/img/app-view.jpg and /dev/null differ
diff --git a/src/img/bg-dark.jpg b/src/img/bg-dark.jpg
new file mode 100644
index 00000000..6e337657
Binary files /dev/null and b/src/img/bg-dark.jpg differ
diff --git a/src/img/bg-light.jpg b/src/img/bg-light.jpg
new file mode 100644
index 00000000..748a2336
Binary files /dev/null and b/src/img/bg-light.jpg differ
diff --git a/src/img/moon-svgrepo-com.svg b/src/img/moon-svgrepo-com.svg
new file mode 100644
index 00000000..dc670b6a
--- /dev/null
+++ b/src/img/moon-svgrepo-com.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/img/sun-svgrepo-com.svg b/src/img/sun-svgrepo-com.svg
new file mode 100644
index 00000000..c3607413
--- /dev/null
+++ b/src/img/sun-svgrepo-com.svg
@@ -0,0 +1,58 @@
+
diff --git a/src/img/undraw_wandering_mind_0mkm.svg b/src/img/undraw_wandering_mind_0mkm.svg
new file mode 100644
index 00000000..d6c391cb
--- /dev/null
+++ b/src/img/undraw_wandering_mind_0mkm.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 19bb154c..3d02bfd3 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,19 +1,14 @@
-import React from "react";
import ReactDOM from "react-dom";
-
-import "bootstrap/dist/css/bootstrap.min.css";
+import React from "react";
+import { withRouter } from "react-router";
import App from "./App";
-import reportWebVitals from "./reportWebVitals";
+
+const AppWithRouter = withRouter(App);
ReactDOM.render(
-
+
,
document.getElementById("root"),
);
-
-// If you want to start measuring performance in your app, pass a function
-// to log results (for example: reportWebVitals(console.log))
-// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
-reportWebVitals();
diff --git a/src/schema/index.js b/src/schema/index.js
new file mode 100644
index 00000000..a9fa0ba7
--- /dev/null
+++ b/src/schema/index.js
@@ -0,0 +1 @@
+export { todoSchema } from "./todo-schema";
diff --git a/src/schema/todo-schema.js b/src/schema/todo-schema.js
new file mode 100644
index 00000000..57c733b2
--- /dev/null
+++ b/src/schema/todo-schema.js
@@ -0,0 +1,7 @@
+import * as Yup from "yup";
+
+const todoSchema = Yup.object().shape({
+ text: Yup.string().required("Please enter at least one character"),
+});
+
+export { todoSchema };
diff --git a/src/themes/dark.js b/src/themes/dark.js
new file mode 100644
index 00000000..6bd87126
--- /dev/null
+++ b/src/themes/dark.js
@@ -0,0 +1,45 @@
+import bgDark from "../img/bg-dark.jpg";
+
+export const dark = {
+ shadow: {
+ default: "0 0 4px rgba(255, 255, 255, 0.5)",
+ input: {
+ hover: "inset 0 0 2px #e4e4e4",
+ isWrong: "inset 0 0 4px #b80000 !important",
+ },
+ fieldButton: {
+ hover: "inset 0 0 2px #e4e4e4",
+ },
+ todoItem: {
+ default: "inset 0 0px 1px rgba(255, 255, 255, 0.75)",
+ },
+ },
+ background: {
+ color: {
+ default: "rgba(0, 0, 0, 0.5)",
+ input: {
+ default: "rgba(0, 0, 0, 0.75)",
+ },
+ roundButton: {
+ hover: "linear-gradient(135deg, rgba(64, 128, 192, 0.5) 0%, rgba(224, 40, 252, 0.5) 100%)",
+ active: "linear-gradient(135deg, rgba(64, 128, 192, 1) 0%, rgba(224, 40, 252, 1) 100%)",
+ },
+ todoItem: {
+ default: "#000000",
+ isDone: "linear-gradient(135deg, rgba(64, 128, 192, 1) 0%, rgba(224, 40, 252, 1) 100%)",
+ },
+ },
+ image: bgDark,
+ },
+ text: {
+ color: {
+ default: "#FFFFFF",
+ placeholder: {
+ default: "#C8C8C8",
+ },
+ fieldButton: {
+ isDone: "#C8C8C8",
+ },
+ },
+ }
+}
\ No newline at end of file
diff --git a/src/themes/global.js b/src/themes/global.js
new file mode 100644
index 00000000..4919201d
--- /dev/null
+++ b/src/themes/global.js
@@ -0,0 +1,56 @@
+import { createGlobalStyle } from "styled-components";
+
+const GlobalStyle = createGlobalStyle`
+ body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ }
+
+ * {
+ box-sizing: border-box;
+ }
+
+ ul,
+ ol {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ }
+
+ a {
+ color: inherit;
+ text-decoration: none;
+ }
+
+
+ *::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+ }
+
+ *::-webkit-scrollbar-thumb {
+ background: rgb(204, 204, 204);
+ border-radius: 4px;
+ }
+
+ *::-webkit-scrollbar-thumb:hover {
+ background: rgb(179, 179, 179);
+ box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.2);
+ }
+
+ *::-webkit-scrollbar-thumb:active {
+ background-color: rgb(153, 153, 153);
+ }
+
+ *::-webkit-scrollbar-track {
+ background: rgb(224, 224, 224);
+ border-radius: 4px;
+ }
+
+ *::-webkit-scrollbar-track:hover,
+ *::-webkit-scrollbar-track:active {
+ background: rgb(212, 212, 212);
+ }
+`;
+
+export { GlobalStyle };
\ No newline at end of file
diff --git a/src/themes/index.js b/src/themes/index.js
new file mode 100644
index 00000000..b0ed0730
--- /dev/null
+++ b/src/themes/index.js
@@ -0,0 +1,3 @@
+export { dark } from "./dark";
+export { light } from "./light";
+export { GlobalStyle } from "./global";
\ No newline at end of file
diff --git a/src/themes/light.js b/src/themes/light.js
new file mode 100644
index 00000000..0066e1e3
--- /dev/null
+++ b/src/themes/light.js
@@ -0,0 +1,45 @@
+import bgLight from "../img/bg-light.jpg";
+
+export const light = {
+ shadow: {
+ default: "0 0 4px rgba(0, 0, 0, 0.25)",
+ input: {
+ hover: "inset 0 0 2px #a0a0a0",
+ isWrong: "inset 0 0 4px #b80000 !important",
+ },
+ fieldButton: {
+ hover: "inset 0 0 2px #a0a0a0",
+ },
+ todoItem: {
+ default: "inset 0 0px 1px rgba(0, 0, 0, 0.75)",
+ },
+ },
+ background: {
+ color: {
+ default: "rgba(255, 255, 255, 0.75)",
+ input: {
+ default: "#FCFCFC",
+ },
+ roundButton: {
+ hover: "linear-gradient(135deg, rgba(64, 128, 192, 0.5) 0%, rgba(224, 40, 252, 0.5) 100%)",
+ active: "linear-gradient(135deg, rgba(64, 128, 192, 1) 0%, rgba(224, 40, 252, 1) 100%)",
+ },
+ todoItem: {
+ default: "#FFFFFF",
+ isDone: "linear-gradient(135deg, rgba(64, 128, 192, 1) 0%, rgba(224, 40, 252, 1) 100%)",
+ },
+ },
+ image: bgLight,
+ },
+ text: {
+ color: {
+ default: "#000000",
+ placeholder: {
+ default: "#888888",
+ },
+ fieldButton: {
+ isDone: "#888888",
+ },
+ },
+ }
+};
\ No newline at end of file