add initial accessibility panel
This commit is contained in:
1 parent
605ff872e8
commit
85c0d8c4ab
15 files changed
+764
-56
No files matched your search
Generated
+51
-7
@@ -24,7 +24,8 @@
|
|||||||
"sharp": "^0.32.6",
|
"sharp": "^0.32.6",
|
||||||
"sitemap": "^1.5.0",
|
"sitemap": "^1.5.0",
|
||||||
"typograf": "^6.11.1",
|
"typograf": "^6.11.1",
|
||||||
"use-media": "^1.4.0"
|
"use-media": "^1.4.0",
|
||||||
|
"valtio": "^2.1.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3.3.1",
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
@@ -1268,13 +1269,13 @@
|
|||||||
"version": "15.7.5",
|
"version": "15.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||||
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
|
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.0.18",
|
"version": "18.0.18",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz",
|
||||||
"integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==",
|
"integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
"@types/scheduler": "*",
|
||||||
@@ -1285,7 +1286,7 @@
|
|||||||
"version": "0.16.2",
|
"version": "0.16.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
|
||||||
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
|
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/sharp": {
|
"node_modules/@types/sharp": {
|
||||||
"version": "0.29.2",
|
"version": "0.29.2",
|
||||||
@@ -4735,6 +4736,12 @@
|
|||||||
"react-is": "^16.13.1"
|
"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": {
|
"node_modules/pump": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||||
@@ -5911,6 +5918,30 @@
|
|||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"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": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
@@ -6778,13 +6809,13 @@
|
|||||||
"version": "15.7.5",
|
"version": "15.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||||
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
|
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"@types/react": {
|
"@types/react": {
|
||||||
"version": "18.0.18",
|
"version": "18.0.18",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.18.tgz",
|
||||||
"integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==",
|
"integrity": "sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
"@types/scheduler": "*",
|
||||||
@@ -6795,7 +6826,7 @@
|
|||||||
"version": "0.16.2",
|
"version": "0.16.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
|
||||||
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
|
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
|
||||||
"dev": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"@types/sharp": {
|
"@types/sharp": {
|
||||||
"version": "0.29.2",
|
"version": "0.29.2",
|
||||||
@@ -9131,6 +9162,11 @@
|
|||||||
"react-is": "^16.13.1"
|
"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": {
|
"pump": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||||
@@ -9951,6 +9987,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"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": {
|
"which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
|||||||
+2
-1
@@ -34,7 +34,8 @@
|
|||||||
"sharp": "^0.32.6",
|
"sharp": "^0.32.6",
|
||||||
"sitemap": "^1.5.0",
|
"sitemap": "^1.5.0",
|
||||||
"typograf": "^6.11.1",
|
"typograf": "^6.11.1",
|
||||||
"use-media": "^1.4.0"
|
"use-media": "^1.4.0",
|
||||||
|
"valtio": "^2.1.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3.3.1",
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
|
|||||||
+1
-4
@@ -8,7 +8,6 @@ import App from "next/app"
|
|||||||
import Head from "next/head"
|
import Head from "next/head"
|
||||||
import Script from "next/script"
|
import Script from "next/script"
|
||||||
import { YMetrika } from "src/components/YMetrika"
|
import { YMetrika } from "src/components/YMetrika"
|
||||||
import { Theme } from "@/ui/theme/Theme"
|
|
||||||
import { ThemeColor } from "@/ui/ThemeColor"
|
import { ThemeColor } from "@/ui/ThemeColor"
|
||||||
|
|
||||||
export default class MyApp extends App {
|
export default class MyApp extends App {
|
||||||
@@ -51,9 +50,7 @@ export default class MyApp extends App {
|
|||||||
</Head>
|
</Head>
|
||||||
<Script src="https://culturaltracking.ru/static/js/spxl.js?pixelId=27154" data-pixel-id="27154"></Script>
|
<Script src="https://culturaltracking.ru/static/js/spxl.js?pixelId=27154" data-pixel-id="27154"></Script>
|
||||||
|
|
||||||
<Theme>
|
<Component {...pageProps} />
|
||||||
<Component {...pageProps} />
|
|
||||||
</Theme>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
|
import { theme, toggleTheme } from "@/store/theme"
|
||||||
import { Button } from "@/ui/Button"
|
import { Button } from "@/ui/Button"
|
||||||
import { HiOutlineEye, HiOutlineEyeOff } from "react-icons/hi"
|
import { HiOutlineEye, HiOutlineEyeOff } from "react-icons/hi"
|
||||||
import { useTheme } from "@/ui/theme/useTheme"
|
import { useSnapshot } from "valtio"
|
||||||
|
|
||||||
export function AccessibilityButton() {
|
export function AccessibilityButton() {
|
||||||
const { theme, setTheme } = useTheme()
|
const t = useSnapshot(theme)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
theme="icon"
|
theme="icon"
|
||||||
size="default"
|
size="default"
|
||||||
onClick={() => {
|
onClick={toggleTheme}
|
||||||
setTheme(theme === "default" ? "contrast" : "default")
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{theme === "default" ? (
|
{t.theme === "default" ? (
|
||||||
<HiOutlineEyeOff size={24} />
|
<HiOutlineEyeOff size={24} />
|
||||||
) : (
|
) : (
|
||||||
<HiOutlineEye size={24} />
|
<HiOutlineEye size={24} />
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import { decreaseFontSize, hideImages, increaseFontSize, reset, setBlackOnWhite, setBlueOnBlue, setBrownOnYellow, setDefaultTheme, setGreenOnBrown, setLetterSpacingOne, setLetterSpacingTwo, setLetterSpacingFour, setLineHeightOneAndHalf, setLineHeightTwo, setLineHeightTwoAndHalf, setSansFont, setSerifFont, setWhiteOnBlack, showImages } from "@/store/theme"
|
||||||
|
import s from "./panel.module.css"
|
||||||
|
|
||||||
|
function AccessibilityPanel() {
|
||||||
|
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={setSansFont}>С засечками</a>
|
||||||
|
<a onClick={setSerifFont}>Без засечек</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}>
|
||||||
|
<a onClick={reset}><i className="fa fa-cog fa-fw"></i>Сброс настроек</a>
|
||||||
|
{/*<a id="mobile-version" href="?mobile=1"><i className="fa fa-mobile fa-fw"></i> Мобильная версия</a>*/}
|
||||||
|
<a onClick={setDefaultTheme}><i className="fa fa-eye-slash fa-fw"></i>Обычная версия</a>
|
||||||
|
{/*<a id="_playlist" href="javascript:void(0)" onClick="playSound('all', this);"><i className="fa fa-play fa-fw"></i>Прослушать всё</a>*/}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AccessibilityPanel
|
||||||
@@ -0,0 +1,433 @@
|
|||||||
|
/*body {
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
width: 96%;
|
||||||
|
padding-top: 90px;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
.viewsettings {
|
||||||
|
background: white;
|
||||||
|
z-index: 10;
|
||||||
|
display: block;
|
||||||
|
/*width: 96%;*/
|
||||||
|
font-size: 20px !important;
|
||||||
|
line-height: 30px;
|
||||||
|
font-family: sans-serif, arial;
|
||||||
|
letter-spacing: normal !important;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
margin: 10px;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
border: 2px solid;
|
||||||
|
/*border-right: 2px solid;
|
||||||
|
border-bottom: 2px solid;
|
||||||
|
border-bottom-right-radius: 25px;
|
||||||
|
border-bottom-left-radius: 25px;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewsettings .row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
margin: 8px 0;
|
||||||
|
}
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainContent {
|
||||||
|
padding-top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedback label {
|
||||||
|
display: block;
|
||||||
|
margin: 16px 0 0 0;
|
||||||
|
}
|
||||||
|
.feedback input {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
.feedback textarea {
|
||||||
|
width: 50%;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
.feedback input[name="agree"] {
|
||||||
|
display: block;
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
#captcha {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.line_1_5 {
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
body.line_2_0 {
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
body.line_2_5 {
|
||||||
|
line-height: 2.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.letter_spacing1 {
|
||||||
|
letter-spacing: normal;
|
||||||
|
}
|
||||||
|
.letter_spacing2 {
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
.letter_spacing4 {
|
||||||
|
letter-spacing: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btn-black-text {
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
#btn-white-text {
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
#btn-blue-text {
|
||||||
|
background-color: #9dd1ff;
|
||||||
|
color: #063462;
|
||||||
|
}
|
||||||
|
#btn-sand-text {
|
||||||
|
background-color: #f7f3d6;
|
||||||
|
color: #4d4b43;
|
||||||
|
}
|
||||||
|
#btn-brown-text {
|
||||||
|
background-color: #3b2716;
|
||||||
|
color: #a9e44d;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.imageOff #btn-hide-images,
|
||||||
|
body.imageOff img {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
body.imageOn #btn-show-images {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.brailleOff #btn-off-braille {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
body.brailleOn #btn-on-braille {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
body.brailleOn {
|
||||||
|
font-family: "Kanischev_Braille" !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.noSerif #btn-font-sans {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
body.noSerif {
|
||||||
|
font-family: sans-serif, Arial;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.sans #btn-font-serif {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
body.sans {
|
||||||
|
font-family: serif, "Times New Roman";
|
||||||
|
}
|
||||||
|
|
||||||
|
body.BlackOnWhite {
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
body.BlackOnWhite a:link,
|
||||||
|
body.BlackOnWhite a:visited,
|
||||||
|
body.BlackOnWhite .viewsettings .block,
|
||||||
|
body.BlackOnWhite .viewsettings,
|
||||||
|
body.BlackOnWhite .additional_text,
|
||||||
|
body.BlackOnWhite .img-wrp::after,
|
||||||
|
body.BlackOnWhite .date {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
body.BlackOnWhite a#active {
|
||||||
|
color: white;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
body.BlackOnWhite .image_placeholder {
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
body.BlackOnWhite a:focus,
|
||||||
|
body.BlackOnWhite input:focus,
|
||||||
|
body.BlackOnWhite textarea:focus,
|
||||||
|
body.BlackOnWhite #attach_cont:focus,
|
||||||
|
body.BlackOnWhite button:focus {
|
||||||
|
outline: #000 solid 5px;
|
||||||
|
}
|
||||||
|
body.BlackOnWhite button,
|
||||||
|
body.BlackOnWhite input,
|
||||||
|
body.BlackOnWhite textarea {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #000;
|
||||||
|
border: 1px solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.WhiteOnBlack {
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
body.WhiteOnBlack a:link,
|
||||||
|
body.WhiteOnBlack a:visited,
|
||||||
|
body.WhiteOnBlack .viewsettings .block,
|
||||||
|
body.WhiteOnBlack .viewsettings,
|
||||||
|
body.WhiteOnBlack .additional_text,
|
||||||
|
body.WhiteOnBlack .img-wrp::after,
|
||||||
|
body.WhiteOnBlack .date {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
body.WhiteOnBlack a#active {
|
||||||
|
color: black;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
body.WhiteOnBlack .image_placeholder {
|
||||||
|
border: 1px solid white;
|
||||||
|
}
|
||||||
|
body.WhiteOnBlack a:focus,
|
||||||
|
body.WhiteOnBlack input:focus,
|
||||||
|
body.WhiteOnBlack textarea:focus,
|
||||||
|
body.WhiteOnBlack #attach_cont:focus,
|
||||||
|
body.WhiteOnBlack button:focus {
|
||||||
|
outline: #fff solid 5px;
|
||||||
|
}
|
||||||
|
body.WhiteOnBlack button,
|
||||||
|
body.BlackOnWhite input,
|
||||||
|
body.BlackOnWhite textarea {
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.BlueOnBlue {
|
||||||
|
background-color: #9dd1ff;
|
||||||
|
color: #063462;
|
||||||
|
}
|
||||||
|
body.BlueOnBlue a:link,
|
||||||
|
body.BlueOnBlue a:visited,
|
||||||
|
body.BlueOnBlue .viewsettings .block,
|
||||||
|
body.BlueOnBlue .viewsettings,
|
||||||
|
body.BlueOnBlue .additional_text,
|
||||||
|
body.BlueOnBlue .img-wrp::after,
|
||||||
|
body.BlueOnBlue .date {
|
||||||
|
color: #063462;
|
||||||
|
}
|
||||||
|
body.BlueOnBlue a#active {
|
||||||
|
color: #9dd1ff;
|
||||||
|
background-color: #063462;
|
||||||
|
}
|
||||||
|
body.BlueOnBlue .image_placeholder {
|
||||||
|
border: 1px solid #063462;
|
||||||
|
}
|
||||||
|
body.BlueOnBlue a:focus,
|
||||||
|
body.BlueOnBlue input:focus,
|
||||||
|
body.BlueOnBlue textarea:focus,
|
||||||
|
body.BlueOnBlue #attach_cont:focus,
|
||||||
|
body.BlueOnBlue button:focus {
|
||||||
|
outline: #063462 solid 5px;
|
||||||
|
}
|
||||||
|
body.BlueOnBlue button,
|
||||||
|
body.BlueOnBlue input,
|
||||||
|
body.BlueOnBlue textarea {
|
||||||
|
background-color: #9dd1ff;
|
||||||
|
color: #063462;
|
||||||
|
border: 1px solid #063462;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.SandTheme {
|
||||||
|
background-color: #f7f3d6;
|
||||||
|
color: #4d4b43;
|
||||||
|
}
|
||||||
|
body.SandTheme a:link,
|
||||||
|
body.SandTheme a:visited,
|
||||||
|
body.SandTheme .viewsettings .block,
|
||||||
|
body.SandTheme .viewsettings,
|
||||||
|
body.SandTheme .additional_text,
|
||||||
|
body.SandTheme .img-wrp::after,
|
||||||
|
body.SandTheme .date {
|
||||||
|
color: #4d4b43;
|
||||||
|
}
|
||||||
|
body.SandTheme a#active {
|
||||||
|
color: #f7f3d6;
|
||||||
|
background-color: #4d4b43;
|
||||||
|
}
|
||||||
|
body.SandTheme .image_placeholder {
|
||||||
|
border: 1px solid #4d4b43;
|
||||||
|
}
|
||||||
|
body.SandTheme a:focus,
|
||||||
|
body.SandTheme input:focus,
|
||||||
|
body.SandTheme textarea:focus,
|
||||||
|
body.SandTheme #attach_cont:focus,
|
||||||
|
body.SandTheme button:focus {
|
||||||
|
outline: #4d4b43 solid 5px;
|
||||||
|
}
|
||||||
|
body.SandTheme button,
|
||||||
|
body.SandTheme input,
|
||||||
|
body.SandTheme textarea {
|
||||||
|
background-color: #f7f3d6;
|
||||||
|
color: #4d4b43;
|
||||||
|
border: 1px solid #4d4b43;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.BrownTheme {
|
||||||
|
background-color: #3b2716;
|
||||||
|
color: #a9e44d;
|
||||||
|
}
|
||||||
|
body.BrownTheme a:link,
|
||||||
|
body.BrownTheme a:visited,
|
||||||
|
body.BrownTheme .viewsettings .block,
|
||||||
|
body.BrownTheme .viewsettings,
|
||||||
|
body.BrownTheme .additional_text,
|
||||||
|
body.BrownTheme .img-wrp::after,
|
||||||
|
body.BrownTheme .date {
|
||||||
|
color: #a9e44d;
|
||||||
|
}
|
||||||
|
body.BrownTheme a#active {
|
||||||
|
color: #3b2716;
|
||||||
|
background-color: #a9e44d;
|
||||||
|
}
|
||||||
|
body.BrownTheme .image_placeholder {
|
||||||
|
border: 1px solid #a9e44d;
|
||||||
|
}
|
||||||
|
body.BrownTheme a:focus,
|
||||||
|
body.BrownTheme input:focus,
|
||||||
|
body.BrownTheme textarea:focus,
|
||||||
|
body.BrownTheme #attach_cont:focus,
|
||||||
|
body.BrownTheme button:focus {
|
||||||
|
outline: #a9e44d solid 5px;
|
||||||
|
}
|
||||||
|
body.BrownTheme button,
|
||||||
|
body.BrownTheme input,
|
||||||
|
body.BrownTheme textarea {
|
||||||
|
background-color: #3b2716;
|
||||||
|
color: #a9e44d;
|
||||||
|
border: 1px solid #a9e44d;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#navmenu-h li a {
|
||||||
|
padding: 0 6px 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news_list_item strong {
|
||||||
|
padding-bottom: 4px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.s-on {
|
||||||
|
background-position: 0 0;
|
||||||
|
}
|
||||||
|
.s-of {
|
||||||
|
background-position: 0 30px;
|
||||||
|
}
|
||||||
|
.image_alt {
|
||||||
|
width: 144px;
|
||||||
|
height: 144px;
|
||||||
|
border: 1px solid black;
|
||||||
|
font-size: 18px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery_album_thumbail {
|
||||||
|
display: block;
|
||||||
|
max-width: 150px;
|
||||||
|
max-height: 150px;
|
||||||
|
overflow: hidden;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#navmenu-h li a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
ul#navmenu-h li a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.additional_text {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 70%;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image_placeholder {
|
||||||
|
font-size: 70%;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 5px;
|
||||||
|
text-align: center;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow: hidden;
|
||||||
|
min-width: 100px;
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.play-button {
|
||||||
|
display: block;
|
||||||
|
min-width: 30px;
|
||||||
|
min-height: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#playlist {
|
||||||
|
float: right;
|
||||||
|
display: block;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
._afisha_table_content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-wrp {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-wrp::after {
|
||||||
|
content: attr(data-alt);
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 2;
|
||||||
|
font-size: 70%;
|
||||||
|
font-style: italic;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
@@ -10,7 +10,6 @@ import { useMobile } from "src/hooks/useMobile"
|
|||||||
import { Navigation } from "@/components/Navigation"
|
import { Navigation } from "@/components/Navigation"
|
||||||
import { Box } from "@/ui/Box"
|
import { Box } from "@/ui/Box"
|
||||||
import { AccessibilityButton } from "../AccessibilityButton"
|
import { AccessibilityButton } from "../AccessibilityButton"
|
||||||
import { useTheme } from "@/ui/theme/useTheme"
|
|
||||||
import { Copyright } from "../Copyright"
|
import { Copyright } from "../Copyright"
|
||||||
import { Spacer } from "../Spacer"
|
import { Spacer } from "../Spacer"
|
||||||
import { Author } from "../Author"
|
import { Author } from "../Author"
|
||||||
@@ -22,6 +21,7 @@ import dynamic from "next/dynamic"
|
|||||||
import qr0 from "src/assets/qr00.png"
|
import qr0 from "src/assets/qr00.png"
|
||||||
import qr1 from "src/assets/qr01.png"
|
import qr1 from "src/assets/qr01.png"
|
||||||
import Image from "next/image"
|
import Image from "next/image"
|
||||||
|
import AccessibilityPanel from "../AccessibilityPanel"
|
||||||
|
|
||||||
const Gosuslugi = dynamic(import("../Gosuslugi").then(module => module.Gosuslugi), {
|
const Gosuslugi = dynamic(import("../Gosuslugi").then(module => module.Gosuslugi), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
@@ -41,7 +41,6 @@ export const App: React.FC<AppProps> = ({ showAuthor = false, menu, ...props })
|
|||||||
const blockStyle = {
|
const blockStyle = {
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
}
|
}
|
||||||
const { theme, setTheme } = useTheme()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigContext.Provider value={{
|
<ConfigContext.Provider value={{
|
||||||
@@ -146,6 +145,8 @@ export const App: React.FC<AppProps> = ({ showAuthor = false, menu, ...props })
|
|||||||
</Footer>
|
</Footer>
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
<AccessibilityPanel/>
|
||||||
|
|
||||||
<Box style={blockStyle}>
|
<Box style={blockStyle}>
|
||||||
<Content style={props.contentStyle}>
|
<Content style={props.contentStyle}>
|
||||||
{props.children}
|
{props.children}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import s from "./wrapper.module.css"
|
import s from "./wrapper.module.css"
|
||||||
|
|
||||||
import cx from "classnames"
|
import cx from "classnames"
|
||||||
import { useTheme } from "@/ui/theme/useTheme"
|
import { useSnapshot } from "valtio"
|
||||||
|
import { theme } from "@/store/theme"
|
||||||
|
|
||||||
export type WrapperProps = {
|
export type WrapperProps = {
|
||||||
header: React.ReactNode
|
header: React.ReactNode
|
||||||
@@ -12,10 +13,10 @@ export type WrapperProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const Wrapper: React.FC<WrapperProps> = props => {
|
export const Wrapper: React.FC<WrapperProps> = props => {
|
||||||
const { theme } = useTheme()
|
const t = useSnapshot(theme)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx(s.container, `theme-${theme}`)} style={props.style}>
|
<div className={cx(s.container, `theme-${t.theme}`, !t.showImages ? "no-images" : null)} style={props.style}>
|
||||||
{props.header}
|
{props.header}
|
||||||
|
|
||||||
<main className={s.main} style={props.mainStyle}>
|
<main className={s.main} style={props.mainStyle}>
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
import { proxy, subscribe, useSnapshot } 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"
|
||||||
|
|
||||||
|
const MIN_FONT_SIZE = 8
|
||||||
|
const MAX_FONT_SIZE = 48
|
||||||
|
const CHANGE_FONT_SIZE_DELTA = 0.2
|
||||||
|
|
||||||
|
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: string
|
||||||
|
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: "Times New Roman",
|
||||||
|
showImages: true,
|
||||||
|
colorScheme: "black-on-white",
|
||||||
|
})
|
||||||
|
|
||||||
|
export function reset() {
|
||||||
|
theme.fontSize = 14
|
||||||
|
theme.lineHeight = 1.5
|
||||||
|
theme.letterSpacing = 1
|
||||||
|
theme.fontType = "Times New Roman"
|
||||||
|
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 setSerifFont() {
|
||||||
|
theme.fontType = "sans-serif"
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setSansFont() {
|
||||||
|
theme.fontType = "Times New Roman"
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
function getColor(scheme: ColorSchemeVariant): [string, string] {
|
||||||
|
switch (theme.colorScheme) {
|
||||||
|
case "black-on-white":
|
||||||
|
return ["black", "white"]
|
||||||
|
case "white-on-black":
|
||||||
|
return ["white", "black"]
|
||||||
|
case "blue-on-blue":
|
||||||
|
return ["oklch(32% 24% 253deg)", "oklch(84% 21% 245deg)"]
|
||||||
|
case "brown-on-yellow":
|
||||||
|
return ["oklch(41% 3% 92deg)", "oklch(96% 9% 101deg)"]
|
||||||
|
case "green-on-brown":
|
||||||
|
return ["oklch(85% 47% 128deg)", "oklch(29% 10% 61deg)"]
|
||||||
|
default:
|
||||||
|
return ["black", "white"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsubscribe = subscribe(theme, () => {
|
||||||
|
document.documentElement.style.setProperty("--font-size-default", `${theme.fontSize}pt`)
|
||||||
|
|
||||||
|
document.documentElement.style.setProperty("--title-font", theme.fontType)
|
||||||
|
document.documentElement.style.setProperty("--text-font", theme.fontType)
|
||||||
|
|
||||||
|
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`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const [t, b] = getColor(theme.colorScheme)
|
||||||
|
document.documentElement.style.setProperty("--color-text", t)
|
||||||
|
document.documentElement.style.setProperty("--color-text-second", t)
|
||||||
|
document.documentElement.style.setProperty("--color-text-opposite", b)
|
||||||
|
document.documentElement.style.setProperty("--color-back-main", b)
|
||||||
|
document.documentElement.style.setProperty("--color-back", b)
|
||||||
|
})
|
||||||
+23
-9
@@ -21,6 +21,8 @@
|
|||||||
--font-size-h2: 3rem;
|
--font-size-h2: 3rem;
|
||||||
--font-size-h3: 1.5rem;
|
--font-size-h3: 1.5rem;
|
||||||
|
|
||||||
|
--letter-spacing: normal;
|
||||||
|
|
||||||
/* COLOR */
|
/* COLOR */
|
||||||
--color-text: hsl(0, 0%, 15%);
|
--color-text: hsl(0, 0%, 15%);
|
||||||
--color-text-second: hsl(240, 10%, 60%);
|
--color-text-second: hsl(240, 10%, 60%);
|
||||||
@@ -89,6 +91,7 @@ body {
|
|||||||
background-color: var(--color-back-main);
|
background-color: var(--color-back-main);
|
||||||
|
|
||||||
font-family: var(--text-font);
|
font-family: var(--text-font);
|
||||||
|
letter-spacing: var(--letter-spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TITLE */
|
/* TITLE */
|
||||||
@@ -168,21 +171,19 @@ h3 {
|
|||||||
/* CONTRAST THEME */
|
/* CONTRAST THEME */
|
||||||
.theme-contrast {
|
.theme-contrast {
|
||||||
/* FONTS */
|
/* FONTS */
|
||||||
--title-font: 'Roboto', Helvetica, sans-serif;
|
/*--title-font: "Roboto", Helvetica, sans-serif;*/
|
||||||
--text-font: 'Roboto', Helvetica, sans-serif;
|
/*--text-font: "Roboto", Helvetica, sans-serif;*/
|
||||||
|
|
||||||
/* TEXT COLOR */
|
/* TEXT COLOR */
|
||||||
--color-text: black;
|
/*--color-text: black;
|
||||||
--color-text-second: black;
|
--color-text-second: black;
|
||||||
--color-text-opposite: white;
|
--color-text-opposite: white;
|
||||||
|
|
||||||
--color-back-main: white;
|
--color-back-main: white;
|
||||||
--color-back: white;
|
--color-back: white;
|
||||||
--color-back-active: hsl(240, 10%, 20%);
|
--color-back-active: hsl(240, 10%, 20%);
|
||||||
/* --color-back-opposite: hsl(240, 10%, 80%); */
|
|
||||||
--color-back-opposite: black;
|
--color-back-opposite: black;
|
||||||
--color-link: hsl(240, 10%, 40%);
|
--color-link: hsl(240, 10%, 40%);
|
||||||
--color-link-opposite: hsl(240, 10%, 60%);
|
--color-link-opposite: hsl(240, 10%, 60%);*/
|
||||||
|
|
||||||
--color-hover: white;
|
--color-hover: white;
|
||||||
--color-hover-back: black;
|
--color-hover-back: black;
|
||||||
@@ -193,9 +194,9 @@ h3 {
|
|||||||
--shadow-active: none;
|
--shadow-active: none;
|
||||||
|
|
||||||
/* FONTS */
|
/* FONTS */
|
||||||
--font-size-default: 16pt;
|
/*--font-size-default: 16pt;*/
|
||||||
--font-size-accent: 24pt;
|
/*--font-size-accent: 24pt;*/
|
||||||
--font-size-second: 14pt;
|
/*--font-size-second: 14pt;*/
|
||||||
|
|
||||||
--font-size-h1: 5rem;
|
--font-size-h1: 5rem;
|
||||||
--font-size-h2: 3rem;
|
--font-size-h2: 3rem;
|
||||||
@@ -207,6 +208,19 @@ h3 {
|
|||||||
--border: 5px solid var(--color-back-opposite);
|
--border: 5px solid var(--color-back-opposite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-contrast.no-images img {
|
||||||
|
display: none;
|
||||||
|
/*opacity: 0.5;*/
|
||||||
|
/*position: relative;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*.theme-contrast.no-images img:after {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 1px solid black;
|
||||||
|
}*/
|
||||||
|
|
||||||
/* CONTRAST + DARK THEME */
|
/* CONTRAST + DARK THEME */
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.theme-contrast {
|
.theme-contrast {
|
||||||
|
|||||||
@@ -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 +1,5 @@
|
|||||||
import { createContext } from "react"
|
import { createContext } from "react"
|
||||||
import { SetTheme, ThemeType } from "./types"
|
import { DEFAULT } from "./const"
|
||||||
|
import { SetTheme, ThemeOptions } from "./types"
|
||||||
|
|
||||||
export const ThemeContext = createContext<[ThemeType, SetTheme]>(["default", () => {}])
|
export const ThemeContext = createContext<[ThemeOptions, SetTheme]>([DEFAULT, () => {}])
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { ThemeOptions } from "./types"
|
||||||
|
|
||||||
|
export const DEFAULT: ThemeOptions = {
|
||||||
|
theme: "default",
|
||||||
|
}
|
||||||
@@ -1,2 +1,5 @@
|
|||||||
export type ThemeType = "default" | "contrast"
|
export type ThemeOptions = {
|
||||||
export type SetTheme = (theme: ThemeType) => void
|
theme: "default" | "contrast"
|
||||||
|
fontSize?: number
|
||||||
|
}
|
||||||
|
export type SetTheme = (theme: ThemeOptions["theme"]) => void
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { useContext } from "react"
|
import { useContext } from "react"
|
||||||
import { ThemeContext } from "./ThemeContext"
|
import { ThemeContext } from "./ThemeContext"
|
||||||
import { SetTheme, ThemeType } from "./types"
|
import { SetTheme, ThemeOptions } from "./types"
|
||||||
|
|
||||||
export type UseThemeResult = {
|
export type UseThemeResult = {
|
||||||
theme: ThemeType
|
theme: ThemeOptions["theme"]
|
||||||
setTheme: SetTheme
|
setTheme: SetTheme
|
||||||
// toggleTheme:
|
// toggleTheme:
|
||||||
}
|
}
|
||||||
@@ -11,5 +11,8 @@ export type UseThemeResult = {
|
|||||||
export function useTheme(): UseThemeResult {
|
export function useTheme(): UseThemeResult {
|
||||||
const [theme, setTheme] = useContext(ThemeContext)
|
const [theme, setTheme] = useContext(ThemeContext)
|
||||||
|
|
||||||
return { theme, setTheme }
|
return {
|
||||||
|
setTheme,
|
||||||
|
theme: theme.theme ?? "default",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user