libs: add support for routing in ui-v2 (#2585)

This commit is contained in:
Alex Hancock
2025-05-19 12:29:42 -04:00
committed by GitHub
parent 7d63d3a77a
commit dc74a0e903
12 changed files with 320 additions and 11 deletions

154
ui-v2/package-lock.json generated
View File

@@ -8,6 +8,8 @@
"name": "goose-v2",
"version": "1.0.0",
"dependencies": {
"@tanstack/react-router": "^1.120.5",
"@tanstack/router": "^0.0.1-beta.53",
"react": "^19.1.0",
"react-dom": "^19.1.0"
},
@@ -358,7 +360,6 @@
"version": "7.27.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
"dev": true,
"license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
@@ -2965,6 +2966,124 @@
"tailwindcss": "4.1.7"
}
},
"node_modules/@tanstack/history": {
"version": "1.115.0",
"resolved": "https://registry.npmjs.org/@tanstack/history/-/history-1.115.0.tgz",
"integrity": "sha512-K7JJNrRVvyjAVnbXOH2XLRhFXDkeP54Kt2P4FR1Kl2KDGlIbkua5VqZQD2rot3qaDrpufyUa63nuLai1kOLTsQ==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@tanstack/react-router": {
"version": "1.120.5",
"resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.120.5.tgz",
"integrity": "sha512-A+YRftGwAeFBxa8DF5ujNYqkSEbjCa1KjxDNYr+jWj16jjTxrz/XqgOJCv5ZfbAqqqOa3yLYoQbWa7OGz5jHuA==",
"license": "MIT",
"dependencies": {
"@tanstack/history": "1.115.0",
"@tanstack/react-store": "^0.7.0",
"@tanstack/router-core": "1.120.5",
"jsesc": "^3.1.0",
"tiny-invariant": "^1.3.3",
"tiny-warning": "^1.0.3"
},
"engines": {
"node": ">=12"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": ">=18.0.0 || >=19.0.0",
"react-dom": ">=18.0.0 || >=19.0.0"
}
},
"node_modules/@tanstack/react-store": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.7.0.tgz",
"integrity": "sha512-S/Rq17HaGOk+tQHV/yrePMnG1xbsKZIl/VsNWnNXt4XW+tTY8dTlvpJH2ZQ3GRALsusG5K6Q3unAGJ2pd9W/Ng==",
"license": "MIT",
"dependencies": {
"@tanstack/store": "0.7.0",
"use-sync-external-store": "^1.4.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@tanstack/router": {
"version": "0.0.1-beta.53",
"resolved": "https://registry.npmjs.org/@tanstack/router/-/router-0.0.1-beta.53.tgz",
"integrity": "sha512-nX1avh939ufOCoXhJ5wihX/ft6sn50ARrj4FAhRYn50KKzo9fXsYSmPyVgqVdW0hJ4n9XXKIMkwwpzEhLQmqrA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.16.7",
"@tanstack/store": "0.0.1-beta.52",
"tiny-invariant": "^1.3.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@tanstack/router-core": {
"version": "1.120.5",
"resolved": "https://registry.npmjs.org/@tanstack/router-core/-/router-core-1.120.5.tgz",
"integrity": "sha512-IXLNv3j7rpTL/YNCWHijZgrnxFuvD4Nz/nUiGSak4x5BKzlnuZEso81xFcIuczVrEW72NxZv8IfzpR5M5Tuc0A==",
"license": "MIT",
"dependencies": {
"@tanstack/history": "1.115.0",
"@tanstack/store": "^0.7.0",
"tiny-invariant": "^1.3.3"
},
"engines": {
"node": ">=12"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@tanstack/router/node_modules/@tanstack/store": {
"version": "0.0.1-beta.52",
"resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.0.1-beta.52.tgz",
"integrity": "sha512-3/5XqeG09sCJnakHpq8qgXjdVpm97aITbi1wfbjLGXdVsss62zpJAvc4vL8ccHf+J/OmoS4dJTNuEZ0alywZtg==",
"license": "MIT",
"dependencies": {
"immer": "^9.0.15"
},
"engines": {
"node": ">=12"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@tanstack/store": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.7.0.tgz",
"integrity": "sha512-CNIhdoUsmD2NolYuaIs8VfWM467RK6oIBAW4nPEKZhg1smZ+/CwtCdpURgp7nxSqOaV9oKkzdWD80+bC66F/Jg==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@testing-library/dom": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
@@ -8200,6 +8319,16 @@
"node": ">= 4"
}
},
"node_modules/immer": {
"version": "9.0.21",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
"integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
}
},
"node_modules/import-fresh": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
@@ -8995,7 +9124,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -11808,7 +11936,6 @@
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"dev": true,
"license": "MIT"
},
"node_modules/regexp.prototype.flags": {
@@ -13581,6 +13708,18 @@
"license": "MIT",
"optional": true
},
"node_modules/tiny-invariant": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
"integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
"license": "MIT"
},
"node_modules/tiny-warning": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
"license": "MIT"
},
"node_modules/tinybench": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
@@ -14139,6 +14278,15 @@
"punycode": "^2.1.0"
}
},
"node_modules/use-sync-external-store": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
"integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
"license": "MIT",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/username": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz",

View File

@@ -32,6 +32,8 @@
"prepare": "cd ../.. && husky install"
},
"dependencies": {
"@tanstack/react-router": "^1.120.5",
"@tanstack/router": "^0.0.1-beta.53",
"react": "^19.1.0",
"react-dom": "^19.1.0"
},

View File

@@ -1,5 +1,7 @@
import React, { Suspense } from 'react';
import { Outlet } from '@tanstack/react-router';
import GooseLogo from './components/GooseLogo';
import SuspenseLoader from './components/SuspenseLoader';
@@ -7,10 +9,11 @@ const App: React.FC = (): React.ReactElement => {
return (
<Suspense fallback={<SuspenseLoader />}>
<div className="p-5 max-w-3xl mx-auto">
<div className="flex items-center gap-4">
<div className="flex items-center gap-4 mb-4">
<GooseLogo />
<h1 className="text-2xl font-bold text-textProminent">Goose v2</h1>
</div>
<Outlet />
</div>
</Suspense>
);

View File

@@ -1,11 +1,17 @@
import React from 'react';
import { RouterProvider } from '@tanstack/react-router';
import ReactDOM from 'react-dom/client';
import App from './App';
import { router } from './routeTree';
import './index.css';
// Initialize the router
await router.load();
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
<RouterProvider router={router} />
</React.StrictMode>
);

View File

@@ -0,0 +1,88 @@
/* eslint-disable */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// This file was automatically generated by TanStack Router.
// You should NOT make any changes in this file as it will be overwritten.
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
// Import Routes
import { Route as rootRoute } from './routes/__root'
import { Route as IndexImport } from './routes/index'
// Create/Update Routes
const IndexRoute = IndexImport.update({
id: '/',
path: '/',
getParentRoute: () => rootRoute,
} as any)
// Populate the FileRoutesByPath interface
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/': {
id: '/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof IndexImport
parentRoute: typeof rootRoute
}
}
}
// Create and export the route tree
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
}
export interface FileRoutesById {
__root__: typeof rootRoute
'/': typeof IndexRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths: '/'
fileRoutesByTo: FileRoutesByTo
to: '/'
id: '__root__' | '/'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
}
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
}
export const routeTree = rootRoute
._addFileChildren(rootRouteChildren)
._addFileTypes<FileRouteTypes>()
/* ROUTE_MANIFEST_START
{
"routes": {
"__root__": {
"filePath": "__root.tsx",
"children": [
"/"
]
},
"/": {
"filePath": "index.tsx"
}
}
}
ROUTE_MANIFEST_END */

14
ui-v2/src/routeTree.ts Normal file
View File

@@ -0,0 +1,14 @@
import { createRouter } from '@tanstack/react-router';
import { rootRoute, indexRoute, aboutRoute } from './routes';
const routeTree = rootRoute.addChildren([indexRoute, aboutRoute]);
export const router = createRouter({ routeTree });
// Register the router instance for type safety
declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}

View File

@@ -0,0 +1,20 @@
import { createRootRoute, Link, Outlet } from '@tanstack/react-router';
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools';
export const Route = createRootRoute({
component: () => (
<>
<div className="p-2 flex gap-2">
<Link to="/" className="[&.active]:font-bold">
Home
</Link>{' '}
<Link to="/about" className="[&.active]:font-bold">
About
</Link>
</div>
<hr />
<Outlet />
<TanStackRouterDevtools />
</>
),
});

View File

@@ -0,0 +1,28 @@
import { createRootRoute, createRoute } from '@tanstack/react-router';
import App from '../App';
export const rootRoute = createRootRoute({
component: App,
});
export const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
component: () => (
<div className="p-5">
<h2>Welcome to Goose v2</h2>
</div>
),
});
export const aboutRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/about',
component: () => (
<div className="p-5">
<h2>About Goose v2</h2>
<p>An AI assistant for developers</p>
</div>
),
});