@tanstack/create 0.68.0 → 0.68.2

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 (132) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/create-app.js +22 -0
  3. package/dist/frameworks/react/add-ons/ai/assets/src/components/demo-AIAssistant.tsx +15 -15
  4. package/dist/frameworks/react/add-ons/ai/assets/src/components/demo-GuitarRecommendation.tsx +8 -6
  5. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-chat.css +21 -21
  6. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-chat.tsx +14 -18
  7. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-image.tsx +20 -26
  8. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-structured.tsx +56 -67
  9. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/guitars/$guitarId.tsx +17 -22
  10. package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/guitars/index.tsx +21 -27
  11. package/dist/frameworks/react/add-ons/apollo-client/assets/src/routes/demo.apollo-client.tsx +35 -38
  12. package/dist/frameworks/react/add-ons/better-auth/assets/src/routes/demo/better-auth.tsx +64 -64
  13. package/dist/frameworks/react/add-ons/clerk/assets/src/routes/demo/clerk.tsx +17 -25
  14. package/dist/frameworks/react/add-ons/convex/assets/src/routes/demo/convex.tsx +30 -45
  15. package/dist/frameworks/react/add-ons/db/assets/src/components/demo.chat-area.tsx +5 -5
  16. package/dist/frameworks/react/add-ons/db/assets/src/components/demo.messages.tsx +7 -11
  17. package/dist/frameworks/react/add-ons/db/assets/src/routes/demo/db-chat.tsx +5 -3
  18. package/dist/frameworks/react/add-ons/drizzle/assets/src/routes/demo/drizzle.tsx.ejs +29 -79
  19. package/dist/frameworks/react/add-ons/form/assets/src/components/demo.FormComponents.tsx.ejs +12 -12
  20. package/dist/frameworks/react/add-ons/form/assets/src/routes/demo/form.address.tsx.ejs +11 -10
  21. package/dist/frameworks/react/add-ons/form/assets/src/routes/demo/form.simple.tsx.ejs +11 -10
  22. package/dist/frameworks/react/add-ons/mcp/assets/src/routes/demo/mcp-todos.tsx +10 -18
  23. package/dist/frameworks/react/add-ons/neon/assets/src/routes/demo/neon.tsx +38 -57
  24. package/dist/frameworks/react/add-ons/oRPC/assets/src/routes/demo/orpc-todo.tsx +10 -18
  25. package/dist/frameworks/react/add-ons/paraglide/assets/src/routes/demo.i18n.tsx.ejs +6 -7
  26. package/dist/frameworks/react/add-ons/posthog/assets/src/routes/demo/posthog.tsx +19 -22
  27. package/dist/frameworks/react/add-ons/powersync/assets/src/routes/demo/powersync.tsx +19 -18
  28. package/dist/frameworks/react/add-ons/prisma/assets/src/routes/demo/prisma.tsx.ejs +29 -79
  29. package/dist/frameworks/react/add-ons/sentry/assets/src/routes/demo/sentry.testing.tsx +71 -102
  30. package/dist/frameworks/react/add-ons/store/assets/src/lib/demo-store-devtools.tsx +3 -3
  31. package/dist/frameworks/react/add-ons/store/assets/src/routes/demo/store.tsx.ejs +9 -14
  32. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.tsx +23 -26
  33. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.tsx +12 -16
  34. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.tsx +14 -17
  35. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.tsx +15 -15
  36. package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.tsx +17 -17
  37. package/dist/frameworks/react/add-ons/storybook/assets/src/routes/demo/storybook.tsx +25 -25
  38. package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/media.tsx +9 -9
  39. package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/quote.tsx +8 -8
  40. package/dist/frameworks/react/add-ons/strapi/assets/src/components/markdown-content.tsx +52 -35
  41. package/dist/frameworks/react/add-ons/strapi/assets/src/components/pagination.tsx +8 -14
  42. package/dist/frameworks/react/add-ons/strapi/assets/src/components/search.tsx +12 -12
  43. package/dist/frameworks/react/add-ons/strapi/assets/src/components/strapi-image.tsx +15 -15
  44. package/dist/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.$articleId.tsx +52 -63
  45. package/dist/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.tsx +46 -61
  46. package/dist/frameworks/react/add-ons/tRPC/assets/src/routes/demo/trpc-todo.tsx +10 -18
  47. package/dist/frameworks/react/add-ons/table/assets/src/routes/demo/table.tsx.ejs +23 -22
  48. package/dist/frameworks/react/add-ons/tanstack-query/assets/src/routes/demo/tanstack-query.tsx.ejs +21 -35
  49. package/dist/frameworks/react/add-ons/workos/assets/src/components/workos-user.tsx +1 -1
  50. package/dist/frameworks/react/add-ons/workos/assets/src/routes/demo/workos.tsx +33 -43
  51. package/dist/frameworks/react/project/base/package.json +1 -0
  52. package/dist/frameworks/react/project/base/src/styles.css.ejs +203 -0
  53. package/dist/frameworks/react/project/base/tsr.config.json +3 -0
  54. package/dist/frameworks/react/project/packages.json +3 -0
  55. package/dist/frameworks/solid/add-ons/better-auth/assets/src/routes/demo.better-auth.tsx +62 -64
  56. package/dist/frameworks/solid/add-ons/convex/assets/src/routes/demo/convex.tsx +30 -43
  57. package/dist/frameworks/solid/add-ons/form/assets/src/routes/demo.form.tsx.ejs +22 -22
  58. package/dist/frameworks/solid/add-ons/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +15 -10
  59. package/dist/frameworks/solid/add-ons/store/assets/src/routes/demo.store.tsx.ejs +9 -14
  60. package/dist/frameworks/solid/add-ons/strapi/assets/src/routes/demo/strapi.tsx +11 -15
  61. package/dist/frameworks/solid/add-ons/strapi/assets/src/routes/demo/strapi_.$articleId.tsx +11 -18
  62. package/dist/frameworks/solid/project/base/package.json +1 -0
  63. package/dist/frameworks/solid/project/base/src/styles.css.ejs +203 -0
  64. package/dist/frameworks/solid/project/base/tsr.config.json +3 -0
  65. package/dist/frameworks/solid/project/packages.json +3 -0
  66. package/package.json +1 -1
  67. package/src/create-app.ts +32 -1
  68. package/src/frameworks/react/add-ons/ai/assets/src/components/demo-AIAssistant.tsx +15 -15
  69. package/src/frameworks/react/add-ons/ai/assets/src/components/demo-GuitarRecommendation.tsx +8 -6
  70. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-chat.css +21 -21
  71. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-chat.tsx +14 -18
  72. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-image.tsx +20 -26
  73. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/ai-structured.tsx +56 -67
  74. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/guitars/$guitarId.tsx +17 -22
  75. package/src/frameworks/react/add-ons/ai/assets/src/routes/demo/guitars/index.tsx +21 -27
  76. package/src/frameworks/react/add-ons/apollo-client/assets/src/routes/demo.apollo-client.tsx +35 -38
  77. package/src/frameworks/react/add-ons/better-auth/assets/src/routes/demo/better-auth.tsx +64 -64
  78. package/src/frameworks/react/add-ons/clerk/assets/src/routes/demo/clerk.tsx +17 -25
  79. package/src/frameworks/react/add-ons/convex/assets/src/routes/demo/convex.tsx +30 -45
  80. package/src/frameworks/react/add-ons/db/assets/src/components/demo.chat-area.tsx +5 -5
  81. package/src/frameworks/react/add-ons/db/assets/src/components/demo.messages.tsx +7 -11
  82. package/src/frameworks/react/add-ons/db/assets/src/routes/demo/db-chat.tsx +5 -3
  83. package/src/frameworks/react/add-ons/drizzle/assets/src/routes/demo/drizzle.tsx.ejs +29 -79
  84. package/src/frameworks/react/add-ons/form/assets/src/components/demo.FormComponents.tsx.ejs +12 -12
  85. package/src/frameworks/react/add-ons/form/assets/src/routes/demo/form.address.tsx.ejs +11 -10
  86. package/src/frameworks/react/add-ons/form/assets/src/routes/demo/form.simple.tsx.ejs +11 -10
  87. package/src/frameworks/react/add-ons/mcp/assets/src/routes/demo/mcp-todos.tsx +10 -18
  88. package/src/frameworks/react/add-ons/neon/assets/src/routes/demo/neon.tsx +38 -57
  89. package/src/frameworks/react/add-ons/oRPC/assets/src/routes/demo/orpc-todo.tsx +10 -18
  90. package/src/frameworks/react/add-ons/paraglide/assets/src/routes/demo.i18n.tsx.ejs +6 -7
  91. package/src/frameworks/react/add-ons/posthog/assets/src/routes/demo/posthog.tsx +19 -22
  92. package/src/frameworks/react/add-ons/powersync/assets/src/routes/demo/powersync.tsx +19 -18
  93. package/src/frameworks/react/add-ons/prisma/assets/src/routes/demo/prisma.tsx.ejs +29 -79
  94. package/src/frameworks/react/add-ons/sentry/assets/src/routes/demo/sentry.testing.tsx +71 -102
  95. package/src/frameworks/react/add-ons/store/assets/src/lib/demo-store-devtools.tsx +3 -3
  96. package/src/frameworks/react/add-ons/store/assets/src/routes/demo/store.tsx.ejs +9 -14
  97. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.tsx +23 -26
  98. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/dialog.tsx +12 -16
  99. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.tsx +14 -17
  100. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.tsx +15 -15
  101. package/src/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.tsx +17 -17
  102. package/src/frameworks/react/add-ons/storybook/assets/src/routes/demo/storybook.tsx +25 -25
  103. package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/media.tsx +9 -9
  104. package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/quote.tsx +8 -8
  105. package/src/frameworks/react/add-ons/strapi/assets/src/components/markdown-content.tsx +52 -35
  106. package/src/frameworks/react/add-ons/strapi/assets/src/components/pagination.tsx +8 -14
  107. package/src/frameworks/react/add-ons/strapi/assets/src/components/search.tsx +12 -12
  108. package/src/frameworks/react/add-ons/strapi/assets/src/components/strapi-image.tsx +15 -15
  109. package/src/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.$articleId.tsx +52 -63
  110. package/src/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.tsx +46 -61
  111. package/src/frameworks/react/add-ons/tRPC/assets/src/routes/demo/trpc-todo.tsx +10 -18
  112. package/src/frameworks/react/add-ons/table/assets/src/routes/demo/table.tsx.ejs +23 -22
  113. package/src/frameworks/react/add-ons/tanstack-query/assets/src/routes/demo/tanstack-query.tsx.ejs +21 -35
  114. package/src/frameworks/react/add-ons/workos/assets/src/components/workos-user.tsx +1 -1
  115. package/src/frameworks/react/add-ons/workos/assets/src/routes/demo/workos.tsx +33 -43
  116. package/src/frameworks/react/project/base/package.json +1 -0
  117. package/src/frameworks/react/project/base/src/styles.css.ejs +203 -0
  118. package/src/frameworks/react/project/base/tsr.config.json +3 -0
  119. package/src/frameworks/react/project/packages.json +3 -0
  120. package/src/frameworks/solid/add-ons/better-auth/assets/src/routes/demo.better-auth.tsx +62 -64
  121. package/src/frameworks/solid/add-ons/convex/assets/src/routes/demo/convex.tsx +30 -43
  122. package/src/frameworks/solid/add-ons/form/assets/src/routes/demo.form.tsx.ejs +22 -22
  123. package/src/frameworks/solid/add-ons/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +15 -10
  124. package/src/frameworks/solid/add-ons/store/assets/src/routes/demo.store.tsx.ejs +9 -14
  125. package/src/frameworks/solid/add-ons/strapi/assets/src/routes/demo/strapi.tsx +11 -15
  126. package/src/frameworks/solid/add-ons/strapi/assets/src/routes/demo/strapi_.$articleId.tsx +11 -18
  127. package/src/frameworks/solid/project/base/package.json +1 -0
  128. package/src/frameworks/solid/project/base/src/styles.css.ejs +203 -0
  129. package/src/frameworks/solid/project/base/tsr.config.json +3 -0
  130. package/src/frameworks/solid/project/packages.json +3 -0
  131. package/tests/create-app.test.ts +39 -3
  132. package/tests/framework-template.test.ts +34 -0
@@ -1,63 +1,58 @@
1
- import { createFileRoute, Link } from "@tanstack/react-router";
2
- import { strapiApi } from "@/data/loaders";
3
- import { StrapiImage } from "@/components/strapi-image";
4
- import { BlockRenderer } from "@/components/blocks";
5
- import type { TArticle } from "@/types/strapi";
1
+ import { createFileRoute, Link } from '@tanstack/react-router'
2
+ import { strapiApi } from '@/data/loaders'
3
+ import { StrapiImage } from '@/components/strapi-image'
4
+ import { BlockRenderer } from '@/components/blocks'
5
+ import type { TArticle } from '@/types/strapi'
6
6
 
7
- export const Route = createFileRoute("/demo/strapi/$articleId")({
7
+ export const Route = createFileRoute('/demo/strapi/$articleId')({
8
8
  component: RouteComponent,
9
9
  errorComponent: ErrorComponent,
10
10
  loader: async ({ params }) => {
11
11
  try {
12
12
  const response = await strapiApi.articles.getArticleByIdData({
13
13
  data: params.articleId,
14
- });
15
- return { success: true, article: response.data };
14
+ })
15
+ return { success: true, article: response.data }
16
16
  } catch (error) {
17
17
  return {
18
18
  success: false,
19
- error: error instanceof Error ? error.message : "Failed to load article",
19
+ error:
20
+ error instanceof Error ? error.message : 'Failed to load article',
20
21
  article: null,
21
- };
22
+ }
22
23
  }
23
24
  },
24
- });
25
+ })
25
26
 
26
27
  function ErrorComponent({ error }: { error: Error }) {
27
28
  return (
28
- <div className="min-h-screen bg-gradient-to-b from-slate-900 via-slate-800 to-slate-900 p-8">
29
- <div className="max-w-4xl mx-auto">
30
- <Link
31
- to="/demo/strapi"
32
- className="inline-flex items-center text-cyan-400 hover:text-cyan-300 mb-6 transition-colors"
33
- >
29
+ <main className="demo-page">
30
+ <div className="mx-auto max-w-4xl">
31
+ <Link to="/demo/strapi" className="mb-6 inline-flex items-center">
34
32
  ← Back to Articles
35
33
  </Link>
36
- <div className="bg-red-900/20 border border-red-500/50 rounded-xl p-8 text-center">
37
- <h1 className="text-2xl font-bold text-red-400 mb-4">Error Loading Article</h1>
38
- <p className="text-gray-300">{error.message}</p>
34
+ <div className="demo-alert demo-alert-danger text-center">
35
+ <h1 className="text-2xl font-bold mb-4">Error Loading Article</h1>
36
+ <p className="demo-muted">{error.message}</p>
39
37
  </div>
40
38
  </div>
41
- </div>
42
- );
39
+ </main>
40
+ )
43
41
  }
44
42
 
45
43
  function RouteComponent() {
46
44
  const { success, article, error } = Route.useLoaderData() as {
47
- success: boolean;
48
- article: TArticle | null;
49
- error?: string;
50
- };
45
+ success: boolean
46
+ article: TArticle | null
47
+ error?: string
48
+ }
51
49
 
52
50
  // Show error state
53
51
  if (!success || !article) {
54
52
  return (
55
- <div className="min-h-screen bg-gradient-to-b from-slate-900 via-slate-800 to-slate-900 p-8">
56
- <div className="max-w-4xl mx-auto">
57
- <Link
58
- to="/demo/strapi"
59
- className="inline-flex items-center text-cyan-400 hover:text-cyan-300 mb-6 transition-colors"
60
- >
53
+ <main className="demo-page">
54
+ <div className="mx-auto max-w-4xl">
55
+ <Link to="/demo/strapi" className="mb-6 inline-flex items-center">
61
56
  <svg
62
57
  xmlns="http://www.w3.org/2000/svg"
63
58
  className="h-5 w-5 mr-2"
@@ -73,31 +68,27 @@ function RouteComponent() {
73
68
  Back to Articles
74
69
  </Link>
75
70
 
76
- <div className="bg-amber-900/20 border border-amber-500/50 rounded-xl p-8">
71
+ <div className="demo-alert">
77
72
  <div className="flex items-start gap-4">
78
- <div className="text-amber-400 text-2xl">⚠️</div>
79
73
  <div>
80
- <h2 className="text-xl font-semibold text-amber-400 mb-2">
81
- {error || "Article Not Found"}
74
+ <h2 className="text-xl font-semibold mb-2">
75
+ {error || 'Article Not Found'}
82
76
  </h2>
83
- <p className="text-gray-300">
77
+ <p className="demo-muted">
84
78
  Make sure the Strapi server is running and the article exists.
85
79
  </p>
86
80
  </div>
87
81
  </div>
88
82
  </div>
89
83
  </div>
90
- </div>
91
- );
84
+ </main>
85
+ )
92
86
  }
93
87
 
94
88
  return (
95
- <div className="min-h-screen bg-gradient-to-b from-slate-900 via-slate-800 to-slate-900 p-8">
96
- <div className="max-w-4xl mx-auto">
97
- <Link
98
- to="/demo/strapi"
99
- className="inline-flex items-center text-cyan-400 hover:text-cyan-300 mb-6 transition-colors"
100
- >
89
+ <main className="demo-page">
90
+ <div className="mx-auto max-w-4xl">
91
+ <Link to="/demo/strapi" className="mb-6 inline-flex items-center">
101
92
  <svg
102
93
  xmlns="http://www.w3.org/2000/svg"
103
94
  className="h-5 w-5 mr-2"
@@ -113,7 +104,7 @@ function RouteComponent() {
113
104
  Back to Articles
114
105
  </Link>
115
106
 
116
- <article className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-xl overflow-hidden">
107
+ <article className="demo-panel overflow-hidden p-0">
117
108
  <StrapiImage
118
109
  src={article.cover?.url}
119
110
  alt={article.cover?.alternativeText || article.title}
@@ -121,23 +112,23 @@ function RouteComponent() {
121
112
  />
122
113
 
123
114
  <div className="p-8">
124
- <h1 className="text-4xl font-bold text-white mb-4">
125
- {article.title || "Untitled"}
126
- </h1>
115
+ <h1 className="demo-title mb-4">{article.title || 'Untitled'}</h1>
127
116
 
128
117
  <div className="flex items-center gap-4 mb-6">
129
118
  {article.author?.name && (
130
- <span className="text-gray-400">
131
- By{" "}
132
- <span className="text-cyan-400">{article.author.name}</span>
119
+ <span className="demo-muted">
120
+ By{' '}
121
+ <span className="text-[var(--sea-ink)]">
122
+ {article.author.name}
123
+ </span>
133
124
  </span>
134
125
  )}
135
126
  {article.createdAt && (
136
- <span className="text-sm text-cyan-400/70">
137
- {new Date(article.createdAt).toLocaleDateString("en-US", {
138
- year: "numeric",
139
- month: "long",
140
- day: "numeric",
127
+ <span className="demo-muted text-sm">
128
+ {new Date(article.createdAt).toLocaleDateString('en-US', {
129
+ year: 'numeric',
130
+ month: 'long',
131
+ day: 'numeric',
141
132
  })}
142
133
  </span>
143
134
  )}
@@ -145,15 +136,13 @@ function RouteComponent() {
145
136
 
146
137
  {article.category?.name && (
147
138
  <div className="mb-6">
148
- <span className="text-xs px-3 py-1 bg-slate-700 text-cyan-400 rounded-full">
149
- {article.category.name}
150
- </span>
139
+ <span className="demo-pill">{article.category.name}</span>
151
140
  </div>
152
141
  )}
153
142
 
154
143
  {article.description && (
155
144
  <div className="mb-8">
156
- <p className="text-xl text-gray-300 leading-relaxed">
145
+ <p className="demo-muted text-xl leading-relaxed">
157
146
  {article.description}
158
147
  </p>
159
148
  </div>
@@ -165,6 +154,6 @@ function RouteComponent() {
165
154
  </div>
166
155
  </article>
167
156
  </div>
168
- </div>
169
- );
157
+ </main>
158
+ )
170
159
  }
@@ -73,28 +73,25 @@ export const Route = createFileRoute('/demo/strapi')({
73
73
 
74
74
  function StrapiServerInstructions() {
75
75
  return (
76
- <div className="bg-slate-800/50 rounded-lg p-6 text-left mt-6">
77
- <h2 className="text-lg font-semibold text-white mb-4">
78
- Start the Strapi Server
79
- </h2>
80
- <div className="space-y-2 text-sm font-mono text-gray-400">
76
+ <div className="demo-card mt-6 text-left">
77
+ <h2 className="demo-section-title mb-4">Start the Strapi Server</h2>
78
+ <div className="demo-muted space-y-2 font-mono text-sm">
81
79
  <p>
82
- <span className="text-cyan-400">$</span> cd ../server
80
+ <span>$</span> cd ../server
83
81
  </p>
84
82
  <p>
85
- <span className="text-cyan-400">$</span> npm install
83
+ <span>$</span> npm install
86
84
  </p>
87
85
  <p>
88
- <span className="text-cyan-400">$</span> npm run develop
86
+ <span>$</span> npm run develop
89
87
  </p>
90
88
  </div>
91
- <p className="text-gray-500 text-sm mt-4">
89
+ <p className="demo-muted text-sm mt-4">
92
90
  Then create an admin at{' '}
93
91
  <a
94
92
  href="http://localhost:1337/admin"
95
93
  target="_blank"
96
94
  rel="noopener noreferrer"
97
- className="text-cyan-400 hover:underline"
98
95
  >
99
96
  http://localhost:1337/admin
100
97
  </a>
@@ -105,22 +102,17 @@ function StrapiServerInstructions() {
105
102
 
106
103
  function ConnectionError({ error }: { error?: string }) {
107
104
  return (
108
- <div className="bg-amber-900/20 border border-amber-500/50 rounded-xl p-8">
105
+ <div className="demo-alert">
109
106
  <div className="flex items-start gap-4">
110
- <div className="text-amber-400 text-2xl">⚠️</div>
111
107
  <div>
112
- <h2 className="text-xl font-semibold text-amber-400 mb-2">
108
+ <h2 className="text-xl font-semibold mb-2">
113
109
  Cannot Connect to Strapi
114
110
  </h2>
115
- <p className="text-gray-300 mb-4">
111
+ <p className="demo-muted mb-4">
116
112
  Make sure your Strapi server is running at{' '}
117
- <code className="text-cyan-400 bg-slate-800 px-2 py-1 rounded">
118
- http://localhost:1337
119
- </code>
113
+ <code>http://localhost:1337</code>
120
114
  </p>
121
- {error && (
122
- <p className="text-gray-500 text-sm mb-4">Error: {error}</p>
123
- )}
115
+ {error && <p className="demo-muted text-sm mb-4">Error: {error}</p>}
124
116
  <StrapiServerInstructions />
125
117
  </div>
126
118
  </div>
@@ -131,13 +123,10 @@ function ConnectionError({ error }: { error?: string }) {
131
123
  function NoArticlesFound({ query }: { query?: string }) {
132
124
  if (query) {
133
125
  return (
134
- <div className="bg-slate-800/50 border border-slate-700 rounded-xl p-8">
126
+ <div className="demo-card">
135
127
  <div className="text-center">
136
- <div className="text-6xl mb-4">🔍</div>
137
- <h2 className="text-2xl font-semibold text-white mb-4">
138
- No Results Found
139
- </h2>
140
- <p className="text-gray-400 mb-6 max-w-md mx-auto">
128
+ <h2 className="text-2xl font-semibold mb-4">No Results Found</h2>
129
+ <p className="demo-muted mb-6 max-w-md mx-auto">
141
130
  No articles match your search for "{query}". Try adjusting your
142
131
  search terms.
143
132
  </p>
@@ -147,54 +136,54 @@ function NoArticlesFound({ query }: { query?: string }) {
147
136
  }
148
137
 
149
138
  return (
150
- <div className="bg-slate-800/50 border border-slate-700 rounded-xl p-8">
139
+ <div className="demo-card">
151
140
  <div className="text-center">
152
- <div className="text-6xl mb-4">📝</div>
153
- <h2 className="text-2xl font-semibold text-white mb-4">
154
- No Articles Yet
155
- </h2>
156
- <p className="text-gray-400 mb-6 max-w-md mx-auto">
141
+ <h2 className="text-2xl font-semibold mb-4">No Articles Yet</h2>
142
+ <p className="demo-muted mb-6 max-w-md mx-auto">
157
143
  Your Strapi server is running, but there are no published articles.
158
144
  Create and publish your first article to see it here.
159
145
  </p>
160
146
 
161
- <div className="bg-slate-900/50 rounded-lg p-6 text-left max-w-md mx-auto">
162
- <h3 className="text-lg font-semibold text-white mb-4">
163
- How to add articles:
164
- </h3>
165
- <ol className="space-y-3 text-gray-400">
147
+ <div className="demo-card max-w-md mx-auto text-left">
148
+ <h3 className="demo-section-title mb-4">How to add articles:</h3>
149
+ <ol className="demo-muted space-y-3">
166
150
  <li className="flex gap-3">
167
- <span className="text-cyan-400 font-bold">1.</span>
151
+ <span className="font-bold">1.</span>
168
152
  <span>
169
153
  Open{' '}
170
154
  <a
171
155
  href="http://localhost:1337/admin"
172
156
  target="_blank"
173
157
  rel="noopener noreferrer"
174
- className="text-cyan-400 hover:underline"
175
158
  >
176
159
  Strapi Admin Panel
177
160
  </a>
178
161
  </span>
179
162
  </li>
180
163
  <li className="flex gap-3">
181
- <span className="text-cyan-400 font-bold">2.</span>
164
+ <span className="font-bold">2.</span>
182
165
  <span>
183
- Go to <strong className="text-white">Content Manager</strong> →{' '}
184
- <strong className="text-white">Article</strong>
166
+ Go to{' '}
167
+ <strong className="text-[var(--sea-ink)]">
168
+ Content Manager
169
+ </strong>{' '}
170
+ → <strong className="text-[var(--sea-ink)]">Article</strong>
185
171
  </span>
186
172
  </li>
187
173
  <li className="flex gap-3">
188
- <span className="text-cyan-400 font-bold">3.</span>
174
+ <span className="font-bold">3.</span>
189
175
  <span>
190
- Click <strong className="text-white">Create new entry</strong>
176
+ Click{' '}
177
+ <strong className="text-[var(--sea-ink)]">
178
+ Create new entry
179
+ </strong>
191
180
  </span>
192
181
  </li>
193
182
  <li className="flex gap-3">
194
- <span className="text-cyan-400 font-bold">4.</span>
183
+ <span className="font-bold">4.</span>
195
184
  <span>
196
185
  Fill in the details and click{' '}
197
- <strong className="text-white">Publish</strong>
186
+ <strong className="text-[var(--sea-ink)]">Publish</strong>
198
187
  </span>
199
188
  </li>
200
189
  </ol>
@@ -208,14 +197,10 @@ function RouteComponent() {
208
197
  const { status, articles, meta, error, query } = Route.useLoaderData()
209
198
 
210
199
  return (
211
- <div className="min-h-screen bg-gradient-to-b from-slate-900 via-slate-800 to-slate-900 p-8">
212
- <div className="max-w-7xl mx-auto">
213
- <h1 className="text-4xl font-bold mb-6 text-white">
214
- <span className="bg-gradient-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent">
215
- Strapi
216
- </span>{' '}
217
- <span className="text-gray-300">Articles</span>
218
- </h1>
200
+ <main className="demo-page demo-page-wide">
201
+ <div>
202
+ <p className="island-kicker mb-2">CMS</p>
203
+ <h1 className="demo-title mb-6">Strapi Articles</h1>
219
204
 
220
205
  <div className="mb-8">
221
206
  <Search />
@@ -235,7 +220,7 @@ function RouteComponent() {
235
220
  params={{ articleId: article.documentId }}
236
221
  className="block"
237
222
  >
238
- <article className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-xl overflow-hidden hover:border-cyan-500/50 transition-all duration-300 hover:shadow-lg hover:shadow-cyan-500/10 cursor-pointer h-full flex flex-col">
223
+ <article className="demo-card h-full cursor-pointer overflow-hidden p-0 transition hover:-translate-y-0.5">
239
224
  <StrapiImage
240
225
  src={article.cover?.url}
241
226
  alt={article.cover?.alternativeText || article.title}
@@ -243,24 +228,24 @@ function RouteComponent() {
243
228
  />
244
229
 
245
230
  <div className="p-6 flex flex-col flex-1">
246
- <h2 className="text-xl font-semibold text-white mb-3">
231
+ <h2 className="text-xl font-semibold mb-3">
247
232
  {article.title || 'Untitled'}
248
233
  </h2>
249
234
 
250
235
  {article.description && (
251
- <p className="text-gray-400 mb-4 leading-relaxed line-clamp-2">
236
+ <p className="demo-muted mb-4 leading-relaxed line-clamp-2">
252
237
  {article.description}
253
238
  </p>
254
239
  )}
255
240
 
256
241
  <div className="mt-auto flex items-center justify-between">
257
242
  {article.author?.name && (
258
- <span className="text-sm text-gray-500">
243
+ <span className="demo-muted text-sm">
259
244
  By {article.author.name}
260
245
  </span>
261
246
  )}
262
247
  {article.createdAt && (
263
- <span className="text-sm text-cyan-400/70">
248
+ <span className="demo-muted text-sm">
264
249
  {new Date(article.createdAt).toLocaleDateString()}
265
250
  </span>
266
251
  )}
@@ -268,7 +253,7 @@ function RouteComponent() {
268
253
 
269
254
  {article.category?.name && (
270
255
  <div className="mt-3">
271
- <span className="text-xs px-2 py-1 bg-slate-700 text-cyan-400 rounded-full">
256
+ <span className="demo-pill">
272
257
  {article.category.name}
273
258
  </span>
274
259
  </div>
@@ -287,6 +272,6 @@ function RouteComponent() {
287
272
  </>
288
273
  )}
289
274
  </div>
290
- </div>
275
+ </main>
291
276
  )
292
277
  }
@@ -30,22 +30,14 @@ function TRPCTodos() {
30
30
  }, [addTodo, todo])
31
31
 
32
32
  return (
33
- <div
34
- className="flex items-center justify-center min-h-screen bg-gradient-to-br from-purple-100 to-blue-100 p-4 text-white"
35
- style={{
36
- backgroundImage:
37
- 'radial-gradient(50% 50% at 95% 5%, #4a90c2 0%, #317eb9 50%, #1e4d72 100%)',
38
- }}
39
- >
40
- <div className="w-full max-w-2xl p-8 rounded-xl backdrop-blur-md bg-black/50 shadow-xl border-8 border-black/10">
41
- <h1 className="text-2xl mb-4">tRPC Todos list</h1>
33
+ <main className="demo-page demo-center">
34
+ <section className="demo-panel w-full max-w-2xl">
35
+ <p className="island-kicker mb-2">tRPC</p>
36
+ <h1 className="demo-title mb-6">Todos</h1>
42
37
  <ul className="mb-4 space-y-2">
43
38
  {data?.map((t) => (
44
- <li
45
- key={t.id}
46
- className="bg-white/10 border border-white/20 rounded-lg p-3 backdrop-blur-sm shadow-md"
47
- >
48
- <span className="text-lg text-white">{t.name}</span>
39
+ <li key={t.id} className="demo-list-item">
40
+ <span className="text-base font-medium">{t.name}</span>
49
41
  </li>
50
42
  ))}
51
43
  </ul>
@@ -60,17 +52,17 @@ function TRPCTodos() {
60
52
  }
61
53
  }}
62
54
  placeholder="Enter a new todo..."
63
- 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"
55
+ className="demo-input"
64
56
  />
65
57
  <button
66
58
  disabled={todo.trim().length === 0}
67
59
  onClick={submitTodo}
68
- 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"
60
+ className="demo-button"
69
61
  >
70
62
  Add todo
71
63
  </button>
72
64
  </div>
73
- </div>
74
- </div>
65
+ </section>
66
+ </main>
75
67
  )
76
68
  }
@@ -144,19 +144,21 @@ function TableDemo() {
144
144
  }, [table.getState().columnFilters[0]?.id])
145
145
 
146
146
  return (
147
- <div className="min-h-screen bg-gray-900 p-6">
147
+ <main className="demo-page demo-page-wide">
148
148
  <div>
149
+ <p className="island-kicker mb-2">TanStack Table</p>
150
+ <h1 className="demo-title mb-6">Table Demo</h1>
149
151
  <DebouncedInput
150
152
  value={globalFilter ?? ''}
151
153
  onChange={(value) => setGlobalFilter(String(value))}
152
- className="w-full p-3 bg-gray-800 text-white rounded-lg border border-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
154
+ className="demo-input"
153
155
  placeholder="Search all columns..."
154
156
  />
155
157
  </div>
156
158
  <div className="h-4" />
157
- <div className="overflow-x-auto rounded-lg border border-gray-700">
158
- <table className="w-full text-sm text-gray-200">
159
- <thead className="bg-gray-800 text-gray-100">
159
+ <div className="demo-table-shell">
160
+ <table className="demo-table text-sm">
161
+ <thead>
160
162
  {table.getHeaderGroups().map((headerGroup) => (
161
163
  <tr key={headerGroup.id}>
162
164
  {headerGroup.headers.map((header) => {
@@ -171,7 +173,7 @@ function TableDemo() {
171
173
  <div
172
174
  {...{
173
175
  className: header.column.getCanSort()
174
- ? 'cursor-pointer select-none hover:text-blue-400 transition-colors'
176
+ ? 'cursor-pointer select-none transition-colors hover:text-[var(--lagoon-deep)]'
175
177
  : '',
176
178
  onClick: header.column.getToggleSortingHandler(),
177
179
  }}
@@ -198,12 +200,12 @@ function TableDemo() {
198
200
  </tr>
199
201
  ))}
200
202
  </thead>
201
- <tbody className="divide-y divide-gray-700">
203
+ <tbody>
202
204
  {table.getRowModel().rows.map((row) => {
203
205
  return (
204
206
  <tr
205
207
  key={row.id}
206
- className="hover:bg-gray-800 transition-colors"
208
+ className="transition-colors"
207
209
  >
208
210
  {row.getVisibleCells().map((cell) => {
209
211
  return (
@@ -222,30 +224,30 @@ function TableDemo() {
222
224
  </table>
223
225
  </div>
224
226
  <div className="h-4" />
225
- <div className="flex flex-wrap items-center gap-2 text-gray-200">
227
+ <div className="demo-muted flex flex-wrap items-center gap-2">
226
228
  <button
227
- className="px-3 py-1 bg-gray-800 rounded-md hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed"
229
+ className="demo-button demo-button-secondary"
228
230
  onClick={() => table.setPageIndex(0)}
229
231
  disabled={!table.getCanPreviousPage()}
230
232
  >
231
233
  {'<<'}
232
234
  </button>
233
235
  <button
234
- className="px-3 py-1 bg-gray-800 rounded-md hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed"
236
+ className="demo-button demo-button-secondary"
235
237
  onClick={() => table.previousPage()}
236
238
  disabled={!table.getCanPreviousPage()}
237
239
  >
238
240
  {'<'}
239
241
  </button>
240
242
  <button
241
- className="px-3 py-1 bg-gray-800 rounded-md hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed"
243
+ className="demo-button demo-button-secondary"
242
244
  onClick={() => table.nextPage()}
243
245
  disabled={!table.getCanNextPage()}
244
246
  >
245
247
  {'>'}
246
248
  </button>
247
249
  <button
248
- className="px-3 py-1 bg-gray-800 rounded-md hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed"
250
+ className="demo-button demo-button-secondary"
249
251
  onClick={() => table.setPageIndex(table.getPageCount() - 1)}
250
252
  disabled={!table.getCanNextPage()}
251
253
  >
@@ -267,7 +269,7 @@ function TableDemo() {
267
269
  const page = e.target.value ? Number(e.target.value) - 1 : 0
268
270
  table.setPageIndex(page)
269
271
  }}
270
- className="w-16 px-2 py-1 bg-gray-800 rounded-md border border-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
272
+ className="demo-input demo-input-fit py-1"
271
273
  />
272
274
  </span>
273
275
  <select
@@ -275,7 +277,7 @@ function TableDemo() {
275
277
  onChange={(e) => {
276
278
  table.setPageSize(Number(e.target.value))
277
279
  }}
278
- className="px-2 py-1 bg-gray-800 rounded-md border border-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
280
+ className="demo-select demo-input-fit py-1"
279
281
  >
280
282
  {[10, 20, 30, 40, 50].map((pageSize) => (
281
283
  <option key={pageSize} value={pageSize}>
@@ -284,24 +286,24 @@ function TableDemo() {
284
286
  ))}
285
287
  </select>
286
288
  </div>
287
- <div className="mt-4 text-gray-400">
289
+ <div className="demo-muted mt-4">
288
290
  {table.getPrePaginationRowModel().rows.length} Rows
289
291
  </div>
290
292
  <div className="mt-4 flex gap-2">
291
293
  <button
292
294
  onClick={() => rerender()}
293
- className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
295
+ className="demo-button"
294
296
  >
295
297
  Force Rerender
296
298
  </button>
297
299
  <button
298
300
  onClick={() => refreshData()}
299
- className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
301
+ className="demo-button"
300
302
  >
301
303
  Refresh Data
302
304
  </button>
303
305
  </div>
304
- <pre className="mt-4 p-4 bg-gray-800 rounded-lg text-gray-300 overflow-auto">
306
+ <pre className="demo-code-block mt-4 overflow-auto">
305
307
  {JSON.stringify(
306
308
  {
307
309
  columnFilters: table.getState().columnFilters,
@@ -311,7 +313,7 @@ function TableDemo() {
311
313
  2,
312
314
  )}
313
315
  </pre>
314
- </div>
316
+ </main>
315
317
  )
316
318
  }
317
319
 
@@ -324,7 +326,7 @@ function Filter({ column }: { column: Column<any, unknown> }) {
324
326
  value={(columnFilterValue ?? '') as string}
325
327
  onChange={(value) => column.setFilterValue(value)}
326
328
  placeholder={`Search...`}
327
- className="w-full px-2 py-1 bg-gray-700 text-white rounded-md border border-gray-600 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
329
+ className="demo-input py-1"
328
330
  />
329
331
  )
330
332
  }
@@ -370,4 +372,3 @@ export default (parentRoute: RootRoute) => createRoute({
370
372
  getParentRoute: () => parentRoute,
371
373
  })
372
374
  <% } %>
373
-