Skip to content

feat(clerk-js): Introduce CSS variable support within appearance prop #6064

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
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
Expand Up @@ -13,8 +13,7 @@ import { Tooltip } from '@/ui/elements/Tooltip';
import { LockDottedCircle } from '@/ui/icons';
import { Textarea } from '@/ui/primitives';
import type { ThemableCssProp } from '@/ui/styledSystem';
import { common } from '@/ui/styledSystem';
import * as utils from '@/ui/utils';
import { colorMix } from '@/ui/utils/colorMix';

export function OAuthConsentInternal() {
const { scopes, oAuthApplicationName, oAuthApplicationLogoUrl, redirectUrl, onDeny, onAllow } =
Expand Down Expand Up @@ -121,10 +120,7 @@ export function OAuthConsentInternal() {
<Box
sx={t => ({
padding: t.space.$3,
background: common.mergedColorsBackground(
utils.colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
})}
>
<Text
Expand Down Expand Up @@ -333,10 +329,7 @@ function ConnectionIcon({ size = 'md', sx }: { size?: 'sm' | 'md'; sx?: Themable
<Box
sx={t => [
{
background: common.mergedColorsBackground(
utils.colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
borderRadius: t.radii.$circle,
borderWidth: t.borderWidths.$normal,
borderStyle: t.borderStyles.$solid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as React from 'react';

import { Switch } from '@/ui/elements/Switch';
import { Tooltip } from '@/ui/elements/Tooltip';
import { colorMix } from '@/ui/utils/colorMix';

import { useProtect } from '../../common';
import { usePlansContext, usePricingTableContext, useSubscriberTypeContext } from '../../contexts';
Expand All @@ -22,8 +23,8 @@ import {
Text,
} from '../../customizables';
import { Check, Plus } from '../../icons';
import { common, InternalThemeProvider } from '../../styledSystem';
import { colors, getClosestProfileScrollBox } from '../../utils';
import { InternalThemeProvider } from '../../styledSystem';
import { getClosestProfileScrollBox } from '../../utils';

interface PricingTableDefaultProps {
plans?: CommercePlanResource[] | null;
Expand Down Expand Up @@ -167,10 +168,7 @@ function Card(props: CardProps) {
gap: 0,
gridTemplateRows: 'subgrid',
gridRow: 'span 5',
background: common.mergedColorsBackground(
colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
borderWidth: t.borderWidths.$normal,
borderStyle: t.borderStyles.$solid,
borderColor: t.colors.$neutralAlpha100,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
import { usePrefersReducedMotion } from '../../hooks';
import { Check, InformationCircle } from '../../icons';
import { common, InternalThemeProvider, mqu, type ThemableCssProp } from '../../styledSystem';
import { colors } from '../../utils';

interface PricingTableMatrixProps {
plans: CommercePlanResource[] | undefined;
Expand Down Expand Up @@ -55,7 +54,7 @@ export function PricingTableMatrix({
});

const highlightBackgroundColor: ThemableCssProp = t => ({
background: common.mergedColorsBackground(colors.setAlpha(t.colors.$colorBackground, 1), t.colors.$neutralAlpha25),
background: common.mergedColorsBackground(t.colors.$colorBackground, t.colors.$neutralAlpha25),
});

const gridTemplateColumns = React.useMemo(() => `repeat(${plans.length + 1}, minmax(9.375rem,1fr))`, [plans.length]);
Expand Down
60 changes: 33 additions & 27 deletions packages/clerk-js/src/ui/customizables/parseVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,33 @@ import type { Theme } from '@clerk/types';

import { spaceScaleKeys } from '../foundations/sizes';
import type { fontSizes, fontWeights } from '../foundations/typography';
import { fromEntries, removeUndefinedProps } from '../utils';
import {
colorOptionToHslaAlphaScale,
colorOptionToHslaLightnessScale,
colors,
fromEntries,
removeUndefinedProps,
} from '../utils';
createAlphaScaleWithTransparentize,
createColorMixLightnessScale,
lighten,
transparentize,
} from '../utils/colorMix';

export const createColorScales = (theme: Theme) => {
const variables = theme.variables || {};

const primaryScale = colorOptionToHslaLightnessScale(variables.colorPrimary, 'primary');
const primaryAlphaScale = colorOptionToHslaAlphaScale(primaryScale?.primary500, 'primaryAlpha');
const dangerScale = colorOptionToHslaLightnessScale(variables.colorDanger, 'danger');
const dangerAlphaScale = colorOptionToHslaAlphaScale(dangerScale?.danger500, 'dangerAlpha');
const successScale = colorOptionToHslaLightnessScale(variables.colorSuccess, 'success');
const successAlphaScale = colorOptionToHslaAlphaScale(successScale?.success500, 'successAlpha');
const warningScale = colorOptionToHslaLightnessScale(variables.colorWarning, 'warning');
const warningAlphaScale = colorOptionToHslaAlphaScale(warningScale?.warning500, 'warningAlpha');
const primaryScale = createColorMixLightnessScale(variables.colorPrimary, 'primary');
const primaryBase = primaryScale?.primary500;
const primaryAlphaScale = primaryBase ? createAlphaScaleWithTransparentize(primaryBase, 'primaryAlpha') : undefined;
const dangerScale = createColorMixLightnessScale(variables.colorDanger, 'danger');
const dangerBase = dangerScale?.danger500;
const dangerAlphaScale = dangerBase ? createAlphaScaleWithTransparentize(dangerBase, 'dangerAlpha') : undefined;
const successScale = createColorMixLightnessScale(variables.colorSuccess, 'success');
const successBase = successScale?.success500;
const successAlphaScale = successBase ? createAlphaScaleWithTransparentize(successBase, 'successAlpha') : undefined;
const warningScale = createColorMixLightnessScale(variables.colorWarning, 'warning');
const warningBase = warningScale?.warning500;
const warningAlphaScale = warningBase ? createAlphaScaleWithTransparentize(warningBase, 'warningAlpha') : undefined;
const neutralAlphaScales =
typeof variables.colorNeutral === 'string' && variables.colorNeutral
? createAlphaScaleWithTransparentize(variables.colorNeutral, 'neutralAlpha')
: {};

return removeUndefinedProps({
...primaryScale,
Expand All @@ -31,22 +39,20 @@ export const createColorScales = (theme: Theme) => {
...successAlphaScale,
...warningScale,
...warningAlphaScale,
...colorOptionToHslaAlphaScale(variables.colorNeutral, 'neutralAlpha'),
primaryHover: colors.adjustForLightness(primaryScale?.primary500),
colorTextOnPrimaryBackground: toHSLA(variables.colorTextOnPrimaryBackground),
colorText: toHSLA(variables.colorText),
colorTextSecondary: toHSLA(variables.colorTextSecondary) || colors.makeTransparent(variables.colorText, 0.35),
colorInputText: toHSLA(variables.colorInputText),
colorBackground: toHSLA(variables.colorBackground),
colorInputBackground: toHSLA(variables.colorInputBackground),
colorShimmer: toHSLA(variables.colorShimmer),
...neutralAlphaScales,
// TODO(Colors): We are not adjusting the lightness based on the colorPrimary lightness
primaryHover: primaryBase ? lighten(primaryBase, '90%') : undefined,
colorTextOnPrimaryBackground: variables.colorTextOnPrimaryBackground,
colorText: variables.colorText,
colorTextSecondary:
variables.colorTextSecondary || (variables.colorText ? transparentize(variables.colorText, '35%') : undefined),
colorInputText: variables.colorInputText,
colorBackground: variables.colorBackground,
colorInputBackground: variables.colorInputBackground,
colorShimmer: variables.colorShimmer,
});
};

export const toHSLA = (str: string | undefined) => {
return str ? colors.toHslaString(str) : undefined;
};

export const createRadiiUnits = (theme: Theme) => {
const { borderRadius } = theme.variables || {};
if (borderRadius === undefined) {
Expand Down
10 changes: 4 additions & 6 deletions packages/clerk-js/src/ui/elements/Card/CardFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react';

import { colorMix } from '@/ui/utils/colorMix';

import { useEnvironment } from '../../contexts';
import { descriptors, Flex, Link, localizationKeys, useAppearance } from '../../customizables';
import { useDevMode } from '../../hooks/useDevMode';
import type { InternalTheme, PropsOfComponent } from '../../styledSystem';
import { common, mqu } from '../../styledSystem';
import { colors } from '../../utils';
import { mqu } from '../../styledSystem';
import { Card } from '.';

type CardFooterProps = PropsOfComponent<typeof Flex> & {
Expand Down Expand Up @@ -50,10 +51,7 @@ export const CardFooter = React.forwardRef<HTMLDivElement, CardFooterProps>((pro
t => ({
marginTop: `-${t.space.$2}`,
paddingTop: t.space.$2,
background: common.mergedColorsBackground(
colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
'&:empty': {
padding: 0,
marginTop: 0,
Expand Down
8 changes: 2 additions & 6 deletions packages/clerk-js/src/ui/elements/Disclosure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { Box, descriptors, Icon, SimpleButton, Span, useAppearance } from '../cu
import { usePrefersReducedMotion } from '../hooks';
import { ChevronDown } from '../icons';
import type { ThemableCssProp } from '../styledSystem';
import { common } from '../styledSystem';
import { colors } from '../utils';
import { colorMix } from '../utils/colorMix';

/* -------------------------------------------------------------------------------------------------
* Disclosure Context
Expand Down Expand Up @@ -168,10 +167,7 @@ const Content = React.forwardRef<HTMLDivElement, ContentProps>(({ children }, re
borderWidth: t.borderWidths.$normal,
borderStyle: t.borderStyles.$solid,
borderColor: t.colors.$neutralAlpha100,
background: common.mergedColorsBackground(
colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
})}
>
{children}
Expand Down
22 changes: 6 additions & 16 deletions packages/clerk-js/src/ui/elements/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import { Box, descriptors, Flex, Heading, Icon, Span, useAppearance } from '../c
import { useDirection, usePrefersReducedMotion, useScrollLock } from '../hooks';
import { Close as CloseIcon } from '../icons';
import type { ThemableCssProp } from '../styledSystem';
import { common } from '../styledSystem';
import { colors } from '../utils';
import { colorMix, transparentize } from '../utils/colorMix';
import { IconButton } from './IconButton';

type FloatingPortalProps = React.ComponentProps<typeof FloatingPortal>;
Expand Down Expand Up @@ -151,7 +150,7 @@ export const FloatingOverlay = React.forwardRef(function FloatingOverlay(
sx={[
t => ({
inset: 0,
backgroundColor: colors.setAlpha(t.colors.$colorBackground, 0.28),
backgroundColor: transparentize(t.colors.$colorBackground, '28%'),
}),
props.sx,
]}
Expand Down Expand Up @@ -298,10 +297,7 @@ const Header = React.forwardRef<HTMLDivElement, HeaderProps>(({ title, children,
sx={[
t => ({
display: 'flex',
background: common.mergedColorsBackground(
colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
borderBlockEndWidth: t.borderWidths.$normal,
borderBlockEndStyle: t.borderStyles.$solid,
borderBlockEndColor: t.colors.$neutralAlpha100,
Expand Down Expand Up @@ -378,10 +374,7 @@ const Footer = React.forwardRef<HTMLDivElement, FooterProps>(({ children, sx, ..
t => ({
display: 'flex',
flexDirection: 'column',
background: common.mergedColorsBackground(
colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
borderBlockStartWidth: t.borderWidths.$normal,
borderBlockStartStyle: t.borderStyles.$solid,
borderBlockStartColor: t.colors.$neutralAlpha100,
Expand Down Expand Up @@ -496,7 +489,7 @@ const Confirmation = React.forwardRef<HTMLDivElement, ConfirmationProps>(
sx={t => ({
position: 'absolute',
inset: 0,
backgroundImage: `linear-gradient(to bottom, ${colors.setAlpha(t.colors.$colorBackground, 0.28)}, ${t.colors.$colorBackground})`,
backgroundImage: `linear-gradient(to bottom, ${transparentize(t.colors.$colorBackground, '28%')}, ${t.colors.$colorBackground})`,
})}
/>

Expand All @@ -521,10 +514,7 @@ const Confirmation = React.forwardRef<HTMLDivElement, ConfirmationProps>(
bottom: 0,
left: 0,
right: 0,
background: common.mergedColorsBackground(
colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
padding: t.space.$4,
borderStartStartRadius: t.radii.$md,
borderStartEndRadius: t.radii.$md,
Expand Down
13 changes: 4 additions & 9 deletions packages/clerk-js/src/ui/elements/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import { useNavigateToFlowStart, usePopover } from '../hooks';
import { Menu } from '../icons';
import { useRouter } from '../router';
import type { PropsOfComponent } from '../styledSystem';
import { animations, common, mqu } from '../styledSystem';
import { animations, mqu } from '../styledSystem';
import { colors } from '../utils';
import { colorMix } from '../utils/colorMix';
import { Card } from './Card';
import { withFloatingTree } from './contexts';
import { DevModeOverlay } from './DevModeNotice';
Expand Down Expand Up @@ -146,10 +147,7 @@ const NavbarContainer = (
width: t.sizes.$57,
position: 'relative',
maxWidth: t.space.$57,
background: common.mergedColorsBackground(
colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
padding: `${t.space.$6} ${t.space.$5} ${t.space.$4} ${t.space.$3}`,
marginRight: `-${t.space.$2}`,
color: t.colors.$colorText,
Expand Down Expand Up @@ -319,10 +317,7 @@ export const NavbarMenuButtonRow = ({ navbarTitleLocalizationKey, ...props }: Na
elementDescriptor={descriptors.navbarMobileMenuRow}
sx={t => ({
display: 'none',
background: common.mergedColorsBackground(
colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
padding: `${t.space.$2} ${t.space.$3} ${t.space.$4} ${t.space.$3}`,
marginBottom: `-${t.space.$2}`,
[mqu.md]: {
Expand Down
9 changes: 3 additions & 6 deletions packages/clerk-js/src/ui/elements/PopoverCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { useEnvironment } from '../contexts';
import { Col, descriptors, Flex, Flow, useAppearance } from '../customizables';
import type { ElementDescriptor } from '../customizables/elementDescriptors';
import type { PropsOfComponent, ThemableCssProp } from '../styledSystem';
import { animations, common } from '../styledSystem';
import { colors } from '../utils';
import { animations } from '../styledSystem';
import { colorMix } from '../utils/colorMix';
import { Card } from './Card';

const PopoverCardRoot = React.forwardRef<
Expand Down Expand Up @@ -81,10 +81,7 @@ const PopoverCardFooter = (props: PropsOfComponent<typeof Flex>) => {
justify='between'
sx={[
t => ({
background: common.mergedColorsBackground(
colors.setAlpha(t.colors.$colorBackground, 1),
t.colors.$neutralAlpha50,
),
backgroundColor: colorMix(t.colors.$colorBackground, t.colors.$neutralAlpha50),
marginTop: `-${t.space.$2}`,
paddingTop: t.space.$2,
'&:empty': {
Expand Down
Loading