@supatype/react-native-auth 0.1.6
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.
- package/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-test.log +14 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/README.md +66 -0
- package/dist/AuthGate.d.ts +15 -0
- package/dist/AuthGate.d.ts.map +1 -0
- package/dist/AuthGate.js +19 -0
- package/dist/AuthGate.js.map +1 -0
- package/dist/LoginForm.d.ts +19 -0
- package/dist/LoginForm.d.ts.map +1 -0
- package/dist/LoginForm.js +45 -0
- package/dist/LoginForm.js.map +1 -0
- package/dist/MagicLinkForm.d.ts +20 -0
- package/dist/MagicLinkForm.d.ts.map +1 -0
- package/dist/MagicLinkForm.js +50 -0
- package/dist/MagicLinkForm.js.map +1 -0
- package/dist/OAuthButton.d.ts +27 -0
- package/dist/OAuthButton.d.ts.map +1 -0
- package/dist/OAuthButton.js +54 -0
- package/dist/OAuthButton.js.map +1 -0
- package/dist/ResetPassword.d.ts +28 -0
- package/dist/ResetPassword.d.ts.map +1 -0
- package/dist/ResetPassword.js +73 -0
- package/dist/ResetPassword.js.map +1 -0
- package/dist/SignUpForm.d.ts +20 -0
- package/dist/SignUpForm.d.ts.map +1 -0
- package/dist/SignUpForm.js +55 -0
- package/dist/SignUpForm.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.d.ts +76 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +77 -0
- package/dist/styles.js.map +1 -0
- package/dist/theme.d.ts +22 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +23 -0
- package/dist/theme.js.map +1 -0
- package/package.json +53 -0
- package/src/AuthGate.tsx +43 -0
- package/src/LoginForm.tsx +142 -0
- package/src/MagicLinkForm.tsx +136 -0
- package/src/OAuthButton.tsx +99 -0
- package/src/ResetPassword.tsx +191 -0
- package/src/SignUpForm.tsx +160 -0
- package/src/index.ts +24 -0
- package/src/react-native.d.ts +103 -0
- package/src/styles.ts +78 -0
- package/src/theme.tsx +45 -0
- package/tests/auth-ui.test.tsx +186 -0
- package/tests/mocks/react-native.ts +23 -0
- package/tsconfig.json +17 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +16 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
> @supatype/react-native-auth@0.1.6 test /home/runner/work/supatype/supatype/packages/react-native-auth
|
|
3
|
+
> vitest run
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[1m[46m RUN [49m[22m [36mv4.0.18 [39m[90m/home/runner/work/supatype/supatype/packages/react-native-auth[39m
|
|
7
|
+
|
|
8
|
+
[32m✓[39m tests/auth-ui.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m 126[2mms[22m[39m
|
|
9
|
+
|
|
10
|
+
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
11
|
+
[2m Tests [22m [1m[32m6 passed[39m[22m[90m (6)[39m
|
|
12
|
+
[2m Start at [22m 19:08:23
|
|
13
|
+
[2m Duration [22m 1.82s[2m (transform 617ms, setup 0ms, import 969ms, tests 126ms, environment 0ms)[22m
|
|
14
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# `@supatype/react-native-auth`
|
|
2
|
+
|
|
3
|
+
Pre-built React Native auth UI for Supatype (email, magic link, OAuth, password reset).
|
|
4
|
+
|
|
5
|
+
Requires a `<SupatypeProvider>` from `@supatype/react` and a client from `@supatype/react-native`.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx expo install @supatype/react @supatype/react-native @supatype/react-native-auth \
|
|
11
|
+
expo-secure-store expo-web-browser expo-linking
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import * as SecureStore from "expo-secure-store"
|
|
18
|
+
import * as WebBrowser from "expo-web-browser"
|
|
19
|
+
import * as Linking from "expo-linking"
|
|
20
|
+
import { SupatypeProvider } from "@supatype/react"
|
|
21
|
+
import { createNativeClient } from "@supatype/react-native"
|
|
22
|
+
import {
|
|
23
|
+
AuthGate,
|
|
24
|
+
AuthThemeProvider,
|
|
25
|
+
LoginForm,
|
|
26
|
+
MagicLinkForm,
|
|
27
|
+
OAuthButton,
|
|
28
|
+
ResetPassword,
|
|
29
|
+
SignUpForm,
|
|
30
|
+
} from "@supatype/react-native-auth"
|
|
31
|
+
|
|
32
|
+
const client = createNativeClient({
|
|
33
|
+
url: process.env.EXPO_PUBLIC_SUPATYPE_URL!,
|
|
34
|
+
anonKey: process.env.EXPO_PUBLIC_SUPATYPE_ANON_KEY!,
|
|
35
|
+
secureStore: SecureStore,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const redirectTo = Linking.createURL("auth/callback")
|
|
39
|
+
|
|
40
|
+
export default function App() {
|
|
41
|
+
return (
|
|
42
|
+
<SupatypeProvider client={client}>
|
|
43
|
+
<AuthThemeProvider>
|
|
44
|
+
<AuthGate
|
|
45
|
+
fallback={
|
|
46
|
+
<>
|
|
47
|
+
<LoginForm />
|
|
48
|
+
<MagicLinkForm redirectTo={redirectTo} />
|
|
49
|
+
<OAuthButton
|
|
50
|
+
provider="google"
|
|
51
|
+
redirectTo={redirectTo}
|
|
52
|
+
webBrowser={WebBrowser}
|
|
53
|
+
/>
|
|
54
|
+
<ResetPassword redirectTo={redirectTo} />
|
|
55
|
+
</>
|
|
56
|
+
}
|
|
57
|
+
>
|
|
58
|
+
{/* signed-in app */}
|
|
59
|
+
</AuthGate>
|
|
60
|
+
</AuthThemeProvider>
|
|
61
|
+
</SupatypeProvider>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
OAuth uses **PKCE** by default via `openOAuth`.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
export interface AuthGateProps {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
/** Rendered when signed out. Default: null. */
|
|
6
|
+
fallback?: React.ReactNode | undefined;
|
|
7
|
+
/** Rendered while the initial session is loading. Default: ActivityIndicator. */
|
|
8
|
+
loadingFallback?: React.ReactNode | undefined;
|
|
9
|
+
style?: StyleProp<ViewStyle> | undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Renders `children` only when a session exists. Must be inside `<SupatypeProvider>`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function AuthGate({ children, fallback, loadingFallback, style, }: AuthGateProps): React.ReactElement;
|
|
15
|
+
//# sourceMappingURL=AuthGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthGate.d.ts","sourceRoot":"","sources":["../src/AuthGate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAA2B,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAItF,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAA;IACtC,iFAAiF;IACjF,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAA;IAC7C,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;CACzC;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,QAAe,EACf,eAAe,EACf,KAAK,GACN,EAAE,aAAa,GAAG,KAAK,CAAC,YAAY,CAoBpC"}
|
package/dist/AuthGate.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { ActivityIndicator, View } from "react-native";
|
|
3
|
+
import { useAuth } from "@supatype/react";
|
|
4
|
+
import { useAuthTheme } from "./theme.js";
|
|
5
|
+
/**
|
|
6
|
+
* Renders `children` only when a session exists. Must be inside `<SupatypeProvider>`.
|
|
7
|
+
*/
|
|
8
|
+
export function AuthGate({ children, fallback = null, loadingFallback, style, }) {
|
|
9
|
+
const { session, loading } = useAuth();
|
|
10
|
+
const theme = useAuthTheme();
|
|
11
|
+
if (loading) {
|
|
12
|
+
return (_jsx(View, { style: [{ flex: 1, alignItems: "center", justifyContent: "center" }, style], testID: "st-auth-gate-loading", children: loadingFallback ?? _jsx(ActivityIndicator, { color: theme.colorPrimary, testID: "st-auth-gate-spinner" }) }));
|
|
13
|
+
}
|
|
14
|
+
if (session === null) {
|
|
15
|
+
return _jsx(_Fragment, { children: fallback });
|
|
16
|
+
}
|
|
17
|
+
return _jsx(_Fragment, { children: children });
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=AuthGate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthGate.js","sourceRoot":"","sources":["../src/AuthGate.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAkC,MAAM,cAAc,CAAA;AACtF,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAWzC;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,QAAQ,EACR,QAAQ,GAAG,IAAI,EACf,eAAe,EACf,KAAK,GACS;IACd,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAA;IACtC,MAAM,KAAK,GAAG,YAAY,EAAE,CAAA;IAE5B,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CACL,KAAC,IAAI,IACH,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,KAAK,CAAC,EAC3E,MAAM,EAAC,sBAAsB,YAE5B,eAAe,IAAI,KAAC,iBAAiB,IAAC,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,MAAM,EAAC,sBAAsB,GAAG,GAC7F,CACR,CAAA;IACH,CAAC;IAED,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,4BAAG,QAAQ,GAAI,CAAA;IACxB,CAAC;IAED,OAAO,4BAAG,QAAQ,GAAI,CAAA;AACxB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import type { Session, SupatypeError } from "@supatype/client";
|
|
4
|
+
export interface LoginFormLabels {
|
|
5
|
+
title?: string | undefined;
|
|
6
|
+
email?: string | undefined;
|
|
7
|
+
password?: string | undefined;
|
|
8
|
+
submit?: string | undefined;
|
|
9
|
+
errorPrefix?: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
export interface LoginFormProps {
|
|
12
|
+
onSuccess?: ((session: Session) => void) | undefined;
|
|
13
|
+
onError?: ((error: SupatypeError) => void) | undefined;
|
|
14
|
+
labels?: LoginFormLabels | undefined;
|
|
15
|
+
style?: StyleProp<ViewStyle> | undefined;
|
|
16
|
+
contentContainerStyle?: StyleProp<ViewStyle> | undefined;
|
|
17
|
+
}
|
|
18
|
+
export declare function LoginForm({ onSuccess, onError, labels, style, contentContainerStyle, }: LoginFormProps): React.ReactElement;
|
|
19
|
+
//# sourceMappingURL=LoginForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../src/LoginForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AACvC,OAAO,EAQL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAK9D,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACpD,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACtD,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS,CAAA;IACpC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;IACxC,qBAAqB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;CACzD;AAUD,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,OAAO,EACP,MAAM,EACN,KAAK,EACL,qBAAqB,GACtB,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,CA8FrC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { KeyboardAvoidingView, Platform, Pressable, ScrollView, Text, TextInput, View, } from "react-native";
|
|
4
|
+
import { useAuth } from "@supatype/react";
|
|
5
|
+
import { useAuthTheme } from "./theme.js";
|
|
6
|
+
import { fieldStyles } from "./styles.js";
|
|
7
|
+
const DEFAULT_LABELS = {
|
|
8
|
+
title: "Sign in",
|
|
9
|
+
email: "Email address",
|
|
10
|
+
password: "Password",
|
|
11
|
+
submit: "Sign in",
|
|
12
|
+
errorPrefix: "",
|
|
13
|
+
};
|
|
14
|
+
export function LoginForm({ onSuccess, onError, labels, style, contentContainerStyle, }) {
|
|
15
|
+
const { signIn } = useAuth();
|
|
16
|
+
const theme = useAuthTheme();
|
|
17
|
+
const styles = fieldStyles(theme);
|
|
18
|
+
const l = { ...DEFAULT_LABELS, ...labels };
|
|
19
|
+
const [email, setEmail] = useState("");
|
|
20
|
+
const [password, setPassword] = useState("");
|
|
21
|
+
const [loading, setLoading] = useState(false);
|
|
22
|
+
const [errorMessage, setErrorMessage] = useState(null);
|
|
23
|
+
async function handleSubmit() {
|
|
24
|
+
setErrorMessage(null);
|
|
25
|
+
setLoading(true);
|
|
26
|
+
try {
|
|
27
|
+
const { data, error } = await signIn({ email, password });
|
|
28
|
+
if (error !== null) {
|
|
29
|
+
const msg = `${l.errorPrefix}${error.message}`;
|
|
30
|
+
setErrorMessage(msg);
|
|
31
|
+
onError?.(error);
|
|
32
|
+
}
|
|
33
|
+
else if (data.session !== null) {
|
|
34
|
+
onSuccess?.(data.session);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
setLoading(false);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return (_jsx(KeyboardAvoidingView, { style: [{ flex: 1 }, style], behavior: Platform.OS === "ios" ? "padding" : undefined, children: _jsxs(ScrollView, { keyboardShouldPersistTaps: "handled", contentContainerStyle: [styles.root, contentContainerStyle], children: [_jsx(Text, { style: styles.title, children: l.title }), errorMessage !== null && (_jsx(Text, { style: styles.error, accessibilityRole: "alert", accessibilityLiveRegion: "polite", children: errorMessage })), _jsxs(View, { children: [_jsx(Text, { style: styles.label, children: l.email }), _jsx(TextInput, { testID: "st-login-email", style: styles.input, value: email, onChangeText: setEmail, autoCapitalize: "none", autoComplete: "email", keyboardType: "email-address", textContentType: "emailAddress", editable: !loading, accessibilityLabel: l.email, placeholderTextColor: theme.colorTextMuted })] }), _jsxs(View, { children: [_jsx(Text, { style: styles.label, children: l.password }), _jsx(TextInput, { testID: "st-login-password", style: styles.input, value: password, onChangeText: setPassword, secureTextEntry: true, autoComplete: "password", textContentType: "password", editable: !loading, accessibilityLabel: l.password, placeholderTextColor: theme.colorTextMuted })] }), _jsx(Pressable, { testID: "st-login-submit", accessibilityRole: "button", accessibilityLabel: l.submit, accessibilityState: { disabled: loading }, disabled: loading, onPress: () => {
|
|
42
|
+
void handleSubmit();
|
|
43
|
+
}, style: [styles.button, loading ? styles.buttonDisabled : null], children: _jsx(Text, { style: styles.buttonText, children: loading ? "Signing in…" : l.submit }) })] }) }));
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=LoginForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginForm.js","sourceRoot":"","sources":["../src/LoginForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import type { SupatypeError } from "@supatype/client";
|
|
4
|
+
export interface MagicLinkFormLabels {
|
|
5
|
+
title?: string | undefined;
|
|
6
|
+
email?: string | undefined;
|
|
7
|
+
submit?: string | undefined;
|
|
8
|
+
successMessage?: string | undefined;
|
|
9
|
+
}
|
|
10
|
+
export interface MagicLinkFormProps {
|
|
11
|
+
/** Deep link / redirect used as `emailRedirectTo` for the magic link. */
|
|
12
|
+
redirectTo?: string | undefined;
|
|
13
|
+
onSent?: (() => void) | undefined;
|
|
14
|
+
onError?: ((error: SupatypeError) => void) | undefined;
|
|
15
|
+
labels?: MagicLinkFormLabels | undefined;
|
|
16
|
+
style?: StyleProp<ViewStyle> | undefined;
|
|
17
|
+
contentContainerStyle?: StyleProp<ViewStyle> | undefined;
|
|
18
|
+
}
|
|
19
|
+
export declare function MagicLinkForm({ redirectTo, onSent, onError, labels, style, contentContainerStyle, }: MagicLinkFormProps): React.ReactElement;
|
|
20
|
+
//# sourceMappingURL=MagicLinkForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MagicLinkForm.d.ts","sourceRoot":"","sources":["../src/MagicLinkForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AACvC,OAAO,EAQL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAKrD,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAA;IACjC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACtD,MAAM,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAA;IACxC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;IACxC,qBAAqB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;CACzD;AASD,wBAAgB,aAAa,CAAC,EAC5B,UAAU,EACV,MAAM,EACN,OAAO,EACP,MAAM,EACN,KAAK,EACL,qBAAqB,GACtB,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAuFzC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { KeyboardAvoidingView, Platform, Pressable, ScrollView, Text, TextInput, View, } from "react-native";
|
|
4
|
+
import { useAuth } from "@supatype/react";
|
|
5
|
+
import { useAuthTheme } from "./theme.js";
|
|
6
|
+
import { fieldStyles } from "./styles.js";
|
|
7
|
+
const DEFAULT_LABELS = {
|
|
8
|
+
title: "Sign in with email",
|
|
9
|
+
email: "Email address",
|
|
10
|
+
submit: "Send magic link",
|
|
11
|
+
successMessage: "Check your email for a sign-in link.",
|
|
12
|
+
};
|
|
13
|
+
export function MagicLinkForm({ redirectTo, onSent, onError, labels, style, contentContainerStyle, }) {
|
|
14
|
+
const { signInWithOtp } = useAuth();
|
|
15
|
+
const theme = useAuthTheme();
|
|
16
|
+
const styles = fieldStyles(theme);
|
|
17
|
+
const l = { ...DEFAULT_LABELS, ...labels };
|
|
18
|
+
const [email, setEmail] = useState("");
|
|
19
|
+
const [loading, setLoading] = useState(false);
|
|
20
|
+
const [errorMessage, setErrorMessage] = useState(null);
|
|
21
|
+
const [sent, setSent] = useState(false);
|
|
22
|
+
async function handleSubmit() {
|
|
23
|
+
setErrorMessage(null);
|
|
24
|
+
setLoading(true);
|
|
25
|
+
try {
|
|
26
|
+
const { error } = await signInWithOtp({
|
|
27
|
+
email,
|
|
28
|
+
...(redirectTo !== undefined && { options: { emailRedirectTo: redirectTo } }),
|
|
29
|
+
});
|
|
30
|
+
if (error !== null) {
|
|
31
|
+
setErrorMessage(error.message);
|
|
32
|
+
onError?.(error);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
setSent(true);
|
|
36
|
+
onSent?.();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
setLoading(false);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (sent) {
|
|
44
|
+
return (_jsx(View, { style: [styles.root, style], testID: "st-magic-link-sent", children: _jsx(Text, { style: styles.muted, accessibilityLiveRegion: "polite", children: l.successMessage }) }));
|
|
45
|
+
}
|
|
46
|
+
return (_jsx(KeyboardAvoidingView, { style: [{ flex: 1 }, style], behavior: Platform.OS === "ios" ? "padding" : undefined, children: _jsxs(ScrollView, { keyboardShouldPersistTaps: "handled", contentContainerStyle: [styles.root, contentContainerStyle], children: [_jsx(Text, { style: styles.title, children: l.title }), errorMessage !== null && (_jsx(Text, { style: styles.error, accessibilityRole: "alert", children: errorMessage })), _jsxs(View, { children: [_jsx(Text, { style: styles.label, children: l.email }), _jsx(TextInput, { testID: "st-magic-link-email", style: styles.input, value: email, onChangeText: setEmail, autoCapitalize: "none", keyboardType: "email-address", editable: !loading, accessibilityLabel: l.email, placeholderTextColor: theme.colorTextMuted })] }), _jsx(Pressable, { testID: "st-magic-link-submit", accessibilityRole: "button", disabled: loading, onPress: () => {
|
|
47
|
+
void handleSubmit();
|
|
48
|
+
}, style: [styles.button, loading ? styles.buttonDisabled : null], children: _jsx(Text, { style: styles.buttonText, children: loading ? "Sending…" : l.submit }) })] }) }));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=MagicLinkForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MagicLinkForm.js","sourceRoot":"","sources":["../src/MagicLinkForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { type ReactNode } from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import type { Session, SupatypeError } from "@supatype/client";
|
|
4
|
+
import { type WebBrowserLike } from "@supatype/react-native";
|
|
5
|
+
export interface OAuthButtonProps {
|
|
6
|
+
provider: string;
|
|
7
|
+
/** Deep link URI (required for mobile OAuth). */
|
|
8
|
+
redirectTo: string;
|
|
9
|
+
/** Pass `import * as WebBrowser from "expo-web-browser"`. */
|
|
10
|
+
webBrowser: WebBrowserLike;
|
|
11
|
+
scopes?: string | undefined;
|
|
12
|
+
onSuccess?: ((session: Session) => void) | undefined;
|
|
13
|
+
onError?: ((error: {
|
|
14
|
+
message: string;
|
|
15
|
+
}) => void) | undefined;
|
|
16
|
+
onCancel?: (() => void) | undefined;
|
|
17
|
+
style?: StyleProp<ViewStyle> | undefined;
|
|
18
|
+
children?: ReactNode | undefined;
|
|
19
|
+
disabled?: boolean | undefined;
|
|
20
|
+
label?: string | undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* OAuth sign-in button. Uses PKCE via `@supatype/react-native` `openOAuth`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function OAuthButton({ provider, redirectTo, webBrowser, scopes, onSuccess, onError, onCancel, style, children, disabled, label, }: OAuthButtonProps): React.ReactElement;
|
|
26
|
+
export type { SupatypeError };
|
|
27
|
+
//# sourceMappingURL=OAuthButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OAuthButton.d.ts","sourceRoot":"","sources":["../src/OAuthButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACvD,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAC9E,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAE9D,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAIvE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,UAAU,EAAE,cAAc,CAAA;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACpD,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC5D,QAAQ,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAA;IACnC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3B;AAMD;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,UAAU,EACV,UAAU,EACV,MAAM,EACN,SAAS,EACT,OAAO,EACP,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,KAAK,GACN,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CAqDvC;AAED,YAAY,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Pressable, Text } from "react-native";
|
|
4
|
+
import { useSupatype } from "@supatype/react";
|
|
5
|
+
import { openOAuth } from "@supatype/react-native";
|
|
6
|
+
import { useAuthTheme } from "./theme.js";
|
|
7
|
+
import { fieldStyles } from "./styles.js";
|
|
8
|
+
function capitalize(s) {
|
|
9
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* OAuth sign-in button. Uses PKCE via `@supatype/react-native` `openOAuth`.
|
|
13
|
+
*/
|
|
14
|
+
export function OAuthButton({ provider, redirectTo, webBrowser, scopes, onSuccess, onError, onCancel, style, children, disabled, label, }) {
|
|
15
|
+
const client = useSupatype();
|
|
16
|
+
const theme = useAuthTheme();
|
|
17
|
+
const styles = fieldStyles(theme);
|
|
18
|
+
const [loading, setLoading] = useState(false);
|
|
19
|
+
const providerName = capitalize(provider);
|
|
20
|
+
const isDisabled = disabled === true || loading;
|
|
21
|
+
async function handlePress() {
|
|
22
|
+
setLoading(true);
|
|
23
|
+
try {
|
|
24
|
+
const { data, error, cancelled } = await openOAuth(client, {
|
|
25
|
+
provider,
|
|
26
|
+
redirectTo,
|
|
27
|
+
webBrowser,
|
|
28
|
+
...(scopes !== undefined && { scopes }),
|
|
29
|
+
});
|
|
30
|
+
if (cancelled) {
|
|
31
|
+
onCancel?.();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (error !== null) {
|
|
35
|
+
onError?.(error);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (data.session !== null) {
|
|
39
|
+
onSuccess?.(data.session);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
onError?.({ message: err instanceof Error ? err.message : "OAuth failed" });
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
setLoading(false);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return (_jsx(Pressable, { testID: `st-oauth-${provider}`, accessibilityRole: "button", accessibilityLabel: label ?? `Sign in with ${providerName}`, accessibilityState: { disabled: isDisabled }, disabled: isDisabled, onPress: () => {
|
|
50
|
+
void handlePress();
|
|
51
|
+
}, style: [styles.secondaryButton, isDisabled ? styles.buttonDisabled : null, style], children: _jsx(Text, { style: styles.secondaryButtonText, children: children ??
|
|
52
|
+
(loading ? `Connecting to ${providerName}…` : (label ?? `Sign in with ${providerName}`)) }) }));
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=OAuthButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OAuthButton.js","sourceRoot":"","sources":["../src/OAuthButton.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import type { Session, SupatypeError } from "@supatype/client";
|
|
4
|
+
export interface ResetPasswordLabels {
|
|
5
|
+
requestTitle?: string | undefined;
|
|
6
|
+
email?: string | undefined;
|
|
7
|
+
requestSubmit?: string | undefined;
|
|
8
|
+
requestSuccess?: string | undefined;
|
|
9
|
+
updateTitle?: string | undefined;
|
|
10
|
+
password?: string | undefined;
|
|
11
|
+
updateSubmit?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface ResetPasswordProps {
|
|
14
|
+
/**
|
|
15
|
+
* When set (from a recovery deep link after the user is signed in via recovery),
|
|
16
|
+
* shows the new-password form and calls `updateUser({ password })`.
|
|
17
|
+
*/
|
|
18
|
+
mode?: "request" | "update" | undefined;
|
|
19
|
+
redirectTo?: string | undefined;
|
|
20
|
+
onRequestSent?: (() => void) | undefined;
|
|
21
|
+
onPasswordUpdated?: ((session: Session | null) => void) | undefined;
|
|
22
|
+
onError?: ((error: SupatypeError) => void) | undefined;
|
|
23
|
+
labels?: ResetPasswordLabels | undefined;
|
|
24
|
+
style?: StyleProp<ViewStyle> | undefined;
|
|
25
|
+
contentContainerStyle?: StyleProp<ViewStyle> | undefined;
|
|
26
|
+
}
|
|
27
|
+
export declare function ResetPassword({ mode, redirectTo, onRequestSent, onPasswordUpdated, onError, labels, style, contentContainerStyle, }: ResetPasswordProps): React.ReactElement;
|
|
28
|
+
//# sourceMappingURL=ResetPassword.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResetPassword.d.ts","sourceRoot":"","sources":["../src/ResetPassword.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AACvC,OAAO,EAQL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAK9D,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAA;IACvC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,aAAa,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAA;IACxC,iBAAiB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACnE,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACtD,MAAM,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAA;IACxC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;IACxC,qBAAqB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;CACzD;AAYD,wBAAgB,aAAa,CAAC,EAC5B,IAAgB,EAChB,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,OAAO,EACP,MAAM,EACN,KAAK,EACL,qBAAqB,GACtB,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAiIzC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { KeyboardAvoidingView, Platform, Pressable, ScrollView, Text, TextInput, View, } from "react-native";
|
|
4
|
+
import { useSupatype } from "@supatype/react";
|
|
5
|
+
import { useAuthTheme } from "./theme.js";
|
|
6
|
+
import { fieldStyles } from "./styles.js";
|
|
7
|
+
const DEFAULT_LABELS = {
|
|
8
|
+
requestTitle: "Reset password",
|
|
9
|
+
email: "Email address",
|
|
10
|
+
requestSubmit: "Send reset link",
|
|
11
|
+
requestSuccess: "Check your email for a password reset link.",
|
|
12
|
+
updateTitle: "Choose a new password",
|
|
13
|
+
password: "New password",
|
|
14
|
+
updateSubmit: "Update password",
|
|
15
|
+
};
|
|
16
|
+
export function ResetPassword({ mode = "request", redirectTo, onRequestSent, onPasswordUpdated, onError, labels, style, contentContainerStyle, }) {
|
|
17
|
+
const client = useSupatype();
|
|
18
|
+
const theme = useAuthTheme();
|
|
19
|
+
const styles = fieldStyles(theme);
|
|
20
|
+
const l = { ...DEFAULT_LABELS, ...labels };
|
|
21
|
+
const [email, setEmail] = useState("");
|
|
22
|
+
const [password, setPassword] = useState("");
|
|
23
|
+
const [loading, setLoading] = useState(false);
|
|
24
|
+
const [errorMessage, setErrorMessage] = useState(null);
|
|
25
|
+
const [sent, setSent] = useState(false);
|
|
26
|
+
async function handleRequest() {
|
|
27
|
+
setErrorMessage(null);
|
|
28
|
+
setLoading(true);
|
|
29
|
+
try {
|
|
30
|
+
const { error } = await client.auth.resetPasswordForEmail(email, redirectTo !== undefined ? { redirectTo } : undefined);
|
|
31
|
+
if (error !== null) {
|
|
32
|
+
setErrorMessage(error.message);
|
|
33
|
+
onError?.(error);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
setSent(true);
|
|
37
|
+
onRequestSent?.();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
setLoading(false);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function handleUpdate() {
|
|
45
|
+
setErrorMessage(null);
|
|
46
|
+
setLoading(true);
|
|
47
|
+
try {
|
|
48
|
+
const { error } = await client.auth.updateUser({ password });
|
|
49
|
+
if (error !== null) {
|
|
50
|
+
setErrorMessage(error.message);
|
|
51
|
+
onError?.(error);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const { data } = await client.auth.getSession();
|
|
55
|
+
onPasswordUpdated?.(data.session);
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
setLoading(false);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (mode === "request" && sent) {
|
|
62
|
+
return (_jsx(View, { style: [styles.root, style], testID: "st-reset-sent", children: _jsx(Text, { style: styles.muted, accessibilityLiveRegion: "polite", children: l.requestSuccess }) }));
|
|
63
|
+
}
|
|
64
|
+
const isUpdate = mode === "update";
|
|
65
|
+
return (_jsx(KeyboardAvoidingView, { style: [{ flex: 1 }, style], behavior: Platform.OS === "ios" ? "padding" : undefined, children: _jsxs(ScrollView, { keyboardShouldPersistTaps: "handled", contentContainerStyle: [styles.root, contentContainerStyle], children: [_jsx(Text, { style: styles.title, children: isUpdate ? l.updateTitle : l.requestTitle }), errorMessage !== null && (_jsx(Text, { style: styles.error, accessibilityRole: "alert", children: errorMessage })), !isUpdate ? (_jsxs(View, { children: [_jsx(Text, { style: styles.label, children: l.email }), _jsx(TextInput, { testID: "st-reset-email", style: styles.input, value: email, onChangeText: setEmail, autoCapitalize: "none", keyboardType: "email-address", editable: !loading, accessibilityLabel: l.email, placeholderTextColor: theme.colorTextMuted })] })) : (_jsxs(View, { children: [_jsx(Text, { style: styles.label, children: l.password }), _jsx(TextInput, { testID: "st-reset-password", style: styles.input, value: password, onChangeText: setPassword, secureTextEntry: true, editable: !loading, accessibilityLabel: l.password, placeholderTextColor: theme.colorTextMuted })] })), _jsx(Pressable, { testID: "st-reset-submit", accessibilityRole: "button", disabled: loading, onPress: () => {
|
|
66
|
+
void (isUpdate ? handleUpdate() : handleRequest());
|
|
67
|
+
}, style: [styles.button, loading ? styles.buttonDisabled : null], children: _jsx(Text, { style: styles.buttonText, children: loading
|
|
68
|
+
? "Please wait…"
|
|
69
|
+
: isUpdate
|
|
70
|
+
? l.updateSubmit
|
|
71
|
+
: l.requestSubmit }) })] }) }));
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=ResetPassword.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResetPassword.js","sourceRoot":"","sources":["../src/ResetPassword.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import type { Session, SupatypeError } from "@supatype/client";
|
|
4
|
+
export interface SignUpFormLabels {
|
|
5
|
+
title?: string | undefined;
|
|
6
|
+
email?: string | undefined;
|
|
7
|
+
password?: string | undefined;
|
|
8
|
+
submit?: string | undefined;
|
|
9
|
+
successMessage?: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
export interface SignUpFormProps {
|
|
12
|
+
onSuccess?: ((session: Session | null) => void) | undefined;
|
|
13
|
+
onError?: ((error: SupatypeError) => void) | undefined;
|
|
14
|
+
labels?: SignUpFormLabels | undefined;
|
|
15
|
+
metadata?: Record<string, unknown> | undefined;
|
|
16
|
+
style?: StyleProp<ViewStyle> | undefined;
|
|
17
|
+
contentContainerStyle?: StyleProp<ViewStyle> | undefined;
|
|
18
|
+
}
|
|
19
|
+
export declare function SignUpForm({ onSuccess, onError, labels, metadata, style, contentContainerStyle, }: SignUpFormProps): React.ReactElement;
|
|
20
|
+
//# sourceMappingURL=SignUpForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SignUpForm.d.ts","sourceRoot":"","sources":["../src/SignUpForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AACvC,OAAO,EAQL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAK9D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC3D,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACtD,MAAM,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;IAC9C,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;IACxC,qBAAqB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;CACzD;AAUD,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,OAAO,EACP,MAAM,EACN,QAAQ,EACR,KAAK,EACL,qBAAqB,GACtB,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CA8GtC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { KeyboardAvoidingView, Platform, Pressable, ScrollView, Text, TextInput, View, } from "react-native";
|
|
4
|
+
import { useAuth } from "@supatype/react";
|
|
5
|
+
import { useAuthTheme } from "./theme.js";
|
|
6
|
+
import { fieldStyles } from "./styles.js";
|
|
7
|
+
const DEFAULT_LABELS = {
|
|
8
|
+
title: "Create account",
|
|
9
|
+
email: "Email address",
|
|
10
|
+
password: "Password",
|
|
11
|
+
submit: "Create account",
|
|
12
|
+
successMessage: "Check your email to confirm your account.",
|
|
13
|
+
};
|
|
14
|
+
export function SignUpForm({ onSuccess, onError, labels, metadata, style, contentContainerStyle, }) {
|
|
15
|
+
const { signUp } = useAuth();
|
|
16
|
+
const theme = useAuthTheme();
|
|
17
|
+
const styles = fieldStyles(theme);
|
|
18
|
+
const l = { ...DEFAULT_LABELS, ...labels };
|
|
19
|
+
const [email, setEmail] = useState("");
|
|
20
|
+
const [password, setPassword] = useState("");
|
|
21
|
+
const [loading, setLoading] = useState(false);
|
|
22
|
+
const [errorMessage, setErrorMessage] = useState(null);
|
|
23
|
+
const [confirmed, setConfirmed] = useState(false);
|
|
24
|
+
async function handleSubmit() {
|
|
25
|
+
setErrorMessage(null);
|
|
26
|
+
setLoading(true);
|
|
27
|
+
try {
|
|
28
|
+
const { data, error } = await signUp({
|
|
29
|
+
email,
|
|
30
|
+
password,
|
|
31
|
+
...(metadata !== undefined && { options: { data: metadata } }),
|
|
32
|
+
});
|
|
33
|
+
if (error !== null) {
|
|
34
|
+
setErrorMessage(error.message);
|
|
35
|
+
onError?.(error);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
if (data.session === null) {
|
|
39
|
+
setConfirmed(true);
|
|
40
|
+
}
|
|
41
|
+
onSuccess?.(data.session);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
setLoading(false);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (confirmed) {
|
|
49
|
+
return (_jsx(View, { style: [styles.root, style], children: _jsx(Text, { style: styles.muted, accessibilityRole: "text", accessibilityLiveRegion: "polite", children: l.successMessage }) }));
|
|
50
|
+
}
|
|
51
|
+
return (_jsx(KeyboardAvoidingView, { style: [{ flex: 1 }, style], behavior: Platform.OS === "ios" ? "padding" : undefined, children: _jsxs(ScrollView, { keyboardShouldPersistTaps: "handled", contentContainerStyle: [styles.root, contentContainerStyle], children: [_jsx(Text, { style: styles.title, children: l.title }), errorMessage !== null && (_jsx(Text, { style: styles.error, accessibilityRole: "alert", accessibilityLiveRegion: "polite", children: errorMessage })), _jsxs(View, { children: [_jsx(Text, { style: styles.label, children: l.email }), _jsx(TextInput, { testID: "st-signup-email", style: styles.input, value: email, onChangeText: setEmail, autoCapitalize: "none", keyboardType: "email-address", autoComplete: "email", textContentType: "emailAddress", editable: !loading, accessibilityLabel: l.email, placeholderTextColor: theme.colorTextMuted })] }), _jsxs(View, { children: [_jsx(Text, { style: styles.label, children: l.password }), _jsx(TextInput, { testID: "st-signup-password", style: styles.input, value: password, onChangeText: setPassword, secureTextEntry: true, autoComplete: "password-new", textContentType: "newPassword", editable: !loading, accessibilityLabel: l.password, placeholderTextColor: theme.colorTextMuted })] }), _jsx(Pressable, { testID: "st-signup-submit", accessibilityRole: "button", accessibilityLabel: l.submit, disabled: loading, onPress: () => {
|
|
52
|
+
void handleSubmit();
|
|
53
|
+
}, style: [styles.button, loading ? styles.buttonDisabled : null], children: _jsx(Text, { style: styles.buttonText, children: loading ? "Creating account…" : l.submit }) })] }) }));
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=SignUpForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SignUpForm.js","sourceRoot":"","sources":["../src/SignUpForm.tsx"],"names":[],"mappings":"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"}
|