Skip to content

Commit c66b7a3

Browse files
feat(frontend): use theme color based on color scheme
1 parent f2537c0 commit c66b7a3

File tree

4 files changed

+50
-3
lines changed

4 files changed

+50
-3
lines changed

packages/frontend/layouts/default.njk

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
<link rel="manifest" href="{{ application.url }}/app.webmanifest">
5555

5656
<meta name="supported-color-schemes" content="light dark">
57+
<meta name="theme-color" content="{{ themeColor(application.themeColor) }}" media="(prefers-color-scheme: light)">
58+
<meta name="theme-color" content="{{ themeColor(application.themeColor, "dark") }}" media="(prefers-color-scheme: dark)">
5759
</head>
5860

5961
<body class="{{ appClasses }}">

packages/frontend/lib/globals/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ export { fieldData } from "./field-data.js";
55
export { icon } from "./icon.js";
66
export { itemId } from "./item-id.js";
77
export { summaryRows } from "./summary-rows.js";
8-
export { themeCustomProperties } from "./theme.js";
8+
export { backgroundColor, themeColor, themeCustomProperties } from "./theme.js";

packages/frontend/lib/globals/theme.js

+35-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,39 @@ export const _getValidatedColor = ({
3838
return newColor;
3939
};
4040

41+
/**
42+
* Return background color
43+
* @param {string} string - Color (as hexadecimal)
44+
* @param {string} colorScheme - Color scheme
45+
* @returns {string} CSS color value (HSL)
46+
*/
47+
export const backgroundColor = (string, colorScheme = "light") => {
48+
const primary = new Color(string).hsl().round();
49+
50+
return new Color({
51+
h: primary.hue(),
52+
s: 5,
53+
l: colorScheme === "light" ? 99 : 10,
54+
})
55+
.hsl()
56+
.toString();
57+
};
58+
59+
/**
60+
* Return theme color
61+
* @param {string} string - Color (as hexadecimal)
62+
* @param {string} colorScheme - Color scheme
63+
* @returns {string} CSS color value (HSL)
64+
*/
65+
export const themeColor = (string, colorScheme = "light") => {
66+
const primary = new Color(string).hsl().round();
67+
const h = primary.hue();
68+
const s = 5;
69+
const l = colorScheme === "light" ? 95 : 20;
70+
71+
return new Color({ h, s, l }).hsl().toString();
72+
};
73+
4174
/**
4275
* Return theme color as CSS custom properties
4376
* @param {string} string - Color (as hexadecimal)
@@ -49,8 +82,8 @@ export const themeCustomProperties = (string) => {
4982
const primarySaturation = 5;
5083

5184
// Calculate neutral lightest and darkest hues used in custom properties
52-
const neutral99 = new Color({ h: primaryHue, s: primarySaturation, l: 99 });
53-
const neutral10 = new Color({ h: primaryHue, s: primarySaturation, l: 10 });
85+
const neutral99 = new Color(backgroundColor(string));
86+
const neutral10 = new Color(backgroundColor(string, "dark"));
5487

5588
// Generate a darker variant of primary colour
5689
const primaryVariant = primary.darken(0.15).desaturate(0.1);

packages/frontend/test/unit/globals/theme.js

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { describe, it } from "node:test";
33
import Color from "color";
44
import {
55
_getValidatedColor,
6+
backgroundColor,
7+
themeColor,
68
themeCustomProperties,
79
} from "../../../lib/globals/theme.js";
810

@@ -16,6 +18,16 @@ describe("frontend/lib/globals/icon", () => {
1618
assert.equal(result.hex(), "#800080");
1719
});
1820

21+
it("Returns background color as HSL", () => {
22+
assert.equal(backgroundColor("#f00"), "hsl(0, 5%, 99%)");
23+
assert.equal(backgroundColor("#f00", "dark"), "hsl(0, 5%, 10%)");
24+
});
25+
26+
it("Returns theme color as HSL", () => {
27+
assert.equal(themeColor("#f00"), "hsl(0, 5%, 95%)");
28+
assert.equal(themeColor("#f00", "dark"), "hsl(0, 5%, 20%)");
29+
});
30+
1931
it("Returns theme color as CSS custom properties", () => {
2032
assert.equal(
2133
themeCustomProperties("#f00"),

0 commit comments

Comments
 (0)