Skip to content

Commit 66691a6

Browse files
authored
feat(ui): Rename appearance.layout -> appearance.options (#7366)
1 parent 62136b7 commit 66691a6

27 files changed

+89
-83
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@clerk/ui': major
3+
---
4+
5+
Renamed `appearance.layout` to `appearance.options` across all appearance configurations. This is a breaking change - update all instances of `appearance.layout` to `appearance.options` in your codebase.
6+

packages/react/src/contexts/__tests__/ClerkProvider.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ describe('ClerkProvider', () => {
5353
expectTypeOf({ ...defaultProps, appearance: {} }).toMatchTypeOf<ClerkProviderProps>();
5454
});
5555

56-
it('includes variables, elements, layout, theme', () => {
56+
it('includes variables, elements, options baseTheme', () => {
5757
expectTypeOf({
5858
...defaultProps,
59-
appearance: { elements: {}, variables: {}, layout: {}, theme: dark },
59+
appearance: { elements: {}, variables: {}, options: {}, thene: dark },
6060
}).toMatchTypeOf<ClerkProviderProps>();
6161
});
6262

@@ -68,7 +68,7 @@ describe('ClerkProvider', () => {
6868

6969
expectTypeOf({
7070
...defaultProps,
71-
appearance: { layout: { nonExistentKey: '' } },
71+
appearance: { options: { nonExistentKey: '' } },
7272
}).not.toMatchTypeOf<ClerkProviderProps>();
7373

7474
// expectTypeOf({

packages/ui/src/components/Checkout/CheckoutComplete.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ export const CheckoutComplete = () => {
166166
const [mousePosition, setMousePosition] = useState({ x: 256, y: 256 });
167167

168168
const prefersReducedMotion = usePrefersReducedMotion();
169-
const { animations: layoutAnimations } = useAppearance().parsedLayout;
169+
const { animations: layoutAnimations } = useAppearance().parsedOptions;
170170
const isMotionSafe = !prefersReducedMotion && layoutAnimations === true;
171171

172172
const checkoutSuccessRootRef = useRef<HTMLSpanElement>(null);

packages/ui/src/components/PricingTable/PricingTableMatrix.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function PricingTableMatrix({
4040
highlightedPlan,
4141
}: PricingTableMatrixProps) {
4242
const prefersReducedMotion = usePrefersReducedMotion();
43-
const { animations: layoutAnimations } = useAppearance().parsedLayout;
43+
const { animations: layoutAnimations } = useAppearance().parsedOptions;
4444
const isMotionSafe = !prefersReducedMotion && layoutAnimations === true;
4545
const pricingTableMatrixId = React.useId();
4646
const segmentedControlId = `${pricingTableMatrixId}-segmented-control`;

packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ describe('SignInStart', () => {
212212
<AppearanceProvider
213213
appearanceKey={'signIn'}
214214
appearance={{
215-
layout: {
215+
options: {
216216
socialButtonsVariant: 'blockButton',
217217
},
218218
}}

packages/ui/src/components/SignUp/SignUpForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ export const SignUpForm = (props: SignUpFormProps) => {
2727
onlyLegalAcceptedMissing = false,
2828
handleEmailPhoneToggle,
2929
} = props;
30-
const { showOptionalFields } = useAppearance().parsedLayout;
30+
const { showOptionalFields } = useAppearance().parsedOptions;
3131

3232
const shouldShow = (name: keyof typeof fields) => {
3333
// In case both email & phone are optional, then don't take into account the
34-
// Layout showOptionalFields prop and the required field.
34+
// Options showOptionalFields prop and the required field.
3535
if ((name === 'emailAddress' || name === 'phoneNumber') && canToggleEmailPhone) {
3636
return !!fields[name];
3737
}

packages/ui/src/components/SignUp/SignUpStart.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function SignUpStartInternal(): JSX.Element {
3737
const clerk = useClerk();
3838
const status = useLoadingStatus();
3939
const signUp = useCoreSignUp();
40-
const { showOptionalFields } = useAppearance().parsedLayout;
40+
const { showOptionalFields } = useAppearance().parsedOptions;
4141
const { userSettings, authConfig } = useEnvironment();
4242
const { navigate } = useRouter();
4343
const { attributes } = userSettings;

packages/ui/src/components/SignUp/__tests__/SignUpStart.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ describe('SignUpStart', () => {
210210
<AppearanceProvider
211211
appearanceKey={'signUp'}
212212
appearance={{
213-
layout: {
213+
options: {
214214
socialButtonsVariant: 'blockButton',
215215
},
216216
}}

packages/ui/src/customizables/__tests__/parseAppearance.test.tsx

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,13 @@ describe('AppearanceProvider element flows', () => {
222222
});
223223
});
224224

225-
describe('AppearanceProvider layout flows', () => {
226-
it('sets the parsedLayout correctly from the globalAppearance prop', () => {
225+
describe('AppearanceProvider options flows', () => {
226+
it('sets the parsedOptions correctly from the globalAppearance prop', () => {
227227
const wrapper = ({ children }) => (
228228
<AppearanceProvider
229229
appearanceKey='signIn'
230230
globalAppearance={{
231-
layout: {
231+
options: {
232232
helpPageUrl: 'https://example.com/help',
233233
logoImageUrl: 'https://placehold.co/64x64.png',
234234
logoLinkUrl: 'https://example.com/',
@@ -246,23 +246,23 @@ describe('AppearanceProvider layout flows', () => {
246246
);
247247

248248
const { result } = renderHook(() => useAppearance(), { wrapper });
249-
expect(result.current.parsedLayout.helpPageUrl).toBe('https://example.com/help');
250-
expect(result.current.parsedLayout.logoImageUrl).toBe('https://placehold.co/64x64.png');
251-
expect(result.current.parsedLayout.logoLinkUrl).toBe('https://example.com/');
252-
expect(result.current.parsedLayout.privacyPageUrl).toBe('https://example.com/privacy');
253-
expect(result.current.parsedLayout.termsPageUrl).toBe('https://example.com/terms');
254-
expect(result.current.parsedLayout.logoPlacement).toBe('inside');
255-
expect(result.current.parsedLayout.showOptionalFields).toBe(false);
256-
expect(result.current.parsedLayout.socialButtonsPlacement).toBe('bottom');
257-
expect(result.current.parsedLayout.socialButtonsVariant).toBe('iconButton');
249+
expect(result.current.parsedOptions.helpPageUrl).toBe('https://example.com/help');
250+
expect(result.current.parsedOptions.logoImageUrl).toBe('https://placehold.co/64x64.png');
251+
expect(result.current.parsedOptions.logoLinkUrl).toBe('https://example.com/');
252+
expect(result.current.parsedOptions.privacyPageUrl).toBe('https://example.com/privacy');
253+
expect(result.current.parsedOptions.termsPageUrl).toBe('https://example.com/terms');
254+
expect(result.current.parsedOptions.logoPlacement).toBe('inside');
255+
expect(result.current.parsedOptions.showOptionalFields).toBe(false);
256+
expect(result.current.parsedOptions.socialButtonsPlacement).toBe('bottom');
257+
expect(result.current.parsedOptions.socialButtonsVariant).toBe('iconButton');
258258
});
259259

260-
it('sets the parsedLayout correctly from the appearance prop', () => {
260+
it('sets the parsedOptions correctly from the appearance prop', () => {
261261
const wrapper = ({ children }) => (
262262
<AppearanceProvider
263263
appearanceKey='signIn'
264264
appearance={{
265-
layout: {
265+
options: {
266266
helpPageUrl: 'https://example.com/help',
267267
logoImageUrl: 'https://placehold.co/64x64.png',
268268
logoLinkUrl: 'https://example.com/',
@@ -280,23 +280,23 @@ describe('AppearanceProvider layout flows', () => {
280280
);
281281

282282
const { result } = renderHook(() => useAppearance(), { wrapper });
283-
expect(result.current.parsedLayout.helpPageUrl).toBe('https://example.com/help');
284-
expect(result.current.parsedLayout.logoImageUrl).toBe('https://placehold.co/64x64.png');
285-
expect(result.current.parsedLayout.logoLinkUrl).toBe('https://example.com/');
286-
expect(result.current.parsedLayout.privacyPageUrl).toBe('https://example.com/privacy');
287-
expect(result.current.parsedLayout.termsPageUrl).toBe('https://example.com/terms');
288-
expect(result.current.parsedLayout.logoPlacement).toBe('outside');
289-
expect(result.current.parsedLayout.showOptionalFields).toBe(true);
290-
expect(result.current.parsedLayout.socialButtonsPlacement).toBe('top');
291-
expect(result.current.parsedLayout.socialButtonsVariant).toBe('blockButton');
283+
expect(result.current.parsedOptions.helpPageUrl).toBe('https://example.com/help');
284+
expect(result.current.parsedOptions.logoImageUrl).toBe('https://placehold.co/64x64.png');
285+
expect(result.current.parsedOptions.logoLinkUrl).toBe('https://example.com/');
286+
expect(result.current.parsedOptions.privacyPageUrl).toBe('https://example.com/privacy');
287+
expect(result.current.parsedOptions.termsPageUrl).toBe('https://example.com/terms');
288+
expect(result.current.parsedOptions.logoPlacement).toBe('outside');
289+
expect(result.current.parsedOptions.showOptionalFields).toBe(true);
290+
expect(result.current.parsedOptions.socialButtonsPlacement).toBe('top');
291+
expect(result.current.parsedOptions.socialButtonsVariant).toBe('blockButton');
292292
});
293293

294-
it('sets the parsedLayout correctly from the globalAppearance and appearance prop', () => {
294+
it('sets the parsedOptions correctly from the globalAppearance and appearance prop', () => {
295295
const wrapper = ({ children }) => (
296296
<AppearanceProvider
297297
appearanceKey='signIn'
298298
globalAppearance={{
299-
layout: {
299+
options: {
300300
helpPageUrl: 'https://example.com/help',
301301
logoImageUrl: 'https://placehold.co/64x64.png',
302302
logoLinkUrl: 'https://example.com/',
@@ -309,7 +309,7 @@ describe('AppearanceProvider layout flows', () => {
309309
},
310310
}}
311311
appearance={{
312-
layout: {
312+
options: {
313313
helpPageUrl: 'https://second.example.com/help',
314314
logoImageUrl: 'https://placehold.co/32x32@2.png',
315315
logoLinkUrl: 'https://second.example.com/',
@@ -327,15 +327,15 @@ describe('AppearanceProvider layout flows', () => {
327327
);
328328

329329
const { result } = renderHook(() => useAppearance(), { wrapper });
330-
expect(result.current.parsedLayout.helpPageUrl).toBe('https://second.example.com/help');
331-
expect(result.current.parsedLayout.logoImageUrl).toBe('https://placehold.co/32x32@2.png');
332-
expect(result.current.parsedLayout.logoLinkUrl).toBe('https://second.example.com/');
333-
expect(result.current.parsedLayout.privacyPageUrl).toBe('https://second.example.com/privacy');
334-
expect(result.current.parsedLayout.termsPageUrl).toBe('https://second.example.com/terms');
335-
expect(result.current.parsedLayout.logoPlacement).toBe('outside');
336-
expect(result.current.parsedLayout.showOptionalFields).toBe(true);
337-
expect(result.current.parsedLayout.socialButtonsPlacement).toBe('top');
338-
expect(result.current.parsedLayout.socialButtonsVariant).toBe('blockButton');
330+
expect(result.current.parsedOptions.helpPageUrl).toBe('https://second.example.com/help');
331+
expect(result.current.parsedOptions.logoImageUrl).toBe('https://placehold.co/32x32@2.png');
332+
expect(result.current.parsedOptions.logoLinkUrl).toBe('https://second.example.com/');
333+
expect(result.current.parsedOptions.privacyPageUrl).toBe('https://second.example.com/privacy');
334+
expect(result.current.parsedOptions.termsPageUrl).toBe('https://second.example.com/terms');
335+
expect(result.current.parsedOptions.logoPlacement).toBe('outside');
336+
expect(result.current.parsedOptions.showOptionalFields).toBe(true);
337+
expect(result.current.parsedOptions.socialButtonsPlacement).toBe('top');
338+
expect(result.current.parsedOptions.socialButtonsVariant).toBe('blockButton');
339339
});
340340

341341
it('removes the base theme when simpleStyles is passed to globalAppearance', () => {
@@ -426,7 +426,7 @@ describe('AppearanceProvider captcha', () => {
426426
expect(result.current.parsedCaptcha.language).toBe('el-GR');
427427
});
428428

429-
it('sets the parsedLayout correctly from the globalAppearance and appearance prop', () => {
429+
it('sets the parsedOptions correctly from the globalAppearance and appearance prop', () => {
430430
const wrapper = ({ children }) => (
431431
<AppearanceProvider
432432
appearanceKey='signIn'

packages/ui/src/customizables/parseAppearance.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { fastDeepMergeAndReplace } from '@clerk/shared/utils';
33

44
import { baseTheme, getBaseTheme } from '../baseTheme';
55
import { createInternalTheme, defaultInternalTheme } from '../foundations';
6-
import type { Appearance, CaptchaAppearanceOptions, Elements, Layout, Theme } from '../internal/appearance';
6+
import type { Appearance, CaptchaAppearanceOptions, Elements, Options, Theme } from '../internal/appearance';
77
import type { InternalTheme } from '../styledSystem';
88
import {
99
createColorScales,
@@ -17,7 +17,7 @@ import {
1717

1818
export type ParsedElements = Elements[];
1919
export type ParsedInternalTheme = InternalTheme;
20-
export type ParsedLayout = Required<Layout>;
20+
export type ParsedOptions = Required<Options>;
2121
export type ParsedCaptcha = Required<CaptchaAppearanceOptions>;
2222

2323
type PublicAppearanceTopLevelKey = keyof Omit<
@@ -34,11 +34,11 @@ export type AppearanceCascade = {
3434
export type ParsedAppearance = {
3535
parsedElements: ParsedElements;
3636
parsedInternalTheme: ParsedInternalTheme;
37-
parsedLayout: ParsedLayout;
37+
parsedOptions: ParsedOptions;
3838
parsedCaptcha: ParsedCaptcha;
3939
};
4040

41-
const defaultLayout: ParsedLayout = {
41+
const defaultOptions: ParsedOptions = {
4242
logoPlacement: 'inside',
4343
socialButtonsPlacement: 'top',
4444
socialButtonsVariant: 'auto',
@@ -75,7 +75,7 @@ export const parseAppearance = (cascade: AppearanceCascade): ParsedAppearance =>
7575
);
7676

7777
const parsedInternalTheme = parseVariables(appearanceList);
78-
const parsedLayout = parseLayout(appearanceList);
78+
const parsedOptions = parseOptions(appearanceList);
7979
const parsedCaptcha = parseCaptcha(appearanceList);
8080

8181
if (
@@ -97,7 +97,7 @@ export const parseAppearance = (cascade: AppearanceCascade): ParsedAppearance =>
9797
return res;
9898
}),
9999
);
100-
return { parsedElements, parsedInternalTheme, parsedLayout, parsedCaptcha };
100+
return { parsedElements, parsedInternalTheme, parsedOptions, parsedCaptcha };
101101
};
102102

103103
const expand = (theme: Theme | undefined, cascade: any[]) => {
@@ -124,8 +124,8 @@ const parseElements = (appearances: Appearance[]) => {
124124
return appearances.map(appearance => ({ ...appearance?.elements }));
125125
};
126126

127-
const parseLayout = (appearanceList: Appearance[]) => {
128-
return { ...defaultLayout, ...appearanceList.reduce((acc, appearance) => ({ ...acc, ...appearance.layout }), {}) };
127+
const parseOptions = (appearanceList: Appearance[]) => {
128+
return { ...defaultOptions, ...appearanceList.reduce((acc, appearance) => ({ ...acc, ...appearance.options }), {}) };
129129
};
130130

131131
const parseCaptcha = (appearanceList: Appearance[]) => {

0 commit comments

Comments
 (0)