@tanstack/cta-ui 0.10.0-alpha.18
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/.cursorrules +7 -0
- package/LICENSE +21 -0
- package/app.config.js +22 -0
- package/components.json +21 -0
- package/lib/index.ts +22 -0
- package/lib-dist/index.d.ts +1 -0
- package/lib-dist/index.js +13 -0
- package/package.json +58 -0
- package/public/favicon.ico +0 -0
- package/public/logo192.png +0 -0
- package/public/logo512.png +0 -0
- package/public/manifest.json +25 -0
- package/public/robots.txt +3 -0
- package/src/api.ts +6 -0
- package/src/client.tsx +8 -0
- package/src/components/Header.tsx +13 -0
- package/src/components/applied-add-on.tsx +149 -0
- package/src/components/file-tree.tsx +77 -0
- package/src/components/file-viewer.tsx +59 -0
- package/src/components/ui/button.tsx +59 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/dialog.tsx +133 -0
- package/src/components/ui/table.tsx +114 -0
- package/src/components/ui/tabs.tsx +64 -0
- package/src/components/ui/toggle-group.tsx +71 -0
- package/src/components/ui/toggle.tsx +47 -0
- package/src/components/ui/tree-view.tsx +492 -0
- package/src/integrations/tanstack-query/layout.tsx +5 -0
- package/src/integrations/tanstack-query/root-provider.tsx +15 -0
- package/src/lib/server-fns.ts +78 -0
- package/src/lib/utils.ts +6 -0
- package/src/logo.svg +44 -0
- package/src/routeTree.gen.ts +111 -0
- package/src/router.tsx +32 -0
- package/src/routes/__root.tsx +57 -0
- package/src/routes/api.demo-names.ts +11 -0
- package/src/routes/demo.tanstack-query.tsx +28 -0
- package/src/routes/index.tsx +222 -0
- package/src/ssr.tsx +12 -0
- package/src/styles.css +138 -0
- package/tsconfig.json +28 -0
- package/tsconfig.lib.json +17 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
|
|
5
|
+
// noinspection JSUnusedGlobalSymbols
|
|
6
|
+
|
|
7
|
+
// This file was automatically generated by TanStack Router.
|
|
8
|
+
// You should NOT make any changes in this file as it will be overwritten.
|
|
9
|
+
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
|
10
|
+
|
|
11
|
+
// Import Routes
|
|
12
|
+
|
|
13
|
+
import { Route as rootRoute } from './routes/__root'
|
|
14
|
+
import { Route as IndexImport } from './routes/index'
|
|
15
|
+
import { Route as DemoTanstackQueryImport } from './routes/demo.tanstack-query'
|
|
16
|
+
|
|
17
|
+
// Create/Update Routes
|
|
18
|
+
|
|
19
|
+
const IndexRoute = IndexImport.update({
|
|
20
|
+
id: '/',
|
|
21
|
+
path: '/',
|
|
22
|
+
getParentRoute: () => rootRoute,
|
|
23
|
+
} as any)
|
|
24
|
+
|
|
25
|
+
const DemoTanstackQueryRoute = DemoTanstackQueryImport.update({
|
|
26
|
+
id: '/demo/tanstack-query',
|
|
27
|
+
path: '/demo/tanstack-query',
|
|
28
|
+
getParentRoute: () => rootRoute,
|
|
29
|
+
} as any)
|
|
30
|
+
|
|
31
|
+
// Populate the FileRoutesByPath interface
|
|
32
|
+
|
|
33
|
+
declare module '@tanstack/react-router' {
|
|
34
|
+
interface FileRoutesByPath {
|
|
35
|
+
'/': {
|
|
36
|
+
id: '/'
|
|
37
|
+
path: '/'
|
|
38
|
+
fullPath: '/'
|
|
39
|
+
preLoaderRoute: typeof IndexImport
|
|
40
|
+
parentRoute: typeof rootRoute
|
|
41
|
+
}
|
|
42
|
+
'/demo/tanstack-query': {
|
|
43
|
+
id: '/demo/tanstack-query'
|
|
44
|
+
path: '/demo/tanstack-query'
|
|
45
|
+
fullPath: '/demo/tanstack-query'
|
|
46
|
+
preLoaderRoute: typeof DemoTanstackQueryImport
|
|
47
|
+
parentRoute: typeof rootRoute
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Create and export the route tree
|
|
53
|
+
|
|
54
|
+
export interface FileRoutesByFullPath {
|
|
55
|
+
'/': typeof IndexRoute
|
|
56
|
+
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface FileRoutesByTo {
|
|
60
|
+
'/': typeof IndexRoute
|
|
61
|
+
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface FileRoutesById {
|
|
65
|
+
__root__: typeof rootRoute
|
|
66
|
+
'/': typeof IndexRoute
|
|
67
|
+
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface FileRouteTypes {
|
|
71
|
+
fileRoutesByFullPath: FileRoutesByFullPath
|
|
72
|
+
fullPaths: '/' | '/demo/tanstack-query'
|
|
73
|
+
fileRoutesByTo: FileRoutesByTo
|
|
74
|
+
to: '/' | '/demo/tanstack-query'
|
|
75
|
+
id: '__root__' | '/' | '/demo/tanstack-query'
|
|
76
|
+
fileRoutesById: FileRoutesById
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface RootRouteChildren {
|
|
80
|
+
IndexRoute: typeof IndexRoute
|
|
81
|
+
DemoTanstackQueryRoute: typeof DemoTanstackQueryRoute
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const rootRouteChildren: RootRouteChildren = {
|
|
85
|
+
IndexRoute: IndexRoute,
|
|
86
|
+
DemoTanstackQueryRoute: DemoTanstackQueryRoute,
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const routeTree = rootRoute
|
|
90
|
+
._addFileChildren(rootRouteChildren)
|
|
91
|
+
._addFileTypes<FileRouteTypes>()
|
|
92
|
+
|
|
93
|
+
/* ROUTE_MANIFEST_START
|
|
94
|
+
{
|
|
95
|
+
"routes": {
|
|
96
|
+
"__root__": {
|
|
97
|
+
"filePath": "__root.tsx",
|
|
98
|
+
"children": [
|
|
99
|
+
"/",
|
|
100
|
+
"/demo/tanstack-query"
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
"/": {
|
|
104
|
+
"filePath": "index.tsx"
|
|
105
|
+
},
|
|
106
|
+
"/demo/tanstack-query": {
|
|
107
|
+
"filePath": "demo.tanstack-query.tsx"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
ROUTE_MANIFEST_END */
|
package/src/router.tsx
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createRouter as createTanstackRouter } from '@tanstack/react-router'
|
|
2
|
+
import { routerWithQueryClient } from '@tanstack/react-router-with-query'
|
|
3
|
+
import * as TanstackQuery from './integrations/tanstack-query/root-provider'
|
|
4
|
+
|
|
5
|
+
// Import the generated route tree
|
|
6
|
+
import { routeTree } from './routeTree.gen'
|
|
7
|
+
|
|
8
|
+
import './styles.css'
|
|
9
|
+
|
|
10
|
+
// Create a new router instance
|
|
11
|
+
export const createRouter = () => {
|
|
12
|
+
const router = routerWithQueryClient(
|
|
13
|
+
createTanstackRouter({
|
|
14
|
+
routeTree,
|
|
15
|
+
context: {
|
|
16
|
+
...TanstackQuery.getContext(),
|
|
17
|
+
},
|
|
18
|
+
scrollRestoration: true,
|
|
19
|
+
defaultPreloadStaleTime: 0,
|
|
20
|
+
}),
|
|
21
|
+
TanstackQuery.getContext().queryClient,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
return router
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Register the router instance for type safety
|
|
28
|
+
declare module '@tanstack/react-router' {
|
|
29
|
+
interface Register {
|
|
30
|
+
router: ReturnType<typeof createRouter>
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Outlet,
|
|
3
|
+
HeadContent,
|
|
4
|
+
Scripts,
|
|
5
|
+
createRootRouteWithContext,
|
|
6
|
+
} from '@tanstack/react-router'
|
|
7
|
+
|
|
8
|
+
import appCss from '../styles.css?url'
|
|
9
|
+
|
|
10
|
+
import type { QueryClient } from '@tanstack/react-query'
|
|
11
|
+
|
|
12
|
+
interface MyRouterContext {
|
|
13
|
+
queryClient: QueryClient
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const Route = createRootRouteWithContext<MyRouterContext>()({
|
|
17
|
+
head: () => ({
|
|
18
|
+
meta: [
|
|
19
|
+
{
|
|
20
|
+
charSet: 'utf-8',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'viewport',
|
|
24
|
+
content: 'width=device-width, initial-scale=1',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: 'Add-On Debugger',
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
links: [
|
|
31
|
+
{
|
|
32
|
+
rel: 'stylesheet',
|
|
33
|
+
href: appCss,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
}),
|
|
37
|
+
|
|
38
|
+
component: () => (
|
|
39
|
+
<RootDocument>
|
|
40
|
+
<Outlet />
|
|
41
|
+
</RootDocument>
|
|
42
|
+
),
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
function RootDocument({ children }: { children: React.ReactNode }) {
|
|
46
|
+
return (
|
|
47
|
+
<html lang="en">
|
|
48
|
+
<head>
|
|
49
|
+
<HeadContent />
|
|
50
|
+
</head>
|
|
51
|
+
<body className="dark">
|
|
52
|
+
{children}
|
|
53
|
+
<Scripts />
|
|
54
|
+
</body>
|
|
55
|
+
</html>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createAPIFileRoute } from '@tanstack/react-start/api'
|
|
2
|
+
|
|
3
|
+
export const APIRoute = createAPIFileRoute('/api/demo-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,28 @@
|
|
|
1
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
2
|
+
import { useQuery } from '@tanstack/react-query'
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute('/demo/tanstack-query')({
|
|
5
|
+
component: TanStackQueryDemo,
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
function TanStackQueryDemo() {
|
|
9
|
+
const { data } = useQuery({
|
|
10
|
+
queryKey: ['people'],
|
|
11
|
+
queryFn: () =>
|
|
12
|
+
fetch('https://swapi.dev/api/people')
|
|
13
|
+
.then((res) => res.json())
|
|
14
|
+
.then((d) => d.results as { name: string }[]),
|
|
15
|
+
initialData: [],
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="p-4">
|
|
20
|
+
<h1 className="text-2xl mb-4">People list from Swapi</h1>
|
|
21
|
+
<ul>
|
|
22
|
+
{data.map((person) => (
|
|
23
|
+
<li key={person.name}>{person.name}</li>
|
|
24
|
+
))}
|
|
25
|
+
</ul>
|
|
26
|
+
</div>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { useState, Fragment } from 'react'
|
|
2
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
3
|
+
import { Info } from 'lucide-react'
|
|
4
|
+
|
|
5
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
|
6
|
+
import {
|
|
7
|
+
Table,
|
|
8
|
+
TableBody,
|
|
9
|
+
TableCell,
|
|
10
|
+
TableHead,
|
|
11
|
+
TableHeader,
|
|
12
|
+
TableRow,
|
|
13
|
+
} from '@/components/ui/table'
|
|
14
|
+
|
|
15
|
+
import AppliedAddOn from '@/components/applied-add-on'
|
|
16
|
+
import FileTree from '@/components/file-tree'
|
|
17
|
+
import FileViewer from '@/components/file-viewer'
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
getAddons,
|
|
21
|
+
getAddonInfo,
|
|
22
|
+
getOriginalOptions,
|
|
23
|
+
runCreateApp,
|
|
24
|
+
} from '@/lib/server-fns'
|
|
25
|
+
import type { AddOn } from '@tanstack/cta-engine'
|
|
26
|
+
|
|
27
|
+
export const Route = createFileRoute('/')({
|
|
28
|
+
component: App,
|
|
29
|
+
loader: async () => {
|
|
30
|
+
const originalOptions = await getOriginalOptions()
|
|
31
|
+
const [codeRouterAddons, fileRouterAddons] = await Promise.all([
|
|
32
|
+
getAddons({
|
|
33
|
+
data: { platform: 'react', mode: 'code-router' },
|
|
34
|
+
}),
|
|
35
|
+
getAddons({
|
|
36
|
+
data: { platform: 'react', mode: 'file-router' },
|
|
37
|
+
}),
|
|
38
|
+
])
|
|
39
|
+
return {
|
|
40
|
+
addOns: {
|
|
41
|
+
'code-router': codeRouterAddons,
|
|
42
|
+
'file-router': fileRouterAddons,
|
|
43
|
+
},
|
|
44
|
+
projectPath: process.env.PROJECT_PATH!,
|
|
45
|
+
output: await runCreateApp({
|
|
46
|
+
data: { withAddOn: true, options: originalOptions },
|
|
47
|
+
}),
|
|
48
|
+
outputWithoutAddon: await runCreateApp({
|
|
49
|
+
data: { withAddOn: false, options: originalOptions },
|
|
50
|
+
}),
|
|
51
|
+
addOnInfo: (await getAddonInfo()) as AddOn,
|
|
52
|
+
originalOptions,
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const CAPTIONS = {
|
|
58
|
+
dependencies: 'Dependencies',
|
|
59
|
+
devDependencies: 'Dev Dependencies',
|
|
60
|
+
scripts: 'Scripts',
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function InfoViewer({ info }: { info: AddOn }) {
|
|
64
|
+
return (
|
|
65
|
+
<div className="text-lg">
|
|
66
|
+
<div className="grid grid-cols-[200px_1fr] gap-4 mb-4">
|
|
67
|
+
<div className="font-medium">Name</div>
|
|
68
|
+
<div className="font-bold">{info.name}</div>
|
|
69
|
+
<div className="font-medium">Description</div>
|
|
70
|
+
<div className="font-bold">{info.description}</div>
|
|
71
|
+
<div className="font-medium">Version</div>
|
|
72
|
+
<div className="font-bold">{info.version}</div>
|
|
73
|
+
<div className="font-medium">Author</div>
|
|
74
|
+
<div className="font-bold">{info.author}</div>
|
|
75
|
+
<div className="font-medium">License</div>
|
|
76
|
+
<div className="font-bold">{info.license}</div>
|
|
77
|
+
{(
|
|
78
|
+
[
|
|
79
|
+
'dependencies',
|
|
80
|
+
'devDependencies',
|
|
81
|
+
'scripts',
|
|
82
|
+
] as (keyof AddOn['packageAdditions'])[]
|
|
83
|
+
)
|
|
84
|
+
.filter(
|
|
85
|
+
(key) =>
|
|
86
|
+
info.packageAdditions[key] &&
|
|
87
|
+
Object.entries(info.packageAdditions[key]).length > 0,
|
|
88
|
+
)
|
|
89
|
+
.map((key) => (
|
|
90
|
+
<Fragment key={key}>
|
|
91
|
+
<div className="font-medium">{CAPTIONS[key]}</div>
|
|
92
|
+
<Table>
|
|
93
|
+
{key !== 'scripts' && (
|
|
94
|
+
<TableHeader>
|
|
95
|
+
<TableRow>
|
|
96
|
+
<TableHead className="w-1/2">Package</TableHead>
|
|
97
|
+
<TableHead className="w-1/2">Version</TableHead>
|
|
98
|
+
</TableRow>
|
|
99
|
+
</TableHeader>
|
|
100
|
+
)}
|
|
101
|
+
<TableBody>
|
|
102
|
+
{Object.entries(info.packageAdditions[key]).map(
|
|
103
|
+
([pkg, version]) => (
|
|
104
|
+
<TableRow key={`${key}-${pkg}`}>
|
|
105
|
+
<TableCell className="w-1/2">{pkg}</TableCell>
|
|
106
|
+
<TableCell className="w-1/2">{version}</TableCell>
|
|
107
|
+
</TableRow>
|
|
108
|
+
),
|
|
109
|
+
)}
|
|
110
|
+
</TableBody>
|
|
111
|
+
</Table>
|
|
112
|
+
</Fragment>
|
|
113
|
+
))}
|
|
114
|
+
{info.routes && (
|
|
115
|
+
<>
|
|
116
|
+
<div className="font-medium">Routes</div>
|
|
117
|
+
<div>
|
|
118
|
+
<Table>
|
|
119
|
+
<TableHeader>
|
|
120
|
+
<TableRow>
|
|
121
|
+
<TableHead className="w-1/2">URL</TableHead>
|
|
122
|
+
<TableHead className="w-1/2">Name</TableHead>
|
|
123
|
+
</TableRow>
|
|
124
|
+
</TableHeader>
|
|
125
|
+
<TableBody>
|
|
126
|
+
{info.routes.map(({ url, name }) => (
|
|
127
|
+
<TableRow key={`${url}-${name}`}>
|
|
128
|
+
<TableCell className="w-1/2">{url}</TableCell>
|
|
129
|
+
<TableCell className="w-1/2">{name}</TableCell>
|
|
130
|
+
</TableRow>
|
|
131
|
+
))}
|
|
132
|
+
</TableBody>
|
|
133
|
+
</Table>
|
|
134
|
+
</div>
|
|
135
|
+
</>
|
|
136
|
+
)}
|
|
137
|
+
{info.commmand && (
|
|
138
|
+
<>
|
|
139
|
+
<div className="font-medium">Setup Command</div>
|
|
140
|
+
<div className="font-bold font-mono">{`${info.command.command} ${info.command.args.join(' ')}`}</div>
|
|
141
|
+
</>
|
|
142
|
+
)}
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function AddOnViewer({ addOnInfo }: { addOnInfo: AddOn }) {
|
|
149
|
+
const [selectedFile, setSelectedFile] = useState<string | null>(null)
|
|
150
|
+
const [showInfo, setShowInfo] = useState(false)
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<div className="flex flex-row">
|
|
154
|
+
<FileTree
|
|
155
|
+
prefix="./"
|
|
156
|
+
tree={addOnInfo.files || {}}
|
|
157
|
+
originalTree={{}}
|
|
158
|
+
onFileSelected={(file) => {
|
|
159
|
+
setSelectedFile(file)
|
|
160
|
+
setShowInfo(false)
|
|
161
|
+
}}
|
|
162
|
+
extraTreeItems={[
|
|
163
|
+
{
|
|
164
|
+
id: 'info',
|
|
165
|
+
name: 'Add-On Info',
|
|
166
|
+
icon: () => <Info className="w-4 h-4 mr-2" />,
|
|
167
|
+
onClick: () => {
|
|
168
|
+
setSelectedFile(null)
|
|
169
|
+
setShowInfo(true)
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
]}
|
|
173
|
+
/>
|
|
174
|
+
<div className="max-w-3/4 w-3/4 pl-2">
|
|
175
|
+
{showInfo && <InfoViewer info={addOnInfo as AddOn} />}
|
|
176
|
+
{selectedFile ? (
|
|
177
|
+
<FileViewer
|
|
178
|
+
filePath={selectedFile}
|
|
179
|
+
modifiedFile={addOnInfo?.files?.[selectedFile] || ''}
|
|
180
|
+
/>
|
|
181
|
+
) : null}
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function App() {
|
|
188
|
+
const {
|
|
189
|
+
projectPath,
|
|
190
|
+
output,
|
|
191
|
+
addOnInfo,
|
|
192
|
+
outputWithoutAddon,
|
|
193
|
+
originalOptions,
|
|
194
|
+
addOns,
|
|
195
|
+
} = Route.useLoaderData()
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<div className="p-5">
|
|
199
|
+
<Tabs defaultValue="add-on">
|
|
200
|
+
<TabsList className="grid grid-cols-2 w-[400px]">
|
|
201
|
+
<TabsTrigger value="add-on">Add-On</TabsTrigger>
|
|
202
|
+
<TabsTrigger value="applied">Applied</TabsTrigger>
|
|
203
|
+
</TabsList>
|
|
204
|
+
<TabsContent value="add-on">
|
|
205
|
+
<AddOnViewer addOnInfo={addOnInfo} />
|
|
206
|
+
</TabsContent>
|
|
207
|
+
<TabsContent value="applied">
|
|
208
|
+
<AppliedAddOn
|
|
209
|
+
projectPath={projectPath}
|
|
210
|
+
output={output}
|
|
211
|
+
addOnInfo={addOnInfo}
|
|
212
|
+
outputWithoutAddon={outputWithoutAddon}
|
|
213
|
+
originalOptions={
|
|
214
|
+
originalOptions as Required<typeof originalOptions>
|
|
215
|
+
}
|
|
216
|
+
addOns={addOns}
|
|
217
|
+
/>
|
|
218
|
+
</TabsContent>
|
|
219
|
+
</Tabs>
|
|
220
|
+
</div>
|
|
221
|
+
)
|
|
222
|
+
}
|
package/src/ssr.tsx
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createStartHandler,
|
|
3
|
+
defaultStreamHandler,
|
|
4
|
+
} from '@tanstack/react-start/server'
|
|
5
|
+
import { getRouterManifest } from '@tanstack/react-start/router-manifest'
|
|
6
|
+
|
|
7
|
+
import { createRouter } from './router'
|
|
8
|
+
|
|
9
|
+
export default createStartHandler({
|
|
10
|
+
createRouter,
|
|
11
|
+
getRouterManifest,
|
|
12
|
+
})(defaultStreamHandler)
|
package/src/styles.css
ADDED
|
@@ -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
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"include": ["**/*.ts", "**/*.tsx"],
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"jsx": "react-jsx",
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
8
|
+
"types": ["vite/client"],
|
|
9
|
+
|
|
10
|
+
/* Bundler mode */
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"allowImportingTsExtensions": true,
|
|
13
|
+
"verbatimModuleSyntax": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
|
|
16
|
+
/* Linting */
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true,
|
|
22
|
+
"noUncheckedSideEffectImports": true,
|
|
23
|
+
"baseUrl": ".",
|
|
24
|
+
"paths": {
|
|
25
|
+
"@/*": ["./src/*"]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"outDir": "./lib-dist",
|
|
6
|
+
"rootDir": "./lib",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"moduleResolution": "nodenext",
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationDir": "./lib-dist"
|
|
14
|
+
},
|
|
15
|
+
"include": ["./lib/*.ts"],
|
|
16
|
+
"exclude": ["node_modules", "dist", "lib-dist"]
|
|
17
|
+
}
|