@tanstack/cta-engine 0.10.0-alpha.6

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 (272) hide show
  1. package/LICENSE +21 -0
  2. package/dist/add-ons.js +109 -0
  3. package/dist/add.js +127 -0
  4. package/dist/cli.js +112 -0
  5. package/dist/config-file.js +23 -0
  6. package/dist/constants.js +5 -0
  7. package/dist/create-app.js +491 -0
  8. package/dist/custom-add-on.js +254 -0
  9. package/dist/environment.js +119 -0
  10. package/dist/index.js +1 -0
  11. package/dist/mcp.js +211 -0
  12. package/dist/options.js +309 -0
  13. package/dist/package-manager.js +30 -0
  14. package/dist/templates.js +6 -0
  15. package/dist/toolchain.js +6 -0
  16. package/dist/types/add-ons.d.ts +5 -0
  17. package/dist/types/add.d.ts +3 -0
  18. package/dist/types/cli.d.ts +1 -0
  19. package/dist/types/config-file.d.ts +7 -0
  20. package/dist/types/constants.d.ts +6 -0
  21. package/dist/types/create-app.d.ts +6 -0
  22. package/dist/types/custom-add-on.d.ts +3 -0
  23. package/dist/types/environment.d.ts +12 -0
  24. package/dist/types/index.d.ts +1 -0
  25. package/dist/types/mcp.d.ts +1 -0
  26. package/dist/types/options.d.ts +3 -0
  27. package/dist/types/package-manager.d.ts +6 -0
  28. package/dist/types/templates.d.ts +1 -0
  29. package/dist/types/toolchain.d.ts +3 -0
  30. package/dist/types/types.d.ts +107 -0
  31. package/dist/types/utils.d.ts +1 -0
  32. package/dist/types.js +1 -0
  33. package/dist/utils.js +8 -0
  34. package/package.json +49 -0
  35. package/src/add-ons.ts +145 -0
  36. package/src/add.ts +184 -0
  37. package/src/cli.ts +163 -0
  38. package/src/config-file.ts +45 -0
  39. package/src/constants.ts +9 -0
  40. package/src/create-app.ts +791 -0
  41. package/src/custom-add-on.ts +323 -0
  42. package/src/environment.ts +144 -0
  43. package/src/index.ts +1 -0
  44. package/src/mcp.ts +252 -0
  45. package/src/options.ts +359 -0
  46. package/src/package-manager.ts +46 -0
  47. package/src/templates.ts +7 -0
  48. package/src/toolchain.ts +7 -0
  49. package/src/types.ts +119 -0
  50. package/src/utils.ts +10 -0
  51. package/templates/react/add-on/clerk/README.md +3 -0
  52. package/templates/react/add-on/clerk/assets/_dot_env.local.append +2 -0
  53. package/templates/react/add-on/clerk/assets/src/integrations/clerk/header-user.tsx +19 -0
  54. package/templates/react/add-on/clerk/assets/src/integrations/clerk/provider.tsx +18 -0
  55. package/templates/react/add-on/clerk/assets/src/routes/demo.clerk.tsx +20 -0
  56. package/templates/react/add-on/clerk/info.json +13 -0
  57. package/templates/react/add-on/clerk/package.json +5 -0
  58. package/templates/react/add-on/convex/README.md +4 -0
  59. package/templates/react/add-on/convex/assets/_dot_cursorrules.append +93 -0
  60. package/templates/react/add-on/convex/assets/_dot_env.local.append +3 -0
  61. package/templates/react/add-on/convex/assets/convex/products.ts +8 -0
  62. package/templates/react/add-on/convex/assets/convex/schema.ts +10 -0
  63. package/templates/react/add-on/convex/assets/src/integrations/convex/provider.tsx +20 -0
  64. package/templates/react/add-on/convex/assets/src/routes/demo.convex.tsx +33 -0
  65. package/templates/react/add-on/convex/info.json +13 -0
  66. package/templates/react/add-on/convex/package.json +6 -0
  67. package/templates/react/add-on/form/assets/src/components/demo.FormComponents.tsx.ejs +300 -0
  68. package/templates/react/add-on/form/assets/src/hooks/demo.form-context.ts +4 -0
  69. package/templates/react/add-on/form/assets/src/hooks/demo.form.ts +22 -0
  70. package/templates/react/add-on/form/assets/src/routes/demo.form.address.tsx.ejs +213 -0
  71. package/templates/react/add-on/form/assets/src/routes/demo.form.simple.tsx.ejs +77 -0
  72. package/templates/react/add-on/form/info.json +26 -0
  73. package/templates/react/add-on/form/package.json +6 -0
  74. package/templates/react/add-on/module-federation/assets/module-federation.config.js.ejs +31 -0
  75. package/templates/react/add-on/module-federation/assets/src/demo-mf-component.tsx +3 -0
  76. package/templates/react/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +11 -0
  77. package/templates/react/add-on/module-federation/info.json +7 -0
  78. package/templates/react/add-on/module-federation/package.json +5 -0
  79. package/templates/react/add-on/netlify/README.md +11 -0
  80. package/templates/react/add-on/netlify/info.json +7 -0
  81. package/templates/react/add-on/sentry/assets/_dot_cursorrules.append +22 -0
  82. package/templates/react/add-on/sentry/assets/_dot_env.local.append +2 -0
  83. package/templates/react/add-on/sentry/assets/src/app/global-middleware.ts +25 -0
  84. package/templates/react/add-on/sentry/assets/src/routes/demo.sentry.testing.tsx +480 -0
  85. package/templates/react/add-on/sentry/info.json +14 -0
  86. package/templates/react/add-on/sentry/package.json +7 -0
  87. package/templates/react/add-on/shadcn/README.md +7 -0
  88. package/templates/react/add-on/shadcn/assets/_dot_cursorrules.append +7 -0
  89. package/templates/react/add-on/shadcn/assets/components.json +21 -0
  90. package/templates/react/add-on/shadcn/assets/src/lib/utils.ts +6 -0
  91. package/templates/react/add-on/shadcn/assets/src/styles.css +138 -0
  92. package/templates/react/add-on/shadcn/info.json +7 -0
  93. package/templates/react/add-on/shadcn/package.json +9 -0
  94. package/templates/react/add-on/start/assets/_dot_gitignore.append +2 -0
  95. package/templates/react/add-on/start/assets/app.config.ts.ejs +19 -0
  96. package/templates/react/add-on/start/assets/src/api.ts +6 -0
  97. package/templates/react/add-on/start/assets/src/client.tsx +8 -0
  98. package/templates/react/add-on/start/assets/src/router.tsx.ejs +77 -0
  99. package/templates/react/add-on/start/assets/src/routes/api.demo-names.ts +11 -0
  100. package/templates/react/add-on/start/assets/src/routes/demo.start.api-request.tsx.ejs +33 -0
  101. package/templates/react/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +50 -0
  102. package/templates/react/add-on/start/assets/src/ssr.tsx +12 -0
  103. package/templates/react/add-on/start/info.json +18 -0
  104. package/templates/react/add-on/start/package.json +13 -0
  105. package/templates/react/add-on/store/assets/src/lib/demo-store.ts +13 -0
  106. package/templates/react/add-on/store/assets/src/routes/demo.store.tsx.ejs +75 -0
  107. package/templates/react/add-on/store/info.json +13 -0
  108. package/templates/react/add-on/store/package.json +6 -0
  109. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/init.ts +9 -0
  110. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/react.ts +4 -0
  111. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/router.ts +18 -0
  112. package/templates/react/add-on/tRPC/assets/src/routes/api.trpc.$.tsx +16 -0
  113. package/templates/react/add-on/tRPC/info.json +9 -0
  114. package/templates/react/add-on/tRPC/package.json +9 -0
  115. package/templates/react/add-on/table/assets/src/data/demo-table-data.ts +50 -0
  116. package/templates/react/add-on/table/assets/src/routes/demo.table.tsx.ejs +373 -0
  117. package/templates/react/add-on/table/info.json +13 -0
  118. package/templates/react/add-on/table/package.json +7 -0
  119. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/layout.tsx +5 -0
  120. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/root-provider.tsx.ejs +70 -0
  121. package/templates/react/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx.ejs +53 -0
  122. package/templates/react/add-on/tanstack-query/info.json +13 -0
  123. package/templates/react/add-on/tanstack-query/package.json +6 -0
  124. package/templates/react/base/README.md.ejs +558 -0
  125. package/templates/react/base/_dot_gitignore +5 -0
  126. package/templates/react/base/_dot_vscode/settings.biome.json +38 -0
  127. package/templates/react/base/_dot_vscode/settings.json +11 -0
  128. package/templates/react/base/index.html.ejs +20 -0
  129. package/templates/react/base/package.biome.json +10 -0
  130. package/templates/react/base/package.eslintprettier.json +11 -0
  131. package/templates/react/base/package.json +29 -0
  132. package/templates/react/base/package.ts.json +7 -0
  133. package/templates/react/base/package.tw.json +6 -0
  134. package/templates/react/base/public/favicon.ico +0 -0
  135. package/templates/react/base/public/logo192.png +0 -0
  136. package/templates/react/base/public/logo512.png +0 -0
  137. package/templates/react/base/public/manifest.json +25 -0
  138. package/templates/react/base/public/robots.txt +3 -0
  139. package/templates/react/base/src/App.css +38 -0
  140. package/templates/react/base/src/App.test.tsx.ejs +10 -0
  141. package/templates/react/base/src/App.tsx.ejs +74 -0
  142. package/templates/react/base/src/components/Header.tsx.ejs +27 -0
  143. package/templates/react/base/src/logo.svg +44 -0
  144. package/templates/react/base/src/reportWebVitals.ts.ejs +28 -0
  145. package/templates/react/base/src/styles.css.ejs +15 -0
  146. package/templates/react/base/toolchain/.prettierignore +3 -0
  147. package/templates/react/base/toolchain/biome.json +31 -0
  148. package/templates/react/base/toolchain/eslint.config.js +5 -0
  149. package/templates/react/base/toolchain/prettier.config.js +10 -0
  150. package/templates/react/base/tsconfig.json.ejs +29 -0
  151. package/templates/react/base/vite.config.js.ejs +23 -0
  152. package/templates/react/code-router/src/main.tsx.ejs +92 -0
  153. package/templates/react/example/tanchat/README.md +37 -0
  154. package/templates/react/example/tanchat/assets/_dot_env.local.append +2 -0
  155. package/templates/react/example/tanchat/assets/public/example-guitar-flowers.jpg +0 -0
  156. package/templates/react/example/tanchat/assets/public/example-guitar-motherboard.jpg +0 -0
  157. package/templates/react/example/tanchat/assets/public/example-guitar-racing.jpg +0 -0
  158. package/templates/react/example/tanchat/assets/public/example-guitar-steamer-trunk.jpg +0 -0
  159. package/templates/react/example/tanchat/assets/public/example-guitar-superhero.jpg +0 -0
  160. package/templates/react/example/tanchat/assets/public/example-guitar-traveling.jpg +0 -0
  161. package/templates/react/example/tanchat/assets/public/example-guitar-video-games.jpg +0 -0
  162. package/templates/react/example/tanchat/assets/src/components/example-AIAssistant.tsx +173 -0
  163. package/templates/react/example/tanchat/assets/src/components/example-GuitarRecommendation.tsx +47 -0
  164. package/templates/react/example/tanchat/assets/src/data/example-guitars.ts +83 -0
  165. package/templates/react/example/tanchat/assets/src/demo.index.css +220 -0
  166. package/templates/react/example/tanchat/assets/src/integrations/tanchat/header-user.tsx +5 -0
  167. package/templates/react/example/tanchat/assets/src/routes/example.chat.tsx +159 -0
  168. package/templates/react/example/tanchat/assets/src/routes/example.guitars/$guitarId.tsx +50 -0
  169. package/templates/react/example/tanchat/assets/src/routes/example.guitars/index.tsx +54 -0
  170. package/templates/react/example/tanchat/assets/src/store/example-assistant.ts +3 -0
  171. package/templates/react/example/tanchat/assets/src/utils/demo.ai.ts +62 -0
  172. package/templates/react/example/tanchat/assets/src/utils/demo.tools.ts +47 -0
  173. package/templates/react/example/tanchat/info.json +19 -0
  174. package/templates/react/example/tanchat/package.json +15 -0
  175. package/templates/react/file-router/package.fr.json +5 -0
  176. package/templates/react/file-router/src/main.tsx.ejs +55 -0
  177. package/templates/react/file-router/src/routes/__root.tsx.ejs +82 -0
  178. package/templates/solid/add-on/form/assets/src/routes/demo.form.tsx.ejs +352 -0
  179. package/templates/solid/add-on/form/info.json +13 -0
  180. package/templates/solid/add-on/form/package.json +5 -0
  181. package/templates/solid/add-on/module-federation/assets/module-federation.config.js.ejs +27 -0
  182. package/templates/solid/add-on/module-federation/assets/src/demo-mf-component.tsx +3 -0
  183. package/templates/solid/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +9 -0
  184. package/templates/solid/add-on/module-federation/info.json +7 -0
  185. package/templates/solid/add-on/module-federation/package.json +5 -0
  186. package/templates/solid/add-on/sentry/assets/_dot_cursorrules.append +22 -0
  187. package/templates/solid/add-on/sentry/assets/_dot_env.local.append +2 -0
  188. package/templates/solid/add-on/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +20 -0
  189. package/templates/solid/add-on/sentry/info.json +13 -0
  190. package/templates/solid/add-on/sentry/package.json +5 -0
  191. package/templates/solid/add-on/solid-ui/README.md +9 -0
  192. package/templates/solid/add-on/solid-ui/assets/src/lib/utils.ts +6 -0
  193. package/templates/solid/add-on/solid-ui/assets/src/styles.css +138 -0
  194. package/templates/solid/add-on/solid-ui/assets/ui.config.json +13 -0
  195. package/templates/solid/add-on/solid-ui/info.json +11 -0
  196. package/templates/solid/add-on/solid-ui/package.json +9 -0
  197. package/templates/solid/add-on/start/assets/app.config.ts +16 -0
  198. package/templates/solid/add-on/start/assets/src/api.ts +6 -0
  199. package/templates/solid/add-on/start/assets/src/client.tsx +7 -0
  200. package/templates/solid/add-on/start/assets/src/router.tsx.ejs +24 -0
  201. package/templates/solid/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +49 -0
  202. package/templates/solid/add-on/start/assets/src/ssr.tsx +12 -0
  203. package/templates/solid/add-on/start/info.json +14 -0
  204. package/templates/solid/add-on/start/package.json +12 -0
  205. package/templates/solid/add-on/store/assets/src/lib/demo-store.ts +13 -0
  206. package/templates/solid/add-on/store/assets/src/routes/demo.store.tsx.ejs +77 -0
  207. package/templates/solid/add-on/store/info.json +13 -0
  208. package/templates/solid/add-on/store/package.json +6 -0
  209. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/header-user.tsx +5 -0
  210. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/provider.tsx +15 -0
  211. package/templates/solid/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx +30 -0
  212. package/templates/solid/add-on/tanstack-query/info.json +13 -0
  213. package/templates/solid/add-on/tanstack-query/package.json +6 -0
  214. package/templates/solid/base/README.md.ejs +215 -0
  215. package/templates/solid/base/_dot_cursorrules.append +35 -0
  216. package/templates/solid/base/_dot_gitignore +5 -0
  217. package/templates/solid/base/_dot_vscode/settings.biome.json +38 -0
  218. package/templates/solid/base/_dot_vscode/settings.json +11 -0
  219. package/templates/solid/base/index.html.ejs +20 -0
  220. package/templates/solid/base/package.biome.json +10 -0
  221. package/templates/solid/base/package.eslintprettier.json +11 -0
  222. package/templates/solid/base/package.json +22 -0
  223. package/templates/solid/base/package.ts.json +5 -0
  224. package/templates/solid/base/package.tw.json +6 -0
  225. package/templates/solid/base/public/favicon.ico +0 -0
  226. package/templates/solid/base/public/logo192.png +0 -0
  227. package/templates/solid/base/public/logo512.png +0 -0
  228. package/templates/solid/base/public/manifest.json +25 -0
  229. package/templates/solid/base/public/robots.txt +3 -0
  230. package/templates/solid/base/src/App.css +0 -0
  231. package/templates/solid/base/src/App.tsx.ejs +47 -0
  232. package/templates/solid/base/src/components/Header.tsx.ejs +26 -0
  233. package/templates/solid/base/src/logo.svg +120 -0
  234. package/templates/solid/base/src/styles.css.ejs +15 -0
  235. package/templates/solid/base/toolchain/.prettierignore +3 -0
  236. package/templates/solid/base/toolchain/biome.json +31 -0
  237. package/templates/solid/base/toolchain/eslint.config.js +5 -0
  238. package/templates/solid/base/toolchain/prettier.config.js +10 -0
  239. package/templates/solid/base/tsconfig.json.ejs +31 -0
  240. package/templates/solid/base/vite.config.js.ejs +22 -0
  241. package/templates/solid/code-router/src/main.tsx.ejs +71 -0
  242. package/templates/solid/example/tanchat/README.md +52 -0
  243. package/templates/solid/example/tanchat/assets/ai-streaming-server/README.md +110 -0
  244. package/templates/solid/example/tanchat/assets/ai-streaming-server/_dot_env.example +1 -0
  245. package/templates/solid/example/tanchat/assets/ai-streaming-server/package.json +26 -0
  246. package/templates/solid/example/tanchat/assets/ai-streaming-server/src/index.ts +102 -0
  247. package/templates/solid/example/tanchat/assets/ai-streaming-server/tsconfig.json +15 -0
  248. package/templates/solid/example/tanchat/assets/src/components/demo.SettingsDialog.tsx +149 -0
  249. package/templates/solid/example/tanchat/assets/src/demo.index.css +227 -0
  250. package/templates/solid/example/tanchat/assets/src/lib/demo-store.ts +13 -0
  251. package/templates/solid/example/tanchat/assets/src/routes/example.chat.tsx +435 -0
  252. package/templates/solid/example/tanchat/assets/src/store/demo.hooks.ts +17 -0
  253. package/templates/solid/example/tanchat/assets/src/store/demo.store.ts +133 -0
  254. package/templates/solid/example/tanchat/info.json +14 -0
  255. package/templates/solid/example/tanchat/package.json +7 -0
  256. package/templates/solid/file-router/package.fr.json +5 -0
  257. package/templates/solid/file-router/src/main.tsx.ejs +47 -0
  258. package/templates/solid/file-router/src/routes/__root.tsx.ejs +41 -0
  259. package/templates/solid/file-router/src/routes/index.tsx +43 -0
  260. package/tests/cra.test.ts +293 -0
  261. package/tests/snapshots/cra/cr-js-npm.json +33 -0
  262. package/tests/snapshots/cra/cr-ts-npm.json +34 -0
  263. package/tests/snapshots/cra/cr-ts-start-npm.json +38 -0
  264. package/tests/snapshots/cra/fr-ts-npm.json +34 -0
  265. package/tests/snapshots/cra/fr-ts-tw-npm.json +33 -0
  266. package/tests/snapshots/cra/solid-cr-js-npm.json +31 -0
  267. package/tests/snapshots/cra/solid-cr-ts-npm.json +32 -0
  268. package/tests/snapshots/cra/solid-cr-ts-start-npm.json +36 -0
  269. package/tests/snapshots/cra/solid-fr-ts-npm.json +33 -0
  270. package/tests/snapshots/cra/solid-fr-ts-tw-npm.json +32 -0
  271. package/tests/test-utilities.ts +87 -0
  272. package/tsconfig.json +11 -0
@@ -0,0 +1,352 @@
1
+ import { <% if (fileRouter) { %>createFileRoute<% } else { %>createRoute<% } %> } from '@tanstack/solid-router'
2
+ import { createForm } from '@tanstack/solid-form'
3
+
4
+ import type { JSX } from 'solid-js/jsx-runtime'
5
+ import type { ValidationError } from '@tanstack/solid-form'
6
+
7
+ <% if (codeRouter) { %>
8
+ import type { RootRoute } from '@tanstack/solid-router'
9
+ <% } else { %>
10
+ export const Route = createFileRoute('/demo/form')({
11
+ component: FormExample,
12
+ })
13
+ <% } %>
14
+ function FieldWrapper(props: {
15
+ children: JSX.Element
16
+ errors: Array<ValidationError>
17
+ label: string
18
+ }) {
19
+ return (
20
+ <div>
21
+ <label for={props.label} class="block font-bold mb-1 text-xl">
22
+ {props.label}
23
+ </label>
24
+ {props.children}
25
+ {props.errors.length ? (
26
+ <div class="text-red-500 mt-1 font-bold">{props.errors.join(', ')}</div>
27
+ ) : null}
28
+ </div>
29
+ )
30
+ }
31
+
32
+ function FormExample() {
33
+ const form = createForm(() => ({
34
+ defaultValues: {
35
+ fullName: '',
36
+ email: '',
37
+ address: {
38
+ street: '',
39
+ city: '',
40
+ state: '',
41
+ zipCode: '',
42
+ country: '',
43
+ },
44
+ phone: '',
45
+ },
46
+ onSubmit: ({ value }) => {
47
+ console.log(value)
48
+ // Show success message
49
+ alert('Form submitted successfully!')
50
+ },
51
+ }))
52
+
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">
62
+ <form
63
+ onSubmit={(e) => {
64
+ e.preventDefault()
65
+ e.stopPropagation()
66
+ form.handleSubmit()
67
+ }}
68
+ class="space-y-6"
69
+ >
70
+ {/* Full Name Field */}
71
+ <div>
72
+ <form.Field
73
+ name="fullName"
74
+ validators={{
75
+ onBlur: ({ value }) => {
76
+ if (value.trim().length === 0) {
77
+ return 'Full name is required'
78
+ }
79
+ if (value.length < 3) {
80
+ return 'Name must be at least 3 characters'
81
+ }
82
+ return undefined
83
+ },
84
+ }}
85
+ children={(field) => (
86
+ <FieldWrapper
87
+ label="Full Name"
88
+ errors={field().state.meta.errors}
89
+ >
90
+ <input
91
+ id="fullName"
92
+ name="fullName"
93
+ value={field().state.value}
94
+ onBlur={field().handleBlur}
95
+ 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
+ />
98
+ </FieldWrapper>
99
+ )}
100
+ />
101
+ </div>
102
+
103
+ {/* Email Field */}
104
+ <div>
105
+ <form.Field
106
+ name="email"
107
+ validators={{
108
+ onBlur: ({ value }) => {
109
+ if (!value || value.trim().length === 0) {
110
+ return 'Email is required'
111
+ }
112
+ if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(value)) {
113
+ return 'Invalid email address'
114
+ }
115
+ return undefined
116
+ },
117
+ }}
118
+ children={(field) => (
119
+ <FieldWrapper
120
+ label="Email Address"
121
+ errors={field().state.meta.errors}
122
+ >
123
+ <input
124
+ id="email"
125
+ name="email"
126
+ type="email"
127
+ value={field().state.value}
128
+ onBlur={field().handleBlur}
129
+ 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
+ />
132
+ </FieldWrapper>
133
+ )}
134
+ />
135
+ </div>
136
+
137
+ {/* Street Address */}
138
+ <div>
139
+ <form.Field
140
+ name="address.street"
141
+ validators={{
142
+ onBlur: ({ value }) => {
143
+ if (!value || value.trim().length === 0) {
144
+ return 'Street address is required'
145
+ }
146
+ return undefined
147
+ },
148
+ }}
149
+ children={(field) => (
150
+ <FieldWrapper
151
+ label="Street Address"
152
+ errors={field().state.meta.errors}
153
+ >
154
+ <input
155
+ id="street"
156
+ name="street"
157
+ value={field().state.value}
158
+ onBlur={field().handleBlur}
159
+ 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
+ />
162
+ </FieldWrapper>
163
+ )}
164
+ />
165
+ </div>
166
+
167
+ {/* City, State, Zip in a row */}
168
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
169
+ {/* City */}
170
+ <form.Field
171
+ name="address.city"
172
+ validators={{
173
+ onBlur: ({ value }) => {
174
+ if (!value || value.trim().length === 0) {
175
+ return 'City is required'
176
+ }
177
+ return undefined
178
+ },
179
+ }}
180
+ children={(field) => (
181
+ <FieldWrapper label="City" errors={field().state.meta.errors}>
182
+ <input
183
+ id="city"
184
+ name="city"
185
+ value={field().state.value}
186
+ onBlur={field().handleBlur}
187
+ 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
+ />
190
+ </FieldWrapper>
191
+ )}
192
+ />
193
+
194
+ {/* State */}
195
+ <form.Field
196
+ name="address.state"
197
+ validators={{
198
+ onBlur: ({ value }) => {
199
+ if (!value || value.trim().length === 0) {
200
+ return 'State is required'
201
+ }
202
+ return undefined
203
+ },
204
+ }}
205
+ children={(field) => (
206
+ <FieldWrapper label="State" errors={field().state.meta.errors}>
207
+ <input
208
+ id="state"
209
+ name="state"
210
+ value={field().state.value}
211
+ onBlur={field().handleBlur}
212
+ 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
+ />
215
+ </FieldWrapper>
216
+ )}
217
+ />
218
+
219
+ {/* Zip Code */}
220
+ <form.Field
221
+ name="address.zipCode"
222
+ validators={{
223
+ onBlur: ({ value }) => {
224
+ if (!value || value.trim().length === 0) {
225
+ return 'Zip code is required'
226
+ }
227
+ if (!/^\d{5}(-\d{4})?$/.test(value)) {
228
+ return 'Invalid zip code format'
229
+ }
230
+ return undefined
231
+ },
232
+ }}
233
+ children={(field) => (
234
+ <FieldWrapper
235
+ label="Zip Code"
236
+ errors={field().state.meta.errors}
237
+ >
238
+ <input
239
+ id="zipCode"
240
+ name="zipCode"
241
+ value={field().state.value}
242
+ onBlur={field().handleBlur}
243
+ 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
+ />
246
+ </FieldWrapper>
247
+ )}
248
+ />
249
+ </div>
250
+
251
+ {/* Country */}
252
+ <div>
253
+ <form.Field
254
+ name="address.country"
255
+ validators={{
256
+ onBlur: ({ value }) => {
257
+ if (!value || value.trim().length === 0) {
258
+ return 'Country is required'
259
+ }
260
+ return undefined
261
+ },
262
+ }}
263
+ children={(field) => (
264
+ <FieldWrapper
265
+ label="Country"
266
+ errors={field().state.meta.errors}
267
+ >
268
+ <select
269
+ id="country"
270
+ name="country"
271
+ value={field().state.value}
272
+ onBlur={field().handleBlur}
273
+ 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
+ >
276
+ <option value="">Select a country</option>
277
+ <option value="US">United States</option>
278
+ <option value="CA">Canada</option>
279
+ <option value="UK">United Kingdom</option>
280
+ <option value="AU">Australia</option>
281
+ <option value="DE">Germany</option>
282
+ <option value="FR">France</option>
283
+ <option value="JP">Japan</option>
284
+ </select>
285
+ </FieldWrapper>
286
+ )}
287
+ />
288
+ </div>
289
+
290
+ {/* Phone Number */}
291
+ <div>
292
+ <form.Field
293
+ name="phone"
294
+ validators={{
295
+ onBlur: ({ value }) => {
296
+ if (!value || value.trim().length === 0) {
297
+ return 'Phone number is required'
298
+ }
299
+ if (
300
+ !/^(\+\d{1,3})?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/.test(
301
+ value,
302
+ )
303
+ ) {
304
+ return 'Invalid phone number format'
305
+ }
306
+ return undefined
307
+ },
308
+ }}
309
+ children={(field) => (
310
+ <FieldWrapper
311
+ label="Phone Number"
312
+ errors={field().state.meta.errors}
313
+ >
314
+ <input
315
+ id="phone"
316
+ name="phone"
317
+ type="tel"
318
+ value={field().state.value}
319
+ onBlur={field().handleBlur}
320
+ 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
+ placeholder="(123) 456-7890"
323
+ />
324
+ </FieldWrapper>
325
+ )}
326
+ />
327
+ </div>
328
+
329
+ {/* Submit Button */}
330
+ <div class="flex justify-end">
331
+ <button
332
+ type="submit"
333
+ 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
+ >
336
+ {form.state.isSubmitting ? 'Submitting...' : 'Submit'}
337
+ </button>
338
+ </div>
339
+ </form>
340
+ </div>
341
+ </div>
342
+ )
343
+ }
344
+
345
+ <% if (codeRouter) { %>
346
+ export default (parentRoute: RootRoute) => createRoute({
347
+ path: '/demo/form',
348
+ component: FormExample,
349
+ getParentRoute: () => parentRoute,
350
+ })
351
+ <% } %>
352
+
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "Form",
3
+ "description": "TanStack Form",
4
+ "phase": "add-on",
5
+ "link": "https://tanstack.com/form/latest",
6
+ "templates": ["file-router", "code-router"],
7
+ "routes": [
8
+ {
9
+ "url": "/demo/form",
10
+ "name": "Form"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "@tanstack/solid-form": "^1.0.0"
4
+ }
5
+ }
@@ -0,0 +1,27 @@
1
+ import packageJSON from './package.json'
2
+
3
+ function remoteConfig(name, url) {
4
+ return {
5
+ type: 'module',
6
+ name,
7
+ entry: url,
8
+ entryGlobalName: 'remote',
9
+ shareScope: 'default',
10
+ }
11
+ }
12
+
13
+ export default {
14
+ filename: 'remoteEntry.js',
15
+ name: '<%= projectName %>',
16
+ exposes: {
17
+ './DemoMfComponent': './src/demo-mf-component.tsx',
18
+ './DemoMfSelfContained': './src/demo-mf-self-contained.tsx',
19
+ },
20
+ remotes: {},
21
+ shared: {
22
+ 'solid-js': {
23
+ singleton: true,
24
+ requiredVersion: packageJSON.dependencies['solid-js'],
25
+ },
26
+ },
27
+ }
@@ -0,0 +1,3 @@
1
+ export function DemoMfComponent() {
2
+ return <div>Solid Federated Component</div>
3
+ }
@@ -0,0 +1,9 @@
1
+ import { render } from 'solid-js/web'
2
+
3
+ function App() {
4
+ return <div>Hello from Solid Self Contained</div>
5
+ }
6
+
7
+ export function DemoMfSelfContained(rootElement: HTMLElement) {
8
+ render(() => <App />, rootElement)
9
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "Module Federation",
3
+ "description": "Module Federation",
4
+ "phase": "add-on",
5
+ "templates": ["code-router"],
6
+ "link": "https://module-federation.io/"
7
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "@module-federation/vite": "^1.1.9"
4
+ }
5
+ }
@@ -0,0 +1,22 @@
1
+ We use Sentry for watching for errors in our deployed application, as well as for instrumentation of our application.
2
+
3
+ ## Error collection
4
+
5
+ Error collection is automatic and configured in `src/router.tsx`.
6
+
7
+ ## Instrumentation
8
+
9
+ We want our server functions intstrumented. So if you see a function name like `createServerFn`, you can instrument it with Sentry. You'll need to import `Sentry`:
10
+
11
+ ```tsx
12
+ import * as Sentry from '@sentry/browser'
13
+ ```
14
+
15
+ And then wrap the implementation of the server function with `Sentry.startSpan`, liks so:
16
+
17
+ ```tsx
18
+ Sentry.startSpan({ name: 'Requesting all the pokemon' }, async () => {
19
+ // Some lengthy operation here
20
+ await fetch('https://api.pokemon.com/data/')
21
+ })
22
+ ```
@@ -0,0 +1,2 @@
1
+ # Your Sentry DSN (from your Sentry account)
2
+ VITE_SENTRY_DSN=
@@ -0,0 +1,20 @@
1
+ import { createFileRoute } from '@tanstack/solid-router'
2
+
3
+ export const Route = createFileRoute('/demo/sentry/bad-event-handler')({
4
+ component: RouteComponent,
5
+ })
6
+
7
+ function RouteComponent() {
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>
19
+ )
20
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "Sentry",
3
+ "phase": "setup",
4
+ "description": "Add Sentry for error monitoring and crash reporting (requires Start).",
5
+ "link": "https://sentry.com/",
6
+ "templates": ["file-router"],
7
+ "routes": [
8
+ {
9
+ "url": "/demo/sentry/bad-event-handler",
10
+ "name": "Sentry"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "@sentry/solid": "^9.1.0"
4
+ }
5
+ }
@@ -0,0 +1,9 @@
1
+ ## Solid-UI
2
+
3
+ This installation of Solid-UI follows the manual instructions but was modified to work with Tailwind V4.
4
+
5
+ To install the components, run the following command (this install button):
6
+
7
+ ```bash
8
+ npx solidui-cli@latest add button
9
+ ```
@@ -0,0 +1,6 @@
1
+ import { type ClassValue, clsx } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -0,0 +1,138 @@
1
+ @import 'tailwindcss';
2
+
3
+ @plugin "tailwindcss-animate";
4
+
5
+ @custom-variant dark (&:is(.dark *));
6
+
7
+ body {
8
+ @apply m-0;
9
+ font-family:
10
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
11
+ 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ }
15
+
16
+ code {
17
+ font-family:
18
+ source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
19
+ }
20
+
21
+ :root {
22
+ --background: oklch(1 0 0);
23
+ --foreground: oklch(0.141 0.005 285.823);
24
+ --card: oklch(1 0 0);
25
+ --card-foreground: oklch(0.141 0.005 285.823);
26
+ --popover: oklch(1 0 0);
27
+ --popover-foreground: oklch(0.141 0.005 285.823);
28
+ --primary: oklch(0.21 0.006 285.885);
29
+ --primary-foreground: oklch(0.985 0 0);
30
+ --secondary: oklch(0.967 0.001 286.375);
31
+ --secondary-foreground: oklch(0.21 0.006 285.885);
32
+ --muted: oklch(0.967 0.001 286.375);
33
+ --muted-foreground: oklch(0.552 0.016 285.938);
34
+ --accent: oklch(0.967 0.001 286.375);
35
+ --accent-foreground: oklch(0.21 0.006 285.885);
36
+ --destructive: oklch(0.577 0.245 27.325);
37
+ --destructive-foreground: oklch(0.577 0.245 27.325);
38
+ --border: oklch(0.92 0.004 286.32);
39
+ --input: oklch(0.92 0.004 286.32);
40
+ --ring: oklch(0.871 0.006 286.286);
41
+ --chart-1: oklch(0.646 0.222 41.116);
42
+ --chart-2: oklch(0.6 0.118 184.704);
43
+ --chart-3: oklch(0.398 0.07 227.392);
44
+ --chart-4: oklch(0.828 0.189 84.429);
45
+ --chart-5: oklch(0.769 0.188 70.08);
46
+ --radius: 0.625rem;
47
+ --sidebar: oklch(0.985 0 0);
48
+ --sidebar-foreground: oklch(0.141 0.005 285.823);
49
+ --sidebar-primary: oklch(0.21 0.006 285.885);
50
+ --sidebar-primary-foreground: oklch(0.985 0 0);
51
+ --sidebar-accent: oklch(0.967 0.001 286.375);
52
+ --sidebar-accent-foreground: oklch(0.21 0.006 285.885);
53
+ --sidebar-border: oklch(0.92 0.004 286.32);
54
+ --sidebar-ring: oklch(0.871 0.006 286.286);
55
+ }
56
+
57
+ .dark {
58
+ --background: oklch(0.141 0.005 285.823);
59
+ --foreground: oklch(0.985 0 0);
60
+ --card: oklch(0.141 0.005 285.823);
61
+ --card-foreground: oklch(0.985 0 0);
62
+ --popover: oklch(0.141 0.005 285.823);
63
+ --popover-foreground: oklch(0.985 0 0);
64
+ --primary: oklch(0.985 0 0);
65
+ --primary-foreground: oklch(0.21 0.006 285.885);
66
+ --secondary: oklch(0.274 0.006 286.033);
67
+ --secondary-foreground: oklch(0.985 0 0);
68
+ --muted: oklch(0.274 0.006 286.033);
69
+ --muted-foreground: oklch(0.705 0.015 286.067);
70
+ --accent: oklch(0.274 0.006 286.033);
71
+ --accent-foreground: oklch(0.985 0 0);
72
+ --destructive: oklch(0.396 0.141 25.723);
73
+ --destructive-foreground: oklch(0.637 0.237 25.331);
74
+ --border: oklch(0.274 0.006 286.033);
75
+ --input: oklch(0.274 0.006 286.033);
76
+ --ring: oklch(0.442 0.017 285.786);
77
+ --chart-1: oklch(0.488 0.243 264.376);
78
+ --chart-2: oklch(0.696 0.17 162.48);
79
+ --chart-3: oklch(0.769 0.188 70.08);
80
+ --chart-4: oklch(0.627 0.265 303.9);
81
+ --chart-5: oklch(0.645 0.246 16.439);
82
+ --sidebar: oklch(0.21 0.006 285.885);
83
+ --sidebar-foreground: oklch(0.985 0 0);
84
+ --sidebar-primary: oklch(0.488 0.243 264.376);
85
+ --sidebar-primary-foreground: oklch(0.985 0 0);
86
+ --sidebar-accent: oklch(0.274 0.006 286.033);
87
+ --sidebar-accent-foreground: oklch(0.985 0 0);
88
+ --sidebar-border: oklch(0.274 0.006 286.033);
89
+ --sidebar-ring: oklch(0.442 0.017 285.786);
90
+ }
91
+
92
+ @theme inline {
93
+ --color-background: var(--background);
94
+ --color-foreground: var(--foreground);
95
+ --color-card: var(--card);
96
+ --color-card-foreground: var(--card-foreground);
97
+ --color-popover: var(--popover);
98
+ --color-popover-foreground: var(--popover-foreground);
99
+ --color-primary: var(--primary);
100
+ --color-primary-foreground: var(--primary-foreground);
101
+ --color-secondary: var(--secondary);
102
+ --color-secondary-foreground: var(--secondary-foreground);
103
+ --color-muted: var(--muted);
104
+ --color-muted-foreground: var(--muted-foreground);
105
+ --color-accent: var(--accent);
106
+ --color-accent-foreground: var(--accent-foreground);
107
+ --color-destructive: var(--destructive);
108
+ --color-destructive-foreground: var(--destructive-foreground);
109
+ --color-border: var(--border);
110
+ --color-input: var(--input);
111
+ --color-ring: var(--ring);
112
+ --color-chart-1: var(--chart-1);
113
+ --color-chart-2: var(--chart-2);
114
+ --color-chart-3: var(--chart-3);
115
+ --color-chart-4: var(--chart-4);
116
+ --color-chart-5: var(--chart-5);
117
+ --radius-sm: calc(var(--radius) - 4px);
118
+ --radius-md: calc(var(--radius) - 2px);
119
+ --radius-lg: var(--radius);
120
+ --radius-xl: calc(var(--radius) + 4px);
121
+ --color-sidebar: var(--sidebar);
122
+ --color-sidebar-foreground: var(--sidebar-foreground);
123
+ --color-sidebar-primary: var(--sidebar-primary);
124
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
125
+ --color-sidebar-accent: var(--sidebar-accent);
126
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
127
+ --color-sidebar-border: var(--sidebar-border);
128
+ --color-sidebar-ring: var(--sidebar-ring);
129
+ }
130
+
131
+ @layer base {
132
+ * {
133
+ @apply border-border outline-ring/50;
134
+ }
135
+ body {
136
+ @apply bg-background text-foreground;
137
+ }
138
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://solid-ui.com/schema.json",
3
+ "tsx": true,
4
+ "tailwind": {
5
+ "css": "src/styles.css",
6
+ "config": "tailwind.config.cjs",
7
+ "prefix": ""
8
+ },
9
+ "aliases": {
10
+ "components": "~/components/ui",
11
+ "utils": "~/lib/utils"
12
+ }
13
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "Solid-UI",
3
+ "description": "Add Solid-UI to your application.",
4
+ "phase": "add-on",
5
+ "link": "https://ui.shadcn.com/",
6
+ "templates": ["file-router", "code-router"],
7
+ "command": {
8
+ "command": "npx",
9
+ "args": ["solidui-cli@latest", "add", "button", "input"]
10
+ }
11
+ }