feat: add complete light and dark presets

This commit is contained in:
Simo committed 2026-07-12 14:45:11 +02:00
1 parent a550b06a58
commit 48c596cf41
2 files changed
+110 -21

No files matched your search

+33 -20
View File
@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import { contrastRatio, derivePublicForegrounds, readableColor } from "@/lib/theme-contrast";
import { PRESETS } from "@/lib/theme-presets";
import { PRESETS, THEME_COLOR_KEYS } from "@/lib/theme-presets";
describe("contrastRatio", () => {
it("calculates the WCAG ratio for black on white", () => {
@@ -13,27 +13,38 @@ describe("contrastRatio", () => {
});
describe("built-in theme presets", () => {
it("defines every theme color in light and dark mode", () => {
for (const preset of Object.values(PRESETS)) {
expect(Object.keys(preset).sort()).toEqual(["dark", "light"]);
for (const palette of [preset.light, preset.dark]) {
expect(Object.keys(palette).sort()).toEqual([...THEME_COLOR_KEYS].sort());
}
}
});
it("derives WCAG-readable public foregrounds for every palette", () => {
for (const preset of Object.values(PRESETS)) {
const backgrounds = [preset.color_background, preset.color_surface];
const foregrounds = [
readableColor(preset.color_text, backgrounds),
readableColor(preset.color_text_muted, backgrounds),
readableColor(preset.color_primary, backgrounds),
readableColor(preset.color_accent, backgrounds),
];
for (const palette of [preset.light, preset.dark]) {
const backgrounds = [palette.color_background, palette.color_surface];
const foregrounds = [
readableColor(palette.color_text, backgrounds),
readableColor(palette.color_text_muted, backgrounds),
readableColor(palette.color_primary, backgrounds),
readableColor(palette.color_accent, backgrounds),
];
for (const foreground of foregrounds) {
for (const background of backgrounds) {
expect(contrastRatio(foreground, background)).toBeGreaterThanOrEqual(4.5);
for (const foreground of foregrounds) {
for (const background of backgrounds) {
expect(contrastRatio(foreground, background)).toBeGreaterThanOrEqual(4.5);
}
}
const buttonText = readableColor(palette.button_text_color, [palette.button_primary_color]);
expect(contrastRatio(buttonText, palette.button_primary_color)).toBeGreaterThanOrEqual(4.5);
const primaryForeground = readableColor(palette.button_text_color, [palette.color_primary]);
expect(contrastRatio(primaryForeground, palette.color_primary)).toBeGreaterThanOrEqual(4.5);
}
const buttonText = readableColor(preset.button_text_color, [preset.button_primary_color]);
expect(contrastRatio(buttonText, preset.button_primary_color)).toBeGreaterThanOrEqual(4.5);
const primaryForeground = readableColor(preset.button_text_color, [preset.color_primary]);
expect(contrastRatio(primaryForeground, preset.color_primary)).toBeGreaterThanOrEqual(4.5);
}
});
@@ -67,9 +78,11 @@ describe("readableColor", () => {
describe("derivePublicForegrounds", () => {
it.each(Object.entries(PRESETS))("makes every semantic pair readable for %s", (_name, preset) => {
const result = derivePublicForegrounds(preset);
for (const pair of result.pairs) {
expect(contrastRatio(pair.foreground, pair.background), pair.name).toBeGreaterThanOrEqual(4.5);
for (const palette of [preset.light, preset.dark]) {
const result = derivePublicForegrounds(palette);
for (const pair of result.pairs) {
expect(contrastRatio(pair.foreground, pair.background), pair.name).toBeGreaterThanOrEqual(4.5);
}
}
});