Skip to content

Commit 2000ed6

Browse files
committed
feat(clerk-js): Introduce CSS variables
1 parent cefaf9b commit 2000ed6

File tree

10 files changed

+151
-141
lines changed

10 files changed

+151
-141
lines changed

packages/clerk-js/sandbox/app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ void (async () => {
345345
signUpUrl: '/sign-up',
346346
});
347347
renderCurrentRoute();
348-
updateVariables();
348+
// updateVariables(); // Commented out as it overrides css variables
349349
updateOtherOptions();
350350
} else {
351351
console.error(`Unknown route: "${route}".`);

packages/clerk-js/sandbox/template.html

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,27 @@
77
name="viewport"
88
content="width=device-width,initial-scale=1"
99
/>
10+
<style>
11+
:root {
12+
--clerk-primary: #2F3037; /* default: #2F3037 */
13+
--clerk-foreground: #212126; /* default: #212126 */
14+
--clerk-background: white; /* default: white */
15+
--clerk-primary-foreground: white; /* default: white */
16+
--clerk-secondary-foreground: #747686; /* default: #747686 */
17+
--clerk-danger: #EF4444; /* default: #EF4444 */
18+
--clerk-input: white; /* default: white */
19+
--clerk-neutral: black; /* default: black */
20+
21+
--clerk-line-height: normal; /* default: normal */
22+
--clerk-spacing: 1rem; /* default: 1rem */
23+
--clerk-border-width: 1px; /* default: 1px */
24+
--clerk-font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* default: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" */
25+
--clerk-font-size: 0.8125rem; /* default: 0.8125rem */
26+
--clerk-font-weight: 400; /* default: 400 */
27+
--clerk-letter-spacing: normal; /* default: normal */
28+
--clerk-border-radius: 0.375rem; /* default: 0.375rem */
29+
}
30+
</style>
1031
<script src="https://cdn.tailwindcss.com"></script>
1132
<script>
1233
tailwind.config = {

packages/clerk-js/src/ui/components/PricingTable/PricingTableMatrix.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as React from 'react';
33

44
import { Avatar } from '@/ui/elements/Avatar';
55
import { SegmentedControl } from '@/ui/elements/SegmentedControl';
6+
import { colorMix } from '@/ui/utils/colorMix';
67

78
import { usePlansContext } from '../../contexts';
89
import {
@@ -21,7 +22,7 @@ import {
2122
} from '../../customizables';
2223
import { usePrefersReducedMotion } from '../../hooks';
2324
import { Check, InformationCircle } from '../../icons';
24-
import { common, InternalThemeProvider, mqu, type ThemableCssProp } from '../../styledSystem';
25+
import { InternalThemeProvider, mqu, type ThemableCssProp } from '../../styledSystem';
2526

2627
interface PricingTableMatrixProps {
2728
plans: CommercePlanResource[] | undefined;
@@ -54,7 +55,7 @@ export function PricingTableMatrix({
5455
});
5556

5657
const highlightBackgroundColor: ThemableCssProp = t => ({
57-
background: common.mergedColorsBackground(t.colors.$colorBackground, t.colors.$neutralAlpha25),
58+
background: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha25),
5859
});
5960

6061
const gridTemplateColumns = React.useMemo(() => `repeat(${plans.length + 1}, minmax(9.375rem,1fr))`, [plans.length]);
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import { clerkCssVar } from '../utils/css';
2+
13
export const borderStyles = Object.freeze({
24
solid: 'solid',
35
dashed: 'dashed',
46
} as const);
57

8+
const borderWidthDefaultVar = clerkCssVar('border-width', '1px');
69
export const borderWidths = Object.freeze({
7-
normal: '1px',
8-
heavy: '2px',
10+
normal: clerkCssVar('border-width-normal', borderWidthDefaultVar),
11+
heavy: clerkCssVar('border-width-heavy', `calc(${borderWidthDefaultVar} * 2)`),
912
});
Lines changed: 30 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
1-
import { createAlphaScaleWithTransparentize, transparentize } from '../utils/colorMix';
1+
import {
2+
createAlphaScaleWithTransparentize,
3+
createColorMixLightnessScale,
4+
lighten,
5+
transparentize,
6+
} from '../utils/colorMix';
7+
import { clerkCssVar } from '../utils/css';
28

39
type ColorScale<Prefix extends string> = {
410
[K in `${Prefix}${'50' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | '950'}`]: string;
511
};
612

713
// Create alpha scales separately to preserve types
814
export const whiteAlpha = createAlphaScaleWithTransparentize('white', 'whiteAlpha');
9-
export const neutralAlpha = createAlphaScaleWithTransparentize('black', 'neutralAlpha');
15+
export const neutralAlpha = createAlphaScaleWithTransparentize(clerkCssVar('neutral', 'black'), 'neutralAlpha');
1016

11-
const primaryAlpha = createAlphaScaleWithTransparentize('#2F3037', 'primaryAlpha');
12-
const dangerAlpha = createAlphaScaleWithTransparentize('#EF4444', 'dangerAlpha');
13-
const warningAlpha = createAlphaScaleWithTransparentize('#F36B16', 'warningAlpha');
14-
const successAlpha = createAlphaScaleWithTransparentize('#22C543', 'successAlpha');
17+
const primaryAlpha = createAlphaScaleWithTransparentize(clerkCssVar('primary', '#2F3037'), 'primaryAlpha');
18+
const dangerAlpha = createAlphaScaleWithTransparentize(clerkCssVar('danger', '#EF4444'), 'dangerAlpha');
19+
const warningAlpha = createAlphaScaleWithTransparentize(clerkCssVar('warning', '#F36B16'), 'warningAlpha');
20+
const successAlpha = createAlphaScaleWithTransparentize(clerkCssVar('success', '#22C543'), 'successAlpha');
21+
22+
const primaryScale = createColorMixLightnessScale(clerkCssVar('primary', '#2F3037'), 'primary');
23+
const dangerScale = createColorMixLightnessScale(clerkCssVar('danger', '#EF4444'), 'danger');
24+
const warningScale = createColorMixLightnessScale(clerkCssVar('warning', '#F36B16'), 'warning');
25+
const successScale = createColorMixLightnessScale(clerkCssVar('success', '#22C543'), 'success');
1526

1627
// Define the base colors object type
1728
type BaseColors = {
@@ -51,63 +62,24 @@ export const colors: Colors = Object.freeze({
5162
// Themable colors
5263
...neutralAlpha,
5364
...whiteAlpha,
54-
colorBackground: 'white',
55-
colorInputBackground: 'white',
56-
colorText: '#212126',
57-
colorTextSecondary: '#747686',
58-
colorInputText: '#131316',
59-
colorTextOnPrimaryBackground: 'white',
60-
colorShimmer: transparentize('white', '36%'),
65+
colorBackground: clerkCssVar('background', 'white'),
66+
colorInputBackground: clerkCssVar('input', 'white'),
67+
colorText: clerkCssVar('foreground', '#212126'),
68+
colorTextSecondary: clerkCssVar('secondary-foreground', '#747686'),
69+
colorInputText: clerkCssVar('input-foreground', '#131316'),
70+
colorTextOnPrimaryBackground: clerkCssVar('primary-foreground', 'white'),
71+
colorShimmer: transparentize(clerkCssVar('shimmer', 'white'), '36%'),
6172
transparent: 'transparent',
6273
white: 'white',
6374
black: 'black',
64-
primary50: '#B9BDBC',
65-
primary100: '#9EA1A2',
66-
primary200: '#828687',
67-
primary300: '#66696D',
68-
primary400: '#4B4D52',
69-
primary500: '#2F3037',
70-
primary600: '#2A2930',
71-
primary700: '#25232A',
72-
primary800: '#201D23',
73-
primary900: '#1B171C',
74-
primary950: '#0F0D12',
75-
primaryHover: '#3B3C45', // primary 500 adjusted for lightness
75+
...primaryScale,
76+
// TODO(Colors): We are not adjusting the lightness based on the colorPrimary lightness
77+
primaryHover: lighten(clerkCssVar('primary', '#2F3037'), '25%'), // primary 500 adjusted for lightness
7678
...primaryAlpha,
77-
danger50: '#FEF2F2',
78-
danger100: '#FEE5E5',
79-
danger200: '#FECACA',
80-
danger300: '#FCA5A5',
81-
danger400: '#F87171',
82-
danger500: '#EF4444',
83-
danger600: '#DC2626',
84-
danger700: '#B91C1C',
85-
danger800: '#991B1B',
86-
danger900: '#7F1D1D',
87-
danger950: '#450A0A',
79+
...dangerScale,
8880
...dangerAlpha,
89-
warning50: '#FFF6ED',
90-
warning100: '#FFEBD5',
91-
warning200: '#FED1AA',
92-
warning300: '#FDB674',
93-
warning400: '#F98C49',
94-
warning500: '#F36B16',
95-
warning600: '#EA520C',
96-
warning700: '#C23A0C',
97-
warning800: '#9A2F12',
98-
warning900: '#7C2912',
99-
warning950: '#431207',
81+
...warningScale,
10082
...warningAlpha,
101-
success50: '#F0FDF2',
102-
success100: '#DCFCE2',
103-
success200: '#BBF7C6',
104-
success300: '#86EF9B',
105-
success400: '#4ADE68',
106-
success500: '#22C543',
107-
success600: '#16A332',
108-
success700: '#15802A',
109-
success800: '#166527',
110-
success900: '#145323',
111-
success950: '#052E0F',
83+
...successScale,
11284
...successAlpha,
11385
} as const);
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { clerkCssVar } from '../utils/css';
2+
13
export const opacity = Object.freeze({
2-
sm: '24%',
3-
disabled: '50%',
4-
inactive: '62%',
4+
sm: clerkCssVar('opacity-sm', '24%'),
5+
disabled: clerkCssVar('opacity-disabled', '50%'),
6+
inactive: clerkCssVar('opacity-inactive', '62%'),
57
} as const);

packages/clerk-js/src/ui/foundations/sizes.ts

Lines changed: 57 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,61 @@
1+
import { clerkCssVar } from '../utils/css';
2+
13
const baseSpaceUnits = Object.freeze({
24
none: '0',
35
xxs: '0.5px',
46
px: '1px',
57
} as const);
68

9+
const dynamicSpaceUnitsDefaultVar = clerkCssVar('spacing', '1rem');
10+
const calcDynamicSpaceUnits = (num: number) => `calc(${dynamicSpaceUnitsDefaultVar} * ((${num} / 0.5) * 0.125))`;
11+
712
const dynamicSpaceUnits = Object.freeze({
8-
'0x25': '0.0625rem',
9-
'0x5': '0.125rem',
10-
'1': '0.25rem',
11-
'1x5': '0.375rem',
12-
'2': '0.5rem',
13-
'2x5': '0.625rem',
14-
'3': '0.75rem',
15-
'3x25': '0.8125rem',
16-
'3x5': '0.875rem',
17-
'4': '1rem',
18-
'4x25': '1.0625rem',
19-
'5': '1.25rem',
20-
'5x5': '1.375rem',
21-
'6': '1.5rem',
22-
'7': '1.75rem',
23-
'7x5': '1.875rem',
24-
'8': '2rem',
25-
'8x5': '2.125rem',
26-
'8x75': '2.1875rem',
27-
'9': '2.25rem',
28-
'10': '2.5rem',
29-
'12': '3rem',
30-
'13': '3.5rem',
31-
'16': '4rem',
32-
'17': '4.25rem',
33-
'20': '5rem',
34-
'24': '6rem',
35-
'28': '7rem',
36-
'32': '8rem',
37-
'36': '9rem',
38-
'40': '10rem',
39-
'44': '11rem',
40-
'48': '12rem',
41-
'52': '13rem',
42-
'56': '14rem',
43-
'57': '14.25rem',
44-
'60': '15rem',
45-
'66': '16.5rem',
46-
'94': '23.5rem',
47-
'100': '25rem',
48-
'108': '27rem',
49-
'120': '30rem',
50-
'140': '35rem',
51-
'160': '40rem',
52-
'176': '44rem',
53-
'220': '55rem',
13+
'0x25': calcDynamicSpaceUnits(0.25), // 0.0625rem
14+
'0x5': calcDynamicSpaceUnits(0.5), // 0.125rem
15+
'1': calcDynamicSpaceUnits(1), // 0.25rem
16+
'1x5': calcDynamicSpaceUnits(1.5), // 0.375rem
17+
'2': calcDynamicSpaceUnits(2), // 0.5rem
18+
'2x5': calcDynamicSpaceUnits(2.5), // 0.625rem
19+
'3': calcDynamicSpaceUnits(3), // 0.75rem
20+
'3x25': calcDynamicSpaceUnits(3.25), // 0.8125rem
21+
'3x5': calcDynamicSpaceUnits(3.5), // 0.875rem
22+
'4': dynamicSpaceUnitsDefaultVar, // 1rem
23+
'4x25': calcDynamicSpaceUnits(4.5), // 1.0625rem
24+
'5': calcDynamicSpaceUnits(5), // 1.25rem
25+
'5x5': calcDynamicSpaceUnits(5.5), // 1.375rem
26+
'6': calcDynamicSpaceUnits(6), // 1.5rem
27+
'7': calcDynamicSpaceUnits(7), // 1.75rem
28+
'7x5': calcDynamicSpaceUnits(7.5), // 1.875rem
29+
'8': calcDynamicSpaceUnits(8), // 2rem
30+
'8x5': calcDynamicSpaceUnits(8.5), // 2.125rem
31+
'8x75': calcDynamicSpaceUnits(8.75), // 2.1875rem
32+
'9': calcDynamicSpaceUnits(9), // 2.25rem
33+
'10': calcDynamicSpaceUnits(10), // 2.5rem
34+
'12': calcDynamicSpaceUnits(12), // 3rem
35+
'13': calcDynamicSpaceUnits(13), // 3.5rem
36+
'16': calcDynamicSpaceUnits(16), // 4rem
37+
'17': calcDynamicSpaceUnits(17), // 4.25rem
38+
'20': calcDynamicSpaceUnits(20), // 5rem
39+
'24': calcDynamicSpaceUnits(24), // 6rem
40+
'28': calcDynamicSpaceUnits(28), // 7rem
41+
'32': calcDynamicSpaceUnits(32), // 8rem
42+
'36': calcDynamicSpaceUnits(36), // 9rem
43+
'40': calcDynamicSpaceUnits(40), // 10rem
44+
'44': calcDynamicSpaceUnits(44), // 11rem
45+
'48': calcDynamicSpaceUnits(48), // 12rem
46+
'52': calcDynamicSpaceUnits(52), // 13rem
47+
'56': calcDynamicSpaceUnits(56), // 14rem
48+
'57': calcDynamicSpaceUnits(57), // 14.25rem
49+
'60': calcDynamicSpaceUnits(60), // 15rem
50+
'66': calcDynamicSpaceUnits(66), // 16.5rem
51+
'94': calcDynamicSpaceUnits(94), // 23.5rem
52+
'100': calcDynamicSpaceUnits(100), // 25rem
53+
'108': calcDynamicSpaceUnits(108), // 27rem
54+
'120': calcDynamicSpaceUnits(120), // 30rem
55+
'140': calcDynamicSpaceUnits(140), // 35rem
56+
'160': calcDynamicSpaceUnits(160), // 40rem
57+
'176': calcDynamicSpaceUnits(176), // 44rem
58+
'220': calcDynamicSpaceUnits(220), // 55rem
5459
} as const);
5560

5661
/**
@@ -64,14 +69,15 @@ const space = Object.freeze({
6469

6570
const sizes = Object.freeze({ ...space } as const);
6671

72+
const radiiDefaultVar = clerkCssVar('border-radius', '0.375rem');
6773
const radii = Object.freeze({
6874
none: '0px',
6975
circle: '50%',
70-
avatar: '0.375rem',
71-
sm: '0.25rem',
72-
md: '0.375rem',
73-
lg: '0.5rem',
74-
xl: '0.75rem',
76+
avatar: clerkCssVar('border-radius-avatar', radiiDefaultVar), // 0.375rem
77+
sm: clerkCssVar('border-radius-sm', `calc(${radiiDefaultVar} * 0.666)`), // 0.25rem
78+
md: clerkCssVar('border-radius-md', radiiDefaultVar), // 0.375rem
79+
lg: clerkCssVar('border-radius-lg', `calc(${radiiDefaultVar} * 1.333)`), // 0.5rem
80+
xl: clerkCssVar('border-radius-xl', `calc(${radiiDefaultVar} * 2)`), // 0.75rem
7581
halfHeight: '99999px',
7682
} as const);
7783

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,42 @@
1+
import { clerkCssVar } from '../utils/css';
2+
13
const fontWeights = Object.freeze({
2-
normal: 400,
3-
medium: 500,
4-
semibold: 600,
5-
bold: 700,
4+
normal: clerkCssVar('font-weight-normal', clerkCssVar('font-weight', '400')),
5+
medium: clerkCssVar('font-weight-medium', '500'),
6+
semibold: clerkCssVar('font-weight-semibold', '600'),
7+
bold: clerkCssVar('font-weight-bold', '700'),
68
} as const);
79

810
const lineHeights = Object.freeze({
9-
normal: 'normal',
10-
extraSmall: '1.33333',
11-
small: '1.38462',
12-
medium: '1.41176',
13-
large: '1.45455',
11+
normal: clerkCssVar('line-height-normal', clerkCssVar('line-height', 'normal')),
12+
extraSmall: clerkCssVar('line-height-extra-small', `calc(${clerkCssVar('line-height', 'normal')} * 1.33333)`), // 1.33333
13+
small: clerkCssVar('line-height-small', `calc(${clerkCssVar('line-height', 'normal')} * 1.38462)`), // 1.38462
14+
medium: clerkCssVar('line-height-medium', `calc(${clerkCssVar('line-height', 'normal')} * 1.41176)`), // 1.41176
15+
large: clerkCssVar('line-height-large', `calc(${clerkCssVar('line-height', 'normal')} * 1.45455)`), // 1.45455
1416
} as const);
1517

1618
const letterSpacings = Object.freeze({
17-
normal: 'normal',
19+
normal: clerkCssVar('letter-spacing-normal', clerkCssVar('letter-spacing', 'normal')),
1820
} as const);
1921

2022
// We want to achieve the md size to be 13px for root font size of 16px
2123
// This is directly related to the createFontSizeScale function in the theme
2224
// ref: src/ui/customizables/parseVariables.ts
2325
const fontSizes = Object.freeze({
24-
xs: '0.6875rem',
25-
sm: '0.75rem',
26-
md: '0.8125rem',
27-
lg: '1.0625rem',
28-
xl: '1.5rem',
26+
xs: clerkCssVar('font-size-xs', `calc(${clerkCssVar('font-size', '0.8125rem')} * 0.8)`), // 0.6875rem
27+
sm: clerkCssVar('font-size-sm', `calc(${clerkCssVar('font-size', '0.8125rem')} * 0.9)`), // 0.75rem
28+
md: clerkCssVar('font-size-md', clerkCssVar('font-size', '0.8125rem')),
29+
lg: clerkCssVar('font-size-lg', `calc(${clerkCssVar('font-size', '0.8125rem')} * 1.3)`), // 1.0625rem
30+
xl: clerkCssVar('font-size-xl', `calc(${clerkCssVar('font-size', '0.8125rem')} * 1.85)`), // 1.5rem
2931
} as const);
3032

3133
const fontStyles = Object.freeze({
32-
normal: 'normal',
34+
normal: clerkCssVar('font-style-normal', clerkCssVar('font-style', 'normal')),
3335
} as const);
3436

3537
const fonts = Object.freeze({
36-
main: 'inherit',
37-
buttons: 'inherit',
38+
main: clerkCssVar('font-family', 'inherit'),
39+
buttons: clerkCssVar('font-family-buttons', clerkCssVar('font-family', 'inherit')),
3840
} as const);
3941

4042
export { fontSizes, fontWeights, letterSpacings, lineHeights, fonts, fontStyles };

0 commit comments

Comments
 (0)