create-tsrouter-app 0.6.8 → 0.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/create-app.js +5 -2
- package/package.json +1 -1
- package/src/create-app.ts +7 -2
- package/templates/react/add-on/form/assets/src/components/demo.FormComponents.tsx +1 -0
- package/templates/react/add-on/form/assets/src/routes/demo.form.address.tsx.ejs +25 -18
- package/templates/react/add-on/form/assets/src/routes/demo.form.simple.tsx.ejs +6 -8
- package/templates/react/add-on/start/assets/{app.config.ts → app.config.ts.ejs} +4 -1
- package/templates/react/add-on/start/assets/src/router.tsx.ejs +17 -5
- package/templates/react/add-on/start/assets/src/routes/api.demo-names.ts +11 -0
- package/templates/react/add-on/start/assets/src/routes/demo.start.api-request.tsx.ejs +33 -0
- package/templates/react/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +2 -1
- package/templates/react/add-on/start/info.json +4 -0
- package/templates/react/add-on/start/package.json +1 -0
- package/templates/react/base/src/components/Header.tsx.ejs +3 -1
- package/templates/react/base/vite.config.js.ejs +1 -1
- package/templates/react/file-router/src/routes/__root.tsx.ejs +1 -1
- package/templates/solid/base/README.md.ejs +1 -1
- package/templates/solid/base/package.json +1 -1
- package/templates/solid/code-router/src/main.tsx.ejs +2 -2
- package/templates/solid/file-router/src/routes/__root.tsx.ejs +1 -1
package/dist/create-app.js
CHANGED
|
@@ -251,7 +251,10 @@ export async function createApp(options, { silent = false, environment, }) {
|
|
|
251
251
|
if (!options.tailwind) {
|
|
252
252
|
await copyFiles(templateDirBase, ['./src/App.css']);
|
|
253
253
|
}
|
|
254
|
-
|
|
254
|
+
// Don't create a vite.config.js file if we are building a Start app
|
|
255
|
+
if (!isAddOnEnabled('start')) {
|
|
256
|
+
await templateFile(templateDirBase, './vite.config.js.ejs');
|
|
257
|
+
}
|
|
255
258
|
await templateFile(templateDirBase, './src/styles.css.ejs');
|
|
256
259
|
copyFiles(templateDirBase, ['./src/logo.svg']);
|
|
257
260
|
if (options.toolchain === 'biome') {
|
|
@@ -436,7 +439,7 @@ ${environment.getErrors().join('\n')}`;
|
|
|
436
439
|
if (options.packageManager === 'deno') {
|
|
437
440
|
startCommand = `deno ${isAddOnEnabled('start') ? 'task dev' : 'start'}`;
|
|
438
441
|
}
|
|
439
|
-
outro(`Created your
|
|
442
|
+
outro(`Created your TanStack app in '${basename(targetDir)}'.
|
|
440
443
|
|
|
441
444
|
Use the following commands to start your app:
|
|
442
445
|
% cd ${options.projectName}
|
package/package.json
CHANGED
package/src/create-app.ts
CHANGED
|
@@ -385,7 +385,12 @@ export async function createApp(
|
|
|
385
385
|
if (!options.tailwind) {
|
|
386
386
|
await copyFiles(templateDirBase, ['./src/App.css'])
|
|
387
387
|
}
|
|
388
|
-
|
|
388
|
+
|
|
389
|
+
// Don't create a vite.config.js file if we are building a Start app
|
|
390
|
+
if (!isAddOnEnabled('start')) {
|
|
391
|
+
await templateFile(templateDirBase, './vite.config.js.ejs')
|
|
392
|
+
}
|
|
393
|
+
|
|
389
394
|
await templateFile(templateDirBase, './src/styles.css.ejs')
|
|
390
395
|
|
|
391
396
|
copyFiles(templateDirBase, ['./src/logo.svg'])
|
|
@@ -707,7 +712,7 @@ ${environment.getErrors().join('\n')}`
|
|
|
707
712
|
startCommand = `deno ${isAddOnEnabled('start') ? 'task dev' : 'start'}`
|
|
708
713
|
}
|
|
709
714
|
|
|
710
|
-
outro(`Created your
|
|
715
|
+
outro(`Created your TanStack app in '${basename(targetDir)}'.
|
|
711
716
|
|
|
712
717
|
Use the following commands to start your app:
|
|
713
718
|
% cd ${options.projectName}
|
|
@@ -7,6 +7,7 @@ export function SubscribeButton({ label }: { label: string }) {
|
|
|
7
7
|
<form.Subscribe selector={(state) => state.isSubmitting}>
|
|
8
8
|
{(isSubmitting) => (
|
|
9
9
|
<button
|
|
10
|
+
type="submit"
|
|
10
11
|
disabled={isSubmitting}
|
|
11
12
|
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"
|
|
12
13
|
>
|
|
@@ -61,10 +61,9 @@ function AddressForm() {
|
|
|
61
61
|
}}
|
|
62
62
|
className="space-y-6"
|
|
63
63
|
>
|
|
64
|
-
<form.AppField
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
/>
|
|
64
|
+
<form.AppField name="fullName">
|
|
65
|
+
{(field) => <field.TextField label="Full Name" />}
|
|
66
|
+
</form.AppField>
|
|
68
67
|
|
|
69
68
|
<form.AppField
|
|
70
69
|
name="email"
|
|
@@ -79,8 +78,9 @@ function AddressForm() {
|
|
|
79
78
|
return undefined
|
|
80
79
|
},
|
|
81
80
|
}}
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
>
|
|
82
|
+
{(field) => <field.TextField label="Email" />}
|
|
83
|
+
</form.AppField>
|
|
84
84
|
|
|
85
85
|
<form.AppField
|
|
86
86
|
name="address.street"
|
|
@@ -92,8 +92,9 @@ function AddressForm() {
|
|
|
92
92
|
return undefined
|
|
93
93
|
},
|
|
94
94
|
}}
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
>
|
|
96
|
+
{(field) => <field.TextField label="Street Address" />}
|
|
97
|
+
</form.AppField>
|
|
97
98
|
|
|
98
99
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
99
100
|
<form.AppField
|
|
@@ -106,8 +107,9 @@ function AddressForm() {
|
|
|
106
107
|
return undefined
|
|
107
108
|
},
|
|
108
109
|
}}
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
>
|
|
111
|
+
{(field) => <field.TextField label="City" />}
|
|
112
|
+
</form.AppField>
|
|
111
113
|
<form.AppField
|
|
112
114
|
name="address.state"
|
|
113
115
|
validators={{
|
|
@@ -118,8 +120,9 @@ function AddressForm() {
|
|
|
118
120
|
return undefined
|
|
119
121
|
},
|
|
120
122
|
}}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
+
>
|
|
124
|
+
{(field) => <field.TextField label="State" />}
|
|
125
|
+
</form.AppField>
|
|
123
126
|
<form.AppField
|
|
124
127
|
name="address.zipCode"
|
|
125
128
|
validators={{
|
|
@@ -133,8 +136,9 @@ function AddressForm() {
|
|
|
133
136
|
return undefined
|
|
134
137
|
},
|
|
135
138
|
}}
|
|
136
|
-
|
|
137
|
-
|
|
139
|
+
>
|
|
140
|
+
{(field) => <field.TextField label="Zip Code" />}
|
|
141
|
+
</form.AppField>
|
|
138
142
|
</div>
|
|
139
143
|
|
|
140
144
|
<form.AppField
|
|
@@ -147,7 +151,8 @@ function AddressForm() {
|
|
|
147
151
|
return undefined
|
|
148
152
|
},
|
|
149
153
|
}}
|
|
150
|
-
|
|
154
|
+
>
|
|
155
|
+
{(field) => (
|
|
151
156
|
<field.Select label="Country">
|
|
152
157
|
<option value="">Select a country</option>
|
|
153
158
|
<option value="US">United States</option>
|
|
@@ -159,7 +164,7 @@ function AddressForm() {
|
|
|
159
164
|
<option value="JP">Japan</option>
|
|
160
165
|
</field.Select>
|
|
161
166
|
)}
|
|
162
|
-
|
|
167
|
+
</form.AppField>
|
|
163
168
|
|
|
164
169
|
<form.AppField
|
|
165
170
|
name="phone"
|
|
@@ -178,10 +183,11 @@ function AddressForm() {
|
|
|
178
183
|
return undefined
|
|
179
184
|
},
|
|
180
185
|
}}
|
|
181
|
-
|
|
186
|
+
>
|
|
187
|
+
{(field) => (
|
|
182
188
|
<field.TextField label="Phone" placeholder="123-456-7890" />
|
|
183
189
|
)}
|
|
184
|
-
|
|
190
|
+
</form.AppField>
|
|
185
191
|
|
|
186
192
|
<div className="flex justify-end">
|
|
187
193
|
<form.AppForm>
|
|
@@ -194,6 +200,7 @@ function AddressForm() {
|
|
|
194
200
|
)
|
|
195
201
|
}
|
|
196
202
|
|
|
203
|
+
|
|
197
204
|
<% if (codeRouter) { %>
|
|
198
205
|
export default (parentRoute: RootRoute) => createRoute({
|
|
199
206
|
path: '/demo/form',
|
|
@@ -49,15 +49,13 @@ function SimpleForm() {
|
|
|
49
49
|
}}
|
|
50
50
|
className="space-y-6"
|
|
51
51
|
>
|
|
52
|
-
<form.AppField
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
/>
|
|
52
|
+
<form.AppField name="title">
|
|
53
|
+
{(field) => <field.TextField label="Title" />}
|
|
54
|
+
</form.AppField>
|
|
56
55
|
|
|
57
|
-
<form.AppField
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
/>
|
|
56
|
+
<form.AppField name="description">
|
|
57
|
+
{(field) => <field.TextArea label="Description" />}
|
|
58
|
+
</form.AppField>
|
|
61
59
|
|
|
62
60
|
<div className="flex justify-end">
|
|
63
61
|
<form.AppForm>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { defineConfig } from '@tanstack/react-start/config'
|
|
2
|
-
import viteTsConfigPaths from 'vite-tsconfig-paths'
|
|
2
|
+
import viteTsConfigPaths from 'vite-tsconfig-paths'<% if (tailwind) { %>
|
|
3
|
+
import tailwindcss from "@tailwindcss/vite"
|
|
4
|
+
<% } %>
|
|
3
5
|
|
|
4
6
|
export default defineConfig({
|
|
5
7
|
tsr: {
|
|
@@ -11,6 +13,7 @@ export default defineConfig({
|
|
|
11
13
|
viteTsConfigPaths({
|
|
12
14
|
projects: ['./tsconfig.json'],
|
|
13
15
|
}),
|
|
16
|
+
<% if (tailwind) { %>tailwindcss(),<% } %>
|
|
14
17
|
],
|
|
15
18
|
},
|
|
16
19
|
})
|
|
@@ -2,8 +2,11 @@ import { createRouter as createTanstackRouter } from '@tanstack/react-router'<%
|
|
|
2
2
|
import * as Sentry from '@sentry/react'
|
|
3
3
|
import * as SentryServer from '@sentry/node'
|
|
4
4
|
import { createIsomorphicFn } from '@tanstack/react-start'
|
|
5
|
+
<% } %><% if (addOnEnabled['tanstack-query']) { %>
|
|
6
|
+
import { routerWithQueryClient } from '@tanstack/react-router-with-query'
|
|
7
|
+
import * as TanstackQuery from './integrations/tanstack-query/root-provider'
|
|
5
8
|
<% } %>
|
|
6
|
-
|
|
9
|
+
|
|
7
10
|
// Import the generated route tree
|
|
8
11
|
import { routeTree } from './routeTree.gen'
|
|
9
12
|
|
|
@@ -11,16 +14,27 @@ import './styles.css'
|
|
|
11
14
|
|
|
12
15
|
// Create a new router instance
|
|
13
16
|
export const createRouter = () => {
|
|
17
|
+
<% if (addOnEnabled['tanstack-query']) { %>
|
|
18
|
+
const router = routerWithQueryClient(createTanstackRouter({
|
|
19
|
+
routeTree,
|
|
20
|
+
context: {
|
|
21
|
+
<% if (addOnEnabled['tanstack-query']) { %>
|
|
22
|
+
...TanstackQuery.getContext(),
|
|
23
|
+
<% } %>
|
|
24
|
+
},
|
|
25
|
+
scrollRestoration: true,
|
|
26
|
+
}), TanstackQuery.getContext().queryClient)
|
|
27
|
+
<% } else { %>
|
|
14
28
|
const router = createTanstackRouter({
|
|
15
29
|
routeTree,
|
|
16
30
|
scrollRestoration: true,
|
|
17
31
|
})
|
|
32
|
+
<% } %>
|
|
18
33
|
return router
|
|
19
34
|
}
|
|
20
35
|
|
|
21
|
-
const router = createRouter()
|
|
22
|
-
|
|
23
36
|
<% if (addOnEnabled.sentry) { %>
|
|
37
|
+
const router = createRouter()
|
|
24
38
|
createIsomorphicFn().server(() => {
|
|
25
39
|
SentryServer.init({
|
|
26
40
|
dsn: import.meta.env.VITE_SENTRY_DSN,
|
|
@@ -44,8 +58,6 @@ const router = createRouter()
|
|
|
44
58
|
})()
|
|
45
59
|
<% } %>
|
|
46
60
|
|
|
47
|
-
|
|
48
|
-
|
|
49
61
|
// Register the router instance for type safety
|
|
50
62
|
declare module '@tanstack/react-router' {
|
|
51
63
|
interface Register {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createAPIFileRoute } from '@tanstack/react-start/api'
|
|
2
|
+
|
|
3
|
+
export const APIRoute = createAPIFileRoute('/demo/start/api/names')({
|
|
4
|
+
GET: async ({ request }) => {
|
|
5
|
+
return new Response(JSON.stringify(['Alice', 'Bob', 'Charlie']), {
|
|
6
|
+
headers: {
|
|
7
|
+
'Content-Type': 'application/json',
|
|
8
|
+
},
|
|
9
|
+
})
|
|
10
|
+
},
|
|
11
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<% if (addOnEnabled['react-query']) { %>
|
|
2
|
+
import { useQuery } from '@tanstack/react-query'
|
|
3
|
+
<% } else { %>
|
|
4
|
+
import { useEffect, useState } from 'react'
|
|
5
|
+
<% } %>
|
|
6
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
7
|
+
|
|
8
|
+
function getNames() {
|
|
9
|
+
return fetch('/api/demo-names').then((res) => res.json())
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Route = createFileRoute('/demo/start/api-request')({
|
|
13
|
+
component: Home,
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
function Home() {
|
|
17
|
+
<% if (addOnEnabled['react-query']) { %>
|
|
18
|
+
const { data: names = [] } = useQuery({
|
|
19
|
+
queryKey: ['names'],
|
|
20
|
+
queryFn: getNames,
|
|
21
|
+
})
|
|
22
|
+
<% } else { %>
|
|
23
|
+
const [names, setNames] = useState<Array<string>>([])
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
getNames().then(setNames)
|
|
26
|
+
}, [])
|
|
27
|
+
<% } %>
|
|
28
|
+
return (
|
|
29
|
+
<div className="p-4">
|
|
30
|
+
<div>{names.join(', ')}</div>
|
|
31
|
+
</div>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as fs from 'fs'
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
2
|
import { createFileRoute, useRouter } from '@tanstack/react-router'
|
|
3
3
|
import { createServerFn } from '@tanstack/react-start'
|
|
4
4
|
|
|
@@ -35,6 +35,7 @@ function Home() {
|
|
|
35
35
|
return (
|
|
36
36
|
<div className="p-4">
|
|
37
37
|
<button
|
|
38
|
+
type="button"
|
|
38
39
|
onClick={() => {
|
|
39
40
|
updateCount({ data: 1 }).then(() => {
|
|
40
41
|
router.invalidate()
|
|
@@ -15,11 +15,13 @@ export default function Header() {
|
|
|
15
15
|
<div className="px-2 font-bold"><Link to="<%= route.url %>"><%= route.name %></Link></div>
|
|
16
16
|
<% } } %>
|
|
17
17
|
</nav>
|
|
18
|
+
<% if (integrations.filter(i => i.type === 'header-user').length > 0) { %>
|
|
18
19
|
<div>
|
|
19
20
|
<% for(const integration of integrations.filter(i => i.type === 'header-user')) { %>
|
|
20
21
|
<<%= integration.name %> />
|
|
21
22
|
<% } %>
|
|
22
|
-
|
|
23
|
+
</div>
|
|
24
|
+
<% } %>
|
|
23
25
|
</header>
|
|
24
26
|
)
|
|
25
27
|
}
|
|
@@ -3,7 +3,7 @@ import viteReact from "@vitejs/plugin-react";<% if (tailwind) { %>
|
|
|
3
3
|
import tailwindcss from "@tailwindcss/vite";
|
|
4
4
|
<% } %><%if (fileRouter) { %>
|
|
5
5
|
import { TanStackRouterVite } from "@tanstack/router-plugin/vite";<% } %><% if (addOnEnabled['module-federation']) { %>
|
|
6
|
-
import {federation} from "@module-federation/vite";<% } %><% if (addOnEnabled.shadcn) { %>
|
|
6
|
+
import { federation } from "@module-federation/vite";<% } %><% if (addOnEnabled.shadcn) { %>
|
|
7
7
|
import { resolve } from "node:path";<% } %><% if (addOnEnabled['module-federation']) { %>
|
|
8
8
|
import federationConfig from "./module-federation.config.js";
|
|
9
9
|
<% } %>
|
|
@@ -132,7 +132,7 @@ Here is an example layout that includes a header:
|
|
|
132
132
|
|
|
133
133
|
```tsx
|
|
134
134
|
import { Outlet, createRootRoute } from '@tanstack/solid-router'
|
|
135
|
-
import { TanStackRouterDevtools } from '@tanstack/router-devtools'
|
|
135
|
+
import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
|
|
136
136
|
|
|
137
137
|
import { Link } from "@tanstack/solid-router";
|
|
138
138
|
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
createRoute,
|
|
6
6
|
createRouter,
|
|
7
7
|
} from "@tanstack/solid-router";
|
|
8
|
-
|
|
8
|
+
import { TanStackRouterDevtools } from "@tanstack/solid-router-devtools";
|
|
9
9
|
import { render } from 'solid-js/web'
|
|
10
10
|
<% for(const route of routes) { %>import <%= route.name %> from "<%= route.path %>";
|
|
11
11
|
<% } %><% if (routes.length > 0) { %>
|
|
@@ -26,7 +26,7 @@ const rootRoute = createRootRoute({
|
|
|
26
26
|
<% } %>
|
|
27
27
|
<% if (routes.length > 0) { %><Header /><% } %>
|
|
28
28
|
<Outlet />
|
|
29
|
-
|
|
29
|
+
<TanStackRouterDevtools />
|
|
30
30
|
<% for(const integration of integrations.filter(i => i.type === 'layout')) { %>
|
|
31
31
|
<<%= integration.name %> />
|
|
32
32
|
<% } %>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Outlet, createRootRouteWithContext } from '@tanstack/solid-router'
|
|
2
|
-
|
|
2
|
+
import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'<% for(const integration of integrations.filter(i => i.type === 'layout' || i.type === 'provider')) { %>
|
|
3
3
|
import <%= integration.name %> from "../<%= integration.path %>";
|
|
4
4
|
<% } %>
|
|
5
5
|
<% if (addOnEnabled['solid-ui']) { %>
|