@authdog/react-elements 0.0.49 → 0.2.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/dist/components/ui/alert.d.mts +12 -0
- package/dist/components/ui/alert.d.ts +12 -0
- package/dist/components/ui/avatar.d.mts +8 -0
- package/dist/components/ui/avatar.d.ts +8 -0
- package/dist/components/ui/badge.d.mts +12 -0
- package/dist/components/ui/badge.d.ts +12 -0
- package/dist/components/ui/button.d.mts +14 -0
- package/dist/components/ui/button.d.ts +14 -0
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/button.mjs.map +1 -1
- package/dist/components/ui/card.d.mts +11 -0
- package/dist/components/ui/card.d.ts +11 -0
- package/dist/components/ui/dropdown-menu.d.mts +27 -0
- package/dist/components/ui/dropdown-menu.d.ts +27 -0
- package/dist/components/ui/input.d.mts +5 -0
- package/dist/components/ui/input.d.ts +5 -0
- package/dist/components/ui/label.d.mts +6 -0
- package/dist/components/ui/label.d.ts +6 -0
- package/dist/components/ui/separator.d.mts +6 -0
- package/dist/components/ui/separator.d.ts +6 -0
- package/dist/components/ui/sheet.d.mts +15 -0
- package/dist/components/ui/sheet.d.ts +15 -0
- package/dist/components/ui/theme-toggle.d.mts +5 -0
- package/dist/components/ui/theme-toggle.d.ts +5 -0
- package/dist/components/ui/theme-toggle.js.map +1 -1
- package/dist/components/ui/theme-toggle.mjs.map +1 -1
- package/dist/index.d.mts +12 -21
- package/dist/index.d.ts +12 -21
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/lib/utils.d.mts +5 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/styles.css +1 -4
- package/package.json +40 -25
- package/.eslintrc.js +0 -9
- package/.storybook/main.ts +0 -21
- package/.storybook/preview.ts +0 -17
- package/.storybook/vitest.setup.ts +0 -7
- package/.turbo/turbo-build.log +0 -77
- package/CHANGELOG.md +0 -286
- package/components.json +0 -20
- package/postcss.config.mjs +0 -11
- package/src/components/core/client-only.tsx +0 -15
- package/src/components/core/navbar.tsx +0 -307
- package/src/components/core/placeholder-alert.tsx +0 -23
- package/src/components/core/user-dropdown.tsx +0 -160
- package/src/components/core/user-profile.tsx +0 -521
- package/src/components/flow/login.tsx +0 -167
- package/src/components/flow/totp-validator.tsx +0 -252
- package/src/components/icons.tsx +0 -30
- package/src/components/ui/alert.tsx +0 -66
- package/src/components/ui/avatar.tsx +0 -53
- package/src/components/ui/badge.tsx +0 -46
- package/src/components/ui/button.tsx +0 -56
- package/src/components/ui/card.tsx +0 -92
- package/src/components/ui/dropdown-menu.tsx +0 -265
- package/src/components/ui/input.tsx +0 -21
- package/src/components/ui/label.tsx +0 -24
- package/src/components/ui/separator.tsx +0 -28
- package/src/components/ui/sheet.tsx +0 -142
- package/src/components/ui/theme-toggle.tsx +0 -56
- package/src/global.css +0 -81
- package/src/index.ts +0 -8
- package/src/lib/utils.ts +0 -6
- package/src/stories/core/Navbar.stories.tsx +0 -51
- package/src/stories/core/PlaceholderAlert.stories.tsx +0 -23
- package/src/stories/core/UserDropdown.stories.tsx +0 -56
- package/src/stories/core/UserProfile.stories.tsx +0 -47
- package/src/stories/flow/LoginForm.stories.tsx +0 -20
- package/src/stories/flow/TotpValidator.stories.tsx +0 -23
- package/src/stories/showcase/Landing.stories.tsx +0 -376
- package/src/stories/ui/Button.stories.tsx +0 -45
- package/src/types.ts +0 -0
- package/tailwind.config.ts +0 -82
- package/tsconfig.json +0 -11
- package/tsup.config.ts +0 -31
- package/vitest.config.ts +0 -39
- package/vitest.shims.d.ts +0 -1
- package/wrangler.prod.toml +0 -4
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
|
-
|
|
5
|
-
import { PlaceholderAlert } from "../../components/core/placeholder-alert";
|
|
6
|
-
import React from "react";
|
|
7
|
-
|
|
8
|
-
const meta = {
|
|
9
|
-
title: "Core/Placeholder Alert",
|
|
10
|
-
component: PlaceholderAlert,
|
|
11
|
-
tags: ["autodocs"],
|
|
12
|
-
} satisfies Meta<typeof PlaceholderAlert>;
|
|
13
|
-
|
|
14
|
-
export default meta;
|
|
15
|
-
|
|
16
|
-
type Story = StoryObj<typeof PlaceholderAlert>;
|
|
17
|
-
|
|
18
|
-
export const Basic: Story = {
|
|
19
|
-
args: {
|
|
20
|
-
title: "Custom Alert Title",
|
|
21
|
-
description: "This is a custom description for the placeholder alert.",
|
|
22
|
-
},
|
|
23
|
-
};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
|
-
|
|
5
|
-
import { UserDropdown } from "../../components/core/user-dropdown";
|
|
6
|
-
import {
|
|
7
|
-
Avatar,
|
|
8
|
-
AvatarFallback,
|
|
9
|
-
AvatarImage,
|
|
10
|
-
} from "../../components/ui/avatar";
|
|
11
|
-
import React from "react";
|
|
12
|
-
|
|
13
|
-
const demoUser = {
|
|
14
|
-
displayName: "Jane Doe",
|
|
15
|
-
emails: [{ value: "jane.doe@example.com" }],
|
|
16
|
-
photos: [{ value: "https://i.pravatar.cc/100" }],
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const trigger = (
|
|
20
|
-
<span className="inline-flex h-10 w-10 items-center justify-center rounded-full border bg-white shadow">
|
|
21
|
-
<Avatar className="h-8 w-8 rounded-full">
|
|
22
|
-
<AvatarImage src="https://i.pravatar.cc/100" />
|
|
23
|
-
<AvatarFallback>JD</AvatarFallback>
|
|
24
|
-
</Avatar>
|
|
25
|
-
</span>
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
const meta = {
|
|
29
|
-
title: "Core/User Dropdown",
|
|
30
|
-
component: UserDropdown,
|
|
31
|
-
tags: ["autodocs"],
|
|
32
|
-
parameters: {
|
|
33
|
-
layout: "centered",
|
|
34
|
-
},
|
|
35
|
-
render: (args) => (
|
|
36
|
-
<div className="p-10">
|
|
37
|
-
<UserDropdown {...args} />
|
|
38
|
-
</div>
|
|
39
|
-
),
|
|
40
|
-
} satisfies Meta<typeof UserDropdown>;
|
|
41
|
-
|
|
42
|
-
export default meta;
|
|
43
|
-
|
|
44
|
-
type Story = StoryObj<typeof UserDropdown>;
|
|
45
|
-
|
|
46
|
-
export const Default: Story = {
|
|
47
|
-
args: {
|
|
48
|
-
trigger,
|
|
49
|
-
user: demoUser,
|
|
50
|
-
links: [{ label: "My Organizations", href: "/organizations" }],
|
|
51
|
-
side: "bottom",
|
|
52
|
-
align: "start",
|
|
53
|
-
onManageAccount: () => console.log("Manage account"),
|
|
54
|
-
onSignout: () => console.log("Sign out"),
|
|
55
|
-
},
|
|
56
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
|
-
|
|
5
|
-
import { UserProfile } from "../../components/core/user-profile";
|
|
6
|
-
import React from "react";
|
|
7
|
-
|
|
8
|
-
const baseUser = {
|
|
9
|
-
id: "user_123",
|
|
10
|
-
displayName: "Jane Doe",
|
|
11
|
-
provider: "google-oauth20",
|
|
12
|
-
emails: [{ id: "e1", value: "jane.primary@example.com" }],
|
|
13
|
-
verifications: [],
|
|
14
|
-
photos: [],
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const meta = {
|
|
18
|
-
title: "Core/User Profile",
|
|
19
|
-
component: UserProfile,
|
|
20
|
-
tags: ["autodocs"],
|
|
21
|
-
parameters: {
|
|
22
|
-
layout: "fullscreen",
|
|
23
|
-
},
|
|
24
|
-
render: (args) => (
|
|
25
|
-
<div className="bg-background p-6 text-foreground">
|
|
26
|
-
<UserProfile {...args} />
|
|
27
|
-
</div>
|
|
28
|
-
),
|
|
29
|
-
} satisfies Meta<typeof UserProfile>;
|
|
30
|
-
|
|
31
|
-
export default meta;
|
|
32
|
-
|
|
33
|
-
type Story = StoryObj<typeof UserProfile>;
|
|
34
|
-
|
|
35
|
-
export const Loaded: Story = {
|
|
36
|
-
args: {
|
|
37
|
-
loading: false,
|
|
38
|
-
user: baseUser,
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const Loading: Story = {
|
|
43
|
-
args: {
|
|
44
|
-
loading: true,
|
|
45
|
-
user: baseUser,
|
|
46
|
-
},
|
|
47
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
|
-
|
|
5
|
-
import { LoginForm } from "../../components/flow/login";
|
|
6
|
-
|
|
7
|
-
const meta = {
|
|
8
|
-
title: "Flows/Login Form",
|
|
9
|
-
component: LoginForm,
|
|
10
|
-
tags: ["autodocs"],
|
|
11
|
-
parameters: {
|
|
12
|
-
layout: "fullscreen",
|
|
13
|
-
},
|
|
14
|
-
} satisfies Meta<typeof LoginForm>;
|
|
15
|
-
|
|
16
|
-
export default meta;
|
|
17
|
-
|
|
18
|
-
type Story = StoryObj<typeof LoginForm>;
|
|
19
|
-
|
|
20
|
-
export const Default: Story = {};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
|
-
|
|
5
|
-
import { TOTPValidator } from "../../components/flow/totp-validator";
|
|
6
|
-
|
|
7
|
-
const meta = {
|
|
8
|
-
title: "Flows/TOTP Validator",
|
|
9
|
-
component: TOTPValidator,
|
|
10
|
-
tags: ["autodocs"],
|
|
11
|
-
} satisfies Meta<typeof TOTPValidator>;
|
|
12
|
-
|
|
13
|
-
export default meta;
|
|
14
|
-
|
|
15
|
-
type Story = StoryObj<typeof TOTPValidator>;
|
|
16
|
-
|
|
17
|
-
export const Default: Story = {
|
|
18
|
-
args: {
|
|
19
|
-
onValidate: async (code: string) => {
|
|
20
|
-
console.log("TOTP submitted", code);
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
|
-
import { Layers, Lock, Rocket, Shield, Sparkles, Users } from "lucide-react";
|
|
5
|
-
import React from "react";
|
|
6
|
-
|
|
7
|
-
import { UserDropdown } from "../../components/core/user-dropdown";
|
|
8
|
-
import {
|
|
9
|
-
Avatar,
|
|
10
|
-
AvatarFallback,
|
|
11
|
-
AvatarImage,
|
|
12
|
-
} from "../../components/ui/avatar";
|
|
13
|
-
import { Button } from "../../components/ui/button";
|
|
14
|
-
|
|
15
|
-
const highlights = [
|
|
16
|
-
{
|
|
17
|
-
title: "Secure foundations",
|
|
18
|
-
description:
|
|
19
|
-
"Every component is wired for Authdog policies, session handling, and multi-factor protections out of the box.",
|
|
20
|
-
Icon: Shield,
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
title: "Composable flows",
|
|
24
|
-
description:
|
|
25
|
-
"Drop in opinionated login, signup, and TOTP experiences or compose your own with the same primitives.",
|
|
26
|
-
Icon: Layers,
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
title: "Design-system ready",
|
|
30
|
-
description:
|
|
31
|
-
"Built on top of Tailwind and Radix, so tokens, colors, and interactions match the rest of your product.",
|
|
32
|
-
Icon: Sparkles,
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
title: "Enterprise friendly",
|
|
36
|
-
description:
|
|
37
|
-
"Handle complex org hierarchies, SSO policies, and delegated admin journeys without reinventing UI.",
|
|
38
|
-
Icon: Users,
|
|
39
|
-
},
|
|
40
|
-
];
|
|
41
|
-
|
|
42
|
-
const buildSteps = [
|
|
43
|
-
{
|
|
44
|
-
title: "Install & theme",
|
|
45
|
-
description:
|
|
46
|
-
"Install the React Elements package, extend your Tailwind config, and drop Storybook around your component stories.",
|
|
47
|
-
meta: "pnpm add @authdog/react-elements",
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
title: "Connect to Authdog",
|
|
51
|
-
description:
|
|
52
|
-
"Pass your environment ID & identity host into flows and hooks to unlock real tenant-aware data.",
|
|
53
|
-
meta: '<Login environmentId="env_xxx" identityHost="https://id.auth.dog" />',
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
title: "Ship polished surfaces",
|
|
57
|
-
description:
|
|
58
|
-
"Combine core UI, flows, and utilities to cover onboarding, profile management, and secure recovery.",
|
|
59
|
-
meta: "<UserDropdown user={currentUser} />",
|
|
60
|
-
},
|
|
61
|
-
];
|
|
62
|
-
|
|
63
|
-
function LoginJourneysSlice() {
|
|
64
|
-
return (
|
|
65
|
-
<div className="text-left">
|
|
66
|
-
<div className="space-y-3">
|
|
67
|
-
<div className="rounded-2xl border border-white/10 bg-white/5 px-4 py-3">
|
|
68
|
-
<p className="text-xs uppercase tracking-wide text-white/60">
|
|
69
|
-
Email address
|
|
70
|
-
</p>
|
|
71
|
-
<p className="text-white">designer@studio.com</p>
|
|
72
|
-
</div>
|
|
73
|
-
<div className="rounded-2xl border border-white/10 bg-white/5 px-4 py-3">
|
|
74
|
-
<p className="text-xs uppercase tracking-wide text-white/60">
|
|
75
|
-
Magic link sent
|
|
76
|
-
</p>
|
|
77
|
-
<p className="text-white">Check your inbox to continue</p>
|
|
78
|
-
</div>
|
|
79
|
-
<Button className="w-full bg-white text-slate-900 hover:bg-white/90">
|
|
80
|
-
Continue
|
|
81
|
-
</Button>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function SecurityMomentsSlice() {
|
|
88
|
-
return (
|
|
89
|
-
<div className="space-y-3 text-left">
|
|
90
|
-
<div className="rounded-2xl border border-emerald-400/30 bg-emerald-500/10 px-4 py-3 text-emerald-100">
|
|
91
|
-
<p className="text-xs uppercase tracking-wide text-emerald-200">
|
|
92
|
-
One-time passcode
|
|
93
|
-
</p>
|
|
94
|
-
<p className="text-3xl font-mono tracking-widest">482 913</p>
|
|
95
|
-
</div>
|
|
96
|
-
<div className="rounded-2xl border border-white/10 bg-white/5 px-4 py-3 text-white/80">
|
|
97
|
-
Trusted device: MacBook Pro · Paris, FR
|
|
98
|
-
</div>
|
|
99
|
-
<Button
|
|
100
|
-
variant="secondary"
|
|
101
|
-
className="w-full bg-emerald-500/20 text-white hover:bg-emerald-500/30"
|
|
102
|
-
>
|
|
103
|
-
Approve & continue
|
|
104
|
-
</Button>
|
|
105
|
-
</div>
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function UserContextSlice() {
|
|
110
|
-
return (
|
|
111
|
-
<div className="rounded-2xl border border-white/10 bg-white/5 p-4 text-left text-white/80">
|
|
112
|
-
<div className="flex items-center gap-3">
|
|
113
|
-
<Avatar className="h-12 w-12">
|
|
114
|
-
<AvatarImage src="https://i.pravatar.cc/140?img=24" alt="Harper" />
|
|
115
|
-
<AvatarFallback>H</AvatarFallback>
|
|
116
|
-
</Avatar>
|
|
117
|
-
<div>
|
|
118
|
-
<p className="text-lg font-semibold text-white">Harper Reed</p>
|
|
119
|
-
<p className="text-sm text-white/70">Product Operations</p>
|
|
120
|
-
</div>
|
|
121
|
-
</div>
|
|
122
|
-
<dl className="mt-4 space-y-2 text-sm">
|
|
123
|
-
<div className="flex items-center justify-between">
|
|
124
|
-
<dt>Workspace</dt>
|
|
125
|
-
<dd className="text-white">Orion Health</dd>
|
|
126
|
-
</div>
|
|
127
|
-
<div className="flex items-center justify-between">
|
|
128
|
-
<dt>Role</dt>
|
|
129
|
-
<dd className="text-white">Global Admin</dd>
|
|
130
|
-
</div>
|
|
131
|
-
<div className="flex items-center justify-between">
|
|
132
|
-
<dt>Last active</dt>
|
|
133
|
-
<dd className="text-white">2 minutes ago</dd>
|
|
134
|
-
</div>
|
|
135
|
-
</dl>
|
|
136
|
-
</div>
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const componentSlices = [
|
|
141
|
-
{
|
|
142
|
-
title: "Login journeys",
|
|
143
|
-
description:
|
|
144
|
-
"Stateful, validated forms with branded headers, inline errors, and social providers baked in.",
|
|
145
|
-
Component: LoginJourneysSlice,
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
title: "Security moments",
|
|
149
|
-
description:
|
|
150
|
-
"Ready-made MFA, device approvals, and risk prompts keep your team secure without extra design cycles.",
|
|
151
|
-
Component: SecurityMomentsSlice,
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
title: "User context",
|
|
155
|
-
description:
|
|
156
|
-
"Profile, session, and organization widgets keep people oriented while you surface critical actions.",
|
|
157
|
-
Component: UserContextSlice,
|
|
158
|
-
},
|
|
159
|
-
];
|
|
160
|
-
|
|
161
|
-
const stats = [
|
|
162
|
-
{ label: "Components & flows", value: "25+" },
|
|
163
|
-
{ label: "SDK downloads", value: "12k+" },
|
|
164
|
-
{ label: "Avg. setup time", value: "<10 min" },
|
|
165
|
-
];
|
|
166
|
-
|
|
167
|
-
const showcaseUser = {
|
|
168
|
-
displayName: "Avery Stone",
|
|
169
|
-
emails: [{ value: "avery.stone@northwind.dev" }],
|
|
170
|
-
photos: [{ value: "https://i.pravatar.cc/120?img=12" }],
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
const Trigger = () => (
|
|
174
|
-
<div className="flex items-center gap-3 rounded-full border border-white/20 bg-white/10 px-3 py-2 text-left text-white shadow-2xl backdrop-blur">
|
|
175
|
-
<Avatar className="h-10 w-10">
|
|
176
|
-
<AvatarImage src={showcaseUser.photos?.[0]?.value} alt="Avery Stone" />
|
|
177
|
-
<AvatarFallback>AS</AvatarFallback>
|
|
178
|
-
</Avatar>
|
|
179
|
-
<div>
|
|
180
|
-
<p className="text-sm font-semibold leading-tight">Avery Stone</p>
|
|
181
|
-
<p className="text-xs text-white/70">Product Lead · Northwind</p>
|
|
182
|
-
</div>
|
|
183
|
-
</div>
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
const meta = {
|
|
187
|
-
title: "Showcase/Landing",
|
|
188
|
-
component: LandingShowcase,
|
|
189
|
-
tags: ["autodocs"],
|
|
190
|
-
parameters: {
|
|
191
|
-
layout: "fullscreen",
|
|
192
|
-
},
|
|
193
|
-
} satisfies Meta<typeof LandingShowcase>;
|
|
194
|
-
|
|
195
|
-
export default meta;
|
|
196
|
-
|
|
197
|
-
type Story = StoryObj<typeof LandingShowcase>;
|
|
198
|
-
|
|
199
|
-
export const FullPage: Story = {
|
|
200
|
-
render: () => <LandingShowcase />,
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
function LandingShowcase() {
|
|
204
|
-
return (
|
|
205
|
-
<div className="min-h-screen bg-slate-950 text-white">
|
|
206
|
-
<div className="mx-auto flex max-w-6xl flex-col gap-16 px-6 py-16">
|
|
207
|
-
<section className="grid items-center gap-12 lg:grid-cols-[1.2fr_minmax(0,1fr)]">
|
|
208
|
-
<div>
|
|
209
|
-
<p className="text-sm font-semibold uppercase tracking-[0.3em] text-slate-300">
|
|
210
|
-
Authdog React Elements
|
|
211
|
-
</p>
|
|
212
|
-
<h1 className="mt-4 text-4xl font-semibold leading-tight text-white sm:text-5xl">
|
|
213
|
-
Design-led authentication surfaces built for product teams.
|
|
214
|
-
</h1>
|
|
215
|
-
<p className="mt-4 text-lg text-white/70">
|
|
216
|
-
Ship login, profile, and security experiences that feel native to
|
|
217
|
-
your product. React Elements bundles Radix-powered primitives,
|
|
218
|
-
Authdog flows, and thoughtful defaults so teams can focus on their
|
|
219
|
-
roadmap—not boilerplate UI.
|
|
220
|
-
</p>
|
|
221
|
-
<div className="mt-8 flex flex-wrap gap-4">
|
|
222
|
-
<Button
|
|
223
|
-
size="lg"
|
|
224
|
-
className="bg-white text-slate-900 hover:bg-white/90"
|
|
225
|
-
>
|
|
226
|
-
Explore components
|
|
227
|
-
</Button>
|
|
228
|
-
<Button size="lg" variant="secondary" asChild>
|
|
229
|
-
<a
|
|
230
|
-
href="https://docs.authdog.com"
|
|
231
|
-
target="_blank"
|
|
232
|
-
rel="noreferrer"
|
|
233
|
-
className="text-white"
|
|
234
|
-
>
|
|
235
|
-
Read the docs
|
|
236
|
-
</a>
|
|
237
|
-
</Button>
|
|
238
|
-
<Button size="lg" variant="ghost" asChild>
|
|
239
|
-
<a
|
|
240
|
-
href="https://github.com/authdog-labs/web-sdk"
|
|
241
|
-
target="_blank"
|
|
242
|
-
rel="noreferrer"
|
|
243
|
-
className="text-white/80"
|
|
244
|
-
>
|
|
245
|
-
View on GitHub
|
|
246
|
-
</a>
|
|
247
|
-
</Button>
|
|
248
|
-
</div>
|
|
249
|
-
<dl className="mt-10 grid gap-8 sm:grid-cols-3">
|
|
250
|
-
{stats.map((stat) => (
|
|
251
|
-
<div key={stat.label}>
|
|
252
|
-
<dt className="text-xs uppercase tracking-wide text-white/60">
|
|
253
|
-
{stat.label}
|
|
254
|
-
</dt>
|
|
255
|
-
<dd className="mt-2 text-3xl font-semibold">{stat.value}</dd>
|
|
256
|
-
</div>
|
|
257
|
-
))}
|
|
258
|
-
</dl>
|
|
259
|
-
</div>
|
|
260
|
-
<div className="rounded-[32px] border border-white/10 bg-white/5 p-6 shadow-[0_40px_120px_rgba(15,23,42,0.35)] backdrop-blur">
|
|
261
|
-
<div className="flex items-center gap-3 text-white/70">
|
|
262
|
-
<Lock className="h-5 w-5 text-white" />
|
|
263
|
-
<span className="text-sm font-medium">
|
|
264
|
-
Live component preview
|
|
265
|
-
</span>
|
|
266
|
-
</div>
|
|
267
|
-
<p className="mt-2 text-sm text-white/60">
|
|
268
|
-
The same dropdown powering production consoles.
|
|
269
|
-
</p>
|
|
270
|
-
<div className="mt-6">
|
|
271
|
-
<UserDropdown
|
|
272
|
-
trigger={<Trigger />}
|
|
273
|
-
triggerWrapperClassName="w-full justify-start"
|
|
274
|
-
user={showcaseUser}
|
|
275
|
-
onManageAccount={() => undefined}
|
|
276
|
-
onSignout={() => undefined}
|
|
277
|
-
links={[
|
|
278
|
-
{ label: "Open Admin", href: "https://app.authdog.com" },
|
|
279
|
-
{ label: "Switch workspace", href: "#" },
|
|
280
|
-
]}
|
|
281
|
-
side="bottom"
|
|
282
|
-
align="start"
|
|
283
|
-
/>
|
|
284
|
-
</div>
|
|
285
|
-
</div>
|
|
286
|
-
</section>
|
|
287
|
-
|
|
288
|
-
<section className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
|
289
|
-
{highlights.map(({ title, description, Icon }) => (
|
|
290
|
-
<div
|
|
291
|
-
key={title}
|
|
292
|
-
className="rounded-3xl border border-white/10 bg-white/5 p-6 text-white/80 shadow-inner"
|
|
293
|
-
>
|
|
294
|
-
<div className="flex items together gap-3 text-white">
|
|
295
|
-
<div className="rounded-2xl border border-white/20 bg-white/10 p-3">
|
|
296
|
-
<Icon className="h-6 w-6" />
|
|
297
|
-
</div>
|
|
298
|
-
<p className="text-lg font-semibold text-white">{title}</p>
|
|
299
|
-
</div>
|
|
300
|
-
<p className="mt-4 text-sm leading-relaxed text-white/70">
|
|
301
|
-
{description}
|
|
302
|
-
</p>
|
|
303
|
-
</div>
|
|
304
|
-
))}
|
|
305
|
-
</section>
|
|
306
|
-
|
|
307
|
-
<section className="rounded-[32px] border border-white/10 bg-gradient-to-br from-slate-900/60 to-slate-900/20 p-8 text-white shadow-[0_20px_80px_rgba(15,23,42,0.4)]">
|
|
308
|
-
<div className="flex flex-col gap-2 text-left">
|
|
309
|
-
<p className="text-sm font-semibold uppercase tracking-[0.3em] text-white/60">
|
|
310
|
-
Build faster
|
|
311
|
-
</p>
|
|
312
|
-
<div className="flex items-center gap-3">
|
|
313
|
-
<Rocket className="h-6 w-6 text-white" />
|
|
314
|
-
<h2 className="text-2xl font-semibold">
|
|
315
|
-
Three steps from idea to production-ready auth
|
|
316
|
-
</h2>
|
|
317
|
-
</div>
|
|
318
|
-
<p className="text-white/70">
|
|
319
|
-
No scaffolding, no copy/pasting from old projects—just focused,
|
|
320
|
-
secure UI primitives that mirror the best of the Authdog console.
|
|
321
|
-
</p>
|
|
322
|
-
</div>
|
|
323
|
-
<div className="mt-8 grid gap-6 md:grid-cols-3">
|
|
324
|
-
{buildSteps.map((step) => (
|
|
325
|
-
<div
|
|
326
|
-
key={step.title}
|
|
327
|
-
className="rounded-2xl border border-white/15 bg-white/5 p-5 text-white/80"
|
|
328
|
-
>
|
|
329
|
-
<p className="text-xs uppercase tracking-wide text-white/60">
|
|
330
|
-
{step.title}
|
|
331
|
-
</p>
|
|
332
|
-
<p className="mt-2 text-sm leading-relaxed">
|
|
333
|
-
{step.description}
|
|
334
|
-
</p>
|
|
335
|
-
<code className="mt-4 inline-block rounded-xl border border-white/20 bg-slate-900/70 px-3 py-2 font-mono text-xs text-emerald-200">
|
|
336
|
-
{step.meta}
|
|
337
|
-
</code>
|
|
338
|
-
</div>
|
|
339
|
-
))}
|
|
340
|
-
</div>
|
|
341
|
-
</section>
|
|
342
|
-
|
|
343
|
-
<section className="space-y-8">
|
|
344
|
-
<div className="max-w-3xl text-left">
|
|
345
|
-
<p className="text-sm font-semibold uppercase tracking-[0.3em] text-white/60">
|
|
346
|
-
What you'll find inside
|
|
347
|
-
</p>
|
|
348
|
-
<h2 className="mt-3 text-3xl font-semibold text-white">
|
|
349
|
-
Opinionated building blocks for every identity moment.
|
|
350
|
-
</h2>
|
|
351
|
-
<p className="mt-3 text-white/70">
|
|
352
|
-
Each component ships with motion, accessibility, and sensible data
|
|
353
|
-
wiring so you can focus on tailoring the story to your customers.
|
|
354
|
-
</p>
|
|
355
|
-
</div>
|
|
356
|
-
<div className="grid gap-6 md:grid-cols-3">
|
|
357
|
-
{componentSlices.map(({ title, description, Component }) => (
|
|
358
|
-
<div
|
|
359
|
-
key={title}
|
|
360
|
-
className="flex flex-col gap-4 rounded-[28px] border border-white/10 bg-white/5 p-6 text-white/80"
|
|
361
|
-
>
|
|
362
|
-
<div>
|
|
363
|
-
<p className="text-lg font-semibold text-white">{title}</p>
|
|
364
|
-
<p className="text-sm text-white/70">{description}</p>
|
|
365
|
-
</div>
|
|
366
|
-
<div className="flex-1">
|
|
367
|
-
<Component />
|
|
368
|
-
</div>
|
|
369
|
-
</div>
|
|
370
|
-
))}
|
|
371
|
-
</div>
|
|
372
|
-
</section>
|
|
373
|
-
</div>
|
|
374
|
-
</div>
|
|
375
|
-
);
|
|
376
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
|
-
|
|
5
|
-
import { Button } from "../../components/ui/button";
|
|
6
|
-
|
|
7
|
-
const meta = {
|
|
8
|
-
title: "UI/Button",
|
|
9
|
-
component: Button,
|
|
10
|
-
tags: ["autodocs"],
|
|
11
|
-
argTypes: {
|
|
12
|
-
variant: {
|
|
13
|
-
control: "select",
|
|
14
|
-
options: [
|
|
15
|
-
"default",
|
|
16
|
-
"destructive",
|
|
17
|
-
"outline",
|
|
18
|
-
"secondary",
|
|
19
|
-
"ghost",
|
|
20
|
-
"link",
|
|
21
|
-
],
|
|
22
|
-
},
|
|
23
|
-
size: {
|
|
24
|
-
control: "select",
|
|
25
|
-
options: ["default", "sm", "lg", "icon"],
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
} satisfies Meta<typeof Button>;
|
|
29
|
-
|
|
30
|
-
export default meta;
|
|
31
|
-
|
|
32
|
-
type Story = StoryObj<typeof Button>;
|
|
33
|
-
|
|
34
|
-
export const Primary: Story = {
|
|
35
|
-
args: {
|
|
36
|
-
children: "Click me",
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export const Secondary: Story = {
|
|
41
|
-
args: {
|
|
42
|
-
variant: "secondary",
|
|
43
|
-
children: "Explore components",
|
|
44
|
-
},
|
|
45
|
-
};
|
package/src/types.ts
DELETED
|
File without changes
|
package/tailwind.config.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import type { Config } from "tailwindcss";
|
|
2
|
-
import tailwindcssAnimate from "tailwindcss-animate";
|
|
3
|
-
|
|
4
|
-
const config = {
|
|
5
|
-
darkMode: ["class"],
|
|
6
|
-
content: [
|
|
7
|
-
"./src/**/*.{js,ts,jsx,tsx}",
|
|
8
|
-
"./src/**/*.stories.{js,ts,jsx,tsx}",
|
|
9
|
-
"./src/components/**/*.{js,ts,jsx,tsx}",
|
|
10
|
-
"./src/components/**/**/*.{js,ts,jsx,tsx}",
|
|
11
|
-
"./src/preview.{js,ts,jsx,tsx}",
|
|
12
|
-
],
|
|
13
|
-
prefix: "",
|
|
14
|
-
theme: {
|
|
15
|
-
container: {
|
|
16
|
-
center: true,
|
|
17
|
-
padding: "2rem",
|
|
18
|
-
screens: {
|
|
19
|
-
"2xl": "1400px",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
extend: {
|
|
23
|
-
colors: {
|
|
24
|
-
border: "hsl(var(--border))",
|
|
25
|
-
input: "hsl(var(--input))",
|
|
26
|
-
ring: "hsl(var(--ring))",
|
|
27
|
-
background: "hsl(var(--background))",
|
|
28
|
-
foreground: "hsl(var(--foreground))",
|
|
29
|
-
primary: {
|
|
30
|
-
DEFAULT: "hsl(var(--primary))",
|
|
31
|
-
foreground: "hsl(var(--primary-foreground))",
|
|
32
|
-
},
|
|
33
|
-
secondary: {
|
|
34
|
-
DEFAULT: "hsl(var(--secondary))",
|
|
35
|
-
foreground: "hsl(var(--secondary-foreground))",
|
|
36
|
-
},
|
|
37
|
-
destructive: {
|
|
38
|
-
DEFAULT: "hsl(var(--destructive))",
|
|
39
|
-
foreground: "hsl(var(--destructive-foreground))",
|
|
40
|
-
},
|
|
41
|
-
muted: {
|
|
42
|
-
DEFAULT: "hsl(var(--muted))",
|
|
43
|
-
foreground: "hsl(var(--muted-foreground))",
|
|
44
|
-
},
|
|
45
|
-
accent: {
|
|
46
|
-
DEFAULT: "hsl(var(--accent))",
|
|
47
|
-
foreground: "hsl(var(--accent-foreground))",
|
|
48
|
-
},
|
|
49
|
-
popover: {
|
|
50
|
-
DEFAULT: "hsl(var(--popover))",
|
|
51
|
-
foreground: "hsl(var(--popover-foreground))",
|
|
52
|
-
},
|
|
53
|
-
card: {
|
|
54
|
-
DEFAULT: "hsl(var(--card))",
|
|
55
|
-
foreground: "hsl(var(--card-foreground))",
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
borderRadius: {
|
|
59
|
-
lg: "var(--radius)",
|
|
60
|
-
md: "calc(var(--radius) - 2px)",
|
|
61
|
-
sm: "calc(var(--radius) - 4px)",
|
|
62
|
-
},
|
|
63
|
-
keyframes: {
|
|
64
|
-
"accordion-down": {
|
|
65
|
-
from: { height: "0" },
|
|
66
|
-
to: { height: "var(--radix-accordion-content-height)" },
|
|
67
|
-
},
|
|
68
|
-
"accordion-up": {
|
|
69
|
-
from: { height: "var(--radix-accordion-content-height)" },
|
|
70
|
-
to: { height: "0" },
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
animation: {
|
|
74
|
-
"accordion-down": "accordion-down 0.2s ease-out",
|
|
75
|
-
"accordion-up": "accordion-up 0.2s ease-out",
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
plugins: [tailwindcssAnimate],
|
|
80
|
-
} satisfies Config;
|
|
81
|
-
|
|
82
|
-
export default config;
|