Skip to content

Commit 6d74b82

Browse files
committed
feat(clerk-js): Add action button variant for UB/OS
1 parent 413a80f commit 6d74b82

File tree

6 files changed

+170
-142
lines changed

6 files changed

+170
-142
lines changed

packages/clerk-js/src/ui/components/OrganizationProfile/ActionConfirmationPage.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ type ActionConfirmationPageProps = FormProps & {
107107
successMessage: LocalizationKey;
108108
submitLabel: LocalizationKey;
109109
onConfirmation: () => Promise<any>;
110-
variant?: 'primaryDanger' | 'primary';
110+
colorScheme?: 'danger' | 'primary';
111111
};
112112

113113
const ActionConfirmationPage = withCardStateProvider((props: ActionConfirmationPageProps) => {
@@ -122,7 +122,7 @@ const ActionConfirmationPage = withCardStateProvider((props: ActionConfirmationP
122122
onSuccess,
123123
onReset,
124124
onConfirmation,
125-
variant = 'primaryDanger',
125+
colorScheme = 'danger',
126126
} = props;
127127
const wizard = useWizard();
128128
const card = useCardState();
@@ -174,7 +174,7 @@ const ActionConfirmationPage = withCardStateProvider((props: ActionConfirmationP
174174
<FormButtonContainer>
175175
<Form.SubmitButton
176176
block={false}
177-
variant={variant}
177+
colorScheme={colorScheme}
178178
localizationKey={submitLabel}
179179
isDisabled={!canSubmit}
180180
/>

packages/clerk-js/src/ui/components/SignIn/SignInAccountSwitcher.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ const _SignInAccountSwitcher = () => {
4545
justifyContent: 'flex-start',
4646
borderRadius: 0,
4747
borderBottom: `${theme.borders.$normal} ${theme.colors.$blackAlpha100}`,
48-
backgroundColor: theme.colors.$colorBackground,
4948
})}
5049
icon={SwitchArrowRight}
5150
>

packages/clerk-js/src/ui/components/UserButton/SessionActions.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,10 @@ export const SignOutAllActions = (props: SignOutAllActionsProps) => {
174174
icon={SignOut}
175175
label={localizationKeys('userButton.action__signOutAll')}
176176
onClick={handleSignOutAllClicked}
177+
variant='action'
178+
colorScheme='danger'
177179
sx={t => ({
178-
color: t.colors.$colorTextSecondary,
180+
backgroundColor: t.colors.$transparent,
179181
padding: `${t.space.$2} ${t.space.$3}`,
180182
borderBottom: 'none',
181183
borderRadius: t.radii.$lg,

packages/clerk-js/src/ui/elements/Actions.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ export const Action = (props: ActionProps) => {
181181
return (
182182
<Button
183183
size='md'
184-
variant='ghost'
184+
variant='action'
185185
textVariant='buttonLarge'
186186
hoverAsFocus
187187
focusRing={false}

packages/clerk-js/src/ui/elements/PreviewButton.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export const PreviewButton = (props: PreviewButtonProps) => {
1616

1717
return (
1818
<Button
19-
variant='ghost'
19+
variant='action'
20+
colorScheme='secondary'
2021
focusRing={false}
2122
block
2223
hoverAsFocus

packages/clerk-js/src/ui/primitives/Button.tsx

+161-135
Original file line numberDiff line numberDiff line change
@@ -10,156 +10,182 @@ import { Flex } from './Flex';
1010

1111
const vars = createCssVariables('accent', 'accentContrast', 'alpha', 'accentLightnessAdjusted');
1212

13-
const { applyVariants, filterProps } = createVariants((theme, props: OwnProps) => {
14-
return {
15-
base: {
16-
margin: 0,
17-
padding: 0,
18-
border: 0,
19-
outline: 0,
20-
userSelect: 'none',
21-
cursor: 'pointer',
22-
backgroundColor: 'unset',
23-
color: 'currentColor',
24-
borderRadius: theme.radii.$md,
25-
position: 'relative',
26-
isolation: 'isolate',
27-
...common.centeredFlex('inline-flex'),
28-
...common.disabled(theme),
29-
transitionProperty: theme.transitionProperty.$common,
30-
transitionDuration: theme.transitionDuration.$controls,
31-
},
32-
variants: {
33-
textVariant: common.textVariants(theme),
34-
size: {
35-
iconLg: {
36-
width: theme.sizes.$13,
37-
},
38-
xs: {
39-
padding: `${theme.space.$1} ${theme.space.$3}`,
40-
},
41-
sm: {
42-
padding: `${theme.space.$1x5} ${theme.space.$3}`,
43-
},
44-
md: {
45-
padding: `${theme.space.$2x5} ${theme.space.$5}`,
46-
},
13+
const { applyVariants, filterProps } = createVariants(
14+
(theme, props: OwnProps & { colorScheme?: 'primary' | 'secondary' | 'danger' }) => {
15+
return {
16+
base: {
17+
margin: 0,
18+
padding: 0,
19+
border: 0,
20+
outline: 0,
21+
userSelect: 'none',
22+
cursor: 'pointer',
23+
backgroundColor: 'unset',
24+
color: 'currentColor',
25+
borderRadius: theme.radii.$md,
26+
position: 'relative',
27+
isolation: 'isolate',
28+
...common.centeredFlex('inline-flex'),
29+
...common.disabled(theme),
30+
transitionProperty: theme.transitionProperty.$common,
31+
transitionDuration: theme.transitionDuration.$controls,
4732
},
48-
colorScheme: {
49-
primary: {
50-
[vars.accent]: theme.colors.$primary500,
51-
[vars.accentContrast]: theme.colors.$colorTextOnPrimaryBackground,
52-
[vars.accentLightnessAdjusted]: theme.colors.$primary400,
53-
[vars.alpha]: theme.colors.$blackAlpha50, //TODO-RETHEME replace with appearance.accent
54-
},
55-
secondary: {
56-
[vars.accent]: theme.colors.$secondary500,
57-
[vars.accentContrast]: theme.colors.$colorTextOnSecondaryBackground,
58-
[vars.accentLightnessAdjusted]: theme.colors.$secondaryHover,
59-
[vars.alpha]: theme.colors.$blackAlpha50, //TODO-RETHEME replace with appearance.accent
60-
},
61-
danger: {
62-
[vars.accent]: theme.colors.$danger500,
63-
[vars.accentContrast]: theme.colors.$white,
64-
[vars.accentLightnessAdjusted]: theme.colors.$dangerAlpha400,
65-
[vars.alpha]: theme.colors.$dangerAlpha50,
33+
variants: {
34+
textVariant: common.textVariants(theme),
35+
size: {
36+
iconLg: {
37+
width: theme.sizes.$13,
38+
},
39+
xs: {
40+
padding: `${theme.space.$1} ${theme.space.$3}`,
41+
},
42+
sm: {
43+
padding: `${theme.space.$1x5} ${theme.space.$3}`,
44+
},
45+
md: {
46+
padding: `${theme.space.$2x5} ${theme.space.$5}`,
47+
},
6648
},
67-
},
68-
variant: {
69-
solid: {
70-
backgroundColor: vars.accent,
71-
color: vars.accentContrast,
72-
boxShadow: theme.shadows.$buttonShadow,
73-
border: theme.borders.$normal,
74-
borderColor: vars.accent,
75-
':after': {
76-
position: 'absolute',
77-
content: '""',
78-
borderRadius: 'inherit',
79-
zIndex: -1,
80-
inset: 0,
81-
opacity: 1,
82-
transitionProperty: theme.transitionProperty.$common,
83-
transitionDuration: theme.transitionDuration.$controls,
84-
background: `linear-gradient(180deg, ${theme.colors.$whiteAlpha150} 0%, ${theme.colors.$transparent} 100%)`,
49+
colorScheme: {
50+
primary: {
51+
[vars.accent]: theme.colors.$primary500,
52+
[vars.accentContrast]: theme.colors.$colorTextOnPrimaryBackground,
53+
[vars.accentLightnessAdjusted]: theme.colors.$primary400,
54+
[vars.alpha]: theme.colors.$blackAlpha50, //TODO-RETHEME replace with appearance.accent
8555
},
86-
':hover::after': {
87-
opacity: 0,
56+
secondary: {
57+
[vars.accent]: theme.colors.$secondary500,
58+
[vars.accentContrast]: theme.colors.$colorTextOnSecondaryBackground,
59+
[vars.accentLightnessAdjusted]: theme.colors.$secondaryHover,
60+
[vars.alpha]: theme.colors.$blackAlpha50, //TODO-RETHEME replace with appearance.accent
8861
},
89-
':active::after': {
90-
opacity: 1,
62+
danger: {
63+
[vars.accent]: theme.colors.$danger500,
64+
[vars.accentContrast]: theme.colors.$white,
65+
[vars.accentLightnessAdjusted]: theme.colors.$dangerAlpha400,
66+
[vars.alpha]: theme.colors.$dangerAlpha50,
9167
},
9268
},
93-
outline: {
94-
color: vars.accentContrast,
95-
backgroundColor: vars.accent,
96-
'&:hover': {
69+
variant: {
70+
solid: {
71+
backgroundColor: vars.accent,
9772
color: vars.accentContrast,
98-
backgroundColor: vars.accentLightnessAdjusted,
73+
boxShadow: theme.shadows.$buttonShadow,
74+
border: theme.borders.$normal,
75+
borderColor: vars.accent,
76+
':after': {
77+
position: 'absolute',
78+
content: '""',
79+
borderRadius: 'inherit',
80+
zIndex: -1,
81+
inset: 0,
82+
opacity: 1,
83+
transitionProperty: theme.transitionProperty.$common,
84+
transitionDuration: theme.transitionDuration.$controls,
85+
background: `linear-gradient(180deg, ${theme.colors.$whiteAlpha150} 0%, ${theme.colors.$transparent} 100%)`,
86+
},
87+
':hover::after': {
88+
opacity: 0,
89+
},
90+
':active::after': {
91+
opacity: 1,
92+
},
9993
},
100-
'&:focus': props.hoverAsFocus
101-
? {
102-
color: vars.accentContrast,
103-
backgroundColor: vars.accentLightnessAdjusted,
104-
}
105-
: undefined,
106-
'&:active': { backgroundColor: vars.accent },
107-
boxShadow: theme.shadows.$secondaryButtonShadow,
108-
border: theme.borders.$normal,
109-
borderColor: theme.colors.$blackAlpha100,
110-
},
111-
ghost: {
112-
color: vars.accent,
113-
'&:hover': {
94+
outline: {
95+
color: vars.accentContrast,
96+
backgroundColor: vars.accent,
97+
'&:hover': {
98+
color: vars.accentContrast,
99+
backgroundColor: vars.accentLightnessAdjusted,
100+
},
101+
'&:focus': props.hoverAsFocus
102+
? {
103+
color: vars.accentContrast,
104+
backgroundColor: vars.accentLightnessAdjusted,
105+
}
106+
: undefined,
107+
'&:active': { backgroundColor: vars.accent },
108+
boxShadow: theme.shadows.$secondaryButtonShadow,
109+
border: theme.borders.$normal,
110+
borderColor: theme.colors.$blackAlpha100,
111+
},
112+
ghost: {
114113
color: vars.accent,
115-
backgroundColor: vars.alpha,
114+
'&:hover': {
115+
color: vars.accent,
116+
backgroundColor: vars.alpha,
117+
},
118+
'&:focus': props.hoverAsFocus
119+
? {
120+
color: vars.accent,
121+
backgroundColor: vars.alpha,
122+
}
123+
: undefined,
124+
},
125+
action: {
126+
color: theme.colors.$colorTextOnSecondaryBackground, //this will break if secondary color is customized to a dark color
127+
'&:hover': {
128+
color:
129+
props.colorScheme === 'danger'
130+
? theme.colors.$dangerAlpha500
131+
: theme.colors.$colorTextOnSecondaryBackground,
132+
backgroundColor:
133+
props.colorScheme === 'danger' ? theme.colors.$dangerAlpha50 : theme.colors.$blackAlpha50,
134+
},
135+
'&:focus': props.hoverAsFocus
136+
? {
137+
color:
138+
props.colorScheme === 'danger'
139+
? theme.colors.$dangerAlpha500
140+
: theme.colors.$colorTextOnSecondaryBackground,
141+
backgroundColor:
142+
props.colorScheme === 'danger' ? theme.colors.$dangerAlpha50 : theme.colors.$blackAlpha50,
143+
}
144+
: undefined,
145+
'&:active': {
146+
backgroundColor: theme.colors.$transparent,
147+
},
116148
},
117-
'&:focus': props.hoverAsFocus
118-
? {
119-
color: vars.accent,
120-
backgroundColor: vars.alpha,
121-
}
122-
: undefined,
149+
link: {
150+
minHeight: 'fit-content',
151+
height: 'fit-content',
152+
width: 'fit-content',
153+
textTransform: 'none',
154+
padding: 0,
155+
color: theme.colors.$primary500,
156+
'&:hover': { textDecoration: 'underline' },
157+
'&:focus': props.hoverAsFocus ? { textDecoration: 'underline' } : undefined,
158+
},
159+
linkDanger: {
160+
minHeight: 'fit-content',
161+
height: 'fit-content',
162+
width: 'fit-content',
163+
textTransform: 'none',
164+
padding: 0,
165+
color: theme.colors.$danger500,
166+
'&:hover': { textDecoration: 'underline' },
167+
'&:focus': props.hoverAsFocus ? { textDecoration: 'underline' } : undefined,
168+
},
169+
unstyled: {},
170+
roundWrapper: { padding: 0, margin: 0, height: 'unset', width: 'unset', minHeight: 'unset' },
123171
},
124-
link: {
125-
minHeight: 'fit-content',
126-
height: 'fit-content',
127-
width: 'fit-content',
128-
textTransform: 'none',
129-
padding: 0,
130-
color: theme.colors.$primary500,
131-
'&:hover': { textDecoration: 'underline' },
132-
'&:focus': props.hoverAsFocus ? { textDecoration: 'underline' } : undefined,
172+
block: {
173+
true: { width: '100%' },
133174
},
134-
linkDanger: {
135-
minHeight: 'fit-content',
136-
height: 'fit-content',
137-
width: 'fit-content',
138-
textTransform: 'none',
139-
padding: 0,
140-
color: theme.colors.$danger500,
141-
'&:hover': { textDecoration: 'underline' },
142-
'&:focus': props.hoverAsFocus ? { textDecoration: 'underline' } : undefined,
175+
focusRing: {
176+
true: { ...common.focusRing(theme) },
143177
},
144-
unstyled: {},
145-
roundWrapper: { padding: 0, margin: 0, height: 'unset', width: 'unset', minHeight: 'unset' },
146-
},
147-
block: {
148-
true: { width: '100%' },
149178
},
150-
focusRing: {
151-
true: { ...common.focusRing(theme) },
179+
defaultVariants: {
180+
textVariant: 'buttonLarge',
181+
variant: 'solid',
182+
colorScheme: 'primary',
183+
size: 'sm',
184+
focusRing: true,
152185
},
153-
},
154-
defaultVariants: {
155-
textVariant: 'buttonLarge',
156-
variant: 'solid',
157-
colorScheme: 'primary',
158-
size: 'sm',
159-
focusRing: true,
160-
},
161-
};
162-
});
186+
};
187+
},
188+
);
163189
type OwnProps = PrimitiveProps<'button'> & {
164190
isLoading?: boolean;
165191
loadingText?: string;

0 commit comments

Comments
 (0)