Skip to content

Commit c7b82a4

Browse files
authored
feat(clerk-js): Remove CSS variables when modern color isn't supported (#6241)
1 parent 5598627 commit c7b82a4

2 files changed

Lines changed: 103 additions & 1 deletion

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { beforeEach, describe, expect, it, vi } from 'vitest';
2+
3+
// Mock cssSupports
4+
vi.mock('../../utils/cssSupports', () => ({
5+
cssSupports: {
6+
modernColor: vi.fn(),
7+
},
8+
}));
9+
10+
import { cssSupports } from '@/ui/utils/cssSupports';
11+
12+
import { removeInvalidValues } from '../parseVariables';
13+
14+
const mockModernColorSupport = vi.mocked(cssSupports.modernColor);
15+
16+
describe('removeInvalidValues', () => {
17+
beforeEach(() => {
18+
vi.clearAllMocks();
19+
mockModernColorSupport.mockReturnValue(false);
20+
});
21+
22+
it('should return the variables as-is if modern color support is present', () => {
23+
mockModernColorSupport.mockReturnValue(true);
24+
const variables = {
25+
colorPrimary: 'var(--color-primary)',
26+
};
27+
28+
const result = removeInvalidValues(variables);
29+
expect(result).toEqual({ colorPrimary: 'var(--color-primary)' });
30+
});
31+
32+
it('should remove invalid string values if modern color support is not present', () => {
33+
mockModernColorSupport.mockReturnValue(false);
34+
const variables = {
35+
colorPrimary: 'var(--color-primary)',
36+
colorDanger: '#ff0000',
37+
};
38+
39+
const result = removeInvalidValues(variables);
40+
expect(result).toEqual({ colorDanger: '#ff0000' });
41+
});
42+
43+
it('should remove invalid object values if modern color support is not present', () => {
44+
mockModernColorSupport.mockReturnValue(false);
45+
const variables = {
46+
colorPrimary: {
47+
400: 'var(--color-primary-500)',
48+
500: '#fff',
49+
},
50+
colorDanger: {
51+
500: '#ff0000',
52+
},
53+
};
54+
55+
const result = removeInvalidValues(variables);
56+
expect(result).toEqual({ colorDanger: { 500: '#ff0000' } });
57+
});
58+
});

packages/clerk-js/src/ui/customizables/parseVariables.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import { spaceScaleKeys } from '../foundations/sizes';
44
import type { fontSizes, fontWeights } from '../foundations/typography';
55
import { colors } from '../utils/colors';
66
import { colorOptionToThemedAlphaScale, colorOptionToThemedLightnessScale } from '../utils/colors/scales';
7+
import { cssSupports } from '../utils/cssSupports';
78
import { fromEntries } from '../utils/fromEntries';
89
import { removeUndefinedProps } from '../utils/removeUndefinedProps';
910

1011
export const createColorScales = (theme: Theme) => {
11-
const variables = theme.variables || {};
12+
const variables = removeInvalidValues(theme.variables || {});
1213

1314
const dangerScale = colorOptionToThemedLightnessScale(variables.colorDanger, 'danger');
1415
const primaryScale = colorOptionToThemedLightnessScale(variables.colorPrimary, 'primary');
@@ -43,6 +44,49 @@ export const createColorScales = (theme: Theme) => {
4344
});
4445
};
4546

47+
export const removeInvalidValues = (variables: NonNullable<Theme['variables']>): NonNullable<Theme['variables']> => {
48+
// Check for modern color support. If present, we can simply return the variables as-is since we support everything
49+
// CSS supports.
50+
if (cssSupports.modernColor()) {
51+
return variables;
52+
}
53+
54+
// If not, we need to remove any values that are specified with CSS variables, as our color scale generation only
55+
// supports CSS variables using modern CSS functionality.
56+
const validVariables: Theme['variables'] = Object.fromEntries(
57+
Object.entries(variables).filter(([key, value]) => {
58+
if (typeof value === 'string') {
59+
const isValid = !value.startsWith('var(');
60+
if (!isValid) {
61+
console.warn(
62+
`Invalid color value: ${value} for key: ${key}, using default value instead. Using CSS variables is not supported in this browser.`,
63+
);
64+
}
65+
return isValid;
66+
}
67+
68+
if (typeof value === 'object') {
69+
return Object.entries(value).every(([key, value]) => {
70+
if (typeof value !== 'string') return true;
71+
72+
const isValid = !value.startsWith('var(');
73+
if (!isValid) {
74+
console.warn(
75+
`Invalid color value: ${value} for key: ${key}, using default value instead. Using CSS variables is not supported in this browser.`,
76+
);
77+
}
78+
79+
return isValid;
80+
});
81+
}
82+
83+
return false;
84+
}),
85+
);
86+
87+
return validVariables;
88+
};
89+
4690
export const createRadiiUnits = (theme: Theme) => {
4791
const { borderRadius } = theme.variables || {};
4892
if (borderRadius === undefined) {

0 commit comments

Comments
 (0)