@asgardeo/react 0.5.33 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,6 +46,10 @@ export interface FieldConfig {
46
46
  * Callback function when the field value changes.
47
47
  */
48
48
  onChange: (value: string) => void;
49
+ /**
50
+ * Callback function when the field loses focus.
51
+ */
52
+ onBlur?: () => void;
49
53
  /**
50
54
  * Whether the field is disabled.
51
55
  */
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3
+ *
4
+ * WSO2 LLC. licenses this file to you under the Apache License,
5
+ * Version 2.0 (the "License"); you may not use this file except
6
+ * in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing,
12
+ * software distributed under the License is distributed on an
13
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ * KIND, either express or implied. See the License for the
15
+ * specific language governing permissions and limitations
16
+ * under the License.
17
+ */
18
+ import { FC } from 'react';
19
+ import { BaseSignInProps as BaseSignInV1Props } from './non-component-driven/BaseSignIn';
20
+ import { BaseSignInProps as BaseSignInV2Props } from './component-driven/BaseSignIn';
21
+ /**
22
+ * Props for the BaseSignIn component.
23
+ * Extends BaseSignInV1Props & BaseSignInV2Props for full compatibility with both React BaseSignIn components.
24
+ */
25
+ export type BaseSignInProps = BaseSignInV1Props | BaseSignInV2Props;
26
+ declare const BaseSignIn: FC<BaseSignInProps>;
27
+ export default BaseSignIn;
@@ -16,13 +16,13 @@
16
16
  * under the License.
17
17
  */
18
18
  import { FC, ReactElement } from 'react';
19
- import { BaseSignInProps } from './non-component-driven/BaseSignIn';
19
+ import { BaseSignInProps as BaseSignInV1Props } from './non-component-driven/BaseSignIn';
20
20
  import { SignInRenderProps } from './component-driven/SignIn';
21
21
  /**
22
22
  * Props for the SignIn component.
23
23
  * Extends BaseSignInProps for full compatibility with the React BaseSignIn component
24
24
  */
25
- export type SignInProps = Pick<BaseSignInProps, 'className' | 'onSuccess' | 'onError' | 'variant' | 'size'> & {
25
+ export type SignInProps = Pick<BaseSignInV1Props, 'className' | 'onSuccess' | 'onError' | 'variant' | 'size'> & {
26
26
  /**
27
27
  * Render function for custom UI (render props pattern).
28
28
  */
@@ -24,6 +24,7 @@ export declare const renderSignInComponents: (components: EmbeddedFlowComponent[
24
24
  buttonClassName?: string;
25
25
  error?: string | null;
26
26
  inputClassName?: string;
27
+ onInputBlur?: (name: string) => void;
27
28
  onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>) => void;
28
29
  size?: "small" | "medium" | "large";
29
30
  variant?: any;
@@ -16,8 +16,67 @@
16
16
  * under the License.
17
17
  */
18
18
  import { EmbeddedFlowExecuteRequestPayload, EmbeddedFlowExecuteResponse } from '@asgardeo/browser';
19
- import { FC } from 'react';
19
+ import { FC, ReactNode } from 'react';
20
20
  import { CardProps } from '../../primitives/Card/Card';
21
+ /**
22
+ * Render props for custom UI rendering
23
+ */
24
+ export interface BaseSignUpRenderProps {
25
+ /**
26
+ * Form values
27
+ */
28
+ values: Record<string, string>;
29
+ /**
30
+ * Form errors
31
+ */
32
+ errors: Record<string, string>;
33
+ /**
34
+ * Touched fields
35
+ */
36
+ touched: Record<string, boolean>;
37
+ /**
38
+ * Whether the form is valid
39
+ */
40
+ isValid: boolean;
41
+ /**
42
+ * Loading state
43
+ */
44
+ isLoading: boolean;
45
+ /**
46
+ * Flow components
47
+ */
48
+ components: any[];
49
+ /**
50
+ * Function to handle input changes
51
+ */
52
+ handleInputChange: (name: string, value: string) => void;
53
+ /**
54
+ * Function to handle form submission
55
+ */
56
+ handleSubmit: (component: any, data?: Record<string, any>) => Promise<void>;
57
+ /**
58
+ * Function to validate the form
59
+ */
60
+ validateForm: () => {
61
+ isValid: boolean;
62
+ errors: Record<string, string>;
63
+ };
64
+ /**
65
+ * Flow title
66
+ */
67
+ title: string;
68
+ /**
69
+ * Flow subtitle
70
+ */
71
+ subtitle: string;
72
+ /**
73
+ * Flow messages
74
+ */
75
+ messages: Array<{
76
+ message: string;
77
+ type: string;
78
+ }>;
79
+ }
21
80
  /**
22
81
  * Props for the BaseSignUp component.
23
82
  */
@@ -86,6 +145,10 @@ export interface BaseSignUpProps {
86
145
  * Whether to redirect after sign-up.
87
146
  */
88
147
  shouldRedirectAfterSignUp?: boolean;
148
+ /**
149
+ * Render props function for custom UI
150
+ */
151
+ children?: (props: BaseSignUpRenderProps) => ReactNode;
89
152
  }
90
153
  /**
91
154
  * Base SignUp component that provides embedded sign-up flow.
@@ -93,6 +156,7 @@ export interface BaseSignUpProps {
93
156
  * It accepts API functions as props to maintain framework independence.
94
157
  *
95
158
  * @example
159
+ * // Default UI
96
160
  * ```tsx
97
161
  * import { BaseSignUp } from '@asgardeo/react';
98
162
  *
@@ -107,20 +171,41 @@ export interface BaseSignUpProps {
107
171
  * // Your API call to handle sign-up
108
172
  * return await handleSignUp(payload);
109
173
  * }}
110
- * onSuccess={(response) => {
111
- * console.log('Success:', response);
112
- * }} * onError={(error) => {
174
+ * onError={(error) => {
113
175
  * console.error('Error:', error);
114
176
  * }}
115
- * onComplete={(redirectUrl) => {
177
+ * onComplete={(response) => {
116
178
  * // Platform-specific redirect handling (e.g., Next.js router.push)
117
- * router.push(redirectUrl); // or window.location.href = redirectUrl
179
+ * router.push(response); // or window.location.href = redirectUrl
118
180
  * }}
119
181
  * className="max-w-md mx-auto"
120
182
  * />
121
183
  * );
122
184
  * };
123
185
  * ```
186
+ *
187
+ * @example
188
+ * // Custom UI with render props
189
+ * ```tsx
190
+ * <BaseSignUp onInitialize={initializeSignUp} onSubmit={handleSignUp}>
191
+ * {({values, errors, handleInputChange, handleSubmit, isLoading, components}) => (
192
+ * <div className="custom-form">
193
+ * <input
194
+ * name="username"
195
+ * value={values.username || ''}
196
+ * onChange={(e) => handleInputChange('username', e.target.value)}
197
+ * />
198
+ * {errors.username && <span>{errors.username}</span>}
199
+ * <button
200
+ * onClick={() => handleSubmit(components[0], values)}
201
+ * disabled={isLoading}
202
+ * >
203
+ * Sign Up
204
+ * </button>
205
+ * </div>
206
+ * )}
207
+ * </BaseSignUp>
208
+ * ```
124
209
  */
125
210
  declare const BaseSignUp: FC<BaseSignUpProps>;
126
211
  export default BaseSignUp;
@@ -15,17 +15,27 @@
15
15
  * specific language governing permissions and limitations
16
16
  * under the License.
17
17
  */
18
- import { FC } from 'react';
19
- import { BaseSignUpProps } from './BaseSignUp';
18
+ import { FC, ReactNode } from 'react';
19
+ import { BaseSignUpProps, BaseSignUpRenderProps } from './BaseSignUp';
20
+ /**
21
+ * Render props function parameters (re-exported from BaseSignUp for convenience)
22
+ */
23
+ export type SignUpRenderProps = BaseSignUpRenderProps;
20
24
  /**
21
25
  * Props for the SignUp component.
22
26
  */
23
- export type SignUpProps = BaseSignUpProps;
27
+ export type SignUpProps = BaseSignUpProps & {
28
+ /**
29
+ * Render props function for custom UI
30
+ */
31
+ children?: (props: SignUpRenderProps) => ReactNode;
32
+ };
24
33
  /**
25
34
  * A styled SignUp component that provides embedded sign-up flow with pre-built styling.
26
35
  * This component handles the API calls for sign-up and delegates UI logic to BaseSignUp.
27
36
  *
28
37
  * @example
38
+ * // Default UI
29
39
  * ```tsx
30
40
  * import { SignUp } from '@asgardeo/react';
31
41
  *
@@ -50,6 +60,45 @@ export type SignUpProps = BaseSignUpProps;
50
60
  * );
51
61
  * };
52
62
  * ```
63
+ *
64
+ * @example
65
+ * // Custom UI with render props
66
+ * ```tsx
67
+ * import { SignUp } from '@asgardeo/react';
68
+ *
69
+ * const App = () => {
70
+ * return (
71
+ * <SignUp
72
+ * onError={(error) => console.error('Error:', error)}
73
+ * onComplete={(response) => console.log('Success:', response)}
74
+ * >
75
+ * {({values, errors, handleInputChange, handleSubmit, isLoading, components}) => (
76
+ * <div className="custom-signup">
77
+ * <h1>Custom Sign Up</h1>
78
+ * {isLoading ? (
79
+ * <p>Loading...</p>
80
+ * ) : (
81
+ * <form onSubmit={(e) => {
82
+ * e.preventDefault();
83
+ * handleSubmit(components[0], values);
84
+ * }}>
85
+ * <input
86
+ * name="username"
87
+ * value={values.username || ''}
88
+ * onChange={(e) => handleInputChange('username', e.target.value)}
89
+ * />
90
+ * {errors.username && <span>{errors.username}</span>}
91
+ * <button type="submit" disabled={isLoading}>
92
+ * {isLoading ? 'Signing up...' : 'Sign Up'}
93
+ * </button>
94
+ * </form>
95
+ * )}
96
+ * </div>
97
+ * )}
98
+ * </SignUp>
99
+ * );
100
+ * };
101
+ * ```
53
102
  */
54
103
  declare const SignUp: FC<SignUpProps>;
55
104
  export default SignUp;
@@ -29,10 +29,6 @@ export interface BaseSignUpOptionProps extends WithPreferences {
29
29
  * The component configuration from the flow response.
30
30
  */
31
31
  component: EmbeddedFlowComponent;
32
- /**
33
- * Global error message to display.
34
- */
35
- error?: string | null;
36
32
  /**
37
33
  * Form validation errors.
38
34
  */
@@ -80,7 +76,6 @@ export declare const createSignUpComponent: ({ component, onSubmit, ...rest }: B
80
76
  */
81
77
  export declare const createSignUpOptionFromComponent: (component: EmbeddedFlowComponent, formValues: Record<string, string>, touchedFields: Record<string, boolean>, formErrors: Record<string, string>, isLoading: boolean, isFormValid: boolean, onInputChange: (name: string, value: string) => void, options?: {
82
78
  buttonClassName?: string;
83
- error?: string | null;
84
79
  inputClassName?: string;
85
80
  key?: string | number;
86
81
  onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>) => void;
@@ -92,7 +87,6 @@ export declare const createSignUpOptionFromComponent: (component: EmbeddedFlowCo
92
87
  */
93
88
  export declare const renderSignUpComponents: (components: EmbeddedFlowComponent[], formValues: Record<string, string>, touchedFields: Record<string, boolean>, formErrors: Record<string, string>, isLoading: boolean, isFormValid: boolean, onInputChange: (name: string, value: string) => void, options?: {
94
89
  buttonClassName?: string;
95
- error?: string | null;
96
90
  inputClassName?: string;
97
91
  onSubmit?: (component: EmbeddedFlowComponent, data?: Record<string, any>) => void;
98
92
  size?: "small" | "medium" | "large";
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3
+ *
4
+ * WSO2 LLC. licenses this file to you under the Apache License,
5
+ * Version 2.0 (the "License"); you may not use this file except
6
+ * in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing,
12
+ * software distributed under the License is distributed on an
13
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ * KIND, either express or implied. See the License for the
15
+ * specific language governing permissions and limitations
16
+ * under the License.
17
+ */
18
+ import { EmbeddedFlowComponent, EmbeddedSignUpFlowErrorResponseV2, EmbeddedFlowExecuteErrorResponse } from '@asgardeo/browser';
19
+ import { UseTranslation } from '../../../hooks/useTranslation';
20
+ /**
21
+ * Transform simple flow response to component-driven format
22
+ */
23
+ export declare const transformSimpleToComponentDriven: (response: any, t: UseTranslation["t"]) => EmbeddedFlowComponent[];
24
+ /**
25
+ * Extract error message from various error response formats.
26
+ *
27
+ * This function supports multiple error formats from different versions of Asgardeo APIs:
28
+ * - **AsgardeoV2 format**: Uses `failureReason` field from responses with `flowStatus: "ERROR"`
29
+ * - **AsgardeoV1 format**: Uses `description` or `message` fields from responses with error `code`
30
+ * - **AsgardeoAPIError**: Parses JSON from error messages to extract detailed error information
31
+ * - **Standard Error objects**: Falls back to the `message` property
32
+ * - **String errors**: Returns the string as-is
33
+ *
34
+ * @param error - The error object, which can be:
35
+ * - AsgardeoV2 error response: `{ flowStatus: "ERROR", failureReason: string, ... }`
36
+ * - AsgardeoV1 error response: `{ code: string, message?: string, description?: string, ... }`
37
+ * - AsgardeoAPIError instance with JSON message
38
+ * - Standard Error object
39
+ * - String error message
40
+ * @param t - Translation function for fallback error messages
41
+ * @returns Localized error message extracted from the error object
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * // AsgardeoV2 error
46
+ * const v2Error = { flowStatus: "ERROR", failureReason: "User already exists" };
47
+ * const message = extractErrorMessage(v2Error, t); // "User already exists"
48
+ *
49
+ * // AsgardeoV1 error
50
+ * const v1Error = { code: "FEE-60005", description: "Error while provisioning user" };
51
+ * const message = extractErrorMessage(v1Error, t); // "Error while provisioning user"
52
+ *
53
+ * // AsgardeoAPIError
54
+ * const apiError = new AsgardeoAPIError('{"failureReason": "Invalid credentials"}');
55
+ * const message = extractErrorMessage(apiError, t); // "Invalid credentials"
56
+ * ```
57
+ */
58
+ export declare const extractErrorMessage: (error: EmbeddedSignUpFlowErrorResponseV2 | EmbeddedFlowExecuteErrorResponse, t: UseTranslation["t"]) => string;
59
+ /**
60
+ * Check if a response is an error response and extract the error message.
61
+ *
62
+ * This function serves as a guard to identify error responses from successful responses
63
+ * in both AsgardeoV1 and AsgardeoV2 API formats. It's particularly useful for flow
64
+ * normalization where error responses should be handled differently from success responses.
65
+ *
66
+ * **Supported Error Response Formats:**
67
+ * - **AsgardeoV2**: Responses with `flowStatus: "ERROR"` and `failureReason`
68
+ * - **AsgardeoV1**: Responses with error `code` and `message`/`description` fields
69
+ *
70
+ * @param response - The API response object to check for error indicators
71
+ * @param t - Translation function for extracting localized error messages
72
+ * @returns `null` if the response is not an error, or the extracted error message string if it is an error
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * // Success response
77
+ * const successResponse = { flowStatus: "INCOMPLETE", data: { components: [] } };
78
+ * const error = checkForErrorResponse(successResponse, t); // null
79
+ *
80
+ * // AsgardeoV2 error response
81
+ * const v2ErrorResponse = {
82
+ * flowStatus: "ERROR",
83
+ * failureReason: "User already exists with the provided username."
84
+ * };
85
+ * const error = checkForErrorResponse(v2ErrorResponse, t); // "User already exists with the provided username."
86
+ *
87
+ * // AsgardeoV1 error response
88
+ * const v1ErrorResponse = {
89
+ * code: "FEE-60005",
90
+ * message: "Error while provisioning user.",
91
+ * description: "Error occurred while provisioning user in the request of flow id: ac57315c-6ca6-49dc-8664-fcdcff354f46"
92
+ * };
93
+ * const error = checkForErrorResponse(v1ErrorResponse, t); // "Error occurred while provisioning user in the request of flow id: ac57315c-6ca6-49dc-8664-fcdcff354f46"
94
+ * ```
95
+ */
96
+ export declare const checkForErrorResponse: (response: any, t: UseTranslation["t"]) => string | null;
97
+ /**
98
+ * Generic transformer that handles both simple and component-driven responses
99
+ * Also handles AsgardeoV2 error responses that should be thrown as errors
100
+ */
101
+ export declare const normalizeFlowResponse: (response: any, t: UseTranslation["t"]) => {
102
+ flowId: string;
103
+ components: EmbeddedFlowComponent[];
104
+ };
@@ -19,6 +19,10 @@ import { Theme } from '@asgardeo/browser';
19
19
  export interface ThemeContextValue {
20
20
  theme: Theme;
21
21
  colorScheme: 'light' | 'dark';
22
+ /**
23
+ * The text direction for the UI.
24
+ */
25
+ direction: 'ltr' | 'rtl';
22
26
  toggleTheme: () => void;
23
27
  /**
24
28
  * Whether branding theme is currently loading
@@ -56,6 +56,11 @@ export interface ThemeConfig {
56
56
  small: string;
57
57
  };
58
58
  colors: ThemeColors;
59
+ /**
60
+ * The text direction for the UI.
61
+ * @default 'ltr'
62
+ */
63
+ direction?: 'ltr' | 'rtl';
59
64
  shadows: {
60
65
  large: string;
61
66
  medium: string;
package/dist/index.d.ts CHANGED
@@ -83,8 +83,8 @@ export { default as SignedOut } from './components/control/SignedOut';
83
83
  export * from './components/control/SignedOut';
84
84
  export { default as Loading } from './components/control/Loading';
85
85
  export * from './components/control/Loading';
86
- export { default as BaseSignIn } from './components/presentation/SignIn/non-component-driven/BaseSignIn';
87
- export * from './components/presentation/SignIn/non-component-driven/BaseSignIn';
86
+ export { default as BaseSignIn } from './components/presentation/SignIn/BaseSignIn';
87
+ export * from './components/presentation/SignIn/BaseSignIn';
88
88
  export { default as SignIn } from './components/presentation/SignIn/SignIn';
89
89
  export * from './components/presentation/SignIn/SignIn';
90
90
  export { default as BaseSignUp } from './components/presentation/SignUp/BaseSignUp';