Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {
type CompatibilityCheckingResult,
checkCompatibility,
} from './check-compatibility';

const collect = async (reactCode: string) => {
const results: CompatibilityCheckingResult[] = [];
const stream = await checkCompatibility(reactCode, '');
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (value) results.push(value);
if (done) break;
}
return results;
};

const findHslResult = (results: CompatibilityCheckingResult[]) =>
results.find((result) => result.entry.slug === 'css-hsl-hsla');

describe('checkCompatibility() — hsl()/hsla() detection', () => {
it('flags background-color: hsl(...) as Outlook-incompatible', async () => {
const results = await collect(
"<Section style={{ backgroundColor: 'hsl(200, 50%, 50%)' }} />",
);
const hslResult = findHslResult(results);
expect(hslResult).toBeDefined();
expect(hslResult?.status).toBe('error');
expect(hslResult?.statsPerEmailClient.outlook?.status).toBe('error');
});

it('flags color: hsla(...) as Outlook-incompatible', async () => {
const results = await collect(
"<Section style={{ color: 'hsla(120, 100%, 50%, 0.5)' }} />",
);
const hslResult = findHslResult(results);
expect(hslResult).toBeDefined();
expect(hslResult?.status).toBe('error');
});

it('tolerates whitespace variations in hsl() arguments', async () => {
const results = await collect(
"<Section style={{ backgroundColor: 'hsl( 200 , 50% , 50% )' }} />",
);
expect(findHslResult(results)).toBeDefined();
});

it('does not flag hex or rgb() colors', async () => {
const results = await collect(
"<Section style={{ color: '#ff0000', backgroundColor: 'rgb(255, 0, 0)' }} />",
);
expect(findHslResult(results)).toBeUndefined();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { getElementAttributes } from '../../utils/caniemail/get-element-attribut
import { getElementNames } from '../../utils/caniemail/get-element-names';
import { snakeToCamel } from '../../utils/snake-to-camel';
import { supportEntries } from './caniemail-data';
import { customSupportEntries } from './custom-support-entries';

export interface CompatibilityCheckingResult {
location: SourceLocation;
Expand Down Expand Up @@ -146,7 +147,7 @@ export const checkCompatibility = async (
);
const readableStream = new ReadableStream<CompatibilityCheckingResult>({
async start(controller) {
for (const entry of supportEntries) {
for (const entry of [...supportEntries, ...customSupportEntries]) {
const compatibilityStats = getCompatibilityStatsForEntry(
entry,
relevantEmailClients,
Expand Down
40 changes: 40 additions & 0 deletions packages/ui/src/actions/email-validation/custom-support-entries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { SupportEntry } from './check-compatibility';

/**
* Manually curated compatibility entries that aren't covered by caniemail's
* dataset. These get merged with `supportEntries` at runtime, so regenerating
* `caniemail-data.ts` via `pnpm caniemail:fetch` won't wipe them.
*/
export const customSupportEntries: SupportEntry[] = [
// https://github.com/resend/react-email/issues/2947
// Outlook (Windows versions using Word's MS rendering engine) silently
// strips `hsl()`/`hsla()` color functions. Caniemail.com doesn't ship an
// entry for this, so we curate one here so the checker can flag it.
{
slug: 'css-hsl-hsla',
title: 'hsl(), hsla()',
description:
'HSL and HSLA color functions. Outlook on Windows silently drops these declarations, so hex or rgb() is safer for broad email client support.',
url: 'https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl',
category: 'css',
tags: [],
keywords: 'color,hsl,hsla',
last_test_date: '2026-04-19',
test_url:
'https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl',
test_results_url: null,
stats: {
outlook: {
windows: [
{ '2007': 'n' },
{ '2010': 'n' },
{ '2013': 'n' },
{ '2016': 'n' },
{ '2019': 'n' },
],
},
},
notes: null,
notes_by_num: null,
},
];
Loading