diff --git a/CHANGELOG.md b/CHANGELOG.md
index 48862fe03..fa44ca008 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [unreleased]
+## [0.41.1] - 2024-05-13
+
+### Fixes
+
+- Custom `inputComponents` (in sign in/up form fields) now get reference-stable callbacks.
+
## [0.41.0] - 2024-05-09
### Breaking changes
diff --git a/examples/for-tests/src/App.js b/examples/for-tests/src/App.js
index e189c5862..9b28b6d16 100644
--- a/examples/for-tests/src/App.js
+++ b/examples/for-tests/src/App.js
@@ -1,4 +1,4 @@
-import { useEffect, useState } from "react";
+import { useEffect, useRef, useState } from "react";
import "./App.css";
import AppWithoutRouter from "./AppWithoutRouter";
@@ -289,21 +289,31 @@ const incorrectFormFields = [
},
];
+const DropdownInputComponent = ({ value, name, onChange }) => {
+ const onChangeRef = useRef(onChange);
+
+ if (onChangeRef.current !== onChange) {
+ throw new Error("callbacks passed to inputComponents should be reference stable");
+ }
+
+ return (
+
+ );
+};
+
const customFields = [
{
id: "select-dropdown",
label: "Select Dropdown",
nonOptionalErrorMsg: "Select dropdown is not an optional",
- inputComponent: ({ value, name, onChange }) => (
-
- ),
+ inputComponent: DropdownInputComponent,
optional: true,
},
{
diff --git a/lib/build/components/assets/blockedIcon.d.ts b/lib/build/components/assets/blockedIcon.d.ts
index 36a055cab..1832c8417 100644
--- a/lib/build/components/assets/blockedIcon.d.ts
+++ b/lib/build/components/assets/blockedIcon.d.ts
@@ -1 +1,2 @@
-export declare const BlockedIcon: () => import("react/jsx-runtime").JSX.Element;
+///
+export declare const BlockedIcon: () => JSX.Element;
diff --git a/lib/build/components/assets/otpEmailIcon.d.ts b/lib/build/components/assets/otpEmailIcon.d.ts
index f1424c14b..1de53f103 100644
--- a/lib/build/components/assets/otpEmailIcon.d.ts
+++ b/lib/build/components/assets/otpEmailIcon.d.ts
@@ -1 +1,2 @@
-export declare const OTPEmailIcon: () => import("react/jsx-runtime").JSX.Element;
+///
+export declare const OTPEmailIcon: () => JSX.Element;
diff --git a/lib/build/components/assets/otpSMSIcon.d.ts b/lib/build/components/assets/otpSMSIcon.d.ts
index cb6600f53..5e409d35a 100644
--- a/lib/build/components/assets/otpSMSIcon.d.ts
+++ b/lib/build/components/assets/otpSMSIcon.d.ts
@@ -1 +1,2 @@
-export declare const OTPSMSIcon: () => import("react/jsx-runtime").JSX.Element;
+///
+export declare const OTPSMSIcon: () => JSX.Element;
diff --git a/lib/build/components/assets/totpIcon.d.ts b/lib/build/components/assets/totpIcon.d.ts
index 091d00d00..8f2bba229 100644
--- a/lib/build/components/assets/totpIcon.d.ts
+++ b/lib/build/components/assets/totpIcon.d.ts
@@ -1 +1,2 @@
-export declare const TOTPIcon: () => import("react/jsx-runtime").JSX.Element;
+///
+export declare const TOTPIcon: () => JSX.Element;
diff --git a/lib/build/emailpassword-shared9.js b/lib/build/emailpassword-shared9.js
index 332ecdaea..dd97bee95 100644
--- a/lib/build/emailpassword-shared9.js
+++ b/lib/build/emailpassword-shared9.js
@@ -455,7 +455,7 @@ function InputComponentWrapper(props) {
value: value,
});
},
- [onInputFocus, field]
+ [onInputFocus, field.id]
);
var useCallbackOnInputBlur = React.useCallback(
function (value) {
@@ -464,7 +464,7 @@ function InputComponentWrapper(props) {
value: value,
});
},
- [onInputBlur, field]
+ [onInputBlur, field.id]
);
var useCallbackOnInputChange = React.useCallback(
function (value) {
@@ -473,7 +473,7 @@ function InputComponentWrapper(props) {
value: value,
});
},
- [onInputChange, field]
+ [onInputChange, field.id]
);
return field.inputComponent !== undefined
? jsxRuntime.jsx(field.inputComponent, {
diff --git a/lib/build/genericComponentOverrideContext.js b/lib/build/genericComponentOverrideContext.js
index 13c41d2cc..9e0f94c98 100644
--- a/lib/build/genericComponentOverrideContext.js
+++ b/lib/build/genericComponentOverrideContext.js
@@ -265,7 +265,7 @@ var SSR_ERROR =
* License for the specific language governing permissions and limitations
* under the License.
*/
-var package_version = "0.41.0";
+var package_version = "0.41.1";
/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
*
diff --git a/lib/build/recipe/emailpassword/components/library/formRow.d.ts b/lib/build/recipe/emailpassword/components/library/formRow.d.ts
index 6ce275da7..16521d4ad 100644
--- a/lib/build/recipe/emailpassword/components/library/formRow.d.ts
+++ b/lib/build/recipe/emailpassword/components/library/formRow.d.ts
@@ -2,8 +2,5 @@ import type { PropsWithChildren } from "react";
declare type FormRowProps = {
hasError?: boolean;
};
-export default function FormRow({
- children,
- hasError,
-}: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
+export default function FormRow({ children, hasError }: PropsWithChildren): JSX.Element;
export {};
diff --git a/lib/build/recipe/multitenancy/components/themes/dynamicLoginMethodsSpinner/index.d.ts b/lib/build/recipe/multitenancy/components/themes/dynamicLoginMethodsSpinner/index.d.ts
index 12fa33fbb..2998db3b7 100644
--- a/lib/build/recipe/multitenancy/components/themes/dynamicLoginMethodsSpinner/index.d.ts
+++ b/lib/build/recipe/multitenancy/components/themes/dynamicLoginMethodsSpinner/index.d.ts
@@ -1,4 +1,3 @@
+///
import type { NormalisedConfig } from "../../../types";
-export declare const DynamicLoginMethodsSpinnerTheme: (props: {
- config: NormalisedConfig;
-}) => import("react/jsx-runtime").JSX.Element;
+export declare const DynamicLoginMethodsSpinnerTheme: (props: { config: NormalisedConfig }) => JSX.Element;
diff --git a/lib/build/recipe/passwordless/components/themes/linkClickedScreen/index.d.ts b/lib/build/recipe/passwordless/components/themes/linkClickedScreen/index.d.ts
index 090465980..b81206107 100644
--- a/lib/build/recipe/passwordless/components/themes/linkClickedScreen/index.d.ts
+++ b/lib/build/recipe/passwordless/components/themes/linkClickedScreen/index.d.ts
@@ -1,2 +1,3 @@
+///
import type { LinkClickedScreenProps } from "../../../types";
-export declare const LinkClickedScreen: (props: LinkClickedScreenProps) => import("react/jsx-runtime").JSX.Element;
+export declare const LinkClickedScreen: (props: LinkClickedScreenProps) => JSX.Element;
diff --git a/lib/build/recipe/passwordless/components/themes/signInUp/phoneNumberInput.d.ts b/lib/build/recipe/passwordless/components/themes/signInUp/phoneNumberInput.d.ts
index 8a40578be..23021e2fd 100644
--- a/lib/build/recipe/passwordless/components/themes/signInUp/phoneNumberInput.d.ts
+++ b/lib/build/recipe/passwordless/components/themes/signInUp/phoneNumberInput.d.ts
@@ -17,4 +17,4 @@ declare function PhoneNumberInput({
export default PhoneNumberInput;
export declare const phoneNumberInputWithInjectedProps: (
injectedProps: Partial
-) => (props: any) => import("react/jsx-runtime").JSX.Element;
+) => (props: any) => JSX.Element;
diff --git a/lib/build/recipe/passwordless/recipe.d.ts b/lib/build/recipe/passwordless/recipe.d.ts
index 46c112da2..1fad76ad5 100644
--- a/lib/build/recipe/passwordless/recipe.d.ts
+++ b/lib/build/recipe/passwordless/recipe.d.ts
@@ -1,3 +1,4 @@
+///
import PasswordlessWebJS from "supertokens-web-js/recipe/passwordless";
import AuthRecipe from "../authRecipe";
import type {
@@ -13,14 +14,14 @@ export declare const otpPhoneFactor: {
name: string;
description: string;
path: string;
- logo: () => import("react/jsx-runtime").JSX.Element;
+ logo: () => JSX.Element;
};
export declare const otpEmailFactor: {
id: string;
name: string;
description: string;
path: string;
- logo: () => import("react/jsx-runtime").JSX.Element;
+ logo: () => JSX.Element;
};
export declare const passwordlessFirstFactors: readonly [string, string, string, string];
export default class Passwordless extends AuthRecipe<
diff --git a/lib/build/recipe/thirdparty/components/library/providerButton.d.ts b/lib/build/recipe/thirdparty/components/library/providerButton.d.ts
index ead01b079..33eb55a42 100644
--- a/lib/build/recipe/thirdparty/components/library/providerButton.d.ts
+++ b/lib/build/recipe/thirdparty/components/library/providerButton.d.ts
@@ -4,8 +4,4 @@ export declare type ProviderButtonProps = {
displayName: string;
logo?: JSX.Element;
};
-export default function ProviderButton({
- logo,
- providerName,
- displayName,
-}: ProviderButtonProps): import("react/jsx-runtime").JSX.Element;
+export default function ProviderButton({ logo, providerName, displayName }: ProviderButtonProps): JSX.Element;
diff --git a/lib/build/recipe/thirdparty/components/themes/signInAndUpCallback/index.d.ts b/lib/build/recipe/thirdparty/components/themes/signInAndUpCallback/index.d.ts
index 8945aff1a..96ebf1db4 100644
--- a/lib/build/recipe/thirdparty/components/themes/signInAndUpCallback/index.d.ts
+++ b/lib/build/recipe/thirdparty/components/themes/signInAndUpCallback/index.d.ts
@@ -1,4 +1,3 @@
+///
import type { NormalisedConfig } from "../../../types";
-export declare const SignInAndUpCallbackTheme: (props: {
- config: NormalisedConfig;
-}) => import("react/jsx-runtime").JSX.Element;
+export declare const SignInAndUpCallbackTheme: (props: { config: NormalisedConfig }) => JSX.Element;
diff --git a/lib/build/recipe/thirdparty/prebuiltui.d.ts b/lib/build/recipe/thirdparty/prebuiltui.d.ts
index 6beeb7748..adfd192bf 100644
--- a/lib/build/recipe/thirdparty/prebuiltui.d.ts
+++ b/lib/build/recipe/thirdparty/prebuiltui.d.ts
@@ -46,7 +46,7 @@ export declare class ThirdPartyPreBuiltUI extends RecipeRouter {
userContext?: UserContext | undefined;
}
>;
- static SignInAndUpCallbackTheme: (props: { config: NormalisedConfig }) => import("react/jsx-runtime").JSX.Element;
+ static SignInAndUpCallbackTheme: (props: { config: NormalisedConfig }) => JSX.Element;
}
declare const SignInAndUp: (
prop?: FeatureBaseProps<{
diff --git a/lib/build/recipe/thirdpartyemailpassword/prebuiltui.d.ts b/lib/build/recipe/thirdpartyemailpassword/prebuiltui.d.ts
index 91d1accf7..7c71c7db3 100644
--- a/lib/build/recipe/thirdpartyemailpassword/prebuiltui.d.ts
+++ b/lib/build/recipe/thirdpartyemailpassword/prebuiltui.d.ts
@@ -50,7 +50,7 @@ export declare class ThirdPartyEmailPasswordPreBuiltUI extends RecipeRouter {
) => JSX.Element;
static ThirdPartySignInAndUpCallbackTheme: (props: {
config: import("../thirdparty/types").NormalisedConfig;
- }) => import("react/jsx-runtime").JSX.Element;
+ }) => JSX.Element;
static ResetPasswordUsingTokenTheme: typeof ResetPasswordUsingTokenTheme;
static SignInAndUpTheme: typeof SignInAndUpTheme;
}
diff --git a/lib/build/recipe/thirdpartypasswordless/components/themes/signInUp/index.d.ts b/lib/build/recipe/thirdpartypasswordless/components/themes/signInUp/index.d.ts
index 184038689..7c7649bfe 100644
--- a/lib/build/recipe/thirdpartypasswordless/components/themes/signInUp/index.d.ts
+++ b/lib/build/recipe/thirdpartypasswordless/components/themes/signInUp/index.d.ts
@@ -1,5 +1,4 @@
+///
import type { ThirdPartyPasswordlessSignInAndUpThemeProps } from "../../../types";
-declare function SignInUpThemeWrapper(
- props: ThirdPartyPasswordlessSignInAndUpThemeProps
-): import("react/jsx-runtime").JSX.Element;
+declare function SignInUpThemeWrapper(props: ThirdPartyPasswordlessSignInAndUpThemeProps): JSX.Element;
export default SignInUpThemeWrapper;
diff --git a/lib/build/recipe/totp/recipe.d.ts b/lib/build/recipe/totp/recipe.d.ts
index 9f75f2a9e..e4f837463 100644
--- a/lib/build/recipe/totp/recipe.d.ts
+++ b/lib/build/recipe/totp/recipe.d.ts
@@ -1,3 +1,4 @@
+///
import TOTPWebJS from "supertokens-web-js/recipe/totp";
import RecipeModule from "../recipeModule";
import type {
@@ -13,7 +14,7 @@ export declare const totpFactor: {
name: string;
description: string;
path: string;
- logo: () => import("react/jsx-runtime").JSX.Element;
+ logo: () => JSX.Element;
};
export default class TOTP extends RecipeModule<
GetRedirectionURLContext,
diff --git a/lib/build/version.d.ts b/lib/build/version.d.ts
index a86c4904e..d1f3c4287 100644
--- a/lib/build/version.d.ts
+++ b/lib/build/version.d.ts
@@ -1 +1 @@
-export declare const package_version = "0.41.0";
+export declare const package_version = "0.41.1";
diff --git a/lib/ts/recipe/emailpassword/components/library/formBase.tsx b/lib/ts/recipe/emailpassword/components/library/formBase.tsx
index 3d44f9832..e045a176b 100644
--- a/lib/ts/recipe/emailpassword/components/library/formBase.tsx
+++ b/lib/ts/recipe/emailpassword/components/library/formBase.tsx
@@ -66,7 +66,7 @@ function InputComponentWrapper(props: {
value,
});
},
- [onInputFocus, field]
+ [onInputFocus, field.id]
);
const useCallbackOnInputBlur = useCallback<(value: string) => void>(
@@ -76,7 +76,7 @@ function InputComponentWrapper(props: {
value,
});
},
- [onInputBlur, field]
+ [onInputBlur, field.id]
);
const useCallbackOnInputChange = useCallback(
@@ -86,7 +86,7 @@ function InputComponentWrapper(props: {
value,
});
},
- [onInputChange, field]
+ [onInputChange, field.id]
);
return field.inputComponent !== undefined ? (
diff --git a/lib/ts/version.ts b/lib/ts/version.ts
index 1cb8c116b..18bbee7e8 100644
--- a/lib/ts/version.ts
+++ b/lib/ts/version.ts
@@ -12,4 +12,4 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
-export const package_version = "0.41.0";
+export const package_version = "0.41.1";
diff --git a/package-lock.json b/package-lock.json
index 57bc0a7b7..66e4beb78 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "supertokens-auth-react",
- "version": "0.41.0",
+ "version": "0.41.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "supertokens-auth-react",
- "version": "0.41.0",
+ "version": "0.41.1",
"license": "Apache-2.0",
"dependencies": {
"intl-tel-input": "^17.0.19",
diff --git a/package.json b/package.json
index b4b183a6e..447db5352 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "supertokens-auth-react",
- "version": "0.41.0",
+ "version": "0.41.1",
"description": "ReactJS SDK that provides login functionality with SuperTokens.",
"main": "./index.js",
"engines": {