@tanstack/create 0.68.0 → 0.68.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/frameworks/react/add-ons/ai/assets/src/components/demo-AIAssistant.tsx +15 -15
  3. package/dist/frameworks/react/add-ons/ai/assets/src/components/demo-GuitarRecommendation.tsx +8 -6
  4. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-chat.css +21 -21
  5. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-chat.tsx +14 -18
  6. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-image.tsx +20 -26
  7. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-structured.tsx +56 -67
  8. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/guitars/$guitarId.tsx +17 -22
  9. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/guitars/index.tsx +21 -27
  10. package/dist/frameworks/react/add-ons/apollo-client/assets/src/routes/demo.apollo-client.tsx +35 -38
  11. package/dist/frameworks/react/add-ons/better-auth/assets/src/routes/demo/better-auth.tsx +64 -64
  12. package/dist/frameworks/react/add-ons/clerk/assets/src/routes/demo/clerk.tsx +17 -25
  13. package/dist/frameworks/react/add-ons/convex/assets/src/routes/demo/convex.tsx +30 -45
  14. package/dist/frameworks/react/add-ons/db/assets/src/components/demo.chat-area.tsx +5 -5
  15. package/dist/frameworks/react/add-ons/db/assets/src/components/demo.messages.tsx +7 -11
  16. package/dist/frameworks/react/add-ons/db/assets/src/routes/demo/db-chat.tsx +5 -3
  17. package/dist/frameworks/react/add-ons/drizzle/assets/src/routes/demo/drizzle.tsx.ejs +29 -79
  18. package/dist/frameworks/react/add-ons/form/assets/src/components/demo.FormComponents.tsx.ejs +12 -12
  19. package/dist/frameworks/react/add-ons/form/assets/src/routes/demo/form.address.tsx.ejs +11 -10
  20. package/dist/frameworks/react/add-ons/form/assets/src/routes/demo/form.simple.tsx.ejs +11 -10
  21. package/dist/frameworks/react/add-ons/mcp/assets/src/routes/demo/mcp-todos.tsx +10 -18
  22. package/dist/frameworks/react/add-ons/neon/assets/src/routes/demo/neon.tsx +38 -57
  23. package/dist/frameworks/react/add-ons/oRPC/assets/src/routes/demo/orpc-todo.tsx +10 -18
  24. package/dist/frameworks/react/add-ons/paraglide/assets/src/routes/demo.i18n.tsx.ejs +6 -7
  25. package/dist/frameworks/react/add-ons/posthog/assets/src/routes/demo/posthog.tsx +19 -22
  26. package/dist/frameworks/react/add-ons/powersync/assets/src/routes/demo/powersync.tsx +19 -18
  27. package/dist/frameworks/react/add-ons/prisma/assets/src/routes/demo/prisma.tsx.ejs +29 -79
  28. package/dist/frameworks/react/add-ons/sentry/assets/src/routes/demo/sentry.testing.tsx +71 -102
  29. package/dist/frameworks/react/add-ons/store/assets/src/lib/demo-store-devtools.tsx +3 -3
  30. package/dist/frameworks/react/add-ons/store/assets/src/routes/demo/store.tsx.ejs +9 -14
  31. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.tsx +23 -26
  32. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.tsx +12 -16
  33. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.tsx +14 -17
  34. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.tsx +15 -15
  35. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.tsx +17 -17
  36. package/dist/frameworks/react/add-ons/storybook/assets/src/routes/demo/storybook.tsx +25 -25
  37. package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/media.tsx +9 -9
  38. package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/quote.tsx +8 -8
  39. package/dist/frameworks/react/add-ons/strapi/assets/src/components/markdown-content.tsx +52 -35
  40. package/dist/frameworks/react/add-ons/strapi/assets/src/components/pagination.tsx +8 -14
  41. package/dist/frameworks/react/add-ons/strapi/assets/src/components/search.tsx +12 -12
  42. package/dist/frameworks/react/add-ons/strapi/assets/src/components/strapi-image.tsx +15 -15
  43. package/dist/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.$articleId.tsx +52 -63
  44. package/dist/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.tsx +46 -61
  45. package/dist/frameworks/react/add-ons/tRPC/assets/src/routes/demo/trpc-todo.tsx +10 -18
  46. package/dist/frameworks/react/add-ons/table/assets/src/routes/demo/table.tsx.ejs +23 -22
  47. package/dist/frameworks/react/add-ons/tanstack-query/assets/src/routes/demo/tanstack-query.tsx.ejs +21 -35
  48. package/dist/frameworks/react/add-ons/workos/assets/src/components/workos-user.tsx +1 -1
  49. package/dist/frameworks/react/add-ons/workos/assets/src/routes/demo/workos.tsx +33 -43
  50. package/dist/frameworks/react/project/base/_dot_gitignore +1 -0
  51. package/dist/frameworks/react/project/base/src/styles.css.ejs +203 -0
  52. package/dist/frameworks/solid/add-ons/better-auth/assets/src/routes/demo.better-auth.tsx +62 -64
  53. package/dist/frameworks/solid/add-ons/convex/assets/src/routes/demo/convex.tsx +30 -43
  54. package/dist/frameworks/solid/add-ons/form/assets/src/routes/demo.form.tsx.ejs +22 -22
  55. package/dist/frameworks/solid/add-ons/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +15 -10
  56. package/dist/frameworks/solid/add-ons/store/assets/src/routes/demo.store.tsx.ejs +9 -14
  57. package/dist/frameworks/solid/add-ons/strapi/assets/src/routes/demo/strapi.tsx +11 -15
  58. package/dist/frameworks/solid/add-ons/strapi/assets/src/routes/demo/strapi_.$articleId.tsx +11 -18
  59. package/dist/frameworks/solid/project/base/_dot_gitignore +1 -0
  60. package/dist/frameworks/solid/project/base/src/styles.css.ejs +203 -0
  61. package/package.json +1 -1
  62. package/src/frameworks/react/add-ons/ai/assets/src/components/demo-AIAssistant.tsx +15 -15
  63. package/src/frameworks/react/add-ons/ai/assets/src/components/demo-GuitarRecommendation.tsx +8 -6
  64. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-chat.css +21 -21
  65. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-chat.tsx +14 -18
  66. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-image.tsx +20 -26
  67. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-structured.tsx +56 -67
  68. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/guitars/$guitarId.tsx +17 -22
  69. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/guitars/index.tsx +21 -27
  70. package/src/frameworks/react/add-ons/apollo-client/assets/src/routes/demo.apollo-client.tsx +35 -38
  71. package/src/frameworks/react/add-ons/better-auth/assets/src/routes/demo/better-auth.tsx +64 -64
  72. package/src/frameworks/react/add-ons/clerk/assets/src/routes/demo/clerk.tsx +17 -25
  73. package/src/frameworks/react/add-ons/convex/assets/src/routes/demo/convex.tsx +30 -45
  74. package/src/frameworks/react/add-ons/db/assets/src/components/demo.chat-area.tsx +5 -5
  75. package/src/frameworks/react/add-ons/db/assets/src/components/demo.messages.tsx +7 -11
  76. package/src/frameworks/react/add-ons/db/assets/src/routes/demo/db-chat.tsx +5 -3
  77. package/src/frameworks/react/add-ons/drizzle/assets/src/routes/demo/drizzle.tsx.ejs +29 -79
  78. package/src/frameworks/react/add-ons/form/assets/src/components/demo.FormComponents.tsx.ejs +12 -12
  79. package/src/frameworks/react/add-ons/form/assets/src/routes/demo/form.address.tsx.ejs +11 -10
  80. package/src/frameworks/react/add-ons/form/assets/src/routes/demo/form.simple.tsx.ejs +11 -10
  81. package/src/frameworks/react/add-ons/mcp/assets/src/routes/demo/mcp-todos.tsx +10 -18
  82. package/src/frameworks/react/add-ons/neon/assets/src/routes/demo/neon.tsx +38 -57
  83. package/src/frameworks/react/add-ons/oRPC/assets/src/routes/demo/orpc-todo.tsx +10 -18
  84. package/src/frameworks/react/add-ons/paraglide/assets/src/routes/demo.i18n.tsx.ejs +6 -7
  85. package/src/frameworks/react/add-ons/posthog/assets/src/routes/demo/posthog.tsx +19 -22
  86. package/src/frameworks/react/add-ons/powersync/assets/src/routes/demo/powersync.tsx +19 -18
  87. package/src/frameworks/react/add-ons/prisma/assets/src/routes/demo/prisma.tsx.ejs +29 -79
  88. package/src/frameworks/react/add-ons/sentry/assets/src/routes/demo/sentry.testing.tsx +71 -102
  89. package/src/frameworks/react/add-ons/store/assets/src/lib/demo-store-devtools.tsx +3 -3
  90. package/src/frameworks/react/add-ons/store/assets/src/routes/demo/store.tsx.ejs +9 -14
  91. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.tsx +23 -26
  92. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.tsx +12 -16
  93. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.tsx +14 -17
  94. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.tsx +15 -15
  95. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.tsx +17 -17
  96. package/src/frameworks/react/add-ons/storybook/assets/src/routes/demo/storybook.tsx +25 -25
  97. package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/media.tsx +9 -9
  98. package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/quote.tsx +8 -8
  99. package/src/frameworks/react/add-ons/strapi/assets/src/components/markdown-content.tsx +52 -35
  100. package/src/frameworks/react/add-ons/strapi/assets/src/components/pagination.tsx +8 -14
  101. package/src/frameworks/react/add-ons/strapi/assets/src/components/search.tsx +12 -12
  102. package/src/frameworks/react/add-ons/strapi/assets/src/components/strapi-image.tsx +15 -15
  103. package/src/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.$articleId.tsx +52 -63
  104. package/src/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.tsx +46 -61
  105. package/src/frameworks/react/add-ons/tRPC/assets/src/routes/demo/trpc-todo.tsx +10 -18
  106. package/src/frameworks/react/add-ons/table/assets/src/routes/demo/table.tsx.ejs +23 -22
  107. package/src/frameworks/react/add-ons/tanstack-query/assets/src/routes/demo/tanstack-query.tsx.ejs +21 -35
  108. package/src/frameworks/react/add-ons/workos/assets/src/components/workos-user.tsx +1 -1
  109. package/src/frameworks/react/add-ons/workos/assets/src/routes/demo/workos.tsx +33 -43
  110. package/src/frameworks/react/project/base/_dot_gitignore +1 -0
  111. package/src/frameworks/react/project/base/src/styles.css.ejs +203 -0
  112. package/src/frameworks/solid/add-ons/better-auth/assets/src/routes/demo.better-auth.tsx +62 -64
  113. package/src/frameworks/solid/add-ons/convex/assets/src/routes/demo/convex.tsx +30 -43
  114. package/src/frameworks/solid/add-ons/form/assets/src/routes/demo.form.tsx.ejs +22 -22
  115. package/src/frameworks/solid/add-ons/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +15 -10
  116. package/src/frameworks/solid/add-ons/store/assets/src/routes/demo.store.tsx.ejs +9 -14
  117. package/src/frameworks/solid/add-ons/strapi/assets/src/routes/demo/strapi.tsx +11 -15
  118. package/src/frameworks/solid/add-ons/strapi/assets/src/routes/demo/strapi_.$articleId.tsx +11 -18
  119. package/src/frameworks/solid/project/base/_dot_gitignore +1 -0
  120. package/src/frameworks/solid/project/base/src/styles.css.ejs +203 -0
  121. package/tests/framework-template.test.ts +15 -0
@@ -1,24 +1,24 @@
1
- import { createFileRoute } from "@tanstack/solid-router";
2
- import { createSignal, Show } from "solid-js";
3
- import { authClient } from "../lib/auth-client";
1
+ import { createFileRoute } from '@tanstack/solid-router'
2
+ import { createSignal, Show } from 'solid-js'
3
+ import { authClient } from '../lib/auth-client'
4
4
 
5
- export const Route = createFileRoute("/demo/better-auth")({
5
+ export const Route = createFileRoute('/demo/better-auth')({
6
6
  component: BetterAuthDemo,
7
- });
7
+ })
8
8
 
9
9
  function BetterAuthDemo() {
10
- const session = authClient.useSession();
11
- const [isSignUp, setIsSignUp] = createSignal(false);
12
- const [email, setEmail] = createSignal("");
13
- const [password, setPassword] = createSignal("");
14
- const [name, setName] = createSignal("");
15
- const [error, setError] = createSignal("");
16
- const [loading, setLoading] = createSignal(false);
10
+ const session = authClient.useSession()
11
+ const [isSignUp, setIsSignUp] = createSignal(false)
12
+ const [email, setEmail] = createSignal('')
13
+ const [password, setPassword] = createSignal('')
14
+ const [name, setName] = createSignal('')
15
+ const [error, setError] = createSignal('')
16
+ const [loading, setLoading] = createSignal(false)
17
17
 
18
18
  const handleSubmit = async (e: Event) => {
19
- e.preventDefault();
20
- setError("");
21
- setLoading(true);
19
+ e.preventDefault()
20
+ setError('')
21
+ setLoading(true)
22
22
 
23
23
  try {
24
24
  if (isSignUp()) {
@@ -26,47 +26,48 @@ function BetterAuthDemo() {
26
26
  email: email(),
27
27
  password: password(),
28
28
  name: name(),
29
- });
29
+ })
30
30
  if (result.error) {
31
- setError(result.error.message || "Sign up failed");
31
+ setError(result.error.message || 'Sign up failed')
32
32
  }
33
33
  } else {
34
34
  const result = await authClient.signIn.email({
35
35
  email: email(),
36
36
  password: password(),
37
- });
37
+ })
38
38
  if (result.error) {
39
- setError(result.error.message || "Sign in failed");
39
+ setError(result.error.message || 'Sign in failed')
40
40
  }
41
41
  }
42
42
  } catch (err) {
43
- setError("An unexpected error occurred");
43
+ setError('An unexpected error occurred')
44
44
  } finally {
45
- setLoading(false);
45
+ setLoading(false)
46
46
  }
47
- };
47
+ }
48
48
 
49
49
  return (
50
50
  <Show
51
51
  when={!session().isPending}
52
52
  fallback={
53
- <div class="flex items-center justify-center py-10">
53
+ <main class="demo-page demo-center">
54
54
  <div class="h-5 w-5 animate-spin rounded-full border-2 border-neutral-200 border-t-neutral-900 dark:border-neutral-800 dark:border-t-neutral-100" />
55
- </div>
55
+ </main>
56
56
  }
57
57
  >
58
58
  <Show
59
59
  when={session().data?.user}
60
60
  fallback={
61
- <div class="flex justify-center py-10 px-4">
62
- <div class="w-full max-w-md p-6">
63
- <h1 class="text-lg font-semibold leading-none tracking-tight">
64
- {isSignUp() ? "Create an account" : "Sign in"}
61
+ <main class="demo-page demo-center">
62
+ <section class="demo-panel w-full max-w-md">
63
+ <p class="island-kicker mb-2">Better Auth</p>
64
+ <h1 class="demo-title">
65
+ {isSignUp() ? 'Create an account' : 'Sign in'}
65
66
  </h1>
66
- <p class="text-sm text-neutral-500 dark:text-neutral-400 mt-2 mb-6">
67
+ <p class="demo-muted mt-2 mb-6 text-sm">
67
68
  {isSignUp()
68
- ? "Enter your information to create an account"
69
- : "Enter your email below to login to your account"}
69
+ ? 'Enter your information to create an account'
70
+ : 'Enter your email below to login to your account'}
70
71
  </p>
71
72
 
72
73
  <form onSubmit={handleSubmit} class="grid gap-4">
@@ -80,7 +81,7 @@ function BetterAuthDemo() {
80
81
  type="text"
81
82
  value={name()}
82
83
  onInput={(e) => setName(e.currentTarget.value)}
83
- class="flex h-9 w-full border border-neutral-300 dark:border-neutral-700 bg-transparent px-3 text-sm focus:outline-none focus:border-neutral-900 dark:focus:border-neutral-100 disabled:cursor-not-allowed disabled:opacity-50"
84
+ class="demo-input"
84
85
  required
85
86
  />
86
87
  </div>
@@ -95,7 +96,7 @@ function BetterAuthDemo() {
95
96
  type="email"
96
97
  value={email()}
97
98
  onInput={(e) => setEmail(e.currentTarget.value)}
98
- class="flex h-9 w-full border border-neutral-300 dark:border-neutral-700 bg-transparent px-3 text-sm focus:outline-none focus:border-neutral-900 dark:focus:border-neutral-100 disabled:cursor-not-allowed disabled:opacity-50"
99
+ class="demo-input"
99
100
  required
100
101
  />
101
102
  </div>
@@ -112,24 +113,22 @@ function BetterAuthDemo() {
112
113
  type="password"
113
114
  value={password()}
114
115
  onInput={(e) => setPassword(e.currentTarget.value)}
115
- class="flex h-9 w-full border border-neutral-300 dark:border-neutral-700 bg-transparent px-3 text-sm focus:outline-none focus:border-neutral-900 dark:focus:border-neutral-100 disabled:cursor-not-allowed disabled:opacity-50"
116
+ class="demo-input"
116
117
  required
117
118
  minLength={8}
118
119
  />
119
120
  </div>
120
121
 
121
122
  <Show when={error()}>
122
- <div class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 p-3">
123
- <p class="text-sm text-red-600 dark:text-red-400">
124
- {error()}
125
- </p>
123
+ <div class="demo-alert demo-alert-danger">
124
+ <p class="text-sm text-red-600">{error()}</p>
126
125
  </div>
127
126
  </Show>
128
127
 
129
128
  <button
130
129
  type="submit"
131
130
  disabled={loading()}
132
- class="w-full h-9 px-4 text-sm font-medium text-white bg-neutral-900 hover:bg-neutral-800 dark:bg-neutral-50 dark:text-neutral-900 dark:hover:bg-neutral-200 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
131
+ class="demo-button w-full"
133
132
  >
134
133
  <Show
135
134
  when={!loading()}
@@ -140,7 +139,7 @@ function BetterAuthDemo() {
140
139
  </span>
141
140
  }
142
141
  >
143
- {isSignUp() ? "Create account" : "Sign in"}
142
+ {isSignUp() ? 'Create account' : 'Sign in'}
144
143
  </Show>
145
144
  </button>
146
145
  </form>
@@ -149,41 +148,40 @@ function BetterAuthDemo() {
149
148
  <button
150
149
  type="button"
151
150
  onClick={() => {
152
- setIsSignUp(!isSignUp());
153
- setError("");
151
+ setIsSignUp(!isSignUp())
152
+ setError('')
154
153
  }}
155
- class="text-sm text-neutral-500 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-100 transition-colors"
154
+ class="demo-muted text-sm transition-colors hover:text-[var(--sea-ink)]"
156
155
  >
157
156
  {isSignUp()
158
- ? "Already have an account? Sign in"
157
+ ? 'Already have an account? Sign in'
159
158
  : "Don't have an account? Sign up"}
160
159
  </button>
161
160
  </div>
162
161
 
163
- <p class="mt-6 text-xs text-center text-neutral-400 dark:text-neutral-500">
164
- Built with{" "}
162
+ <p class="demo-muted mt-6 text-center text-xs">
163
+ Built with{' '}
165
164
  <a
166
165
  href="https://better-auth.com"
167
166
  target="_blank"
168
167
  rel="noopener noreferrer"
169
- class="font-medium hover:text-neutral-600 dark:hover:text-neutral-300"
168
+ class="font-medium"
170
169
  >
171
170
  BETTER-AUTH
172
171
  </a>
173
172
  .
174
173
  </p>
175
- </div>
176
- </div>
174
+ </section>
175
+ </main>
177
176
  }
178
177
  >
179
178
  {(user) => (
180
- <div class="flex justify-center py-10 px-4">
181
- <div class="w-full max-w-md p-6 space-y-6">
179
+ <main class="demo-page demo-center">
180
+ <section class="demo-panel w-full max-w-md space-y-6">
182
181
  <div class="space-y-1.5">
183
- <h1 class="text-lg font-semibold leading-none tracking-tight">
184
- Welcome back
185
- </h1>
186
- <p class="text-sm text-neutral-500 dark:text-neutral-400">
182
+ <p class="island-kicker mb-2">Better Auth</p>
183
+ <h1 class="demo-title">Welcome back</h1>
184
+ <p class="demo-muted text-sm">
187
185
  You're signed in as {user().email}
188
186
  </p>
189
187
  </div>
@@ -194,7 +192,7 @@ function BetterAuthDemo() {
194
192
  fallback={
195
193
  <div class="h-10 w-10 bg-neutral-200 dark:bg-neutral-800 flex items-center justify-center">
196
194
  <span class="text-sm font-medium text-neutral-600 dark:text-neutral-400">
197
- {user().name?.charAt(0).toUpperCase() || "U"}
195
+ {user().name?.charAt(0).toUpperCase() || 'U'}
198
196
  </span>
199
197
  </div>
200
198
  }
@@ -211,29 +209,29 @@ function BetterAuthDemo() {
211
209
 
212
210
  <button
213
211
  onClick={() => {
214
- void authClient.signOut();
212
+ void authClient.signOut()
215
213
  }}
216
- class="w-full h-9 px-4 text-sm font-medium border border-neutral-300 dark:border-neutral-700 hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors"
214
+ class="demo-button demo-button-secondary w-full"
217
215
  >
218
216
  Sign out
219
217
  </button>
220
218
 
221
- <p class="text-xs text-center text-neutral-400 dark:text-neutral-500">
222
- Built with{" "}
219
+ <p class="demo-muted text-center text-xs">
220
+ Built with{' '}
223
221
  <a
224
222
  href="https://better-auth.com"
225
223
  target="_blank"
226
224
  rel="noopener noreferrer"
227
- class="font-medium hover:text-neutral-600 dark:hover:text-neutral-300"
225
+ class="font-medium"
228
226
  >
229
227
  BETTER-AUTH
230
228
  </a>
231
229
  .
232
230
  </p>
233
- </div>
234
- </div>
231
+ </section>
232
+ </main>
235
233
  )}
236
234
  </Show>
237
235
  </Show>
238
- );
236
+ )
239
237
  }
@@ -38,34 +38,25 @@ function ConvexTodos() {
38
38
  const totalCount = () => todos?.data()?.length || 0
39
39
 
40
40
  return (
41
- <div
42
- class="min-h-screen flex items-center justify-center p-4"
43
- style={{
44
- background:
45
- 'linear-gradient(135deg, #667a56 0%, #8fbc8f 25%, #90ee90 50%, #98fb98 75%, #f0fff0 100%)',
46
- }}
47
- >
48
- <div class="w-full max-w-2xl">
49
- {/* Header Card */}
50
- <div class="bg-white/95 backdrop-blur-sm rounded-2xl shadow-2xl border border-green-200/50 p-8 mb-6">
41
+ <main class="demo-page">
42
+ <div class="mx-auto w-full max-w-2xl space-y-6">
43
+ <section class="demo-panel">
51
44
  <div class="text-center">
52
- <h1 class="text-4xl font-bold text-green-800 mb-2">Convex Todos</h1>
53
- <p class="text-green-600 text-lg">Powered by real-time sync</p>
45
+ <p class="island-kicker mb-2">Convex</p>
46
+ <h1 class="demo-title">Todos</h1>
47
+ <p class="demo-muted mt-2">Powered by real-time sync</p>
54
48
  <Show when={totalCount() > 0}>
55
49
  <div class="mt-4 flex justify-center space-x-6 text-sm">
56
- <span class="text-green-700 font-medium">
57
- {completedCount()} completed
58
- </span>
59
- <span class="text-gray-600">
50
+ <span class="font-medium">{completedCount()} completed</span>
51
+ <span class="demo-muted">
60
52
  {totalCount() - completedCount()} remaining
61
53
  </span>
62
54
  </div>
63
55
  </Show>
64
56
  </div>
65
- </div>
57
+ </section>
66
58
 
67
- {/* Add Todo Card */}
68
- <div class="bg-white/95 backdrop-blur-sm rounded-2xl shadow-xl border border-green-200/50 p-6 mb-6">
59
+ <section class="demo-card">
69
60
  <div class="flex gap-3">
70
61
  <input
71
62
  type="text"
@@ -77,46 +68,43 @@ function ConvexTodos() {
77
68
  }
78
69
  }}
79
70
  placeholder="What needs to be done?"
80
- class="flex-1 px-4 py-3 rounded-xl border-2 border-green-200 focus:border-green-400 focus:outline-none text-gray-800 placeholder-gray-500 bg-white/80 transition-colors"
71
+ class="demo-input min-w-0 flex-1"
81
72
  />
82
73
  <button
83
74
  onClick={handleAddTodo}
84
75
  disabled={!newTodo().trim()}
85
- class="bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700 disabled:from-gray-300 disabled:to-gray-400 disabled:cursor-not-allowed text-white font-semibold py-3 px-6 rounded-xl transition-all duration-200 flex items-center gap-2 shadow-lg hover:shadow-xl"
76
+ class="demo-button"
86
77
  >
87
78
  <Plus size={20} />
88
79
  Add
89
80
  </button>
90
81
  </div>
91
- </div>
82
+ </section>
92
83
 
93
- {/* Todos List */}
94
- <div class="bg-white/95 backdrop-blur-sm rounded-2xl shadow-xl border border-green-200/50 overflow-hidden">
84
+ <section class="demo-card overflow-hidden p-0">
95
85
  <Show when={todos.isLoading()}>
96
86
  <div class="p-8 text-center">
97
- <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-green-500 mx-auto mb-4"></div>
98
- <p class="text-green-600">Loading todos...</p>
87
+ <div class="mx-auto mb-4 h-8 w-8 animate-spin rounded-full border-b-2 border-[var(--lagoon-deep)]"></div>
88
+ <p class="demo-muted">Loading todos...</p>
99
89
  </div>
100
90
  </Show>
101
91
  <Show
102
92
  when={todos.data()?.length !== 0}
103
93
  fallback={
104
94
  <div class="p-12 text-center">
105
- <Circle size={48} class="text-green-300 mx-auto mb-4" />
106
- <h3 class="text-xl font-semibold text-green-800 mb-2">
107
- No todos yet
108
- </h3>
109
- <p class="text-green-600">
95
+ <Circle size={48} class="demo-muted mx-auto mb-4" />
96
+ <h3 class="demo-section-title mb-2">No todos yet</h3>
97
+ <p class="demo-muted">
110
98
  Add your first todo above to get started!
111
99
  </p>
112
100
  </div>
113
101
  }
114
102
  >
115
- <div class="divide-y divide-green-100">
103
+ <div class="divide-y divide-[var(--line)]">
116
104
  <For each={todos.data()}>
117
105
  {(todo, index) => (
118
106
  <div
119
- class={`p-4 flex items-center gap-4 hover:bg-green-50/50 transition-colors ${
107
+ class={`p-4 flex items-center gap-4 transition-colors hover:bg-[var(--link-bg-hover)] ${
120
108
  todo.completed ? 'opacity-75' : ''
121
109
  }`}
122
110
  style={{
@@ -127,8 +115,8 @@ function ConvexTodos() {
127
115
  onClick={() => handleToggleTodo(todo._id)}
128
116
  class={`flex-shrink-0 w-6 h-6 rounded-full border-2 flex items-center justify-center transition-all duration-200 ${
129
117
  todo.completed
130
- ? 'bg-green-500 border-green-500 text-white'
131
- : 'border-green-300 hover:border-green-400 text-transparent hover:text-green-400'
118
+ ? 'border-[var(--lagoon-deep)] bg-[var(--lagoon)] text-[var(--sea-ink)]'
119
+ : 'border-[var(--line)] text-transparent hover:border-[var(--lagoon-deep)] hover:text-[var(--lagoon-deep)]'
132
120
  }`}
133
121
  >
134
122
  <Check size={14} />
@@ -137,8 +125,8 @@ function ConvexTodos() {
137
125
  <span
138
126
  class={`flex-1 text-lg transition-all duration-200 ${
139
127
  todo.completed
140
- ? 'line-through text-gray-500'
141
- : 'text-gray-800'
128
+ ? 'line-through demo-muted'
129
+ : 'text-[var(--sea-ink)]'
142
130
  }`}
143
131
  >
144
132
  {todo.text}
@@ -146,7 +134,7 @@ function ConvexTodos() {
146
134
 
147
135
  <button
148
136
  onClick={() => handleRemoveTodo(todo._id)}
149
- class="flex-shrink-0 p-2 text-red-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors"
137
+ class="demo-button demo-button-danger flex-shrink-0 p-2"
150
138
  >
151
139
  <Trash2 size={18} />
152
140
  </button>
@@ -155,15 +143,14 @@ function ConvexTodos() {
155
143
  </For>
156
144
  </div>
157
145
  </Show>
158
- </div>
146
+ </section>
159
147
 
160
- {/* Footer */}
161
148
  <div class="text-center mt-6">
162
- <p class="text-green-700/80 text-sm">
163
- Built with Convex • Real-time updates Always in sync
149
+ <p class="demo-muted text-sm">
150
+ Built with Convex, real-time updates, and synced state.
164
151
  </p>
165
152
  </div>
166
153
  </div>
167
- </div>
154
+ </main>
168
155
  )
169
156
  }
@@ -18,12 +18,12 @@ function FieldWrapper(props: {
18
18
  }) {
19
19
  return (
20
20
  <div>
21
- <label for={props.label} class="block font-bold mb-1 text-xl">
21
+ <label for={props.label} class="mb-2 block text-sm font-semibold text-[var(--sea-ink)]">
22
22
  {props.label}
23
23
  </label>
24
24
  {props.children}
25
25
  {props.errors.length ? (
26
- <div class="text-red-500 mt-1 font-bold">{props.errors.join(', ')}</div>
26
+ <div class="mt-1 text-sm font-semibold text-red-600">{props.errors.join(', ')}</div>
27
27
  ) : null}
28
28
  </div>
29
29
  )
@@ -51,14 +51,15 @@ function FormExample() {
51
51
  }))
52
52
 
53
53
  return (
54
- <div
55
- class="flex items-center justify-center min-h-screen bg-gradient-to-br from-purple-100 to-blue-100 p-4 text-white"
56
- style={{
57
- 'background-image':
58
- 'radial-gradient(50% 50% at 5% 40%, #f4a460 0%, #8b4513 70%, #1a0f0a 100%)',
59
- }}
60
- >
61
- <div class="w-full max-w-2xl p-8 rounded-xl backdrop-blur-md bg-black/50 shadow-xl border-8 border-black/10">
54
+ <main class="demo-page demo-center">
55
+ <section class="demo-panel w-full max-w-2xl">
56
+ <div class="mb-6">
57
+ <p class="island-kicker mb-2">TanStack Form</p>
58
+ <h1 class="demo-title">Address Form</h1>
59
+ <p class="demo-muted mt-2">
60
+ Nested fields, field-level validation, and a select input.
61
+ </p>
62
+ </div>
62
63
  <form
63
64
  onSubmit={(e) => {
64
65
  e.preventDefault()
@@ -93,7 +94,7 @@ function FormExample() {
93
94
  value={field().state.value}
94
95
  onBlur={field().handleBlur}
95
96
  onChange={(e) => field().handleChange(e.target.value)}
96
- class="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
97
+ class="demo-input"
97
98
  />
98
99
  </FieldWrapper>
99
100
  )}
@@ -127,7 +128,7 @@ function FormExample() {
127
128
  value={field().state.value}
128
129
  onBlur={field().handleBlur}
129
130
  onChange={(e) => field().handleChange(e.target.value)}
130
- class="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
131
+ class="demo-input"
131
132
  />
132
133
  </FieldWrapper>
133
134
  )}
@@ -157,7 +158,7 @@ function FormExample() {
157
158
  value={field().state.value}
158
159
  onBlur={field().handleBlur}
159
160
  onChange={(e) => field().handleChange(e.target.value)}
160
- class="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
161
+ class="demo-input"
161
162
  />
162
163
  </FieldWrapper>
163
164
  )}
@@ -185,7 +186,7 @@ function FormExample() {
185
186
  value={field().state.value}
186
187
  onBlur={field().handleBlur}
187
188
  onChange={(e) => field().handleChange(e.target.value)}
188
- class="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
189
+ class="demo-input"
189
190
  />
190
191
  </FieldWrapper>
191
192
  )}
@@ -210,7 +211,7 @@ function FormExample() {
210
211
  value={field().state.value}
211
212
  onBlur={field().handleBlur}
212
213
  onChange={(e) => field().handleChange(e.target.value)}
213
- class="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
214
+ class="demo-input"
214
215
  />
215
216
  </FieldWrapper>
216
217
  )}
@@ -241,7 +242,7 @@ function FormExample() {
241
242
  value={field().state.value}
242
243
  onBlur={field().handleBlur}
243
244
  onChange={(e) => field().handleChange(e.target.value)}
244
- class="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
245
+ class="demo-input"
245
246
  />
246
247
  </FieldWrapper>
247
248
  )}
@@ -271,7 +272,7 @@ function FormExample() {
271
272
  value={field().state.value}
272
273
  onBlur={field().handleBlur}
273
274
  onChange={(e) => field().handleChange(e.target.value)}
274
- class="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
275
+ class="demo-select"
275
276
  >
276
277
  <option value="">Select a country</option>
277
278
  <option value="US">United States</option>
@@ -318,7 +319,7 @@ function FormExample() {
318
319
  value={field().state.value}
319
320
  onBlur={field().handleBlur}
320
321
  onChange={(e) => field().handleChange(e.target.value)}
321
- class="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
322
+ class="demo-input"
322
323
  placeholder="(123) 456-7890"
323
324
  />
324
325
  </FieldWrapper>
@@ -331,14 +332,14 @@ function FormExample() {
331
332
  <button
332
333
  type="submit"
333
334
  disabled={form.state.isSubmitting}
334
- class="px-6 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-colors disabled:opacity-50"
335
+ class="demo-button"
335
336
  >
336
337
  {form.state.isSubmitting ? 'Submitting...' : 'Submit'}
337
338
  </button>
338
339
  </div>
339
340
  </form>
340
- </div>
341
- </div>
341
+ </section>
342
+ </main>
342
343
  )
343
344
  }
344
345
 
@@ -349,4 +350,3 @@ export default (parentRoute: RootRoute) => createRoute({
349
350
  getParentRoute: () => parentRoute,
350
351
  })
351
352
  <% } %>
352
-
@@ -6,15 +6,20 @@ export const Route = createFileRoute('/demo/sentry/bad-event-handler')({
6
6
 
7
7
  function RouteComponent() {
8
8
  return (
9
- <div className="p-4">
10
- <button
11
- type="button"
12
- onClick={() => {
13
- throw new Error('Sentry Frontend Error')
14
- }}
15
- >
16
- Throw error
17
- </button>
18
- </div>
9
+ <main class="demo-page demo-center">
10
+ <section class="demo-panel w-full max-w-md text-center">
11
+ <p class="island-kicker mb-2">Sentry</p>
12
+ <h1 class="demo-title mb-6">Error Handler Demo</h1>
13
+ <button
14
+ type="button"
15
+ onClick={() => {
16
+ throw new Error('Sentry Frontend Error')
17
+ }}
18
+ class="demo-button"
19
+ >
20
+ Throw error
21
+ </button>
22
+ </section>
23
+ </main>
19
24
  )
20
25
  }
@@ -20,7 +20,7 @@ function FirstName() {
20
20
  onInput={(e) =>
21
21
  store.setState((state) => ({ ...state, firstName: e.target.value }))
22
22
  }
23
- class="bg-white/10 rounded-lg px-4 py-2 outline-none border border-white/20 hover:border-white/40 focus:border-white/60 transition-colors duration-200 placeholder-white/40"
23
+ class="demo-input"
24
24
  />
25
25
  )
26
26
  }
@@ -34,7 +34,7 @@ function LastName() {
34
34
  onInput={(e) =>
35
35
  store.setState((state) => ({ ...state, lastName: e.target.value }))
36
36
  }
37
- class="bg-white/10 rounded-lg px-4 py-2 outline-none border border-white/20 hover:border-white/40 focus:border-white/60 transition-colors duration-200 placeholder-white/40"
37
+ class="demo-input"
38
38
  />
39
39
  )
40
40
  }
@@ -42,7 +42,7 @@ function LastName() {
42
42
  function FullName() {
43
43
  const fName = useStore(fullName)
44
44
  return (
45
- <div class="bg-white/10 rounded-lg px-4 py-2 outline-none ">
45
+ <div class="demo-list-item font-medium">
46
46
  {fName()}
47
47
  </div>
48
48
  )
@@ -50,20 +50,15 @@ function FullName() {
50
50
 
51
51
  function DemoStore() {
52
52
  return (
53
- <div
54
- class="min-h-[calc(100vh-32px)] text-white p-8 flex items-center justify-center w-full h-full"
55
- style={{
56
- 'background-image':
57
- 'radial-gradient(50% 50% at 80% 80%, #f4a460 0%, #8b4513 70%, #1a0f0a 100%)',
58
- }}
59
- >
60
- <div class="bg-white/10 backdrop-blur-lg rounded-xl p-8 shadow-lg flex flex-col gap-4 text-3xl min-w-1/2">
61
- <h1 class="text-4xl font-bold mb-5">Store Example</h1>
53
+ <main class="demo-page demo-center">
54
+ <section class="demo-panel flex w-full max-w-xl flex-col gap-4">
55
+ <p class="island-kicker">TanStack Store</p>
56
+ <h1 class="demo-title mb-2">Store Example</h1>
62
57
  <FirstName />
63
58
  <LastName />
64
59
  <FullName />
65
- </div>
66
- </div>
60
+ </section>
61
+ </main>
67
62
  )
68
63
  }
69
64