Skip to content

Commit ebfd3b1

Browse files
refactor(ui): Extract OAuth ListGroup component (#8283)
1 parent 4847a2b commit ebfd3b1

5 files changed

Lines changed: 162 additions & 66 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import { Box, Text, descriptors } from '@/ui/customizables';
2+
import { common } from '@/ui/styledSystem';
3+
import { colors } from '@/ui/utils/colors';
4+
import type { ComponentProps } from 'react';
5+
6+
export function ListGroup({ children, sx, ...props }: Omit<ComponentProps<typeof Box>, 'elementDescriptor'>) {
7+
return (
8+
<Box
9+
{...props}
10+
sx={[
11+
t => ({
12+
textAlign: 'start',
13+
borderWidth: t.borderWidths.$normal,
14+
borderStyle: t.borderStyles.$solid,
15+
borderColor: t.colors.$borderAlpha100,
16+
borderRadius: t.radii.$lg,
17+
overflow: 'hidden',
18+
}),
19+
sx,
20+
]}
21+
elementDescriptor={descriptors.listGroup}
22+
>
23+
{children}
24+
</Box>
25+
);
26+
}
27+
28+
export function ListGroupHeader({ children, sx, ...props }: Omit<ComponentProps<typeof Box>, 'elementDescriptor'>) {
29+
return (
30+
<Box
31+
{...props}
32+
sx={[
33+
t => ({
34+
padding: t.space.$3,
35+
background: common.mergedColorsBackground(
36+
colors.setAlpha(t.colors.$colorBackground, 1),
37+
t.colors.$neutralAlpha50,
38+
),
39+
}),
40+
sx,
41+
]}
42+
elementDescriptor={descriptors.listGroupHeader}
43+
>
44+
{children}
45+
</Box>
46+
);
47+
}
48+
49+
export function ListGroupHeaderTitle(props: Omit<ComponentProps<typeof Text>, 'elementDescriptor'>) {
50+
return (
51+
<Text
52+
{...props}
53+
variant='subtitle'
54+
elementDescriptor={descriptors.listGroupHeaderTitle}
55+
/>
56+
);
57+
}
58+
59+
export function ListGroupContent({
60+
children,
61+
sx,
62+
...props
63+
}: Omit<ComponentProps<typeof Box>, 'as' | 'elementDescriptor'>) {
64+
return (
65+
<Box
66+
{...props}
67+
as='ul'
68+
sx={[t => ({ margin: t.sizes.$none, padding: t.sizes.$none }), sx]}
69+
elementDescriptor={descriptors.listGroupContent}
70+
>
71+
{children}
72+
</Box>
73+
);
74+
}
75+
76+
export function ListGroupItem({
77+
children,
78+
sx,
79+
...props
80+
}: Omit<ComponentProps<typeof Box>, 'as' | 'elementDescriptor'>) {
81+
return (
82+
<Box
83+
{...props}
84+
as='li'
85+
sx={[
86+
t => ({
87+
display: 'flex',
88+
alignItems: 'baseline',
89+
paddingInline: t.space.$3,
90+
paddingBlock: t.space.$2,
91+
borderTopWidth: t.borderWidths.$normal,
92+
borderTopStyle: t.borderStyles.$solid,
93+
borderTopColor: t.colors.$borderAlpha100,
94+
'&::before': {
95+
content: '""',
96+
display: 'inline-block',
97+
width: t.space.$1,
98+
height: t.space.$1,
99+
background: t.colors.$colorMutedForeground,
100+
borderRadius: t.radii.$circle,
101+
transform: 'translateY(-0.1875rem)',
102+
marginInlineEnd: t.space.$2,
103+
flexShrink: 0,
104+
},
105+
}),
106+
sx,
107+
]}
108+
elementDescriptor={descriptors.listGroupItem}
109+
>
110+
{children}
111+
</Box>
112+
);
113+
}
114+
115+
export function ListGroupItemLabel(props: Omit<ComponentProps<typeof Text>, 'elementDescriptor'>) {
116+
return (
117+
<Text
118+
{...props}
119+
variant='subtitle'
120+
elementDescriptor={descriptors.listGroupItemLabel}
121+
/>
122+
);
123+
}

packages/ui/src/components/OAuthConsent/OAuthConsent.tsx

Lines changed: 24 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ import { common } from '@/ui/styledSystem';
1414
import { colors } from '@/ui/utils/colors';
1515
import { LogoGroup, LogoGroupItem, LogoGroupIcon, LogoGroupSeparator } from './LogoGroup';
1616
import { OrgSelect } from './OrgSelect';
17+
import {
18+
ListGroup,
19+
ListGroupContent,
20+
ListGroupHeader,
21+
ListGroupHeaderTitle,
22+
ListGroupItem,
23+
ListGroupItemLabel,
24+
} from './ListGroup';
1725

1826
const OFFLINE_ACCESS_SCOPE = 'offline_access';
1927

@@ -121,76 +129,26 @@ export function OAuthConsentInternal() {
121129
</Header.Root>
122130

123131
{selectOptions.length > 0 && (
124-
<Box>
125-
<OrgSelect
126-
options={selectOptions}
127-
value={selectedValue}
128-
onChange={setSelectedValue}
129-
/>
130-
</Box>
132+
<OrgSelect
133+
options={selectOptions}
134+
value={selectedValue}
135+
onChange={setSelectedValue}
136+
/>
131137
)}
132138

133-
<Box
134-
sx={t => ({
135-
textAlign: 'start',
136-
borderWidth: t.borderWidths.$normal,
137-
borderStyle: t.borderStyles.$solid,
138-
borderColor: t.colors.$borderAlpha100,
139-
borderRadius: t.radii.$lg,
140-
overflow: 'hidden',
141-
})}
142-
>
143-
<Box
144-
sx={t => ({
145-
padding: t.space.$3,
146-
background: common.mergedColorsBackground(
147-
colors.setAlpha(t.colors.$colorBackground, 1),
148-
t.colors.$neutralAlpha50,
149-
),
150-
})}
151-
>
152-
<Text
153-
variant='subtitle'
154-
localizationKey={`This will allow ${oAuthApplicationName} access to:`}
155-
/>
156-
</Box>
157-
<Box
158-
as='ul'
159-
sx={t => ({ margin: t.sizes.$none, padding: t.sizes.$none })}
160-
>
139+
<ListGroup>
140+
<ListGroupHeader>
141+
<ListGroupHeaderTitle localizationKey={`This will allow ${oAuthApplicationName} access to:`} />
142+
</ListGroupHeader>
143+
<ListGroupContent>
161144
{displayedScopes.map(item => (
162-
<Box
163-
key={item.scope}
164-
sx={t => ({
165-
display: 'flex',
166-
alignItems: 'baseline',
167-
paddingInline: t.space.$3,
168-
paddingBlock: t.space.$2,
169-
borderTopWidth: t.borderWidths.$normal,
170-
borderTopStyle: t.borderStyles.$solid,
171-
borderTopColor: t.colors.$borderAlpha100,
172-
'&::before': {
173-
content: '""',
174-
display: 'inline-block',
175-
width: t.space.$1,
176-
height: t.space.$1,
177-
background: t.colors.$colorMutedForeground,
178-
borderRadius: t.radii.$circle,
179-
transform: 'translateY(-0.1875rem)',
180-
marginInlineEnd: t.space.$2,
181-
flexShrink: 0,
182-
},
183-
})}
184-
as='li'
185-
>
186-
<Text
187-
variant='subtitle'
188-
localizationKey={item.description || item.scope || ''}
189-
/>
190-
</Box>
145+
<ListGroupItem key={item.scope}>
146+
<ListGroupItemLabel>{item.description || item.scope || ''}</ListGroupItemLabel>
147+
</ListGroupItem>
191148
))}
192-
</Box>
193-
</Box>
149+
</ListGroupContent>
150+
</ListGroup>
151+
194152
<Alert colorScheme='warning'>
195153
<Text
196154
colorScheme='warning'

packages/ui/src/components/OAuthConsent/OrgSelect.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export function OrgSelect({ options, value, onChange }: OrgSelectProps) {
7878
sx={theme => ({
7979
inlineSize: 'min(100%, 16rem)',
8080
paddingInline: theme.space.$3,
81+
marginInline: 'auto',
8182
})}
8283
>
8384
<Image

packages/ui/src/customizables/elementDescriptors.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ export const APPEARANCE_KEYS = containsAllElementsConfigKeys([
5858
'logoGroupIcon',
5959
'logoGroupSeparator',
6060

61+
'listGroup',
62+
'listGroupHeader',
63+
'listGroupHeaderTitle',
64+
'listGroupContent',
65+
'listGroupItem',
66+
'listGroupItemLabel',
67+
6168
'header',
6269
'headerTitle',
6370
'headerSubtitle',

packages/ui/src/internal/appearance.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,13 @@ export type ElementsConfig = {
186186
logoGroupIcon: WithOptions;
187187
logoGroupSeparator: WithOptions;
188188

189+
listGroup: WithOptions;
190+
listGroupHeader: WithOptions;
191+
listGroupHeaderTitle: WithOptions;
192+
listGroupContent: WithOptions;
193+
listGroupItem: WithOptions;
194+
listGroupItemLabel: WithOptions;
195+
189196
header: WithOptions;
190197
headerTitle: WithOptions;
191198
headerSubtitle: WithOptions;

0 commit comments

Comments
 (0)