21 files changed
+684
-111
No files matched your search
@@ -1,2 +0,0 @@
|
||||
[tools]
|
||||
node = "20"
|
||||
Generated
+179
-24
@@ -24,9 +24,11 @@
|
||||
"sharp": "^0.32.6",
|
||||
"sitemap": "^1.5.0",
|
||||
"typograf": "^6.11.1",
|
||||
"use-media": "^1.4.0"
|
||||
"use-media": "^1.4.0",
|
||||
"valtio": "^2.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@types/classnames": "^2.2.10",
|
||||
"@types/markdown-it": "^12.2.3",
|
||||
"@types/node": "^18.13.0",
|
||||
@@ -90,16 +92,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
|
||||
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
|
||||
"integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.6.0",
|
||||
"globals": "^13.19.0",
|
||||
"espree": "^10.0.1",
|
||||
"globals": "^14.0.0",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
@@ -107,12 +109,56 @@
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
||||
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/espree": {
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
|
||||
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"acorn": "^8.15.0",
|
||||
"acorn-jsx": "^5.3.2",
|
||||
"eslint-visitor-keys": "^4.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/globals": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
|
||||
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "8.57.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
|
||||
@@ -1223,13 +1269,13 @@
|
||||
"version": "15.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz",
|
||||
"integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "*",
|
||||
@@ -1240,7 +1286,7 @@
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
|
||||
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/@types/sharp": {
|
||||
"version": "0.29.2",
|
||||
@@ -1501,9 +1547,9 @@
|
||||
"integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ=="
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
@@ -2832,6 +2878,30 @@
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/@eslint/eslintrc": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
|
||||
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.6.0",
|
||||
"globals": "^13.19.0",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"minimatch": "^3.1.2",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
@@ -4666,6 +4736,12 @@
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-compare": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz",
|
||||
"integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
@@ -5842,6 +5918,30 @@
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/valtio": {
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmjs.org/valtio/-/valtio-2.1.7.tgz",
|
||||
"integrity": "sha512-DwJhCDpujuQuKdJ2H84VbTjEJJteaSmqsuUltsfbfdbotVfNeTE4K/qc/Wi57I9x8/2ed4JNdjEna7O6PfavRg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"proxy-compare": "^3.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=18.0.0",
|
||||
"react": ">=18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
@@ -6015,20 +6115,45 @@
|
||||
"dev": true
|
||||
},
|
||||
"@eslint/eslintrc": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
|
||||
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
|
||||
"integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.6.0",
|
||||
"globals": "^13.19.0",
|
||||
"espree": "^10.0.1",
|
||||
"globals": "^14.0.0",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"minimatch": "^3.1.2",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-visitor-keys": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
||||
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
|
||||
"dev": true
|
||||
},
|
||||
"espree": {
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
|
||||
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "^8.15.0",
|
||||
"acorn-jsx": "^5.3.2",
|
||||
"eslint-visitor-keys": "^4.2.1"
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
|
||||
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@eslint/js": {
|
||||
@@ -6684,13 +6809,13 @@
|
||||
"version": "15.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "18.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz",
|
||||
"integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"requires": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "*",
|
||||
@@ -6701,7 +6826,7 @@
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
|
||||
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"@types/sharp": {
|
||||
"version": "0.29.2",
|
||||
@@ -6848,9 +6973,9 @@
|
||||
"integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ=="
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn-jsx": {
|
||||
@@ -7537,6 +7662,23 @@
|
||||
"text-table": "^0.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eslint/eslintrc": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
|
||||
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.6.0",
|
||||
"globals": "^13.19.0",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"minimatch": "^3.1.2",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
@@ -9020,6 +9162,11 @@
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"proxy-compare": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz",
|
||||
"integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q=="
|
||||
},
|
||||
"pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
@@ -9840,6 +9987,14 @@
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"valtio": {
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmjs.org/valtio/-/valtio-2.1.7.tgz",
|
||||
"integrity": "sha512-DwJhCDpujuQuKdJ2H84VbTjEJJteaSmqsuUltsfbfdbotVfNeTE4K/qc/Wi57I9x8/2ed4JNdjEna7O6PfavRg==",
|
||||
"requires": {
|
||||
"proxy-compare": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
||||
+5
-3
@@ -7,8 +7,8 @@
|
||||
"start": "next start",
|
||||
"dev": "next dev --turbo",
|
||||
"build": "next build",
|
||||
"lint": "next lint",
|
||||
"format": "next lint --fix",
|
||||
"lint": "eslint .",
|
||||
"format": "eslint --fix .",
|
||||
"sitemap": "node scripts/sitemap.js",
|
||||
"feed": "node scripts/feed.js"
|
||||
},
|
||||
@@ -34,9 +34,11 @@
|
||||
"sharp": "^0.32.6",
|
||||
"sitemap": "^1.5.0",
|
||||
"typograf": "^6.11.1",
|
||||
"use-media": "^1.4.0"
|
||||
"use-media": "^1.4.0",
|
||||
"valtio": "^2.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@types/classnames": "^2.2.10",
|
||||
"@types/markdown-it": "^12.2.3",
|
||||
"@types/node": "^18.13.0",
|
||||
|
||||
@@ -8,7 +8,6 @@ import App from "next/app"
|
||||
import Head from "next/head"
|
||||
import Script from "next/script"
|
||||
import { YMetrika } from "src/components/YMetrika"
|
||||
import { Theme } from "@/ui/theme/Theme"
|
||||
import { ThemeColor } from "@/ui/ThemeColor"
|
||||
|
||||
export default class MyApp extends App {
|
||||
@@ -51,9 +50,7 @@ export default class MyApp extends App {
|
||||
</Head>
|
||||
<Script src="https://culturaltracking.ru/static/js/spxl.js?pixelId=27154" data-pixel-id="27154"></Script>
|
||||
|
||||
<Theme>
|
||||
<Component {...pageProps} />
|
||||
</Theme>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
import { theme, toggleTheme } from "@/store/theme"
|
||||
import { Button } from "@/ui/Button"
|
||||
import { HiOutlineEye, HiOutlineEyeOff } from "react-icons/hi"
|
||||
import { useTheme } from "@/ui/theme/useTheme"
|
||||
import { useSnapshot } from "valtio"
|
||||
|
||||
export function AccessibilityButton() {
|
||||
const { theme, setTheme } = useTheme()
|
||||
const t = useSnapshot(theme)
|
||||
|
||||
return (
|
||||
<Button
|
||||
theme="icon"
|
||||
size="default"
|
||||
onClick={() => {
|
||||
setTheme(theme === "default" ? "contrast" : "default")
|
||||
}}
|
||||
onClick={toggleTheme}
|
||||
>
|
||||
{theme === "default" ? (
|
||||
{t.theme === "default" ? (
|
||||
<HiOutlineEyeOff size={24} />
|
||||
) : (
|
||||
<HiOutlineEye size={24} />
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import play from "@/play"
|
||||
import { state as playState, setVoice } from "@/store/play"
|
||||
import { decreaseFontSize, hideImages, increaseFontSize, reset, setBlackOnWhite, setBlueOnBlue, setBrownOnYellow, setDefaultTheme, setGreenOnBrown, setLetterSpacingOne, setLetterSpacingTwo, setLetterSpacingFour, setLineHeightOneAndHalf, setLineHeightTwo, setLineHeightTwoAndHalf, setSerifFont, setSansSerifFont, setWhiteOnBlack, showImages } from "@/store/theme"
|
||||
import { HiCog, HiOutlineEyeOff, HiPlay } from "react-icons/hi"
|
||||
import { useSnapshot } from "valtio"
|
||||
import s from "./panel.module.css"
|
||||
import VoiceSelect from "./voice"
|
||||
|
||||
function AccessibilityPanel() {
|
||||
const p = useSnapshot(playState)
|
||||
|
||||
return ( <div className={s.viewsettings}>
|
||||
<div className={s.row}>
|
||||
<div className={s.block}>
|
||||
<p>Размер шрифта:</p>
|
||||
<a onClick={decreaseFontSize} title="уменьшить размер шрифта">A-</a>
|
||||
<a onClick={increaseFontSize} title="увеличить размер шрифта"><strong>A+</strong></a>
|
||||
</div>
|
||||
|
||||
<div className={s.block}>
|
||||
<p>Изображения:</p>
|
||||
<a onClick={showImages}>Включить</a>
|
||||
<a onClick={hideImages}>Выключить</a>
|
||||
</div>
|
||||
|
||||
<div className={s.block}>
|
||||
<p>Цвет сайта:</p>
|
||||
<a onClick={setBlackOnWhite} title="черные буквы на белом фоне" style={{color: "black", backgroundColor: "white"}}>Ц</a>
|
||||
<a onClick={setWhiteOnBlack} title="белые буквы на черном фоне" style={{color: "white", backgroundColor: "black"}}>Ц</a>
|
||||
<a onClick={setBlueOnBlue} title="синии буквы на голубом фоне" style={{color: "oklch(32% 24% 253deg)", backgroundColor: "oklch(84% 21% 245deg)"}}>Ц</a>
|
||||
<a onClick={setBrownOnYellow} title="коричневые буквы на желтом фоне" style={{color: "oklch(41% 3% 92deg)", backgroundColor: "oklch(96% 9% 101deg)"}}>Ц</a>
|
||||
<a onClick={setGreenOnBrown} title="зеленые буквы на коричневом фоне" style={{color: "oklch(85% 47% 128deg)", backgroundColor: "oklch(29% 10% 61deg)"}}>Ц</a>
|
||||
</div>
|
||||
|
||||
<div className={s.block}>
|
||||
<p>Шрифт:</p>
|
||||
<a onClick={setSerifFont}>С засечками</a>
|
||||
<a onClick={setSansSerifFont}>Без засечек</a>
|
||||
{/*<a id="btn-on-braille" href="javascript:void(0)" onClick="smSetting('fontBraille', 'brailleOn')" title="только для печати">Брайля</a>*/}
|
||||
{/*<a id="btn-off-braille" href="javascript:void(0)" onClick="smSetting('fontBraille', 'brailleOff')">Обычный</a>*/}
|
||||
</div>
|
||||
|
||||
<div className={s.block}>
|
||||
<p>Высота строк:</p>
|
||||
<a onClick={setLineHeightOneAndHalf}>1.5</a>
|
||||
<a onClick={setLineHeightTwo}>2.0</a>
|
||||
<a onClick={setLineHeightTwoAndHalf}>2.5</a>
|
||||
</div>
|
||||
|
||||
<div className={s.block}>
|
||||
<p>Межбуквенный интервал:</p>
|
||||
<a onClick={setLetterSpacingOne}>1</a>
|
||||
<a onClick={setLetterSpacingTwo}>2</a>
|
||||
<a onClick={setLetterSpacingFour}>4</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={s.row}>
|
||||
<button onClick={reset}>
|
||||
<HiCog />
|
||||
Сброс настроек
|
||||
</button>
|
||||
<button onClick={setDefaultTheme}>
|
||||
<HiOutlineEyeOff />
|
||||
Обычная версия
|
||||
</button>
|
||||
<button onClick={play}>
|
||||
<HiPlay />
|
||||
Прослушать всё
|
||||
</button>
|
||||
<VoiceSelect value={p.voice} onChange={(event) => {
|
||||
setVoice(event.target.value)
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AccessibilityPanel
|
||||
@@ -0,0 +1,91 @@
|
||||
/*body {
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
width: 96%;
|
||||
padding-top: 90px;
|
||||
}*/
|
||||
|
||||
.viewsettings {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
color: black;
|
||||
background: white;
|
||||
z-index: 10;
|
||||
font-size: 20px !important;
|
||||
line-height: 30px;
|
||||
font-family: sans-serif;
|
||||
letter-spacing: normal !important;
|
||||
|
||||
/*position: fixed;
|
||||
top: 0;*/
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
|
||||
text-align: center;
|
||||
border: 2px solid;
|
||||
}
|
||||
|
||||
.viewsettings .row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.viewsettings p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.viewsettings a {
|
||||
border: 1px solid;
|
||||
text-decoration: none;
|
||||
padding: 4px 10px;
|
||||
cursor: pointer;
|
||||
|
||||
color: black;
|
||||
}
|
||||
.viewsettings a:hover {
|
||||
background-color: #cfcfcf !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.viewsettings a:focus {
|
||||
outline: 1px solid !important;
|
||||
}
|
||||
|
||||
.viewsettings .block {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
line-height: 30px;
|
||||
border: 2px solid;
|
||||
padding: 6px 10px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.viewsettings .block a {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.viewsettings button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
border: 1px solid;
|
||||
font-size: 20px !important;
|
||||
padding: 4px 10px;
|
||||
cursor: pointer;
|
||||
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.viewsettings button:hover {
|
||||
background-color: #cfcfcf !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.viewsettings button:focus {
|
||||
outline: 1px solid !important;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
function useVoices() {
|
||||
return window.speechSynthesis
|
||||
.getVoices()
|
||||
.map(v => {
|
||||
return {
|
||||
name: `${v.name} (${v.lang})`,
|
||||
value: v.name,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export type VoiceSelectProps = React.SelectHTMLAttributes<HTMLSelectElement>
|
||||
|
||||
function VoiceSelect(props: VoiceSelectProps) {
|
||||
const voices = useVoices()
|
||||
return (
|
||||
<select {...props}>
|
||||
{voices.map(voice => (
|
||||
<option key={voice.value} value={voice.value}>
|
||||
{voice.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)
|
||||
}
|
||||
|
||||
export default VoiceSelect
|
||||
@@ -10,7 +10,6 @@ import { useMobile } from "src/hooks/useMobile"
|
||||
import { Navigation } from "@/components/Navigation"
|
||||
import { Box } from "@/ui/Box"
|
||||
import { AccessibilityButton } from "../AccessibilityButton"
|
||||
import { useTheme } from "@/ui/theme/useTheme"
|
||||
import { Copyright } from "../Copyright"
|
||||
import { Spacer } from "../Spacer"
|
||||
import { Author } from "../Author"
|
||||
@@ -22,6 +21,8 @@ import dynamic from "next/dynamic"
|
||||
import qr0 from "src/assets/qr00.png"
|
||||
import qr1 from "src/assets/qr01.png"
|
||||
import Image from "next/image"
|
||||
import AccessibilityPanel from "../AccessibilityPanel"
|
||||
import useAccessibility from "@/hooks/useAccessibility"
|
||||
|
||||
const Gosuslugi = dynamic(import("../Gosuslugi").then(module => module.Gosuslugi), {
|
||||
ssr: false,
|
||||
@@ -37,11 +38,11 @@ export type AppProps = {
|
||||
|
||||
export const App: React.FC<AppProps> = ({ showAuthor = false, menu, ...props }) => {
|
||||
const hideBreadcrumbs = useMobile()
|
||||
const accessibility = useAccessibility()
|
||||
const router = useRouter()
|
||||
const blockStyle = {
|
||||
justifyContent: "center",
|
||||
}
|
||||
const { theme, setTheme } = useTheme()
|
||||
|
||||
return (
|
||||
<ConfigContext.Provider value={{
|
||||
@@ -51,6 +52,10 @@ export const App: React.FC<AppProps> = ({ showAuthor = false, menu, ...props })
|
||||
<Wrapper
|
||||
header={(
|
||||
<header>
|
||||
{!accessibility ? null : (
|
||||
<AccessibilityPanel/>
|
||||
)}
|
||||
|
||||
<Navigation style={{
|
||||
padding: "var(--size-s)",
|
||||
}} />
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import s from "./wrapper.module.css"
|
||||
|
||||
import cx from "classnames"
|
||||
import { useTheme } from "@/ui/theme/useTheme"
|
||||
import { useSnapshot } from "valtio"
|
||||
import { theme } from "@/store/theme"
|
||||
|
||||
export type WrapperProps = {
|
||||
header: React.ReactNode
|
||||
@@ -12,10 +13,10 @@ export type WrapperProps = {
|
||||
}
|
||||
|
||||
export const Wrapper: React.FC<WrapperProps> = props => {
|
||||
const { theme } = useTheme()
|
||||
const t = useSnapshot(theme)
|
||||
|
||||
return (
|
||||
<div className={cx(s.container, `theme-${theme}`)} style={props.style}>
|
||||
<div className={cx(s.container, `theme-${t.theme}`, `font-${t.fontType}`, t.colorScheme ?? "black-on-white", !t.showImages ? "no-images" : null)} style={props.style}>
|
||||
{props.header}
|
||||
|
||||
<main className={s.main} style={props.mainStyle}>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-back-main);
|
||||
|
||||
font-family: var(--text-font);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { theme } from "@/store/theme"
|
||||
import { useSnapshot } from "valtio"
|
||||
|
||||
function useAccessibility(): boolean {
|
||||
const t = useSnapshot(theme)
|
||||
|
||||
return t.theme === "contrast"
|
||||
}
|
||||
|
||||
export default useAccessibility
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import { state } from "./store/play"
|
||||
|
||||
|
||||
function play() {
|
||||
const synth = window.speechSynthesis
|
||||
|
||||
const a = document.querySelector("article")
|
||||
if (!a || !a.textContent) {
|
||||
return
|
||||
}
|
||||
|
||||
const u = new SpeechSynthesisUtterance(a.textContent)
|
||||
const voice = synth.getVoices().find((v) => v.name === state.voice)
|
||||
if (voice) {
|
||||
u.voice = voice
|
||||
}
|
||||
synth.speak(u)
|
||||
}
|
||||
|
||||
export default play
|
||||
@@ -0,0 +1,13 @@
|
||||
import { proxy } from "valtio"
|
||||
|
||||
type State = {
|
||||
voice: string
|
||||
}
|
||||
|
||||
export const state = proxy<State>({
|
||||
voice: "Milena",
|
||||
})
|
||||
|
||||
export function setVoice(value: string) {
|
||||
state.voice = value
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
import { proxy, subscribe } from "valtio"
|
||||
|
||||
export type ThemeName = "default" | "contrast"
|
||||
export type ColorSchemeVariant = "black-on-white" | "white-on-black" | "blue-on-blue" | "brown-on-yellow" | "green-on-brown"
|
||||
export type FontTypeVariant = "serif" | "sans-serif"
|
||||
|
||||
const MIN_FONT_SIZE = 8
|
||||
const MAX_FONT_SIZE = 48
|
||||
const CHANGE_FONT_SIZE_DELTA = 1
|
||||
|
||||
function clamp(val: number, min: number, max: number): number {
|
||||
if (val < min) {
|
||||
return min
|
||||
}
|
||||
if (val > max) {
|
||||
return max
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
export type ThemeOptions = {
|
||||
theme: ThemeName
|
||||
fontType: FontTypeVariant
|
||||
fontSize: number
|
||||
lineHeight: number
|
||||
letterSpacing: number
|
||||
showImages: boolean
|
||||
colorScheme: ColorSchemeVariant
|
||||
}
|
||||
|
||||
export const theme = proxy<ThemeOptions>({
|
||||
theme: "default",
|
||||
fontSize: 14,
|
||||
lineHeight: 1.5,
|
||||
letterSpacing: 1,
|
||||
fontType: "sans-serif",
|
||||
showImages: true,
|
||||
colorScheme: "black-on-white",
|
||||
})
|
||||
|
||||
export function reset() {
|
||||
theme.fontSize = 14
|
||||
theme.lineHeight = 1.5
|
||||
theme.letterSpacing = 1
|
||||
theme.fontType = "sans-serif"
|
||||
theme.showImages = true
|
||||
theme.colorScheme = "black-on-white"
|
||||
}
|
||||
|
||||
export function setDefaultTheme() {
|
||||
theme.theme = "default"
|
||||
reset()
|
||||
}
|
||||
|
||||
export function toggleTheme() {
|
||||
theme.theme = theme.theme === "default" ? "contrast" : "default"
|
||||
}
|
||||
|
||||
export function increaseFontSize() {
|
||||
theme.fontSize = clamp(theme.fontSize + CHANGE_FONT_SIZE_DELTA, MIN_FONT_SIZE, MAX_FONT_SIZE)
|
||||
}
|
||||
|
||||
export function decreaseFontSize() {
|
||||
theme.fontSize = clamp(theme.fontSize - CHANGE_FONT_SIZE_DELTA, MIN_FONT_SIZE, MAX_FONT_SIZE)
|
||||
}
|
||||
|
||||
export function setSansSerifFont() {
|
||||
theme.fontType = "sans-serif"
|
||||
}
|
||||
|
||||
export function setSerifFont() {
|
||||
theme.fontType = "serif"
|
||||
}
|
||||
|
||||
export function showImages() {
|
||||
theme.showImages = true
|
||||
}
|
||||
|
||||
export function hideImages() {
|
||||
theme.showImages = false
|
||||
}
|
||||
|
||||
export function setBlackOnWhite() {
|
||||
theme.colorScheme = "black-on-white"
|
||||
}
|
||||
|
||||
export function setWhiteOnBlack() {
|
||||
theme.colorScheme = "white-on-black"
|
||||
}
|
||||
|
||||
export function setBlueOnBlue() {
|
||||
theme.colorScheme = "blue-on-blue"
|
||||
}
|
||||
|
||||
export function setBrownOnYellow() {
|
||||
theme.colorScheme = "brown-on-yellow"
|
||||
}
|
||||
|
||||
export function setGreenOnBrown() {
|
||||
theme.colorScheme = "green-on-brown"
|
||||
}
|
||||
|
||||
export function setLineHeightOneAndHalf() {
|
||||
theme.lineHeight = 1.5
|
||||
}
|
||||
|
||||
export function setLineHeightTwo() {
|
||||
theme.lineHeight = 2
|
||||
}
|
||||
|
||||
export function setLineHeightTwoAndHalf() {
|
||||
theme.lineHeight = 2.5
|
||||
}
|
||||
|
||||
export function setLetterSpacingOne() {
|
||||
theme.letterSpacing = 1
|
||||
}
|
||||
|
||||
export function setLetterSpacingTwo() {
|
||||
theme.letterSpacing = 2
|
||||
}
|
||||
|
||||
export function setLetterSpacingFour() {
|
||||
theme.letterSpacing = 4
|
||||
}
|
||||
|
||||
const unsubscribe = subscribe(theme, () => {
|
||||
document.documentElement.style.setProperty("--font-size-default", `${theme.fontSize}pt`)
|
||||
document.documentElement.style.setProperty("--font-size-second", `${theme.fontSize}pt`)
|
||||
document.documentElement.style.setProperty("--font-size-accent", `${theme.fontSize}pt`)
|
||||
document.documentElement.style.setProperty("--article-line-height", `${theme.lineHeight}em`)
|
||||
if (theme.letterSpacing === 1) {
|
||||
document.documentElement.style.setProperty("--letter-spacing", "normal")
|
||||
} else {
|
||||
document.documentElement.style.setProperty("--letter-spacing", `${theme.letterSpacing}px`)
|
||||
}
|
||||
|
||||
// TODO remove this from here and move this logic directly to body tag after moving from pages to app
|
||||
document.body.classList.forEach(name => {
|
||||
document.body.classList.remove(name)
|
||||
})
|
||||
if (theme.theme === "contrast") {
|
||||
document.body.classList.add("theme-contrast")
|
||||
document.body.classList.add(theme.colorScheme)
|
||||
}
|
||||
})
|
||||
+94
-30
@@ -21,6 +21,8 @@
|
||||
--font-size-h2: 3rem;
|
||||
--font-size-h3: 1.5rem;
|
||||
|
||||
--letter-spacing: normal;
|
||||
|
||||
/* COLOR */
|
||||
--color-text: hsl(0, 0%, 15%);
|
||||
--color-text-second: hsl(240, 10%, 60%);
|
||||
@@ -89,6 +91,7 @@ body {
|
||||
background-color: var(--color-back-main);
|
||||
|
||||
font-family: var(--text-font);
|
||||
letter-spacing: var(--letter-spacing);
|
||||
}
|
||||
|
||||
/* TITLE */
|
||||
@@ -167,35 +170,16 @@ h3 {
|
||||
|
||||
/* CONTRAST THEME */
|
||||
.theme-contrast {
|
||||
/* FONTS */
|
||||
--title-font: 'Roboto', Helvetica, sans-serif;
|
||||
--text-font: 'Roboto', Helvetica, sans-serif;
|
||||
|
||||
/* TEXT COLOR */
|
||||
--color-text: black;
|
||||
--color-text-second: black;
|
||||
--color-text-opposite: white;
|
||||
|
||||
--color-back-main: white;
|
||||
--color-back: white;
|
||||
--color-back-active: hsl(240, 10%, 20%);
|
||||
/* --color-back-opposite: hsl(240, 10%, 80%); */
|
||||
--color-back-opposite: black;
|
||||
--color-link: hsl(240, 10%, 40%);
|
||||
--color-link-opposite: hsl(240, 10%, 60%);
|
||||
|
||||
--color-hover: white;
|
||||
--color-hover-back: black;
|
||||
/*margin-top: 235px;*/
|
||||
|
||||
/* EFFECTS */
|
||||
/* --radius: 0px; */
|
||||
--shadow: none;
|
||||
--shadow-active: none;
|
||||
|
||||
/* FONTS */
|
||||
--font-size-default: 16pt;
|
||||
--font-size-accent: 24pt;
|
||||
--font-size-second: 14pt;
|
||||
/*--font-size-default: 16pt;*/
|
||||
/*--font-size-accent: 24pt;*/
|
||||
/*--font-size-second: 14pt;*/
|
||||
|
||||
--font-size-h1: 5rem;
|
||||
--font-size-h2: 3rem;
|
||||
@@ -207,23 +191,103 @@ h3 {
|
||||
--border: 5px solid var(--color-back-opposite);
|
||||
}
|
||||
|
||||
/* CONTRAST + DARK THEME */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.theme-contrast {
|
||||
/* TEXT COLOR */
|
||||
.theme-contrast.font-sans-serif {
|
||||
--title-font: "Roboto", Helvetica, sans-serif;
|
||||
--text-font: "Roboto", Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.theme-contrast.font-serif {
|
||||
--title-font: "Times New Roman", serif;
|
||||
--text-font: "Times New Roman", serif;
|
||||
}
|
||||
|
||||
.theme-contrast.black-on-white {
|
||||
--color-text: black;
|
||||
--color-text-second: black;
|
||||
--color-text-opposite: white;
|
||||
--color-back-main: white;
|
||||
--color-back: white;
|
||||
--color-back-opposite: black;
|
||||
|
||||
--color-hover: white;
|
||||
--color-hover-back: black;
|
||||
|
||||
--color-back-active: black;
|
||||
--color-link: black;
|
||||
--color-link-opposite: white;
|
||||
}
|
||||
|
||||
.theme-contrast.white-on-black {
|
||||
--color-text: white;
|
||||
--color-text-second: white;
|
||||
--color-text-opposite: black;
|
||||
|
||||
--color-back-main: black;
|
||||
--color-back: black;
|
||||
--color-back-opposite: white;
|
||||
|
||||
--color-hover: black;
|
||||
--color-hover-back: white;
|
||||
|
||||
/*--color-back-active: hsl(240, 10%, 20%);*/
|
||||
/*--color-link: hsl(240, 10%, 40%);*/
|
||||
/*--color-link-opposite: hsl(240, 10%, 60%);*/
|
||||
}
|
||||
|
||||
--color-hover: white;
|
||||
--color-hover-back: white;
|
||||
.theme-contrast.blue-on-blue {
|
||||
--color-text: oklch(32% 24% 253deg);
|
||||
--color-text-second: oklch(32% 24% 253deg);
|
||||
--color-text-opposite: oklch(84% 21% 245deg);
|
||||
--color-back-main: oklch(84% 21% 245deg);
|
||||
--color-back: oklch(84% 21% 245deg);
|
||||
--color-back-opposite: oklch(32% 24% 253deg);
|
||||
|
||||
--color-hover: oklch(84% 21% 245deg);
|
||||
--color-hover-back: oklch(32% 24% 253deg);
|
||||
|
||||
/*--color-back-active: hsl(240, 10%, 20%);*/
|
||||
/*--color-link: hsl(240, 10%, 40%);*/
|
||||
/*--color-link-opposite: hsl(240, 10%, 60%);*/
|
||||
}
|
||||
|
||||
.theme-contrast.brown-on-yellow {
|
||||
--color-text: oklch(41% 3% 92deg);
|
||||
--color-text-second: oklch(41% 3% 92deg);
|
||||
--color-text-opposite: oklch(96% 9% 101deg);
|
||||
--color-back-main: oklch(96% 9% 101deg);
|
||||
--color-back: oklch(96% 9% 101deg);
|
||||
--color-back-opposite: oklch(41% 3% 92deg);
|
||||
|
||||
--color-hover: oklch(96% 9% 101deg);
|
||||
--color-hover-back: oklch(41% 3% 92deg);
|
||||
|
||||
/*--color-back-active: hsl(240, 10%, 20%);*/
|
||||
/*--color-link: hsl(240, 10%, 40%);*/
|
||||
/*--color-link-opposite: hsl(240, 10%, 60%);*/
|
||||
}
|
||||
|
||||
.theme-contrast.green-on-brown {
|
||||
--color-text: oklch(85% 47% 128deg);
|
||||
--color-text-second: oklch(85% 47% 128deg);
|
||||
--color-text-opposite: oklch(29% 10% 61deg);
|
||||
--color-back-main: oklch(29% 10% 61deg);
|
||||
--color-back: oklch(29% 10% 61deg);
|
||||
--color-back-opposite: oklch(85% 47% 128deg);
|
||||
|
||||
--color-hover: oklch(29% 10% 61deg);
|
||||
--color-hover-back: oklch(85% 47% 128deg);
|
||||
|
||||
/*--color-back-active: hsl(240, 10%, 20%);*/
|
||||
/*--color-link: hsl(240, 10%, 40%);*/
|
||||
/*--color-link-opposite: hsl(240, 10%, 60%);*/
|
||||
}
|
||||
|
||||
.theme-contrast.no-images img {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*.theme-contrast.no-images img:after {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid black;
|
||||
}*/
|
||||
@@ -1,17 +0,0 @@
|
||||
import { useLocalStorage } from "react-use"
|
||||
import { ThemeContext } from "./ThemeContext"
|
||||
import { ThemeType } from "./types"
|
||||
|
||||
export type ThemeProps = {
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
export const Theme: React.FC<ThemeProps> = ({ children }) => {
|
||||
const [theme, setTheme] = useLocalStorage<ThemeType>("hudozka-theme", "default")
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={[theme ?? "default", setTheme]}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import { createContext } from "react"
|
||||
import { SetTheme, ThemeType } from "./types"
|
||||
|
||||
export const ThemeContext = createContext<[ThemeType, SetTheme]>(["default", () => {}])
|
||||
@@ -1,2 +0,0 @@
|
||||
export type ThemeType = "default" | "contrast"
|
||||
export type SetTheme = (theme: ThemeType) => void
|
||||
@@ -1,15 +0,0 @@
|
||||
import { useContext } from "react"
|
||||
import { ThemeContext } from "./ThemeContext"
|
||||
import { SetTheme, ThemeType } from "./types"
|
||||
|
||||
export type UseThemeResult = {
|
||||
theme: ThemeType
|
||||
setTheme: SetTheme
|
||||
// toggleTheme:
|
||||
}
|
||||
|
||||
export function useTheme(): UseThemeResult {
|
||||
const [theme, setTheme] = useContext(ThemeContext)
|
||||
|
||||
return { theme, setTheme }
|
||||
}
|
||||
Reference in new issue
Block a user