Skip to content

Commit 8cc3129

Browse files
authored
feat(ui): add explicit radio indicator to ConfigureSSO provider cards (#8664)
1 parent 17925fe commit 8cc3129

4 files changed

Lines changed: 43 additions & 32 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@clerk/ui": patch
3+
---
4+
5+
Add a visible radio indicator to each provider card on the `<ConfigureSSO />` Select Provider step.

packages/ui/src/components/ConfigureSSO/steps/SelectProviderStep.tsx

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,18 @@ import { useUser } from '@clerk/shared/react/index';
33
import React from 'react';
44

55
import type { LocalizationKey } from '@/customizables';
6-
import { Box, Col, descriptors, Flow, Grid, localizationKeys, Span, Text, useLocalizations } from '@/customizables';
6+
import {
7+
Box,
8+
Col,
9+
descriptors,
10+
Flow,
11+
Grid,
12+
localizationKeys,
13+
RadioInput,
14+
Span,
15+
Text,
16+
useLocalizations,
17+
} from '@/customizables';
718
import { useCardState } from '@/elements/contexts';
819
import { common, mqu } from '@/styledSystem';
920
import { Alert } from '@/ui/elements/Alert';
@@ -95,7 +106,7 @@ export const SelectProviderStep = (): JSX.Element => {
95106
key={group.id}
96107
elementDescriptor={descriptors.configureSSOProviderGroup}
97108
elementId={descriptors.configureSSOProviderGroup.setId(group.id)}
98-
sx={theme => ({ gap: theme.space.$3 })}
109+
gap={3}
99110
>
100111
<Text
101112
elementDescriptor={descriptors.configureSSOProviderGroupLabel}
@@ -178,53 +189,46 @@ const ProviderCard = ({ name, value, iconId, label, checked, onChange }: Provide
178189
elementDescriptor={descriptors.configureSSOProviderCard}
179190
elementId={descriptors.configureSSOProviderCard.setId(value)}
180191
isActive={checked}
181-
sx={theme => ({
182-
// Outline-button look (mirrors SimpleButton variant='outline' for visual continuity).
183-
borderWidth: theme.borderWidths.$normal,
184-
borderStyle: theme.borderStyles.$solid,
185-
borderColor: theme.colors.$borderAlpha150,
186-
borderRadius: theme.radii.$md,
187-
color: theme.colors.$neutralAlpha600,
192+
sx={t => ({
188193
display: 'flex',
189194
flexDirection: 'column',
190195
alignItems: 'center',
191196
justifyContent: 'center',
192-
gap: theme.space.$2,
193-
height: theme.sizes.$32,
194-
padding: theme.space.$1x5,
195-
backgroundColor: theme.colors.$colorBackground,
197+
gap: t.space.$2,
198+
height: t.sizes.$32,
199+
padding: t.space.$1x5,
196200
cursor: 'pointer',
197201
position: 'relative',
198-
'&:hover': { backgroundColor: theme.colors.$neutralAlpha50 },
199-
// Keyboard focus indication — fires when the inner input is focused.
202+
...common.borderVariants(t).normal,
200203
'&:has(input:focus-visible)': {
201-
...common.focusRingStyles(theme),
202-
borderColor: theme.colors.$borderAlpha300,
204+
...common.focusRingStyles(t),
205+
borderColor: t.colors.$borderAlpha300,
206+
},
207+
'&:hover': {
208+
backgroundColor: t.colors.$neutralAlpha50,
203209
},
204-
// Selected ring — CSS-driven via :checked so it survives focus changes.
205210
'&:has(input:checked)': {
206-
borderColor: theme.colors.$borderAlpha300,
207-
...common.focusRingStyles(theme),
211+
backgroundColor: t.colors.$neutralAlpha50,
208212
},
209213
})}
210214
>
211-
<input
212-
type='radio'
215+
<RadioInput
216+
elementDescriptor={descriptors.configureSSOProviderCardRadio}
217+
elementId={descriptors.configureSSOProviderCardRadio.setId(value)}
213218
name={name}
214219
value={value}
215220
checked={checked}
216221
onChange={onChange}
217-
css={{
222+
focusRing={false}
223+
sx={theme => ({
218224
position: 'absolute',
219-
width: '1px',
220-
height: '1px',
221-
padding: 0,
222-
margin: '-1px',
223-
overflow: 'hidden',
224-
clip: 'rect(0,0,0,0)',
225-
whiteSpace: 'nowrap',
226-
borderWidth: 0,
227-
}}
225+
top: theme.space.$1x5,
226+
insetInlineStart: theme.space.$1x5,
227+
margin: 0,
228+
width: 'fit-content',
229+
boxShadow: 'none',
230+
'&:hover': { boxShadow: 'none' },
231+
})}
228232
/>
229233

230234
<Span

packages/ui/src/customizables/elementDescriptors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ export const APPEARANCE_KEYS = containsAllElementsConfigKeys([
558558
'configureSSOProviderGroupLabel',
559559
'configureSSOProviderGrid',
560560
'configureSSOProviderCard',
561+
'configureSSOProviderCardRadio',
561562
'configureSSOProviderCardIcon',
562563
'configureSSOProviderCardLabel',
563564

packages/ui/src/internal/appearance.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ export type ElementsConfig = {
694694
configureSSOProviderGroupLabel: WithOptions<string>;
695695
configureSSOProviderGrid: WithOptions;
696696
configureSSOProviderCard: WithOptions<string, ActiveState>;
697+
configureSSOProviderCardRadio: WithOptions<string>;
697698
configureSSOProviderCardIcon: WithOptions<string>;
698699
configureSSOProviderCardLabel: WithOptions<string>;
699700

0 commit comments

Comments
 (0)