@ccatto/auth-ui 0.1.0
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/README.md +94 -0
- package/dist/index.cjs +150 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +56 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.js +146 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# @ccatto/auth-ui
|
|
2
|
+
|
|
3
|
+
Presentational React forms for authentication flows: sign-in, register, and a `LoginCatto` card wrapper. Designed to slot into the Catto app template (`@ccatto/ui` + `next-intl` + your auth client of choice).
|
|
4
|
+
|
|
5
|
+
The components are **bring-your-own-auth** — they don't import Better Auth, JWT, or any other backend. You pass an `onSubmit` callback that does the auth call (and any navigation that should follow); the form handles the loading state and error display.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
yarn add @ccatto/auth-ui
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Peer deps: `react`, `next-intl`, `@ccatto/ui`.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
// app/[locale]/(public)/signin/page.tsx
|
|
19
|
+
'use client';
|
|
20
|
+
|
|
21
|
+
import { LoginCatto } from '@ccatto/auth-ui';
|
|
22
|
+
import { signIn } from '@/lib/auth-client-better';
|
|
23
|
+
import { useRouter } from '@/navigation';
|
|
24
|
+
|
|
25
|
+
export default function Page() {
|
|
26
|
+
const router = useRouter();
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<LoginCatto
|
|
30
|
+
onSubmit={async ({ email, password }) => {
|
|
31
|
+
const result = await signIn.email({ email, password });
|
|
32
|
+
if (result?.error) throw new Error(result.error.message);
|
|
33
|
+
router.push('/dashboard'); // or '/paddles', or wherever
|
|
34
|
+
}}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
// app/[locale]/(public)/signin/register/page.tsx
|
|
42
|
+
'use client';
|
|
43
|
+
|
|
44
|
+
import { RegisterUserFormCatto } from '@ccatto/auth-ui';
|
|
45
|
+
import { signUp } from '@/lib/auth-client-better';
|
|
46
|
+
import { useRouter } from '@/navigation';
|
|
47
|
+
|
|
48
|
+
export default function Page() {
|
|
49
|
+
const router = useRouter();
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<RegisterUserFormCatto
|
|
53
|
+
onSubmit={async ({ name, email, password }) => {
|
|
54
|
+
const result = await signUp.email({ name, email, password });
|
|
55
|
+
if (result?.error) throw new Error(result.error.message);
|
|
56
|
+
router.push('/dashboard');
|
|
57
|
+
}}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Translation keys
|
|
64
|
+
|
|
65
|
+
Default namespace is `auth`; override with the `i18nNamespace` prop. Within the namespace the components expect:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"signIn": {
|
|
70
|
+
"cardTitle": "Sign in to your account",
|
|
71
|
+
"emailLabel": "Email",
|
|
72
|
+
"passwordLabel": "Password",
|
|
73
|
+
"submit": "Sign in",
|
|
74
|
+
"submitting": "Signing in…",
|
|
75
|
+
"errorGeneric": "Sign in failed. Check your credentials and try again."
|
|
76
|
+
},
|
|
77
|
+
"register": {
|
|
78
|
+
"nameLabel": "Name",
|
|
79
|
+
"emailLabel": "Email",
|
|
80
|
+
"passwordLabel": "Password",
|
|
81
|
+
"submit": "Create account",
|
|
82
|
+
"submitting": "Creating account…",
|
|
83
|
+
"errorGeneric": "Could not create your account. Try again or contact support."
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Exports
|
|
89
|
+
|
|
90
|
+
- `LoginCatto` — `CardCatto` wrapper around `SignInEmailPassFormCatto`. Same props plus `cardVariant` / `cardWidth`.
|
|
91
|
+
- `SignInEmailPassFormCatto` — email + password form.
|
|
92
|
+
- `RegisterUserFormCatto` — name + email + password form.
|
|
93
|
+
|
|
94
|
+
All forms accept `i18nNamespace?: string` (default `'auth'`) and a required `onSubmit` callback.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var ui = require('@ccatto/ui');
|
|
5
|
+
var nextIntl = require('next-intl');
|
|
6
|
+
var react = require('react');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
|
|
9
|
+
// src/LoginCatto.tsx
|
|
10
|
+
var SignInEmailPassFormCatto = ({
|
|
11
|
+
onSubmit,
|
|
12
|
+
i18nNamespace = "auth"
|
|
13
|
+
}) => {
|
|
14
|
+
const t = nextIntl.useTranslations(i18nNamespace);
|
|
15
|
+
const [email, setEmail] = react.useState("");
|
|
16
|
+
const [password, setPassword] = react.useState("");
|
|
17
|
+
const [error, setError] = react.useState(null);
|
|
18
|
+
const [submitting, setSubmitting] = react.useState(false);
|
|
19
|
+
const handleSubmit = async (e) => {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
setError(null);
|
|
22
|
+
setSubmitting(true);
|
|
23
|
+
try {
|
|
24
|
+
await onSubmit({ email, password });
|
|
25
|
+
} catch (err) {
|
|
26
|
+
setError(err instanceof Error ? err.message : t("signIn.errorGeneric"));
|
|
27
|
+
} finally {
|
|
28
|
+
setSubmitting(false);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4 p-4", children: [
|
|
32
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
33
|
+
ui.InputCatto,
|
|
34
|
+
{
|
|
35
|
+
type: "email",
|
|
36
|
+
label: t("signIn.emailLabel"),
|
|
37
|
+
value: email,
|
|
38
|
+
onChange: (value) => setEmail(value),
|
|
39
|
+
required: true,
|
|
40
|
+
autoComplete: "email"
|
|
41
|
+
}
|
|
42
|
+
),
|
|
43
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
44
|
+
ui.InputCatto,
|
|
45
|
+
{
|
|
46
|
+
type: "password",
|
|
47
|
+
label: t("signIn.passwordLabel"),
|
|
48
|
+
value: password,
|
|
49
|
+
onChange: (value) => setPassword(value),
|
|
50
|
+
required: true,
|
|
51
|
+
autoComplete: "current-password"
|
|
52
|
+
}
|
|
53
|
+
),
|
|
54
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: error }),
|
|
55
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.ButtonCatto, { type: "submit", variant: "primary", disabled: submitting, children: submitting ? t("signIn.submitting") : t("signIn.submit") })
|
|
56
|
+
] });
|
|
57
|
+
};
|
|
58
|
+
var SignInEmailPassFormCatto_default = SignInEmailPassFormCatto;
|
|
59
|
+
var LoginCatto = ({
|
|
60
|
+
cardVariant = "midnightEmber",
|
|
61
|
+
cardWidth = "5xl",
|
|
62
|
+
i18nNamespace = "auth",
|
|
63
|
+
...formProps
|
|
64
|
+
}) => {
|
|
65
|
+
const t = nextIntl.useTranslations(i18nNamespace);
|
|
66
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-6 h-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
67
|
+
ui.CardCatto,
|
|
68
|
+
{
|
|
69
|
+
title: t("signIn.cardTitle"),
|
|
70
|
+
variant: cardVariant,
|
|
71
|
+
width: cardWidth,
|
|
72
|
+
headerComponent: /* @__PURE__ */ jsxRuntime.jsx(
|
|
73
|
+
SignInEmailPassFormCatto_default,
|
|
74
|
+
{
|
|
75
|
+
...formProps,
|
|
76
|
+
i18nNamespace
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
) });
|
|
81
|
+
};
|
|
82
|
+
var LoginCatto_default = LoginCatto;
|
|
83
|
+
var RegisterUserFormCatto = ({
|
|
84
|
+
onSubmit,
|
|
85
|
+
i18nNamespace = "auth"
|
|
86
|
+
}) => {
|
|
87
|
+
const t = nextIntl.useTranslations(i18nNamespace);
|
|
88
|
+
const [name, setName] = react.useState("");
|
|
89
|
+
const [email, setEmail] = react.useState("");
|
|
90
|
+
const [password, setPassword] = react.useState("");
|
|
91
|
+
const [error, setError] = react.useState(null);
|
|
92
|
+
const [submitting, setSubmitting] = react.useState(false);
|
|
93
|
+
const handleSubmit = async (e) => {
|
|
94
|
+
e.preventDefault();
|
|
95
|
+
setError(null);
|
|
96
|
+
setSubmitting(true);
|
|
97
|
+
try {
|
|
98
|
+
await onSubmit({ name, email, password });
|
|
99
|
+
} catch (err) {
|
|
100
|
+
setError(err instanceof Error ? err.message : t("register.errorGeneric"));
|
|
101
|
+
} finally {
|
|
102
|
+
setSubmitting(false);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4 p-4", children: [
|
|
106
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107
|
+
ui.InputCatto,
|
|
108
|
+
{
|
|
109
|
+
type: "text",
|
|
110
|
+
label: t("register.nameLabel"),
|
|
111
|
+
value: name,
|
|
112
|
+
onChange: (value) => setName(value),
|
|
113
|
+
required: true,
|
|
114
|
+
autoComplete: "name"
|
|
115
|
+
}
|
|
116
|
+
),
|
|
117
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
118
|
+
ui.InputCatto,
|
|
119
|
+
{
|
|
120
|
+
type: "email",
|
|
121
|
+
label: t("register.emailLabel"),
|
|
122
|
+
value: email,
|
|
123
|
+
onChange: (value) => setEmail(value),
|
|
124
|
+
required: true,
|
|
125
|
+
autoComplete: "email"
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
129
|
+
ui.InputCatto,
|
|
130
|
+
{
|
|
131
|
+
type: "password",
|
|
132
|
+
label: t("register.passwordLabel"),
|
|
133
|
+
value: password,
|
|
134
|
+
onChange: (value) => setPassword(value),
|
|
135
|
+
required: true,
|
|
136
|
+
autoComplete: "new-password",
|
|
137
|
+
minLength: 8
|
|
138
|
+
}
|
|
139
|
+
),
|
|
140
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: error }),
|
|
141
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.ButtonCatto, { type: "submit", variant: "primary", disabled: submitting, children: submitting ? t("register.submitting") : t("register.submit") })
|
|
142
|
+
] });
|
|
143
|
+
};
|
|
144
|
+
var RegisterUserFormCatto_default = RegisterUserFormCatto;
|
|
145
|
+
|
|
146
|
+
exports.LoginCatto = LoginCatto_default;
|
|
147
|
+
exports.RegisterUserFormCatto = RegisterUserFormCatto_default;
|
|
148
|
+
exports.SignInEmailPassFormCatto = SignInEmailPassFormCatto_default;
|
|
149
|
+
//# sourceMappingURL=index.cjs.map
|
|
150
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/SignInEmailPassFormCatto.tsx","../src/LoginCatto.tsx","../src/RegisterUserFormCatto.tsx"],"names":["useTranslations","useState","jsxs","jsx","InputCatto","ButtonCatto","CardCatto"],"mappings":"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","file":"index.cjs","sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { ButtonCatto, InputCatto } from '@ccatto/ui';\nimport { useTranslations } from 'next-intl';\n\nexport interface SignInValues {\n email: string;\n password: string;\n}\n\nexport interface SignInEmailPassFormCattoProps {\n /**\n * Called with `{ email, password }` when the user submits the form. Throw\n * (or reject) to surface an error message in the form. The component owns\n * its own loading + error UI; the caller owns the auth client and any\n * navigation that should happen on success.\n */\n onSubmit: (values: SignInValues) => Promise<void> | void;\n /**\n * next-intl namespace this form's labels are read from. The keys it expects\n * inside the namespace are `signIn.cardTitle`, `signIn.emailLabel`,\n * `signIn.passwordLabel`, `signIn.submit`, `signIn.submitting`,\n * `signIn.errorGeneric`. Defaults to `auth`.\n */\n i18nNamespace?: string;\n}\n\nconst SignInEmailPassFormCatto = ({\n onSubmit,\n i18nNamespace = 'auth',\n}: SignInEmailPassFormCattoProps) => {\n const t = useTranslations(i18nNamespace);\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [submitting, setSubmitting] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n setSubmitting(true);\n try {\n await onSubmit({ email, password });\n } catch (err) {\n setError(err instanceof Error ? err.message : t('signIn.errorGeneric'));\n } finally {\n setSubmitting(false);\n }\n };\n\n return (\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-4 p-4\">\n <InputCatto\n type=\"email\"\n label={t('signIn.emailLabel')}\n value={email}\n onChange={(value) => setEmail(value)}\n required\n autoComplete=\"email\"\n />\n <InputCatto\n type=\"password\"\n label={t('signIn.passwordLabel')}\n value={password}\n onChange={(value) => setPassword(value)}\n required\n autoComplete=\"current-password\"\n />\n {error && (\n <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p>\n )}\n <ButtonCatto type=\"submit\" variant=\"primary\" disabled={submitting}>\n {submitting ? t('signIn.submitting') : t('signIn.submit')}\n </ButtonCatto>\n </form>\n );\n};\n\nexport default SignInEmailPassFormCatto;\n","'use client';\n\nimport { CardCatto } from '@ccatto/ui';\nimport { useTranslations } from 'next-intl';\nimport SignInEmailPassFormCatto, {\n type SignInEmailPassFormCattoProps,\n} from './SignInEmailPassFormCatto';\n\nexport interface LoginCattoProps extends SignInEmailPassFormCattoProps {\n /** CardCatto variant. Defaults to 'midnightEmber'. */\n cardVariant?: string;\n /** CardCatto width. Defaults to '5xl'. */\n cardWidth?: string;\n}\n\nconst LoginCatto = ({\n cardVariant = 'midnightEmber',\n cardWidth = '5xl',\n i18nNamespace = 'auth',\n ...formProps\n}: LoginCattoProps) => {\n const t = useTranslations(i18nNamespace);\n\n return (\n <div className=\"mt-6 h-full\">\n <CardCatto\n title={t('signIn.cardTitle')}\n // CardCatto's variant + width props are loosely typed here so consumers\n // can pass any of the package's themes without us having to track the\n // union in two places.\n variant={cardVariant as never}\n width={cardWidth as never}\n headerComponent={\n <SignInEmailPassFormCatto\n {...formProps}\n i18nNamespace={i18nNamespace}\n />\n }\n />\n </div>\n );\n};\n\nexport default LoginCatto;\n","'use client';\n\nimport { useState } from 'react';\nimport { ButtonCatto, InputCatto } from '@ccatto/ui';\nimport { useTranslations } from 'next-intl';\n\nexport interface RegisterValues {\n name: string;\n email: string;\n password: string;\n}\n\nexport interface RegisterUserFormCattoProps {\n /**\n * Called with `{ name, email, password }` when the user submits the form.\n * Throw (or reject) to surface an error message. The component owns its\n * own loading + error UI; the caller owns the auth client and any\n * post-register navigation.\n */\n onSubmit: (values: RegisterValues) => Promise<void> | void;\n /**\n * next-intl namespace this form's labels are read from. The keys it expects\n * inside the namespace are `register.nameLabel`, `register.emailLabel`,\n * `register.passwordLabel`, `register.submit`, `register.submitting`,\n * `register.errorGeneric`. Defaults to `auth`.\n */\n i18nNamespace?: string;\n}\n\nconst RegisterUserFormCatto = ({\n onSubmit,\n i18nNamespace = 'auth',\n}: RegisterUserFormCattoProps) => {\n const t = useTranslations(i18nNamespace);\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [submitting, setSubmitting] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n setSubmitting(true);\n try {\n await onSubmit({ name, email, password });\n } catch (err) {\n setError(err instanceof Error ? err.message : t('register.errorGeneric'));\n } finally {\n setSubmitting(false);\n }\n };\n\n return (\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-4 p-4\">\n <InputCatto\n type=\"text\"\n label={t('register.nameLabel')}\n value={name}\n onChange={(value) => setName(value)}\n required\n autoComplete=\"name\"\n />\n <InputCatto\n type=\"email\"\n label={t('register.emailLabel')}\n value={email}\n onChange={(value) => setEmail(value)}\n required\n autoComplete=\"email\"\n />\n <InputCatto\n type=\"password\"\n label={t('register.passwordLabel')}\n value={password}\n onChange={(value) => setPassword(value)}\n required\n autoComplete=\"new-password\"\n minLength={8}\n />\n {error && (\n <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p>\n )}\n <ButtonCatto type=\"submit\" variant=\"primary\" disabled={submitting}>\n {submitting ? t('register.submitting') : t('register.submit')}\n </ButtonCatto>\n </form>\n );\n};\n\nexport default RegisterUserFormCatto;\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface SignInValues {
|
|
4
|
+
email: string;
|
|
5
|
+
password: string;
|
|
6
|
+
}
|
|
7
|
+
interface SignInEmailPassFormCattoProps {
|
|
8
|
+
/**
|
|
9
|
+
* Called with `{ email, password }` when the user submits the form. Throw
|
|
10
|
+
* (or reject) to surface an error message in the form. The component owns
|
|
11
|
+
* its own loading + error UI; the caller owns the auth client and any
|
|
12
|
+
* navigation that should happen on success.
|
|
13
|
+
*/
|
|
14
|
+
onSubmit: (values: SignInValues) => Promise<void> | void;
|
|
15
|
+
/**
|
|
16
|
+
* next-intl namespace this form's labels are read from. The keys it expects
|
|
17
|
+
* inside the namespace are `signIn.cardTitle`, `signIn.emailLabel`,
|
|
18
|
+
* `signIn.passwordLabel`, `signIn.submit`, `signIn.submitting`,
|
|
19
|
+
* `signIn.errorGeneric`. Defaults to `auth`.
|
|
20
|
+
*/
|
|
21
|
+
i18nNamespace?: string;
|
|
22
|
+
}
|
|
23
|
+
declare const SignInEmailPassFormCatto: ({ onSubmit, i18nNamespace, }: SignInEmailPassFormCattoProps) => react_jsx_runtime.JSX.Element;
|
|
24
|
+
|
|
25
|
+
interface LoginCattoProps extends SignInEmailPassFormCattoProps {
|
|
26
|
+
/** CardCatto variant. Defaults to 'midnightEmber'. */
|
|
27
|
+
cardVariant?: string;
|
|
28
|
+
/** CardCatto width. Defaults to '5xl'. */
|
|
29
|
+
cardWidth?: string;
|
|
30
|
+
}
|
|
31
|
+
declare const LoginCatto: ({ cardVariant, cardWidth, i18nNamespace, ...formProps }: LoginCattoProps) => react_jsx_runtime.JSX.Element;
|
|
32
|
+
|
|
33
|
+
interface RegisterValues {
|
|
34
|
+
name: string;
|
|
35
|
+
email: string;
|
|
36
|
+
password: string;
|
|
37
|
+
}
|
|
38
|
+
interface RegisterUserFormCattoProps {
|
|
39
|
+
/**
|
|
40
|
+
* Called with `{ name, email, password }` when the user submits the form.
|
|
41
|
+
* Throw (or reject) to surface an error message. The component owns its
|
|
42
|
+
* own loading + error UI; the caller owns the auth client and any
|
|
43
|
+
* post-register navigation.
|
|
44
|
+
*/
|
|
45
|
+
onSubmit: (values: RegisterValues) => Promise<void> | void;
|
|
46
|
+
/**
|
|
47
|
+
* next-intl namespace this form's labels are read from. The keys it expects
|
|
48
|
+
* inside the namespace are `register.nameLabel`, `register.emailLabel`,
|
|
49
|
+
* `register.passwordLabel`, `register.submit`, `register.submitting`,
|
|
50
|
+
* `register.errorGeneric`. Defaults to `auth`.
|
|
51
|
+
*/
|
|
52
|
+
i18nNamespace?: string;
|
|
53
|
+
}
|
|
54
|
+
declare const RegisterUserFormCatto: ({ onSubmit, i18nNamespace, }: RegisterUserFormCattoProps) => react_jsx_runtime.JSX.Element;
|
|
55
|
+
|
|
56
|
+
export { LoginCatto, type LoginCattoProps, RegisterUserFormCatto, type RegisterUserFormCattoProps, type RegisterValues, SignInEmailPassFormCatto, type SignInEmailPassFormCattoProps, type SignInValues };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface SignInValues {
|
|
4
|
+
email: string;
|
|
5
|
+
password: string;
|
|
6
|
+
}
|
|
7
|
+
interface SignInEmailPassFormCattoProps {
|
|
8
|
+
/**
|
|
9
|
+
* Called with `{ email, password }` when the user submits the form. Throw
|
|
10
|
+
* (or reject) to surface an error message in the form. The component owns
|
|
11
|
+
* its own loading + error UI; the caller owns the auth client and any
|
|
12
|
+
* navigation that should happen on success.
|
|
13
|
+
*/
|
|
14
|
+
onSubmit: (values: SignInValues) => Promise<void> | void;
|
|
15
|
+
/**
|
|
16
|
+
* next-intl namespace this form's labels are read from. The keys it expects
|
|
17
|
+
* inside the namespace are `signIn.cardTitle`, `signIn.emailLabel`,
|
|
18
|
+
* `signIn.passwordLabel`, `signIn.submit`, `signIn.submitting`,
|
|
19
|
+
* `signIn.errorGeneric`. Defaults to `auth`.
|
|
20
|
+
*/
|
|
21
|
+
i18nNamespace?: string;
|
|
22
|
+
}
|
|
23
|
+
declare const SignInEmailPassFormCatto: ({ onSubmit, i18nNamespace, }: SignInEmailPassFormCattoProps) => react_jsx_runtime.JSX.Element;
|
|
24
|
+
|
|
25
|
+
interface LoginCattoProps extends SignInEmailPassFormCattoProps {
|
|
26
|
+
/** CardCatto variant. Defaults to 'midnightEmber'. */
|
|
27
|
+
cardVariant?: string;
|
|
28
|
+
/** CardCatto width. Defaults to '5xl'. */
|
|
29
|
+
cardWidth?: string;
|
|
30
|
+
}
|
|
31
|
+
declare const LoginCatto: ({ cardVariant, cardWidth, i18nNamespace, ...formProps }: LoginCattoProps) => react_jsx_runtime.JSX.Element;
|
|
32
|
+
|
|
33
|
+
interface RegisterValues {
|
|
34
|
+
name: string;
|
|
35
|
+
email: string;
|
|
36
|
+
password: string;
|
|
37
|
+
}
|
|
38
|
+
interface RegisterUserFormCattoProps {
|
|
39
|
+
/**
|
|
40
|
+
* Called with `{ name, email, password }` when the user submits the form.
|
|
41
|
+
* Throw (or reject) to surface an error message. The component owns its
|
|
42
|
+
* own loading + error UI; the caller owns the auth client and any
|
|
43
|
+
* post-register navigation.
|
|
44
|
+
*/
|
|
45
|
+
onSubmit: (values: RegisterValues) => Promise<void> | void;
|
|
46
|
+
/**
|
|
47
|
+
* next-intl namespace this form's labels are read from. The keys it expects
|
|
48
|
+
* inside the namespace are `register.nameLabel`, `register.emailLabel`,
|
|
49
|
+
* `register.passwordLabel`, `register.submit`, `register.submitting`,
|
|
50
|
+
* `register.errorGeneric`. Defaults to `auth`.
|
|
51
|
+
*/
|
|
52
|
+
i18nNamespace?: string;
|
|
53
|
+
}
|
|
54
|
+
declare const RegisterUserFormCatto: ({ onSubmit, i18nNamespace, }: RegisterUserFormCattoProps) => react_jsx_runtime.JSX.Element;
|
|
55
|
+
|
|
56
|
+
export { LoginCatto, type LoginCattoProps, RegisterUserFormCatto, type RegisterUserFormCattoProps, type RegisterValues, SignInEmailPassFormCatto, type SignInEmailPassFormCattoProps, type SignInValues };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { InputCatto, ButtonCatto, CardCatto } from '@ccatto/ui';
|
|
3
|
+
import { useTranslations } from 'next-intl';
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
// src/LoginCatto.tsx
|
|
8
|
+
var SignInEmailPassFormCatto = ({
|
|
9
|
+
onSubmit,
|
|
10
|
+
i18nNamespace = "auth"
|
|
11
|
+
}) => {
|
|
12
|
+
const t = useTranslations(i18nNamespace);
|
|
13
|
+
const [email, setEmail] = useState("");
|
|
14
|
+
const [password, setPassword] = useState("");
|
|
15
|
+
const [error, setError] = useState(null);
|
|
16
|
+
const [submitting, setSubmitting] = useState(false);
|
|
17
|
+
const handleSubmit = async (e) => {
|
|
18
|
+
e.preventDefault();
|
|
19
|
+
setError(null);
|
|
20
|
+
setSubmitting(true);
|
|
21
|
+
try {
|
|
22
|
+
await onSubmit({ email, password });
|
|
23
|
+
} catch (err) {
|
|
24
|
+
setError(err instanceof Error ? err.message : t("signIn.errorGeneric"));
|
|
25
|
+
} finally {
|
|
26
|
+
setSubmitting(false);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4 p-4", children: [
|
|
30
|
+
/* @__PURE__ */ jsx(
|
|
31
|
+
InputCatto,
|
|
32
|
+
{
|
|
33
|
+
type: "email",
|
|
34
|
+
label: t("signIn.emailLabel"),
|
|
35
|
+
value: email,
|
|
36
|
+
onChange: (value) => setEmail(value),
|
|
37
|
+
required: true,
|
|
38
|
+
autoComplete: "email"
|
|
39
|
+
}
|
|
40
|
+
),
|
|
41
|
+
/* @__PURE__ */ jsx(
|
|
42
|
+
InputCatto,
|
|
43
|
+
{
|
|
44
|
+
type: "password",
|
|
45
|
+
label: t("signIn.passwordLabel"),
|
|
46
|
+
value: password,
|
|
47
|
+
onChange: (value) => setPassword(value),
|
|
48
|
+
required: true,
|
|
49
|
+
autoComplete: "current-password"
|
|
50
|
+
}
|
|
51
|
+
),
|
|
52
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: error }),
|
|
53
|
+
/* @__PURE__ */ jsx(ButtonCatto, { type: "submit", variant: "primary", disabled: submitting, children: submitting ? t("signIn.submitting") : t("signIn.submit") })
|
|
54
|
+
] });
|
|
55
|
+
};
|
|
56
|
+
var SignInEmailPassFormCatto_default = SignInEmailPassFormCatto;
|
|
57
|
+
var LoginCatto = ({
|
|
58
|
+
cardVariant = "midnightEmber",
|
|
59
|
+
cardWidth = "5xl",
|
|
60
|
+
i18nNamespace = "auth",
|
|
61
|
+
...formProps
|
|
62
|
+
}) => {
|
|
63
|
+
const t = useTranslations(i18nNamespace);
|
|
64
|
+
return /* @__PURE__ */ jsx("div", { className: "mt-6 h-full", children: /* @__PURE__ */ jsx(
|
|
65
|
+
CardCatto,
|
|
66
|
+
{
|
|
67
|
+
title: t("signIn.cardTitle"),
|
|
68
|
+
variant: cardVariant,
|
|
69
|
+
width: cardWidth,
|
|
70
|
+
headerComponent: /* @__PURE__ */ jsx(
|
|
71
|
+
SignInEmailPassFormCatto_default,
|
|
72
|
+
{
|
|
73
|
+
...formProps,
|
|
74
|
+
i18nNamespace
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
) });
|
|
79
|
+
};
|
|
80
|
+
var LoginCatto_default = LoginCatto;
|
|
81
|
+
var RegisterUserFormCatto = ({
|
|
82
|
+
onSubmit,
|
|
83
|
+
i18nNamespace = "auth"
|
|
84
|
+
}) => {
|
|
85
|
+
const t = useTranslations(i18nNamespace);
|
|
86
|
+
const [name, setName] = useState("");
|
|
87
|
+
const [email, setEmail] = useState("");
|
|
88
|
+
const [password, setPassword] = useState("");
|
|
89
|
+
const [error, setError] = useState(null);
|
|
90
|
+
const [submitting, setSubmitting] = useState(false);
|
|
91
|
+
const handleSubmit = async (e) => {
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
setError(null);
|
|
94
|
+
setSubmitting(true);
|
|
95
|
+
try {
|
|
96
|
+
await onSubmit({ name, email, password });
|
|
97
|
+
} catch (err) {
|
|
98
|
+
setError(err instanceof Error ? err.message : t("register.errorGeneric"));
|
|
99
|
+
} finally {
|
|
100
|
+
setSubmitting(false);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4 p-4", children: [
|
|
104
|
+
/* @__PURE__ */ jsx(
|
|
105
|
+
InputCatto,
|
|
106
|
+
{
|
|
107
|
+
type: "text",
|
|
108
|
+
label: t("register.nameLabel"),
|
|
109
|
+
value: name,
|
|
110
|
+
onChange: (value) => setName(value),
|
|
111
|
+
required: true,
|
|
112
|
+
autoComplete: "name"
|
|
113
|
+
}
|
|
114
|
+
),
|
|
115
|
+
/* @__PURE__ */ jsx(
|
|
116
|
+
InputCatto,
|
|
117
|
+
{
|
|
118
|
+
type: "email",
|
|
119
|
+
label: t("register.emailLabel"),
|
|
120
|
+
value: email,
|
|
121
|
+
onChange: (value) => setEmail(value),
|
|
122
|
+
required: true,
|
|
123
|
+
autoComplete: "email"
|
|
124
|
+
}
|
|
125
|
+
),
|
|
126
|
+
/* @__PURE__ */ jsx(
|
|
127
|
+
InputCatto,
|
|
128
|
+
{
|
|
129
|
+
type: "password",
|
|
130
|
+
label: t("register.passwordLabel"),
|
|
131
|
+
value: password,
|
|
132
|
+
onChange: (value) => setPassword(value),
|
|
133
|
+
required: true,
|
|
134
|
+
autoComplete: "new-password",
|
|
135
|
+
minLength: 8
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: error }),
|
|
139
|
+
/* @__PURE__ */ jsx(ButtonCatto, { type: "submit", variant: "primary", disabled: submitting, children: submitting ? t("register.submitting") : t("register.submit") })
|
|
140
|
+
] });
|
|
141
|
+
};
|
|
142
|
+
var RegisterUserFormCatto_default = RegisterUserFormCatto;
|
|
143
|
+
|
|
144
|
+
export { LoginCatto_default as LoginCatto, RegisterUserFormCatto_default as RegisterUserFormCatto, SignInEmailPassFormCatto_default as SignInEmailPassFormCatto };
|
|
145
|
+
//# sourceMappingURL=index.js.map
|
|
146
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/SignInEmailPassFormCatto.tsx","../src/LoginCatto.tsx","../src/RegisterUserFormCatto.tsx"],"names":["useTranslations","jsx","useState","jsxs","InputCatto","ButtonCatto"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { ButtonCatto, InputCatto } from '@ccatto/ui';\nimport { useTranslations } from 'next-intl';\n\nexport interface SignInValues {\n email: string;\n password: string;\n}\n\nexport interface SignInEmailPassFormCattoProps {\n /**\n * Called with `{ email, password }` when the user submits the form. Throw\n * (or reject) to surface an error message in the form. The component owns\n * its own loading + error UI; the caller owns the auth client and any\n * navigation that should happen on success.\n */\n onSubmit: (values: SignInValues) => Promise<void> | void;\n /**\n * next-intl namespace this form's labels are read from. The keys it expects\n * inside the namespace are `signIn.cardTitle`, `signIn.emailLabel`,\n * `signIn.passwordLabel`, `signIn.submit`, `signIn.submitting`,\n * `signIn.errorGeneric`. Defaults to `auth`.\n */\n i18nNamespace?: string;\n}\n\nconst SignInEmailPassFormCatto = ({\n onSubmit,\n i18nNamespace = 'auth',\n}: SignInEmailPassFormCattoProps) => {\n const t = useTranslations(i18nNamespace);\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [submitting, setSubmitting] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n setSubmitting(true);\n try {\n await onSubmit({ email, password });\n } catch (err) {\n setError(err instanceof Error ? err.message : t('signIn.errorGeneric'));\n } finally {\n setSubmitting(false);\n }\n };\n\n return (\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-4 p-4\">\n <InputCatto\n type=\"email\"\n label={t('signIn.emailLabel')}\n value={email}\n onChange={(value) => setEmail(value)}\n required\n autoComplete=\"email\"\n />\n <InputCatto\n type=\"password\"\n label={t('signIn.passwordLabel')}\n value={password}\n onChange={(value) => setPassword(value)}\n required\n autoComplete=\"current-password\"\n />\n {error && (\n <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p>\n )}\n <ButtonCatto type=\"submit\" variant=\"primary\" disabled={submitting}>\n {submitting ? t('signIn.submitting') : t('signIn.submit')}\n </ButtonCatto>\n </form>\n );\n};\n\nexport default SignInEmailPassFormCatto;\n","'use client';\n\nimport { CardCatto } from '@ccatto/ui';\nimport { useTranslations } from 'next-intl';\nimport SignInEmailPassFormCatto, {\n type SignInEmailPassFormCattoProps,\n} from './SignInEmailPassFormCatto';\n\nexport interface LoginCattoProps extends SignInEmailPassFormCattoProps {\n /** CardCatto variant. Defaults to 'midnightEmber'. */\n cardVariant?: string;\n /** CardCatto width. Defaults to '5xl'. */\n cardWidth?: string;\n}\n\nconst LoginCatto = ({\n cardVariant = 'midnightEmber',\n cardWidth = '5xl',\n i18nNamespace = 'auth',\n ...formProps\n}: LoginCattoProps) => {\n const t = useTranslations(i18nNamespace);\n\n return (\n <div className=\"mt-6 h-full\">\n <CardCatto\n title={t('signIn.cardTitle')}\n // CardCatto's variant + width props are loosely typed here so consumers\n // can pass any of the package's themes without us having to track the\n // union in two places.\n variant={cardVariant as never}\n width={cardWidth as never}\n headerComponent={\n <SignInEmailPassFormCatto\n {...formProps}\n i18nNamespace={i18nNamespace}\n />\n }\n />\n </div>\n );\n};\n\nexport default LoginCatto;\n","'use client';\n\nimport { useState } from 'react';\nimport { ButtonCatto, InputCatto } from '@ccatto/ui';\nimport { useTranslations } from 'next-intl';\n\nexport interface RegisterValues {\n name: string;\n email: string;\n password: string;\n}\n\nexport interface RegisterUserFormCattoProps {\n /**\n * Called with `{ name, email, password }` when the user submits the form.\n * Throw (or reject) to surface an error message. The component owns its\n * own loading + error UI; the caller owns the auth client and any\n * post-register navigation.\n */\n onSubmit: (values: RegisterValues) => Promise<void> | void;\n /**\n * next-intl namespace this form's labels are read from. The keys it expects\n * inside the namespace are `register.nameLabel`, `register.emailLabel`,\n * `register.passwordLabel`, `register.submit`, `register.submitting`,\n * `register.errorGeneric`. Defaults to `auth`.\n */\n i18nNamespace?: string;\n}\n\nconst RegisterUserFormCatto = ({\n onSubmit,\n i18nNamespace = 'auth',\n}: RegisterUserFormCattoProps) => {\n const t = useTranslations(i18nNamespace);\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [submitting, setSubmitting] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n setSubmitting(true);\n try {\n await onSubmit({ name, email, password });\n } catch (err) {\n setError(err instanceof Error ? err.message : t('register.errorGeneric'));\n } finally {\n setSubmitting(false);\n }\n };\n\n return (\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-4 p-4\">\n <InputCatto\n type=\"text\"\n label={t('register.nameLabel')}\n value={name}\n onChange={(value) => setName(value)}\n required\n autoComplete=\"name\"\n />\n <InputCatto\n type=\"email\"\n label={t('register.emailLabel')}\n value={email}\n onChange={(value) => setEmail(value)}\n required\n autoComplete=\"email\"\n />\n <InputCatto\n type=\"password\"\n label={t('register.passwordLabel')}\n value={password}\n onChange={(value) => setPassword(value)}\n required\n autoComplete=\"new-password\"\n minLength={8}\n />\n {error && (\n <p className=\"text-sm text-red-600 dark:text-red-400\">{error}</p>\n )}\n <ButtonCatto type=\"submit\" variant=\"primary\" disabled={submitting}>\n {submitting ? t('register.submitting') : t('register.submit')}\n </ButtonCatto>\n </form>\n );\n};\n\nexport default RegisterUserFormCatto;\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ccatto/auth-ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Catto Auth UI - presentational React forms (sign-in, register, login) for Catto-based apps. Bring your own auth client.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Chris Catto",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"react",
|
|
9
|
+
"react-components",
|
|
10
|
+
"authentication",
|
|
11
|
+
"auth-ui",
|
|
12
|
+
"sign-in",
|
|
13
|
+
"register",
|
|
14
|
+
"next-intl",
|
|
15
|
+
"tailwindcss",
|
|
16
|
+
"catto"
|
|
17
|
+
],
|
|
18
|
+
"homepage": "https://github.com/ccatto/catto-packages/tree/main/packages/auth-ui",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/ccatto/catto-packages.git",
|
|
22
|
+
"directory": "packages/auth-ui"
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"type": "module",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"require": "./dist/index.cjs"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"main": "./dist/index.cjs",
|
|
36
|
+
"module": "./dist/index.js",
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsup",
|
|
44
|
+
"clean": "rimraf dist",
|
|
45
|
+
"dev": "tsup --watch",
|
|
46
|
+
"typecheck": "tsc --noEmit"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@ccatto/ui": "*",
|
|
50
|
+
"@types/react": "^19.0.0",
|
|
51
|
+
"glob": "^13.0.0",
|
|
52
|
+
"next-intl": "^4.0.0",
|
|
53
|
+
"react": "^19.0.0",
|
|
54
|
+
"rimraf": "^6.0.0",
|
|
55
|
+
"tsup": "^8.0.0",
|
|
56
|
+
"typescript": "^5.7.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@ccatto/ui": ">=1.0.0",
|
|
60
|
+
"next-intl": ">=3.0.0",
|
|
61
|
+
"react": ">=18.0.0"
|
|
62
|
+
}
|
|
63
|
+
}
|