diff --git a/package.json b/package.json index 5d6cb787..705b2696 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ } }, "dependencies": { + "color-rgba": "^2.3.0", "fs-extra": "^10.0.0", "klaw": "^3.0.0", "react-beautiful-dnd": "^13.1.0", @@ -95,6 +96,7 @@ "@traptitech/markdown-it-katex": "^3.4.3", "@traptitech/markdown-it-spoiler": "^1.1.6", "@trivago/prettier-plugin-sort-imports": "^2.0.2", + "@types/color-rgba": "^2.1.0", "@types/lodash.defaultsdeep": "^4.6.6", "@types/lodash.isequal": "^4.5.5", "@types/markdown-it": "^12.0.2", diff --git a/src/components/ui/Header.tsx b/src/components/ui/Header.tsx index 3492985a..f3b69134 100644 --- a/src/components/ui/Header.tsx +++ b/src/components/ui/Header.tsx @@ -31,8 +31,10 @@ const Header = styled.div` align-items: center; background-size: cover !important; background-position: center !important; - //background-color: var(--primary-header); - background-color: rgba(54, 54, 54, 0.75); + background-color: rgba( + var(--primary-header-rgb), + max(var(--min-opacity), 0.75) + ); backdrop-filter: blur(10px); z-index: 20; position: absolute; diff --git a/src/context/Theme.tsx b/src/context/Theme.tsx index e5697881..c30fbbd0 100644 --- a/src/context/Theme.tsx +++ b/src/context/Theme.tsx @@ -1,3 +1,4 @@ +import rgba from "color-rgba"; import { observer } from "mobx-react-lite"; import { Helmet } from "react-helmet"; import { createGlobalStyle } from "styled-components"; @@ -71,6 +72,8 @@ export type Theme = Overrides & { font?: Fonts; css?: string; monospaceFont?: MonospaceFonts; + + "min-opacity"?: number; }; export interface ThemeOptions { @@ -287,7 +290,13 @@ const GlobalTheme = createGlobalStyle<{ theme: Theme }>` export const generateVariables = (theme: Theme) => { return (Object.keys(theme) as Variables[]).map((key) => { - return `--${key}: ${theme[key]};`; + const colour = rgba(theme[key]); + if (colour) { + const [r, g, b] = colour; + return `--${key}: ${theme[key]}; --${key}-rgb: ${r}, ${g}, ${b};`; + } else { + return `--${key}: ${theme[key]};`; + } }); }; diff --git a/src/mobx/stores/helpers/STheme.ts b/src/mobx/stores/helpers/STheme.ts index b2b20c4c..4a110e56 100644 --- a/src/mobx/stores/helpers/STheme.ts +++ b/src/mobx/stores/helpers/STheme.ts @@ -1,3 +1,4 @@ +import rgba from "color-rgba"; import { makeAutoObservable, computed, action } from "mobx"; import { @@ -93,13 +94,15 @@ export default class STheme { ...PRESETS[this.getBase()], ...this.settings.get("appearance:theme:overrides"), light: this.isLight(), + + "min-opacity": 1, }; } @computed computeVariables(): Theme { const variables = this.getVariables() as Record< string, - string | boolean + string | boolean | number >; for (const key of Object.keys(variables)) { @@ -204,15 +207,11 @@ export default class STheme { function getContrastingColour(hex: string, fallback?: string): string { if (typeof hex !== "string") return "black"; - // TODO: Switch to color-parse - // Try parse hex value. - hex = hex.replace(/#/g, ""); - const r = parseInt(hex.substr(0, 2), 16) / 255; - const g = parseInt(hex.substr(2, 2), 16) / 255; - const b = parseInt(hex.substr(4, 2), 16) / 255; + const colour = rgba(hex); + if (!colour) return fallback ? getContrastingColour(fallback) : "black"; - if (isNaN(r) || isNaN(g) || isNaN(b)) - return fallback ? getContrastingColour(fallback) : "black"; - - return r * 0.299 + g * 0.587 + b * 0.114 >= 0.186 ? "black" : "white"; + const [r, g, b] = colour; + return (r / 255) * 0.299 + (g / 255) * 0.587 + (b / 255) * 0.114 >= 0.186 + ? "black" + : "white"; } diff --git a/yarn.lock b/yarn.lock index 688dfdfb..d07ef105 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1303,6 +1303,11 @@ javascript-natural-sort "0.7.1" lodash "4.17.21" +"@types/color-rgba@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/color-rgba/-/color-rgba-2.1.0.tgz#0182795370deae5c2c62f71ea6e91c6bab87394d" + integrity sha512-tWcJLEiKdZ3ihJdThfLCe6Kw5vo0lgGcuucGkbtzcp1zifDA1E2Z96wxeSS/r+ytpHD15NCAWabX8GV911ywCA== + "@types/debug@^4.1.6": version "4.1.7" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" @@ -1642,6 +1647,11 @@ ajv@^8.0.1, ajv@^8.6.0: require-from-string "^2.0.2" uri-js "^4.2.2" +almost-equal@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/almost-equal/-/almost-equal-1.1.0.tgz#f851c631138757994276aa2efbe8dfa3066cccdd" + integrity sha1-+FHGMROHV5lCdqou++jfowZszN0= + ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -1934,11 +1944,34 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-parse@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/color-parse/-/color-parse-1.4.2.tgz#78651f5d34df1a57f997643d86f7f87268ad4eb5" + integrity sha512-RI7s49/8yqDj3fECFZjUI1Yi0z/Gq1py43oNJivAIIDSyJiOZLfYCRQEgn8HEVAj++PcRe8AnL2XF0fRJ3BTnA== + dependencies: + color-name "^1.0.0" + +color-rgba@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/color-rgba/-/color-rgba-2.3.0.tgz#d5eb481d7933d2542d1f222ea10ad40d159e9d35" + integrity sha512-z/5fMOY8/IzrBHPBk+n3ATNSM/1atXcHCRPTGPLlzYJ4fn7CRD46zzt3lkLtQ44cL8UIUU4JBXDVrhWj1khiwg== + dependencies: + color-parse "^1.4.1" + color-space "^1.14.6" + +color-space@^1.14.6: + version "1.16.0" + resolved "https://registry.yarnpkg.com/color-space/-/color-space-1.16.0.tgz#611781bca41cd8582a1466fd9e28a7d3d89772a2" + integrity sha512-A6WMiFzunQ8KEPFmj02OnnoUnqhmSaHaZ/0LVFcPTdlvm8+3aMJ5x1HRHy3bDHPkovkf4sS0f4wsVvwk71fKkg== + dependencies: + hsluv "^0.0.3" + mumath "^3.3.4" + colorette@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.3.0.tgz#ff45d2f0edb244069d3b772adeb04fed38d0a0af" @@ -2742,6 +2775,11 @@ hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react- dependencies: react-is "^16.7.0" +hsluv@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/hsluv/-/hsluv-0.0.3.tgz#829107dafb4a9f8b52a1809ed02e091eade6754c" + integrity sha1-gpEH2vtKn4tSoYCe0C4JHq3mdUw= + idb@^6.0.0: version "6.1.2" resolved "https://registry.yarnpkg.com/idb/-/idb-6.1.2.tgz#82ef5c951b8e1f47875d36ccafa4bedafc62f2f1" @@ -3276,6 +3314,13 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +mumath@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/mumath/-/mumath-3.3.4.tgz#48d4a0f0fd8cad4e7b32096ee89b161a63d30bbf" + integrity sha1-SNSg8P2MrU57Mglu6JsWGmPTC78= + dependencies: + almost-equal "^1.1.0" + nanoid@^3.1.30: version "3.1.30" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"