@tanstack/create 0.67.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 +34 -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
@@ -44,36 +44,25 @@ function ConvexTodos() {
44
44
  const totalCount = todos?.length || 0
45
45
 
46
46
  return (
47
- <div
48
- className="min-h-screen flex items-center justify-center p-4"
49
- style={{
50
- background:
51
- 'linear-gradient(135deg, #667a56 0%, #8fbc8f 25%, #90ee90 50%, #98fb98 75%, #f0fff0 100%)',
52
- }}
53
- >
54
- <div className="w-full max-w-2xl">
55
- {/* Header Card */}
56
- <div className="bg-white/95 backdrop-blur-sm rounded-2xl shadow-2xl border border-green-200/50 p-8 mb-6">
47
+ <main className="demo-page">
48
+ <div className="mx-auto w-full max-w-2xl space-y-6">
49
+ <section className="demo-panel">
57
50
  <div className="text-center">
58
- <h1 className="text-4xl font-bold text-green-800 mb-2">
59
- Convex Todos
60
- </h1>
61
- <p className="text-green-600 text-lg">Powered by real-time sync</p>
51
+ <p className="island-kicker mb-2">Convex</p>
52
+ <h1 className="demo-title">Todos</h1>
53
+ <p className="demo-muted mt-2">Powered by real-time sync</p>
62
54
  {totalCount > 0 && (
63
55
  <div className="mt-4 flex justify-center space-x-6 text-sm">
64
- <span className="text-green-700 font-medium">
65
- {completedCount} completed
66
- </span>
67
- <span className="text-gray-600">
56
+ <span className="font-medium">{completedCount} completed</span>
57
+ <span className="demo-muted">
68
58
  {totalCount - completedCount} remaining
69
59
  </span>
70
60
  </div>
71
61
  )}
72
62
  </div>
73
- </div>
63
+ </section>
74
64
 
75
- {/* Add Todo Card */}
76
- <div className="bg-white/95 backdrop-blur-sm rounded-2xl shadow-xl border border-green-200/50 p-6 mb-6">
65
+ <section className="demo-card">
77
66
  <div className="flex gap-3">
78
67
  <input
79
68
  type="text"
@@ -85,42 +74,39 @@ function ConvexTodos() {
85
74
  }
86
75
  }}
87
76
  placeholder="What needs to be done?"
88
- className="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"
77
+ className="demo-input min-w-0 flex-1"
89
78
  />
90
79
  <button
91
80
  onClick={handleAddTodo}
92
81
  disabled={!newTodo.trim()}
93
- className="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"
82
+ className="demo-button"
94
83
  >
95
84
  <Plus size={20} />
96
85
  Add
97
86
  </button>
98
87
  </div>
99
- </div>
88
+ </section>
100
89
 
101
- {/* Todos List */}
102
- <div className="bg-white/95 backdrop-blur-sm rounded-2xl shadow-xl border border-green-200/50 overflow-hidden">
90
+ <section className="demo-card overflow-hidden p-0">
103
91
  {!todos ? (
104
92
  <div className="p-8 text-center">
105
- <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-green-500 mx-auto mb-4"></div>
106
- <p className="text-green-600">Loading todos...</p>
93
+ <div className="mx-auto mb-4 h-8 w-8 animate-spin rounded-full border-b-2 border-[var(--lagoon-deep)]"></div>
94
+ <p className="demo-muted">Loading todos...</p>
107
95
  </div>
108
96
  ) : todos.length === 0 ? (
109
97
  <div className="p-12 text-center">
110
- <Circle size={48} className="text-green-300 mx-auto mb-4" />
111
- <h3 className="text-xl font-semibold text-green-800 mb-2">
112
- No todos yet
113
- </h3>
114
- <p className="text-green-600">
98
+ <Circle size={48} className="demo-muted mx-auto mb-4" />
99
+ <h3 className="demo-section-title mb-2">No todos yet</h3>
100
+ <p className="demo-muted">
115
101
  Add your first todo above to get started!
116
102
  </p>
117
103
  </div>
118
104
  ) : (
119
- <div className="divide-y divide-green-100">
105
+ <div className="divide-y divide-[var(--line)]">
120
106
  {todos.map((todo, index) => (
121
107
  <div
122
108
  key={todo._id}
123
- className={`p-4 flex items-center gap-4 hover:bg-green-50/50 transition-colors ${
109
+ className={`p-4 flex items-center gap-4 transition-colors hover:bg-[var(--link-bg-hover)] ${
124
110
  todo.completed ? 'opacity-75' : ''
125
111
  }`}
126
112
  style={{
@@ -131,8 +117,8 @@ function ConvexTodos() {
131
117
  onClick={() => handleToggleTodo(todo._id)}
132
118
  className={`flex-shrink-0 w-6 h-6 rounded-full border-2 flex items-center justify-center transition-all duration-200 ${
133
119
  todo.completed
134
- ? 'bg-green-500 border-green-500 text-white'
135
- : 'border-green-300 hover:border-green-400 text-transparent hover:text-green-400'
120
+ ? 'border-[var(--lagoon-deep)] bg-[var(--lagoon)] text-[var(--sea-ink)]'
121
+ : 'border-[var(--line)] text-transparent hover:border-[var(--lagoon-deep)] hover:text-[var(--lagoon-deep)]'
136
122
  }`}
137
123
  >
138
124
  <Check size={14} />
@@ -141,8 +127,8 @@ function ConvexTodos() {
141
127
  <span
142
128
  className={`flex-1 text-lg transition-all duration-200 ${
143
129
  todo.completed
144
- ? 'line-through text-gray-500'
145
- : 'text-gray-800'
130
+ ? 'line-through demo-muted'
131
+ : 'text-[var(--sea-ink)]'
146
132
  }`}
147
133
  >
148
134
  {todo.text}
@@ -150,7 +136,7 @@ function ConvexTodos() {
150
136
 
151
137
  <button
152
138
  onClick={() => handleRemoveTodo(todo._id)}
153
- className="flex-shrink-0 p-2 text-red-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors"
139
+ className="demo-button demo-button-danger flex-shrink-0 p-2"
154
140
  >
155
141
  <Trash2 size={18} />
156
142
  </button>
@@ -158,15 +144,14 @@ function ConvexTodos() {
158
144
  ))}
159
145
  </div>
160
146
  )}
161
- </div>
147
+ </section>
162
148
 
163
- {/* Footer */}
164
149
  <div className="text-center mt-6">
165
- <p className="text-green-700/80 text-sm">
166
- Built with Convex • Real-time updates Always in sync
150
+ <p className="demo-muted text-sm">
151
+ Built with Convex, real-time updates, and synced state.
167
152
  </p>
168
153
  </div>
169
154
  </div>
170
- </div>
155
+ </main>
171
156
  )
172
157
  }
@@ -27,16 +27,16 @@ export default function ChatArea() {
27
27
 
28
28
  return (
29
29
  <>
30
- <div className="px-4 py-6 space-y-4">
30
+ <div className="flex-1 space-y-4 overflow-auto px-4 py-6">
31
31
  <Messages messages={messages} user={user} />
32
32
  </div>
33
33
 
34
- <div className="bg-white border-t border-gray-200 px-4 py-4">
34
+ <div className="border-t border-[var(--line)] bg-[var(--chip-bg)] px-4 py-4">
35
35
  <div className="flex items-center space-x-3">
36
36
  <select
37
37
  value={user}
38
38
  onChange={(e) => setUser(e.target.value)}
39
- className="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
39
+ className="demo-select demo-input-fit text-sm"
40
40
  >
41
41
  <option value="Alice">Alice</option>
42
42
  <option value="Bob">Bob</option>
@@ -49,14 +49,14 @@ export default function ChatArea() {
49
49
  onChange={(e) => setMessage(e.target.value)}
50
50
  onKeyDown={handleKeyPress}
51
51
  placeholder="Type a message..."
52
- className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
52
+ className="demo-input"
53
53
  />
54
54
  </div>
55
55
 
56
56
  <button
57
57
  onClick={postMessage}
58
58
  disabled={message.trim() === ''}
59
- className="px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
59
+ className="demo-button"
60
60
  >
61
61
  Send
62
62
  </button>
@@ -2,14 +2,10 @@ import type { Message } from '#/db-collections'
2
2
 
3
3
  export const getAvatarColor = (username: string) => {
4
4
  const colors = [
5
- 'bg-blue-500',
6
- 'bg-green-500',
7
- 'bg-purple-500',
8
- 'bg-pink-500',
9
- 'bg-indigo-500',
10
- 'bg-red-500',
11
- 'bg-yellow-500',
12
- 'bg-teal-500',
5
+ 'bg-[var(--lagoon-deep)]',
6
+ 'bg-[var(--palm)]',
7
+ 'bg-[var(--sea-ink-soft)]',
8
+ 'bg-[var(--lagoon)]',
13
9
  ]
14
10
  const index = username
15
11
  .split('')
@@ -49,12 +45,12 @@ export default function Messages({
49
45
  <div
50
46
  className={`px-4 py-2 rounded-2xl ${
51
47
  msg.user === user
52
- ? 'bg-blue-500 text-white rounded-br-md'
53
- : 'bg-white text-gray-800 border border-gray-200 rounded-bl-md'
48
+ ? 'bg-[var(--lagoon-deep)] text-white rounded-br-md'
49
+ : 'border border-[var(--line)] bg-[var(--chip-bg)] text-[var(--sea-ink)] rounded-bl-md'
54
50
  }`}
55
51
  >
56
52
  {msg.user !== user && (
57
- <p className="text-xs text-gray-500 mb-1 font-medium">
53
+ <p className="demo-muted mb-1 text-xs font-medium">
58
54
  {msg.user}
59
55
  </p>
60
56
  )}
@@ -8,8 +8,10 @@ export const Route = createFileRoute('/demo/db-chat')({
8
8
 
9
9
  function App() {
10
10
  return (
11
- <div className="flex flex-col h-screen bg-gray-50">
12
- <ChatArea />
13
- </div>
11
+ <main className="demo-page demo-center">
12
+ <section className="demo-panel flex h-[70vh] w-full max-w-3xl flex-col overflow-hidden p-0">
13
+ <ChatArea />
14
+ </section>
15
+ </main>
14
16
  )
15
17
  }
@@ -47,141 +47,91 @@ function DemoDrizzle() {
47
47
  }
48
48
 
49
49
  return (
50
- <div
51
- className="flex items-center justify-center min-h-screen p-4 text-white"
52
- style={{
53
- background:
54
- 'linear-gradient(135deg, #0c1a2b 0%, #1a2332 50%, #16202e 100%)',
55
- }}
56
- >
57
- <div
58
- className="w-full max-w-2xl p-8 rounded-xl shadow-2xl border border-white/10"
59
- style={{
60
- background:
61
- 'linear-gradient(135deg, rgba(22, 32, 46, 0.95) 0%, rgba(12, 26, 43, 0.95) 100%)',
62
- backdropFilter: 'blur(10px)',
63
- }}
64
- >
65
- <div
66
- className="flex items-center justify-center gap-4 mb-8 p-4 rounded-lg"
67
- style={{
68
- background:
69
- 'linear-gradient(90deg, rgba(93, 103, 227, 0.1) 0%, rgba(139, 92, 246, 0.1) 100%)',
70
- border: '1px solid rgba(93, 103, 227, 0.2)',
71
- }}
72
- >
73
- <div className="relative group">
74
- <div className="absolute -inset-2 bg-gradient-to-r from-indigo-500 via-purple-500 to-indigo-500 rounded-lg blur-lg opacity-60 group-hover:opacity-100 transition duration-500"></div>
75
- <div className="relative bg-gradient-to-br from-indigo-600 to-purple-600 p-3 rounded-lg">
76
- <img
77
- src="/drizzle.svg"
78
- alt="Drizzle Logo"
79
- className="w-8 h-8 transform group-hover:scale-110 transition-transform duration-300"
80
- />
81
- </div>
50
+ <main className="demo-page demo-center">
51
+ <section className="demo-panel w-full max-w-2xl">
52
+ <header className="mb-8 flex items-center gap-4">
53
+ <span className="demo-card flex h-14 w-14 items-center justify-center p-3">
54
+ <img src="/drizzle.svg" alt="Drizzle Logo" className="h-8 w-8" />
55
+ </span>
56
+ <div>
57
+ <p className="island-kicker mb-2">Database</p>
58
+ <h1 className="demo-title">Drizzle Demo</h1>
82
59
  </div>
83
- <h1 className="text-3xl font-bold bg-gradient-to-r from-indigo-300 via-purple-300 to-indigo-300 text-transparent bg-clip-text">
84
- Drizzle Database Demo
85
- </h1>
86
- </div>
60
+ </header>
87
61
 
88
- <h2 className="text-2xl font-bold mb-4 text-indigo-200">Todos</h2>
62
+ <h2 className="demo-section-title mb-4">Todos</h2>
89
63
 
90
64
  <ul className="space-y-3 mb-6">
91
65
  {todos.map((todo) => (
92
66
  <li
93
67
  key={todo.id}
94
- className="rounded-lg p-4 shadow-md border transition-all hover:scale-[1.02] cursor-pointer group"
95
- style={{
96
- background:
97
- 'linear-gradient(135deg, rgba(93, 103, 227, 0.15) 0%, rgba(139, 92, 246, 0.15) 100%)',
98
- borderColor: 'rgba(93, 103, 227, 0.3)',
99
- }}
68
+ className="demo-list-item"
100
69
  >
101
70
  <div className="flex items-center justify-between">
102
- <span className="text-lg font-medium text-white group-hover:text-indigo-200 transition-colors">
103
- {todo.title}
104
- </span>
105
- <span className="text-xs text-indigo-300/70">#{todo.id}</span>
71
+ <span className="font-medium">{todo.title}</span>
72
+ <span className="demo-muted text-xs">#{todo.id}</span>
106
73
  </div>
107
74
  </li>
108
75
  ))}
109
76
  {todos.length === 0 && (
110
- <li className="text-center py-8 text-indigo-300/70">
77
+ <li className="demo-list-item text-center demo-muted">
111
78
  No todos yet. Create one below!
112
79
  </li>
113
80
  )}
114
81
  </ul>
115
82
 
116
- <form onSubmit={handleSubmit} className="flex gap-2">
83
+ <form onSubmit={handleSubmit} className="flex flex-col gap-2 sm:flex-row">
117
84
  <input
118
85
  type="text"
119
86
  name="title"
120
87
  placeholder="Add a new todo..."
121
- className="flex-1 px-4 py-3 rounded-lg border focus:outline-none focus:ring-2 transition-all text-white placeholder-indigo-300/50"
122
- style={{
123
- background: 'rgba(93, 103, 227, 0.1)',
124
- borderColor: 'rgba(93, 103, 227, 0.3)',
125
- focusRing: 'rgba(93, 103, 227, 0.5)',
126
- }}
88
+ className="demo-input min-w-0 flex-1"
127
89
  />
128
90
  <button
129
91
  type="submit"
130
- className="px-6 py-3 font-semibold rounded-lg shadow-lg transition-all duration-200 hover:shadow-xl hover:scale-105 active:scale-95 whitespace-nowrap"
131
- style={{
132
- background: 'linear-gradient(135deg, #5d67e3 0%, #8b5cf6 100%)',
133
- color: 'white',
134
- }}
92
+ className="demo-button whitespace-nowrap"
135
93
  >
136
94
  Add Todo
137
95
  </button>
138
96
  </form>
139
97
 
140
- <div
141
- className="mt-8 p-6 rounded-lg border"
142
- style={{
143
- background: 'rgba(93, 103, 227, 0.05)',
144
- borderColor: 'rgba(93, 103, 227, 0.2)',
145
- }}
146
- >
147
- <h3 className="text-lg font-semibold mb-2 text-indigo-200">
98
+ <div className="demo-card mt-8">
99
+ <h3 className="demo-section-title mb-2">
148
100
  Powered by Drizzle ORM
149
101
  </h3>
150
- <p className="text-sm text-indigo-300/80 mb-4">
102
+ <p className="demo-muted mb-4 text-sm">
151
103
  Next-generation ORM for Node.js & TypeScript with PostgreSQL
152
104
  </p>
153
105
  <div className="space-y-2 text-sm">
154
- <p className="text-indigo-200 font-medium">Setup Instructions:</p>
155
- <ol className="list-decimal list-inside space-y-2 text-indigo-300/80">
106
+ <p className="font-medium">Setup Instructions:</p>
107
+ <ol className="demo-muted list-inside list-decimal space-y-2">
156
108
  <li>
157
109
  Configure your{' '}
158
- <code className="px-2 py-1 rounded bg-black/30 text-purple-300">
159
- DATABASE_URL
160
- </code>{' '}
110
+ <code>DATABASE_URL</code>{' '}
161
111
  in .env.local
162
112
  </li>
163
113
  <li>
164
114
  Run:{' '}
165
- <code className="px-2 py-1 rounded bg-black/30 text-purple-300">
115
+ <code>
166
116
  <%- getPackageManagerExecuteScript('drizzle-kit', ['generate']) %>
167
117
  </code>
168
118
  </li>
169
119
  <li>
170
120
  Run:{' '}
171
- <code className="px-2 py-1 rounded bg-black/30 text-purple-300">
121
+ <code>
172
122
  <%- getPackageManagerExecuteScript('drizzle-kit', ['migrate']) %>
173
123
  </code>
174
124
  </li>
175
125
  <li>
176
126
  Optional:{' '}
177
- <code className="px-2 py-1 rounded bg-black/30 text-purple-300">
127
+ <code>
178
128
  <%- getPackageManagerExecuteScript('drizzle-kit', ['studio']) %>
179
129
  </code>
180
130
  </li>
181
131
  </ol>
182
132
  </div>
183
133
  </div>
184
- </div>
185
- </div>
134
+ </section>
135
+ </main>
186
136
  )
187
137
  }
@@ -33,7 +33,7 @@ function ErrorMessages({
33
33
  {errors.map((error) => (
34
34
  <div
35
35
  key={typeof error === 'string' ? error : error.message}
36
- className="text-red-500 mt-1 font-bold"
36
+ className="mt-1 text-sm font-semibold text-red-600"
37
37
  >
38
38
  {typeof error === 'string' ? error : error.message}
39
39
  </div>
@@ -54,7 +54,7 @@ export function TextField({
54
54
 
55
55
  return (
56
56
  <div>
57
- <Label htmlFor={label} className="mb-2 text-xl font-bold">
57
+ <Label htmlFor={label} className="mb-2 text-sm font-semibold text-[var(--sea-ink)]">
58
58
  {label}
59
59
  </Label>
60
60
  <Input
@@ -80,7 +80,7 @@ export function TextArea({
80
80
 
81
81
  return (
82
82
  <div>
83
- <Label htmlFor={label} className="mb-2 text-xl font-bold">
83
+ <Label htmlFor={label} className="mb-2 text-sm font-semibold text-[var(--sea-ink)]">
84
84
  {label}
85
85
  </Label>
86
86
  <ShadcnTextarea
@@ -143,7 +143,7 @@ export function Slider({ label }: { label: string }) {
143
143
 
144
144
  return (
145
145
  <div>
146
- <Label htmlFor={label} className="mb-2 text-xl font-bold">
146
+ <Label htmlFor={label} className="mb-2 text-sm font-semibold text-[var(--sea-ink)]">
147
147
  {label}
148
148
  </Label>
149
149
  <ShadcnSlider
@@ -186,7 +186,7 @@ export function SubscribeButton({ label }: { label: string }) {
186
186
  <button
187
187
  type="submit"
188
188
  disabled={isSubmitting}
189
- className="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"
189
+ className="demo-button"
190
190
  >
191
191
  {label}
192
192
  </button>
@@ -205,7 +205,7 @@ function ErrorMessages({
205
205
  {errors.map((error) => (
206
206
  <div
207
207
  key={typeof error === 'string' ? error : error.message}
208
- className="text-red-500 mt-1 font-bold"
208
+ className="mt-1 text-sm font-semibold text-red-600"
209
209
  >
210
210
  {typeof error === 'string' ? error : error.message}
211
211
  </div>
@@ -226,14 +226,14 @@ export function TextField({
226
226
 
227
227
  return (
228
228
  <div>
229
- <label htmlFor={label} className="block font-bold mb-1 text-xl">
229
+ <label htmlFor={label} className="mb-2 block text-sm font-semibold text-[var(--sea-ink)]">
230
230
  {label}
231
231
  <input
232
232
  value={field.state.value}
233
233
  placeholder={placeholder}
234
234
  onBlur={field.handleBlur}
235
235
  onChange={(e) => field.handleChange(e.target.value)}
236
- className="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
236
+ className="demo-input mt-2"
237
237
  />
238
238
  </label>
239
239
  {field.state.meta.isTouched && <ErrorMessages errors={errors} />}
@@ -253,14 +253,14 @@ export function TextArea({
253
253
 
254
254
  return (
255
255
  <div>
256
- <label htmlFor={label} className="block font-bold mb-1 text-xl">
256
+ <label htmlFor={label} className="mb-2 block text-sm font-semibold text-[var(--sea-ink)]">
257
257
  {label}
258
258
  <textarea
259
259
  value={field.state.value}
260
260
  onBlur={field.handleBlur}
261
261
  rows={rows}
262
262
  onChange={(e) => field.handleChange(e.target.value)}
263
- className="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
263
+ className="demo-textarea mt-2"
264
264
  />
265
265
  </label>
266
266
  {field.state.meta.isTouched && <ErrorMessages errors={errors} />}
@@ -281,7 +281,7 @@ export function Select({
281
281
 
282
282
  return (
283
283
  <div>
284
- <label htmlFor={label} className="block font-bold mb-1 text-xl">
284
+ <label htmlFor={label} className="mb-2 block text-sm font-semibold text-[var(--sea-ink)]">
285
285
  {label}
286
286
  </label>
287
287
  <select
@@ -289,7 +289,7 @@ export function Select({
289
289
  value={field.state.value}
290
290
  onBlur={field.handleBlur}
291
291
  onChange={(e) => field.handleChange(e.target.value)}
292
- className="w-full px-4 py-2 rounded-md border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500"
292
+ className="demo-select"
293
293
  >
294
294
  {values.map((value) => (
295
295
  <option key={value.value} value={value.value}>
@@ -45,14 +45,15 @@ function AddressForm() {
45
45
  })
46
46
 
47
47
  return (
48
- <div
49
- className="flex items-center justify-center min-h-screen bg-gradient-to-br from-purple-100 to-blue-100 p-4 text-white"
50
- style={{
51
- backgroundImage:
52
- 'radial-gradient(50% 50% at 5% 40%, #f4a460 0%, #8b4513 70%, #1a0f0a 100%)',
53
- }}
54
- >
55
- <div className="w-full max-w-2xl p-8 rounded-xl backdrop-blur-md bg-black/50 shadow-xl border-8 border-black/10">
48
+ <main className="demo-page demo-center">
49
+ <section className="demo-panel w-full max-w-2xl">
50
+ <div className="mb-6">
51
+ <p className="island-kicker mb-2">TanStack Form</p>
52
+ <h1 className="demo-title">Address Form</h1>
53
+ <p className="demo-muted mt-2">
54
+ Nested fields, field-level validation, and a select input.
55
+ </p>
56
+ </div>
56
57
  <form
57
58
  onSubmit={(e) => {
58
59
  e.preventDefault()
@@ -198,8 +199,8 @@ function AddressForm() {
198
199
  </form.AppForm>
199
200
  </div>
200
201
  </form>
201
- </div>
202
- </div>
202
+ </section>
203
+ </main>
203
204
  )
204
205
  }
205
206
 
@@ -33,14 +33,15 @@ function SimpleForm() {
33
33
  })
34
34
 
35
35
  return (
36
- <div
37
- className="flex items-center justify-center min-h-screen bg-gradient-to-br from-purple-100 to-blue-100 p-4 text-white"
38
- style={{
39
- backgroundImage:
40
- 'radial-gradient(50% 50% at 5% 40%, #add8e6 0%, #0000ff 70%, #00008b 100%)',
41
- }}
42
- >
43
- <div className="w-full max-w-2xl p-8 rounded-xl backdrop-blur-md bg-black/50 shadow-xl border-8 border-black/10">
36
+ <main className="demo-page demo-center">
37
+ <section className="demo-panel w-full max-w-2xl">
38
+ <div className="mb-6">
39
+ <p className="island-kicker mb-2">TanStack Form</p>
40
+ <h1 className="demo-title">Simple Form</h1>
41
+ <p className="demo-muted mt-2">
42
+ A small validated form using the generated field helpers.
43
+ </p>
44
+ </div>
44
45
  <form
45
46
  onSubmit={(e) => {
46
47
  e.preventDefault()
@@ -63,8 +64,8 @@ function SimpleForm() {
63
64
  </form.AppForm>
64
65
  </div>
65
66
  </form>
66
- </div>
67
- </div>
67
+ </section>
68
+ </main>
68
69
  )
69
70
  }
70
71
 
@@ -32,22 +32,14 @@ function ORPCTodos() {
32
32
  }, [todo])
33
33
 
34
34
  return (
35
- <div
36
- className="flex items-center justify-center min-h-screen bg-gradient-to-br from-teal-200 to-emerald-900 p-4 text-white"
37
- style={{
38
- backgroundImage:
39
- 'radial-gradient(70% 70% at 20% 20%, #07A798 0%, #045C4B 60%, #01251F 100%)',
40
- }}
41
- >
42
- <div className="w-full max-w-2xl p-8 rounded-xl backdrop-blur-md bg-black/50 shadow-xl border-8 border-black/10">
43
- <h1 className="text-2xl mb-4">MCP Todos list</h1>
35
+ <main className="demo-page demo-center">
36
+ <section className="demo-panel w-full max-w-2xl">
37
+ <p className="island-kicker mb-2">MCP</p>
38
+ <h1 className="demo-title mb-6">Todos</h1>
44
39
  <ul className="mb-4 space-y-2">
45
40
  {todos?.map((t) => (
46
- <li
47
- key={t.id}
48
- className="bg-white/10 border border-white/20 rounded-lg p-3 backdrop-blur-sm shadow-md"
49
- >
50
- <span className="text-lg text-white">{t.title}</span>
41
+ <li key={t.id} className="demo-list-item">
42
+ <span className="text-base font-medium">{t.title}</span>
51
43
  </li>
52
44
  ))}
53
45
  </ul>
@@ -62,17 +54,17 @@ function ORPCTodos() {
62
54
  }
63
55
  }}
64
56
  placeholder="Enter a new todo..."
65
- className="w-full px-4 py-3 rounded-lg border border-white/20 bg-white/10 backdrop-blur-sm text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent"
57
+ className="demo-input"
66
58
  />
67
59
  <button
68
60
  disabled={todo.trim().length === 0}
69
61
  onClick={submitTodo}
70
- className="bg-blue-500 hover:bg-blue-600 disabled:bg-blue-500/50 disabled:cursor-not-allowed text-white font-bold py-3 px-4 rounded-lg transition-colors"
62
+ className="demo-button"
71
63
  >
72
64
  Add todo
73
65
  </button>
74
66
  </div>
75
- </div>
76
- </div>
67
+ </section>
68
+ </main>
77
69
  )
78
70
  }