import { getContrast } from "color2k"; import ColorScales from "./index"; // WCAG Contrast Thresholds const WCAG_AA_MINIMUM = 4.5; // Normal text const WCAG_LARGE_TEXT_MINIMUM = 3.0; // Large text, graphics, UI components, hi /saturation text const STEP_14_MAXIMUM = 6.5; describe("Color Scale Contrast Compliance", () => { const colorNames = [ "cyan", "blue", "green", "orange", "red", "pink", "violet", "yellow", "grey", ]; describe("Light Mode", () => { colorNames.forEach((color) => { describe(`${color} scale`, () => { const scale = ColorScales.light[color]; const step1Hex = scale[`${color}1`].data.hexString; const step2Hex = scale[`${color}2`].data.hexString; const step3Hex = scale[`${color}3`].data.hexString; const step10Hex = scale[`${color}10`].data.hexString; const step11Hex = scale[`${color}11`].data.hexString; const step12Hex = scale[`${color}12`].data.hexString; const step13Hex = scale[`${color}13`].data.hexString; const step14Hex = scale[`${color}14`].data.hexString; it(`step 10 (hi saturation text) meets WCAG large text (≥${WCAG_LARGE_TEXT_MINIMUM}:1) vs step 3 (uiElement background)`, () => { const contrast = getContrast(step10Hex, step3Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_LARGE_TEXT_MINIMUM); }); it(`step 13 (highContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs solid background`, () => { const contrast = getContrast(step13Hex, step10Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it(`step 14 (lowContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) and stays below white (≤${STEP_14_MAXIMUM}:1)`, () => { const contrast = getContrast(step14Hex, step10Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); expect(contrast).toBeLessThanOrEqual(STEP_14_MAXIMUM); }); it("step 14 has LESS contrast than step 13 (semantic correctness)", () => { const contrast13 = getContrast(step13Hex, step10Hex); const contrast14 = getContrast(step14Hex, step10Hex); expect(contrast14).toBeLessThan(contrast13); }); it(`step 12 (hiContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 1 (app background)`, () => { const contrast = getContrast(step12Hex, step1Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it(`step 12 (hiContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 2 (surface background)`, () => { const contrast = getContrast(step12Hex, step2Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it(`step 11 (lowContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 1 (app background)`, () => { const contrast = getContrast(step11Hex, step1Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it(`step 11 (lowContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 2 (surface background)`, () => { const contrast = getContrast(step11Hex, step2Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it("step 11 has LESS contrast than step 12 vs step 1 (semantic correctness)", () => { const contrast11 = getContrast(step11Hex, step1Hex); const contrast12 = getContrast(step12Hex, step1Hex); expect(contrast11).toBeLessThan(contrast12); }); it(`step 12 (hiContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 3 (uiElement background)`, () => { const contrast = getContrast(step12Hex, step3Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it(`step 11 (lowContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 3 (uiElement background)`, () => { const contrast = getContrast(step11Hex, step3Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); }); }); }); describe("Dark Mode", () => { colorNames.forEach((color) => { describe(`${color} scale`, () => { const scale = ColorScales.dark[color]; const step1Hex = scale[`${color}1`].data.hexString; const step2Hex = scale[`${color}2`].data.hexString; const step3Hex = scale[`${color}3`].data.hexString; const step10Hex = scale[`${color}10`].data.hexString; const step11Hex = scale[`${color}11`].data.hexString; const step12Hex = scale[`${color}12`].data.hexString; const step13Hex = scale[`${color}13`].data.hexString; const step14Hex = scale[`${color}14`].data.hexString; it(`step 10 (hi saturation text) meets WCAG large text (≥${WCAG_LARGE_TEXT_MINIMUM}:1) vs step 3 (uiElement background)`, () => { const contrast = getContrast(step10Hex, step3Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_LARGE_TEXT_MINIMUM); }); it(`step 13 (highContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs solid background`, () => { const contrast = getContrast(step13Hex, step10Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it(`step 14 (lowContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) and stays below white (≤${STEP_14_MAXIMUM}:1)`, () => { const contrast = getContrast(step14Hex, step10Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); expect(contrast).toBeLessThanOrEqual(STEP_14_MAXIMUM); }); it("step 14 has LESS contrast than step 13 (semantic correctness)", () => { const contrast13 = getContrast(step13Hex, step10Hex); const contrast14 = getContrast(step14Hex, step10Hex); expect(contrast14).toBeLessThan(contrast13); }); it(`step 12 (hiContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 1 (app background)`, () => { const contrast = getContrast(step12Hex, step1Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it(`step 12 (hiContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 2 (surface background)`, () => { const contrast = getContrast(step12Hex, step2Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it(`step 11 (lowContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 1 (app background)`, () => { const contrast = getContrast(step11Hex, step1Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it(`step 11 (lowContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 2 (surface background)`, () => { const contrast = getContrast(step11Hex, step2Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it("step 11 has LESS contrast than step 12 vs step 1 (semantic correctness)", () => { const contrast11 = getContrast(step11Hex, step1Hex); const contrast12 = getContrast(step12Hex, step1Hex); expect(contrast11).toBeLessThan(contrast12); }); it(`step 12 (hiContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 3 (uiElement background)`, () => { const contrast = getContrast(step12Hex, step3Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); it(`step 11 (lowContrast text) meets WCAG AA (≥${WCAG_AA_MINIMUM}:1) vs step 3 (uiElement background)`, () => { const contrast = getContrast(step11Hex, step3Hex); expect(contrast).toBeGreaterThanOrEqual(WCAG_AA_MINIMUM); }); }); }); }); });