diff --git a/.changeset/two-aliens-glow.md b/.changeset/two-aliens-glow.md new file mode 100644 index 00000000000..847dff581fd --- /dev/null +++ b/.changeset/two-aliens-glow.md @@ -0,0 +1,5 @@ +--- +'@clerk/react': patch +--- + +Prevent props from leaking to child elements in SignUpButton & SignInButton diff --git a/packages/react/src/components/SignInButton.tsx b/packages/react/src/components/SignInButton.tsx index fb45e4acbb6..729217fcffd 100644 --- a/packages/react/src/components/SignInButton.tsx +++ b/packages/react/src/components/SignInButton.tsx @@ -8,6 +8,8 @@ import { withClerk } from './withClerk'; export const SignInButton = withClerk( ({ clerk, children, ...props }: WithClerkProp>) => { const { + // @ts-expect-error - appearance is a valid prop for SignInProps & SignInButtonPropsModal + appearance, signUpFallbackRedirectUrl, forceRedirectUrl, fallbackRedirectUrl, @@ -33,7 +35,7 @@ export const SignInButton = withClerk( }; if (mode === 'modal') { - return clerk.openSignIn({ ...opts, appearance: props.appearance }); + return clerk.openSignIn({ ...opts, appearance }); } return clerk.redirectToSignIn({ ...opts, diff --git a/packages/react/src/components/SignUpButton.tsx b/packages/react/src/components/SignUpButton.tsx index 14cd75d4ac9..8beac5f6360 100644 --- a/packages/react/src/components/SignUpButton.tsx +++ b/packages/react/src/components/SignUpButton.tsx @@ -8,6 +8,10 @@ import { withClerk } from './withClerk'; export const SignUpButton = withClerk( ({ clerk, children, ...props }: WithClerkProp>) => { const { + // @ts-expect-error - appearance is a valid prop for SignUpProps & SignUpButtonPropsModal + appearance, + // @ts-expect-error - unsafeMetadata is a valid prop for SignUpProps & SignUpButtonPropsModal + unsafeMetadata, fallbackRedirectUrl, forceRedirectUrl, signInFallbackRedirectUrl, @@ -34,8 +38,8 @@ export const SignUpButton = withClerk( if (mode === 'modal') { return clerk.openSignUp({ ...opts, - appearance: props.appearance, - unsafeMetadata: props.unsafeMetadata, + appearance, + unsafeMetadata, }); } diff --git a/packages/react/src/components/__tests__/SignInButton.test.tsx b/packages/react/src/components/__tests__/SignInButton.test.tsx index b9eba07aa57..03523dd2d15 100644 --- a/packages/react/src/components/__tests__/SignInButton.test.tsx +++ b/packages/react/src/components/__tests__/SignInButton.test.tsx @@ -105,4 +105,18 @@ describe('', () => { ); }).toThrow(); }); + + it('does not pass appearance prop to child element', () => { + const { container } = render( + + + , + ); + + const button = container.querySelector('button'); + expect(button?.hasAttribute('appearance')).toBe(false); + }); }); diff --git a/packages/react/src/components/__tests__/SignUpButton.test.tsx b/packages/react/src/components/__tests__/SignUpButton.test.tsx index f3156c19bb9..89f0d63e153 100644 --- a/packages/react/src/components/__tests__/SignUpButton.test.tsx +++ b/packages/react/src/components/__tests__/SignUpButton.test.tsx @@ -109,4 +109,29 @@ describe('', () => { ); }).toThrow(); }); + + it('does not pass unsafeMetadata prop to child element', () => { + const { container } = render( + + + , + ); + + const button = container.querySelector('button'); + expect(button?.hasAttribute('unsafeMetadata')).toBe(false); + }); + + it('does not pass appearance prop to child element', () => { + const { container } = render( + + + , + ); + + const button = container.querySelector('button'); + expect(button?.hasAttribute('appearance')).toBe(false); + }); });