From 4b970fee3aec1924d9958f27920cbddfe0f599b0 Mon Sep 17 00:00:00 2001 From: Bryce Kalow Date: Wed, 3 Dec 2025 22:56:16 -0600 Subject: [PATCH 1/3] Rename appearance.layout -> appearance.options --- .changeset/rename-appearance-layout-to-options.md | 6 ++++++ .../react/src/contexts/__tests__/ClerkProvider.test.tsx | 6 +++--- .../src/components/SignIn/__tests__/SignInStart.test.tsx | 2 +- .../src/components/SignUp/__tests__/SignUpStart.test.tsx | 2 +- .../src/customizables/__tests__/parseAppearance.test.tsx | 8 ++++---- packages/ui/src/customizables/parseAppearance.ts | 4 ++-- packages/ui/src/internal/appearance.ts | 6 +++--- 7 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 .changeset/rename-appearance-layout-to-options.md diff --git a/.changeset/rename-appearance-layout-to-options.md b/.changeset/rename-appearance-layout-to-options.md new file mode 100644 index 00000000000..54f3c8343f1 --- /dev/null +++ b/.changeset/rename-appearance-layout-to-options.md @@ -0,0 +1,6 @@ +--- +'@clerk/ui': major +--- + +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. + diff --git a/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx b/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx index f5de7b7c282..8477d7a5e24 100644 --- a/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx +++ b/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx @@ -53,10 +53,10 @@ describe('ClerkProvider', () => { expectTypeOf({ ...defaultProps, appearance: {} }).toMatchTypeOf(); }); - it('includes variables, elements, layout baseTheme', () => { + it('includes variables, elements, options baseTheme', () => { expectTypeOf({ ...defaultProps, - appearance: { elements: {}, variables: {}, layout: {}, baseTheme: dark }, + appearance: { elements: {}, variables: {}, options: {}, baseTheme: dark }, }).toMatchTypeOf(); }); @@ -68,7 +68,7 @@ describe('ClerkProvider', () => { expectTypeOf({ ...defaultProps, - appearance: { layout: { nonExistentKey: '' } }, + appearance: { options: { nonExistentKey: '' } }, }).not.toMatchTypeOf(); // expectTypeOf({ diff --git a/packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx b/packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx index 27badf3fc20..a60b3883474 100644 --- a/packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx +++ b/packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx @@ -212,7 +212,7 @@ describe('SignInStart', () => { { { { { { }, }} appearance={{ - layout: { + options: { helpPageUrl: 'https://second.example.com/help', logoImageUrl: 'https://placehold.co/32x32@2.png', logoLinkUrl: 'https://second.example.com/', diff --git a/packages/ui/src/customizables/parseAppearance.ts b/packages/ui/src/customizables/parseAppearance.ts index 720dad3f7f4..599944633fd 100644 --- a/packages/ui/src/customizables/parseAppearance.ts +++ b/packages/ui/src/customizables/parseAppearance.ts @@ -22,7 +22,7 @@ export type ParsedCaptcha = Required; type PublicAppearanceTopLevelKey = keyof Omit< Appearance, - 'baseTheme' | 'theme' | 'elements' | 'layout' | 'variables' | 'captcha' | 'cssLayerName' + 'baseTheme' | 'theme' | 'elements' | 'options' | 'variables' | 'captcha' | 'cssLayerName' >; export type AppearanceCascade = { @@ -126,7 +126,7 @@ const parseElements = (appearances: Appearance[]) => { }; const parseLayout = (appearanceList: Appearance[]) => { - return { ...defaultLayout, ...appearanceList.reduce((acc, appearance) => ({ ...acc, ...appearance.layout }), {}) }; + return { ...defaultLayout, ...appearanceList.reduce((acc, appearance) => ({ ...acc, ...appearance.options }), {}) }; }; const parseCaptcha = (appearanceList: Appearance[]) => { diff --git a/packages/ui/src/internal/appearance.ts b/packages/ui/src/internal/appearance.ts index a0ae91c2c0a..bf14eb89b8f 100644 --- a/packages/ui/src/internal/appearance.ts +++ b/packages/ui/src/internal/appearance.ts @@ -867,7 +867,7 @@ export type BaseTheme = (BaseThemeTaggedType | 'clerk' | 'simple') & { cssLayerN export type Theme = { /** * A theme used as the base theme for the components. - * For further customisation, you can use the {@link Theme.layout}, {@link Theme.variables} and {@link Theme.elements} props. + * For further customisation, you can use the {@link Theme.options}, {@link Theme.variables} and {@link Theme.elements} props. * * Supports both object-based themes and string-based themes: * @@ -884,7 +884,7 @@ export type Theme = { /** * @deprecated Use `theme` instead. This property will be removed in a future version. * A theme used as the base theme for the components. - * For further customisation, you can use the {@link Theme.layout}, {@link Theme.variables} and {@link Theme.elements} props. + * For further customisation, you can use the {@link Theme.options}, {@link Theme.variables} and {@link Theme.elements} props. * * @example * import { dark } from "@clerk/ui/themes"; @@ -896,7 +896,7 @@ export type Theme = { * customizations that hard to implement with just CSS. * Eg: placing the logo outside the card element */ - layout?: Layout; + options?: Layout; /** * General theme overrides. This styles will be merged with our base theme. * Can override global styles like colors, fonts etc. From b256290c75f139f41e8915b4b16077223fb8d588 Mon Sep 17 00:00:00 2001 From: Bryce Kalow Date: Wed, 3 Dec 2025 22:56:30 -0600 Subject: [PATCH 2/3] adds changeset --- .changeset/hide-optional-fields-by-default.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/hide-optional-fields-by-default.md diff --git a/.changeset/hide-optional-fields-by-default.md b/.changeset/hide-optional-fields-by-default.md new file mode 100644 index 00000000000..7d3f00342bc --- /dev/null +++ b/.changeset/hide-optional-fields-by-default.md @@ -0,0 +1,6 @@ +--- +'@clerk/ui': minor +--- + +Changed the default value of `appearance.layout.showOptionalFields` from `true` to `false`. Optional fields are now hidden by default during sign up. Users can still explicitly set `showOptionalFields: true` to show optional fields. + From 563dd656f875df034954ae42d42073220744d588 Mon Sep 17 00:00:00 2001 From: Bryce Kalow Date: Wed, 3 Dec 2025 23:13:20 -0600 Subject: [PATCH 3/3] update usages --- .../components/Checkout/CheckoutComplete.tsx | 2 +- .../PricingTable/PricingTableMatrix.tsx | 2 +- .../ui/src/components/SignUp/SignUpForm.tsx | 4 +- .../ui/src/components/SignUp/SignUpStart.tsx | 2 +- .../__tests__/parseAppearance.test.tsx | 64 +++++++++---------- .../ui/src/customizables/parseAppearance.ts | 16 ++--- packages/ui/src/elements/Animated.tsx | 2 +- packages/ui/src/elements/ApplicationLogo.tsx | 6 +- packages/ui/src/elements/Card/CardFooter.tsx | 4 +- packages/ui/src/elements/Card/CardRoot.tsx | 2 +- packages/ui/src/elements/Drawer.tsx | 4 +- packages/ui/src/elements/FormControl.tsx | 2 +- packages/ui/src/elements/Header.tsx | 2 +- .../ui/src/elements/LegalConsentCheckbox.tsx | 6 +- packages/ui/src/elements/PopoverCard.tsx | 2 +- .../ui/src/elements/ReversibleContainer.tsx | 2 +- packages/ui/src/elements/SocialButtons.tsx | 2 +- packages/ui/src/elements/Tooltip.tsx | 2 +- .../ui/src/elements/withAvatarShimmer.tsx | 4 +- .../src/hooks/__tests__/useDevMode.test.tsx | 8 +-- packages/ui/src/hooks/useDevMode.tsx | 2 +- packages/ui/src/internal/appearance.ts | 4 +- packages/ui/src/internal/index.ts | 2 +- 23 files changed, 73 insertions(+), 73 deletions(-) diff --git a/packages/ui/src/components/Checkout/CheckoutComplete.tsx b/packages/ui/src/components/Checkout/CheckoutComplete.tsx index 20c1c907920..c329a310c71 100644 --- a/packages/ui/src/components/Checkout/CheckoutComplete.tsx +++ b/packages/ui/src/components/Checkout/CheckoutComplete.tsx @@ -166,7 +166,7 @@ export const CheckoutComplete = () => { const [mousePosition, setMousePosition] = useState({ x: 256, y: 256 }); const prefersReducedMotion = usePrefersReducedMotion(); - const { animations: layoutAnimations } = useAppearance().parsedLayout; + const { animations: layoutAnimations } = useAppearance().parsedOptions; const isMotionSafe = !prefersReducedMotion && layoutAnimations === true; const checkoutSuccessRootRef = useRef(null); diff --git a/packages/ui/src/components/PricingTable/PricingTableMatrix.tsx b/packages/ui/src/components/PricingTable/PricingTableMatrix.tsx index b8094e50e3d..4666b96d894 100644 --- a/packages/ui/src/components/PricingTable/PricingTableMatrix.tsx +++ b/packages/ui/src/components/PricingTable/PricingTableMatrix.tsx @@ -40,7 +40,7 @@ export function PricingTableMatrix({ highlightedPlan, }: PricingTableMatrixProps) { const prefersReducedMotion = usePrefersReducedMotion(); - const { animations: layoutAnimations } = useAppearance().parsedLayout; + const { animations: layoutAnimations } = useAppearance().parsedOptions; const isMotionSafe = !prefersReducedMotion && layoutAnimations === true; const pricingTableMatrixId = React.useId(); const segmentedControlId = `${pricingTableMatrixId}-segmented-control`; diff --git a/packages/ui/src/components/SignUp/SignUpForm.tsx b/packages/ui/src/components/SignUp/SignUpForm.tsx index 3e6591d5e76..6f8b09453d2 100644 --- a/packages/ui/src/components/SignUp/SignUpForm.tsx +++ b/packages/ui/src/components/SignUp/SignUpForm.tsx @@ -27,11 +27,11 @@ export const SignUpForm = (props: SignUpFormProps) => { onlyLegalAcceptedMissing = false, handleEmailPhoneToggle, } = props; - const { showOptionalFields } = useAppearance().parsedLayout; + const { showOptionalFields } = useAppearance().parsedOptions; const shouldShow = (name: keyof typeof fields) => { // In case both email & phone are optional, then don't take into account the - // Layout showOptionalFields prop and the required field. + // Options showOptionalFields prop and the required field. if ((name === 'emailAddress' || name === 'phoneNumber') && canToggleEmailPhone) { return !!fields[name]; } diff --git a/packages/ui/src/components/SignUp/SignUpStart.tsx b/packages/ui/src/components/SignUp/SignUpStart.tsx index b7f1b73a6f4..c32e64d23e2 100644 --- a/packages/ui/src/components/SignUp/SignUpStart.tsx +++ b/packages/ui/src/components/SignUp/SignUpStart.tsx @@ -37,7 +37,7 @@ function SignUpStartInternal(): JSX.Element { const clerk = useClerk(); const status = useLoadingStatus(); const signUp = useCoreSignUp(); - const { showOptionalFields } = useAppearance().parsedLayout; + const { showOptionalFields } = useAppearance().parsedOptions; const { userSettings, authConfig } = useEnvironment(); const { navigate } = useRouter(); const { attributes } = userSettings; diff --git a/packages/ui/src/customizables/__tests__/parseAppearance.test.tsx b/packages/ui/src/customizables/__tests__/parseAppearance.test.tsx index 5aef6f60d66..b849d8be6a4 100644 --- a/packages/ui/src/customizables/__tests__/parseAppearance.test.tsx +++ b/packages/ui/src/customizables/__tests__/parseAppearance.test.tsx @@ -222,8 +222,8 @@ describe('AppearanceProvider element flows', () => { }); }); -describe('AppearanceProvider layout flows', () => { - it('sets the parsedLayout correctly from the globalAppearance prop', () => { +describe('AppearanceProvider options flows', () => { + it('sets the parsedOptions correctly from the globalAppearance prop', () => { const wrapper = ({ children }) => ( { ); const { result } = renderHook(() => useAppearance(), { wrapper }); - expect(result.current.parsedLayout.helpPageUrl).toBe('https://example.com/help'); - expect(result.current.parsedLayout.logoImageUrl).toBe('https://placehold.co/64x64.png'); - expect(result.current.parsedLayout.logoLinkUrl).toBe('https://example.com/'); - expect(result.current.parsedLayout.privacyPageUrl).toBe('https://example.com/privacy'); - expect(result.current.parsedLayout.termsPageUrl).toBe('https://example.com/terms'); - expect(result.current.parsedLayout.logoPlacement).toBe('inside'); - expect(result.current.parsedLayout.showOptionalFields).toBe(false); - expect(result.current.parsedLayout.socialButtonsPlacement).toBe('bottom'); - expect(result.current.parsedLayout.socialButtonsVariant).toBe('iconButton'); + expect(result.current.parsedOptions.helpPageUrl).toBe('https://example.com/help'); + expect(result.current.parsedOptions.logoImageUrl).toBe('https://placehold.co/64x64.png'); + expect(result.current.parsedOptions.logoLinkUrl).toBe('https://example.com/'); + expect(result.current.parsedOptions.privacyPageUrl).toBe('https://example.com/privacy'); + expect(result.current.parsedOptions.termsPageUrl).toBe('https://example.com/terms'); + expect(result.current.parsedOptions.logoPlacement).toBe('inside'); + expect(result.current.parsedOptions.showOptionalFields).toBe(false); + expect(result.current.parsedOptions.socialButtonsPlacement).toBe('bottom'); + expect(result.current.parsedOptions.socialButtonsVariant).toBe('iconButton'); }); - it('sets the parsedLayout correctly from the appearance prop', () => { + it('sets the parsedOptions correctly from the appearance prop', () => { const wrapper = ({ children }) => ( { ); const { result } = renderHook(() => useAppearance(), { wrapper }); - expect(result.current.parsedLayout.helpPageUrl).toBe('https://example.com/help'); - expect(result.current.parsedLayout.logoImageUrl).toBe('https://placehold.co/64x64.png'); - expect(result.current.parsedLayout.logoLinkUrl).toBe('https://example.com/'); - expect(result.current.parsedLayout.privacyPageUrl).toBe('https://example.com/privacy'); - expect(result.current.parsedLayout.termsPageUrl).toBe('https://example.com/terms'); - expect(result.current.parsedLayout.logoPlacement).toBe('outside'); - expect(result.current.parsedLayout.showOptionalFields).toBe(true); - expect(result.current.parsedLayout.socialButtonsPlacement).toBe('top'); - expect(result.current.parsedLayout.socialButtonsVariant).toBe('blockButton'); + expect(result.current.parsedOptions.helpPageUrl).toBe('https://example.com/help'); + expect(result.current.parsedOptions.logoImageUrl).toBe('https://placehold.co/64x64.png'); + expect(result.current.parsedOptions.logoLinkUrl).toBe('https://example.com/'); + expect(result.current.parsedOptions.privacyPageUrl).toBe('https://example.com/privacy'); + expect(result.current.parsedOptions.termsPageUrl).toBe('https://example.com/terms'); + expect(result.current.parsedOptions.logoPlacement).toBe('outside'); + expect(result.current.parsedOptions.showOptionalFields).toBe(true); + expect(result.current.parsedOptions.socialButtonsPlacement).toBe('top'); + expect(result.current.parsedOptions.socialButtonsVariant).toBe('blockButton'); }); - it('sets the parsedLayout correctly from the globalAppearance and appearance prop', () => { + it('sets the parsedOptions correctly from the globalAppearance and appearance prop', () => { const wrapper = ({ children }) => ( { ); const { result } = renderHook(() => useAppearance(), { wrapper }); - expect(result.current.parsedLayout.helpPageUrl).toBe('https://second.example.com/help'); - expect(result.current.parsedLayout.logoImageUrl).toBe('https://placehold.co/32x32@2.png'); - expect(result.current.parsedLayout.logoLinkUrl).toBe('https://second.example.com/'); - expect(result.current.parsedLayout.privacyPageUrl).toBe('https://second.example.com/privacy'); - expect(result.current.parsedLayout.termsPageUrl).toBe('https://second.example.com/terms'); - expect(result.current.parsedLayout.logoPlacement).toBe('outside'); - expect(result.current.parsedLayout.showOptionalFields).toBe(true); - expect(result.current.parsedLayout.socialButtonsPlacement).toBe('top'); - expect(result.current.parsedLayout.socialButtonsVariant).toBe('blockButton'); + expect(result.current.parsedOptions.helpPageUrl).toBe('https://second.example.com/help'); + expect(result.current.parsedOptions.logoImageUrl).toBe('https://placehold.co/32x32@2.png'); + expect(result.current.parsedOptions.logoLinkUrl).toBe('https://second.example.com/'); + expect(result.current.parsedOptions.privacyPageUrl).toBe('https://second.example.com/privacy'); + expect(result.current.parsedOptions.termsPageUrl).toBe('https://second.example.com/terms'); + expect(result.current.parsedOptions.logoPlacement).toBe('outside'); + expect(result.current.parsedOptions.showOptionalFields).toBe(true); + expect(result.current.parsedOptions.socialButtonsPlacement).toBe('top'); + expect(result.current.parsedOptions.socialButtonsVariant).toBe('blockButton'); }); it('removes the baseTheme when simpleStyles is passed to globalAppearance', () => { @@ -426,7 +426,7 @@ describe('AppearanceProvider captcha', () => { expect(result.current.parsedCaptcha.language).toBe('el-GR'); }); - it('sets the parsedLayout correctly from the globalAppearance and appearance prop', () => { + it('sets the parsedOptions correctly from the globalAppearance and appearance prop', () => { const wrapper = ({ children }) => ( ; +export type ParsedOptions = Required; export type ParsedCaptcha = Required; type PublicAppearanceTopLevelKey = keyof Omit< @@ -34,11 +34,11 @@ export type AppearanceCascade = { export type ParsedAppearance = { parsedElements: ParsedElements; parsedInternalTheme: ParsedInternalTheme; - parsedLayout: ParsedLayout; + parsedOptions: ParsedOptions; parsedCaptcha: ParsedCaptcha; }; -const defaultLayout: ParsedLayout = { +const defaultOptions: ParsedOptions = { logoPlacement: 'inside', socialButtonsPlacement: 'top', socialButtonsVariant: 'auto', @@ -75,7 +75,7 @@ export const parseAppearance = (cascade: AppearanceCascade): ParsedAppearance => ); const parsedInternalTheme = parseVariables(appearanceList); - const parsedLayout = parseLayout(appearanceList); + const parsedOptions = parseOptions(appearanceList); const parsedCaptcha = parseCaptcha(appearanceList); if ( @@ -97,7 +97,7 @@ export const parseAppearance = (cascade: AppearanceCascade): ParsedAppearance => return res; }), ); - return { parsedElements, parsedInternalTheme, parsedLayout, parsedCaptcha }; + return { parsedElements, parsedInternalTheme, parsedOptions, parsedCaptcha }; }; const expand = (theme: Theme | undefined, cascade: any[]) => { @@ -125,8 +125,8 @@ const parseElements = (appearances: Appearance[]) => { return appearances.map(appearance => ({ ...appearance?.elements })); }; -const parseLayout = (appearanceList: Appearance[]) => { - return { ...defaultLayout, ...appearanceList.reduce((acc, appearance) => ({ ...acc, ...appearance.options }), {}) }; +const parseOptions = (appearanceList: Appearance[]) => { + return { ...defaultOptions, ...appearanceList.reduce((acc, appearance) => ({ ...acc, ...appearance.options }), {}) }; }; const parseCaptcha = (appearanceList: Appearance[]) => { diff --git a/packages/ui/src/elements/Animated.tsx b/packages/ui/src/elements/Animated.tsx index 6a7598cfa46..93f1ab4129a 100644 --- a/packages/ui/src/elements/Animated.tsx +++ b/packages/ui/src/elements/Animated.tsx @@ -7,7 +7,7 @@ type AnimatedProps = PropsWithChildren<{ asChild?: boolean }>; export const Animated = (props: AnimatedProps) => { const { children, asChild } = props; - const { animations } = useAppearance().parsedLayout; + const { animations } = useAppearance().parsedOptions; const [parent] = useAutoAnimate(); if (asChild) { diff --git a/packages/ui/src/elements/ApplicationLogo.tsx b/packages/ui/src/elements/ApplicationLogo.tsx index 8d70114c850..e4198b46890 100644 --- a/packages/ui/src/elements/ApplicationLogo.tsx +++ b/packages/ui/src/elements/ApplicationLogo.tsx @@ -48,10 +48,10 @@ export const ApplicationLogo: React.FC = (props: Applicati const imageRef = React.useRef(null); const [loaded, setLoaded] = React.useState(false); const { logoImageUrl, applicationName, homeUrl } = useEnvironment().displayConfig; - const { parsedLayout } = useAppearance(); - const imageSrc = src || parsedLayout.logoImageUrl || logoImageUrl; + const { parsedOptions } = useAppearance(); + const imageSrc = src || parsedOptions.logoImageUrl || logoImageUrl; const imageAlt = alt || applicationName; - const logoUrl = href || parsedLayout.logoLinkUrl || homeUrl; + const logoUrl = href || parsedOptions.logoLinkUrl || homeUrl; if (!imageSrc) { return null; diff --git a/packages/ui/src/elements/Card/CardFooter.tsx b/packages/ui/src/elements/Card/CardFooter.tsx index 344d18bba8d..4ba2f2ab849 100644 --- a/packages/ui/src/elements/Card/CardFooter.tsx +++ b/packages/ui/src/elements/Card/CardFooter.tsx @@ -15,7 +15,7 @@ export const CardFooter = React.forwardRef((pro const { displayConfig } = useEnvironment(); const { branded } = displayConfig; const { showDevModeNotice } = useDevMode(); - const { helpPageUrl, privacyPageUrl, termsPageUrl } = useAppearance().parsedLayout; + const { helpPageUrl, privacyPageUrl, termsPageUrl } = useAppearance().parsedOptions; const sponsorOrLinksExist = !!(branded || helpPageUrl || privacyPageUrl || termsPageUrl); const showSponsorAndLinks = isProfileFooter ? branded : sponsorOrLinksExist; @@ -87,7 +87,7 @@ const CardFooterLink = (props: PropsOfComponent): JSX.Element => { }; export const CardFooterLinks = React.memo((): JSX.Element | null => { - const { helpPageUrl, privacyPageUrl, termsPageUrl } = useAppearance().parsedLayout; + const { helpPageUrl, privacyPageUrl, termsPageUrl } = useAppearance().parsedOptions; if (!helpPageUrl && !privacyPageUrl && !termsPageUrl) { return null; diff --git a/packages/ui/src/elements/Card/CardRoot.tsx b/packages/ui/src/elements/Card/CardRoot.tsx index e010d8cb759..18f1d4b88d9 100644 --- a/packages/ui/src/elements/Card/CardRoot.tsx +++ b/packages/ui/src/elements/Card/CardRoot.tsx @@ -15,7 +15,7 @@ export const CardRoot = React.forwardRef((props, return ( <> - {appearance.parsedLayout.logoPlacement === 'outside' && ( + {appearance.parsedOptions.logoPlacement === 'outside' && ( ({ position: 'relative', diff --git a/packages/ui/src/elements/Drawer.tsx b/packages/ui/src/elements/Drawer.tsx index fdacf3b852b..29fb30caa35 100644 --- a/packages/ui/src/elements/Drawer.tsx +++ b/packages/ui/src/elements/Drawer.tsx @@ -201,7 +201,7 @@ interface ContentProps { const Content = React.forwardRef(({ children }, ref) => { const prefersReducedMotion = usePrefersReducedMotion(); - const { animations: layoutAnimations } = useAppearance().parsedLayout; + const { animations: layoutAnimations } = useAppearance().parsedOptions; const isMotionSafe = !prefersReducedMotion && layoutAnimations === true; const { strategy, refs, context, getFloatingProps, direction } = useDrawerContext(); const mergedRefs = useMergeRefs([ref, refs.setFloating]); @@ -454,7 +454,7 @@ interface ConfirmationProps { const Confirmation = React.forwardRef( ({ open, onOpenChange, children, actionsSlot, roleProps }, ref) => { const prefersReducedMotion = usePrefersReducedMotion(); - const { animations: layoutAnimations } = useAppearance().parsedLayout; + const { animations: layoutAnimations } = useAppearance().parsedOptions; const isMotionSafe = !prefersReducedMotion && layoutAnimations === true; const { refs, context } = useFloating({ diff --git a/packages/ui/src/elements/FormControl.tsx b/packages/ui/src/elements/FormControl.tsx index 045c1aa77e6..4e655b59fac 100644 --- a/packages/ui/src/elements/FormControl.tsx +++ b/packages/ui/src/elements/FormControl.tsx @@ -20,7 +20,7 @@ import type { FeedbackType, useFormControlFeedback } from '../utils/useFormContr function useFormTextAnimation() { const prefersReducedMotion = usePrefersReducedMotion(); - const { animations: appearanceAnimations } = useAppearance().parsedLayout; + const { animations: appearanceAnimations } = useAppearance().parsedOptions; const getFormTextAnimation = useCallback( (enterAnimation: boolean, options?: { inDelay?: boolean }): ThemableCssProp => { diff --git a/packages/ui/src/elements/Header.tsx b/packages/ui/src/elements/Header.tsx index 9c1c85ea812..17aa0286bfd 100644 --- a/packages/ui/src/elements/Header.tsx +++ b/packages/ui/src/elements/Header.tsx @@ -17,7 +17,7 @@ const Root = React.memo( const { sx, children, contentSx, gap = 6, showLogo = false, showDivider = false, ...rest } = props; const appearance = useAppearance(); - const logoIsVisible = appearance.parsedLayout.logoPlacement === 'inside' && showLogo; + const logoIsVisible = appearance.parsedOptions.logoPlacement === 'inside' && showLogo; const verticalDividerIsVisible = showDivider && logoIsVisible; return ( diff --git a/packages/ui/src/elements/LegalConsentCheckbox.tsx b/packages/ui/src/elements/LegalConsentCheckbox.tsx index e9ae27b16d4..fc72ff6ade8 100644 --- a/packages/ui/src/elements/LegalConsentCheckbox.tsx +++ b/packages/ui/src/elements/LegalConsentCheckbox.tsx @@ -72,10 +72,10 @@ export const LegalCheckbox = ( }, ) => { const { displayConfig } = useEnvironment(); - const { parsedLayout } = useAppearance(); + const { parsedOptions } = useAppearance(); - const termsLink = parsedLayout.termsPageUrl || displayConfig.termsUrl; - const privacyPolicy = parsedLayout.privacyPageUrl || displayConfig.privacyPolicyUrl; + const termsLink = parsedOptions.termsPageUrl || displayConfig.termsUrl; + const privacyPolicy = parsedOptions.privacyPageUrl || displayConfig.privacyPolicyUrl; return ( diff --git a/packages/ui/src/elements/PopoverCard.tsx b/packages/ui/src/elements/PopoverCard.tsx index a05073c28fd..92ac88cf2a7 100644 --- a/packages/ui/src/elements/PopoverCard.tsx +++ b/packages/ui/src/elements/PopoverCard.tsx @@ -74,7 +74,7 @@ const PopoverCardContent = (props: PropsOfComponent) => { const PopoverCardFooter = (props: PropsOfComponent) => { const { sx, children, ...rest } = props; const { branded } = useEnvironment().displayConfig; - const { privacyPageUrl, termsPageUrl, helpPageUrl } = useAppearance().parsedLayout; + const { privacyPageUrl, termsPageUrl, helpPageUrl } = useAppearance().parsedOptions; const shouldShowTagOrLinks = branded || privacyPageUrl || termsPageUrl || helpPageUrl; return ( diff --git a/packages/ui/src/elements/ReversibleContainer.tsx b/packages/ui/src/elements/ReversibleContainer.tsx index be18a6c761f..27d5dfbb279 100644 --- a/packages/ui/src/elements/ReversibleContainer.tsx +++ b/packages/ui/src/elements/ReversibleContainer.tsx @@ -11,7 +11,7 @@ export const SocialButtonsReversibleContainerWithDivider = (props: React.PropsWi return ( {childrenWithDivider} diff --git a/packages/ui/src/elements/SocialButtons.tsx b/packages/ui/src/elements/SocialButtons.tsx index 59fa511e1cb..2435f6f5111 100644 --- a/packages/ui/src/elements/SocialButtons.tsx +++ b/packages/ui/src/elements/SocialButtons.tsx @@ -69,7 +69,7 @@ export const SocialButtons = React.memo((props: SocialButtonsRootProps) => { const totalEnabledAuthMethods = useTotalEnabledAuthMethods(); const card = useCardState(); const clerk = useClerk(); - const { socialButtonsVariant } = useAppearance().parsedLayout; + const { socialButtonsVariant } = useAppearance().parsedOptions; type TStrategy = OAuthStrategy | Web3Strategy | PhoneCodeChannel; diff --git a/packages/ui/src/elements/Tooltip.tsx b/packages/ui/src/elements/Tooltip.tsx index 12412e48333..ee3447341ca 100644 --- a/packages/ui/src/elements/Tooltip.tsx +++ b/packages/ui/src/elements/Tooltip.tsx @@ -46,7 +46,7 @@ export function useTooltip({ const setOpen = setControlledOpen ?? setUncontrolledOpen; const prefersReducedMotion = usePrefersReducedMotion(); - const { animations: layoutAnimations } = useAppearance().parsedLayout; + const { animations: layoutAnimations } = useAppearance().parsedOptions; const isMotionSafe = !prefersReducedMotion && layoutAnimations === true; const data = useFloating({ diff --git a/packages/ui/src/elements/withAvatarShimmer.tsx b/packages/ui/src/elements/withAvatarShimmer.tsx index 849c39b57c2..ef39f14c3c9 100644 --- a/packages/ui/src/elements/withAvatarShimmer.tsx +++ b/packages/ui/src/elements/withAvatarShimmer.tsx @@ -10,14 +10,14 @@ import type { ThemableCssProp } from '../styledSystem'; */ export const withAvatarShimmer = (Component: React.ComponentType) => { return forwardRef((props, ref) => { - const { parsedLayout } = useAppearance(); + const { parsedOptions } = useAppearance(); return ( { }) as EnvironmentResource, ); mockUseAppearance.mockImplementationOnce(() => ({ - parsedLayout: { + parsedOptions: { unsafe_disableDevelopmentModeWarnings: false, }, })); @@ -57,7 +57,7 @@ describe('useDevMode', () => { }) as EnvironmentResource, ); mockUseAppearance.mockImplementationOnce(() => ({ - parsedLayout: { + parsedOptions: { unsafe_disableDevelopmentModeWarnings: false, }, })); @@ -79,7 +79,7 @@ describe('useDevMode', () => { }) as EnvironmentResource, ); mockUseAppearance.mockImplementationOnce(() => ({ - parsedLayout: { + parsedOptions: { unsafe_disableDevelopmentModeWarnings: false, }, })); @@ -101,7 +101,7 @@ describe('useDevMode', () => { }) as EnvironmentResource, ); mockUseAppearance.mockImplementationOnce(() => ({ - parsedLayout: { + parsedOptions: { unsafe_disableDevelopmentModeWarnings: true, }, })); diff --git a/packages/ui/src/hooks/useDevMode.tsx b/packages/ui/src/hooks/useDevMode.tsx index 19fb9cddf80..08550d633ef 100644 --- a/packages/ui/src/hooks/useDevMode.tsx +++ b/packages/ui/src/hooks/useDevMode.tsx @@ -6,7 +6,7 @@ import { useAppearance } from '../customizables'; export function useDevMode() { const { displayConfig, isDevelopmentOrStaging } = useEnvironment(); const isDevelopment = isDevelopmentOrStaging(); - const { unsafe_disableDevelopmentModeWarnings = false } = useAppearance().parsedLayout; + const { unsafe_disableDevelopmentModeWarnings = false } = useAppearance().parsedOptions; const developmentUiDisabled = isDevelopment && unsafe_disableDevelopmentModeWarnings; const showDevModeNotice = useMemo( () => !developmentUiDisabled && displayConfig.showDevModeWarning, diff --git a/packages/ui/src/internal/appearance.ts b/packages/ui/src/internal/appearance.ts index bf14eb89b8f..75b3b576097 100644 --- a/packages/ui/src/internal/appearance.ts +++ b/packages/ui/src/internal/appearance.ts @@ -896,7 +896,7 @@ export type Theme = { * customizations that hard to implement with just CSS. * Eg: placing the logo outside the card element */ - options?: Layout; + options?: Options; /** * General theme overrides. This styles will be merged with our base theme. * Can override global styles like colors, fonts etc. @@ -917,7 +917,7 @@ export type Theme = { captcha?: CaptchaAppearanceOptions; }; -export type Layout = { +export type Options = { /** * Controls whether the logo will be rendered inside or outside the component card. * To customise the logo further, you can use {@link Appearance.elements} diff --git a/packages/ui/src/internal/index.ts b/packages/ui/src/internal/index.ts index 211e987d817..a2c5c22e4a0 100644 --- a/packages/ui/src/internal/index.ts +++ b/packages/ui/src/internal/index.ts @@ -52,7 +52,7 @@ export type { ElementState, FontFamily, IdSelectors, - Layout, + Options, OAuthConsentTheme, OrganizationListTheme, OrganizationProfileTheme,