@olwiba/ui 0.0.29 → 0.0.32
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/dist/index.d.ts +3 -0
- package/dist/index.js +41 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/app/AuthSection.tsx +38 -23
package/package.json
CHANGED
package/src/app/AuthSection.tsx
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import {
|
|
5
|
-
import { Badge,
|
|
4
|
+
import { Building2, ShieldCheck, Sparkles } from 'lucide-react';
|
|
5
|
+
import { Badge, CardContent, CardDescription, CardHeader, CardTitle, Label, cn } from '@olwiba/cn';
|
|
6
|
+
import { Button } from '../primitives/Button';
|
|
7
|
+
import { Card } from '../primitives/Card';
|
|
8
|
+
import { Input } from '../primitives/Input';
|
|
9
|
+
import type { AppShellRenderLink } from './AppShell';
|
|
10
|
+
|
|
11
|
+
const defaultRenderLink: AppShellRenderLink = ({ href, children, className }) => (
|
|
12
|
+
<a href={href} className={className}>{children}</a>
|
|
13
|
+
);
|
|
6
14
|
|
|
7
15
|
// ─── Centered layout ──────────────────────────────────────────────────────────
|
|
8
16
|
|
|
9
|
-
function CenteredAuth({ children }: { children: React.ReactNode }) {
|
|
17
|
+
function CenteredAuth({ children, brand, className }: { children: React.ReactNode; brand?: React.ReactNode; className?: string }) {
|
|
10
18
|
return (
|
|
11
|
-
<section className=
|
|
12
|
-
|
|
19
|
+
<section className={cn('flex min-h-screen flex-col justify-center bg-background py-12 px-4 sm:px-6 lg:px-8', className)}>
|
|
20
|
+
{brand && (
|
|
21
|
+
<div className="mx-auto w-full max-w-md text-center mb-8">
|
|
22
|
+
{brand}
|
|
23
|
+
</div>
|
|
24
|
+
)}
|
|
25
|
+
<div className="mx-auto w-full max-w-md">
|
|
13
26
|
{children}
|
|
14
27
|
</div>
|
|
15
28
|
</section>
|
|
@@ -61,11 +74,14 @@ export interface AuthFormProps {
|
|
|
61
74
|
/** (signup) Link back to the sign-in page */
|
|
62
75
|
signInHref?: string;
|
|
63
76
|
forgotPasswordHref?: string;
|
|
77
|
+
/** Brand node — in centered layout renders above the card; in split layout renders inside the card */
|
|
64
78
|
brand?: React.ReactNode;
|
|
65
79
|
/** Error message displayed below the form fields */
|
|
66
80
|
error?: string;
|
|
67
81
|
/** Disables the submit button and shows a loading label */
|
|
68
82
|
loading?: boolean;
|
|
83
|
+
/** Render prop for links — use to inject framework-native link components (e.g. TanStack Router Link) */
|
|
84
|
+
renderLink?: AppShellRenderLink;
|
|
69
85
|
}
|
|
70
86
|
|
|
71
87
|
function DefaultForm({
|
|
@@ -78,11 +94,12 @@ function DefaultForm({
|
|
|
78
94
|
brand,
|
|
79
95
|
error,
|
|
80
96
|
loading,
|
|
97
|
+
renderLink = defaultRenderLink,
|
|
81
98
|
}: AuthFormProps) {
|
|
82
99
|
const isSignUp = mode === 'signup';
|
|
83
100
|
|
|
84
101
|
return (
|
|
85
|
-
<Card className="w-full
|
|
102
|
+
<Card className="w-full">
|
|
86
103
|
<CardHeader>
|
|
87
104
|
{brand && <div className="mb-2">{brand}</div>}
|
|
88
105
|
<CardTitle>{isSignUp ? 'Create an account' : 'Sign in'}</CardTitle>
|
|
@@ -101,17 +118,17 @@ function DefaultForm({
|
|
|
101
118
|
</div>
|
|
102
119
|
)}
|
|
103
120
|
<div className="space-y-2">
|
|
104
|
-
<Label htmlFor="auth-email">Email</Label>
|
|
121
|
+
<Label htmlFor="auth-email">Email address</Label>
|
|
105
122
|
<Input id="auth-email" name="email" type="email" placeholder="name@company.com" autoComplete="email" />
|
|
106
123
|
</div>
|
|
107
124
|
<div className="space-y-2">
|
|
108
125
|
<div className="flex items-center justify-between">
|
|
109
126
|
<Label htmlFor="auth-password">Password</Label>
|
|
110
|
-
{!isSignUp && forgotPasswordHref && (
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
)}
|
|
127
|
+
{!isSignUp && forgotPasswordHref && renderLink({
|
|
128
|
+
href: forgotPasswordHref,
|
|
129
|
+
className: 'text-xs text-muted-foreground underline underline-offset-4 hover:text-foreground',
|
|
130
|
+
children: 'Forgot password?',
|
|
131
|
+
})}
|
|
115
132
|
</div>
|
|
116
133
|
<Input
|
|
117
134
|
id="auth-password"
|
|
@@ -139,17 +156,13 @@ function DefaultForm({
|
|
|
139
156
|
{isSignUp ? (
|
|
140
157
|
<>
|
|
141
158
|
Already have an account?{' '}
|
|
142
|
-
|
|
143
|
-
Sign in
|
|
144
|
-
</a>
|
|
159
|
+
{renderLink({ href: signInHref, className: 'text-foreground underline underline-offset-4', children: 'Sign in' })}
|
|
145
160
|
</>
|
|
146
161
|
) : (
|
|
147
162
|
signUpHref && (
|
|
148
163
|
<>
|
|
149
164
|
New here?{' '}
|
|
150
|
-
|
|
151
|
-
Create an account
|
|
152
|
-
</a>
|
|
165
|
+
{renderLink({ href: signUpHref, className: 'text-foreground underline underline-offset-4', children: 'Create an account' })}
|
|
153
166
|
</>
|
|
154
167
|
)
|
|
155
168
|
)}
|
|
@@ -178,9 +191,8 @@ export function AuthSection({
|
|
|
178
191
|
className,
|
|
179
192
|
...formProps
|
|
180
193
|
}: AuthSectionProps) {
|
|
181
|
-
const form = children ?? <DefaultForm {...formProps} />;
|
|
182
|
-
|
|
183
194
|
if (layout === 'split') {
|
|
195
|
+
const form = children ?? <DefaultForm {...formProps} />;
|
|
184
196
|
return (
|
|
185
197
|
<div className={cn('h-full', className)}>
|
|
186
198
|
<SplitAuth panel={panel}>{form}</SplitAuth>
|
|
@@ -188,9 +200,12 @@ export function AuthSection({
|
|
|
188
200
|
);
|
|
189
201
|
}
|
|
190
202
|
|
|
203
|
+
// Centered: brand renders above the card, not inside it
|
|
204
|
+
const { brand, ...restFormProps } = formProps;
|
|
205
|
+
const form = children ?? <DefaultForm {...restFormProps} />;
|
|
191
206
|
return (
|
|
192
|
-
<
|
|
193
|
-
|
|
194
|
-
</
|
|
207
|
+
<CenteredAuth brand={brand} className={className}>
|
|
208
|
+
{form}
|
|
209
|
+
</CenteredAuth>
|
|
195
210
|
);
|
|
196
211
|
}
|