Skip to content

Commit 7e8923d

Browse files
Added react and tanstack router for very basic project listing via IPC core method. Using hash based routing
1 parent 9cabcfd commit 7e8923d

14 files changed

+326
-23
lines changed

index.html

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ <h1>💖 Hello World!</h1>
1212
>
1313
Test IPC
1414
</button>
15+
<div id="app"></div>
1516
<script type="module" src="/src/renderer/index.ts"></script>
1617
</body>
1718
</html>

package.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,12 @@
2626
"@elek-io/core": "^0.1.1",
2727
"@sentry/electron": "^4.17.0",
2828
"@sentry/vite-plugin": "^2.13.0",
29+
"@tanstack/react-router": "^1.15.23",
30+
"@tanstack/router-devtools": "^1.15.23",
2931
"dugite": "^2.5.2",
30-
"electron-squirrel-startup": "^1.0.0"
32+
"electron-squirrel-startup": "^1.0.0",
33+
"react": "^18.2.0",
34+
"react-dom": "^18.2.0"
3135
},
3236
"devDependencies": {
3337
"@changesets/cli": "^2.27.1",
@@ -39,6 +43,9 @@
3943
"@electron-forge/plugin-auto-unpack-natives": "^7.2.0",
4044
"@electron-forge/plugin-vite": "^7.2.0",
4145
"@electron-forge/publisher-github": "^7.2.0",
46+
"@tanstack/router-vite-plugin": "^1.15.22",
47+
"@types/react": "^18.2.55",
48+
"@types/react-dom": "^18.2.19",
4249
"@typescript-eslint/eslint-plugin": "^5.0.0",
4350
"@typescript-eslint/parser": "^5.0.0",
4451
"electron": "^28.2.1",

src/main/index.ts

+6-9
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ import {
1010
protocol,
1111
screen,
1212
} from 'electron';
13-
import installExtension, {
14-
REACT_DEVELOPER_TOOLS,
15-
} from 'electron-devtools-installer';
1613
import Path from 'path';
1714

1815
Sentry.init({
@@ -132,7 +129,7 @@ class Main {
132129

133130
if (app.isPackaged) {
134131
// Uncomment to debug a production build
135-
// window.webContents.openDevTools();
132+
window.webContents.openDevTools();
136133
// installExtension(REACT_DEVELOPER_TOOLS)
137134
// .then((name) => console.log(`Added Chrome extension: ${name}`))
138135
// .catch((err) =>
@@ -147,11 +144,11 @@ class Main {
147144
} else {
148145
// Client is in development
149146
window.webContents.openDevTools();
150-
installExtension(REACT_DEVELOPER_TOOLS)
151-
.then((name) => console.log(`Added Chrome extension: ${name}`))
152-
.catch((err) =>
153-
console.log('An error occurred adding Chrome extension: ', err)
154-
);
147+
// installExtension(REACT_DEVELOPER_TOOLS)
148+
// .then((name) => console.log(`Added Chrome extension: ${name}`))
149+
// .catch((err) =>
150+
// console.log('An error occurred adding Chrome extension: ', err)
151+
// );
155152

156153
console.log(
157154
'Loading frontend in development by URL:',

src/renderer/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* ```
2727
*/
2828
import * as Sentry from '@sentry/electron/renderer';
29+
import './react/app';
2930

3031
Sentry.init({
3132
dsn: 'https://c839d5cdaec666911ba459803882d9d0@o4504985675431936.ingest.sentry.io/4506688843546624',

src/renderer/react/app.tsx

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {
2+
RouterProvider,
3+
createHashHistory,
4+
createRouter,
5+
} from '@tanstack/react-router';
6+
import { StrictMode } from 'react';
7+
import ReactDOM from 'react-dom/client';
8+
9+
// Import the generated route tree
10+
import { routeTree } from './routeTree.gen';
11+
12+
// Create a new router instance
13+
const hashHistory = createHashHistory(); // Use hash based routing since in production electron just loads the index.html via the file protocol
14+
const router = createRouter({
15+
routeTree,
16+
history: hashHistory,
17+
context: { core: window.ipc.core },
18+
});
19+
20+
// Register the router instance for type safety
21+
declare module '@tanstack/react-router' {
22+
interface Register {
23+
router: typeof router;
24+
}
25+
}
26+
27+
// Render the app
28+
const rootElement = document.getElementById('app')!;
29+
if (!rootElement.innerHTML) {
30+
const root = ReactDOM.createRoot(rootElement);
31+
root.render(
32+
<StrictMode>
33+
Current URL: "{window.location.href}"
34+
<RouterProvider router={router} />
35+
</StrictMode>
36+
);
37+
}

src/renderer/react/routeTree.gen.ts

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* prettier-ignore-start */
2+
3+
/* eslint-disable */
4+
5+
// @ts-nocheck
6+
7+
// noinspection JSUnusedGlobalSymbols
8+
9+
// This file is auto-generated by TanStack Router
10+
11+
// Import Routes
12+
13+
import { Route as rootRoute } from './routes/__root'
14+
import { Route as ProjectsImport } from './routes/projects'
15+
import { Route as IndexImport } from './routes/index'
16+
17+
// Create/Update Routes
18+
19+
const ProjectsRoute = ProjectsImport.update({
20+
path: '/projects',
21+
getParentRoute: () => rootRoute,
22+
} as any)
23+
24+
const IndexRoute = IndexImport.update({
25+
path: '/',
26+
getParentRoute: () => rootRoute,
27+
} as any)
28+
29+
// Populate the FileRoutesByPath interface
30+
31+
declare module '@tanstack/react-router' {
32+
interface FileRoutesByPath {
33+
'/': {
34+
preLoaderRoute: typeof IndexImport
35+
parentRoute: typeof rootRoute
36+
}
37+
'/projects': {
38+
preLoaderRoute: typeof ProjectsImport
39+
parentRoute: typeof rootRoute
40+
}
41+
}
42+
}
43+
44+
// Create and export the route tree
45+
46+
export const routeTree = rootRoute.addChildren([IndexRoute, ProjectsRoute])
47+
48+
/* prettier-ignore-end */

src/renderer/react/routes/__root.tsx

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {
2+
createRootRouteWithContext,
3+
Link,
4+
Outlet,
5+
} from '@tanstack/react-router';
6+
import { TanStackRouterDevtools } from '@tanstack/router-devtools';
7+
import { ContextBridgeApi } from '../../preload';
8+
9+
interface RouterContext {
10+
core: ContextBridgeApi['core'];
11+
}
12+
13+
// Use the routerContext to create your root route
14+
export const Route = createRootRouteWithContext<RouterContext>()({
15+
component: () => (
16+
<>
17+
<div className="p-2 flex gap-2">
18+
<Link to="/" className="[&.active]:font-bold">
19+
Home
20+
</Link>{' '}
21+
<Link to="/projects" className="[&.active]:font-bold">
22+
Projects
23+
</Link>
24+
</div>
25+
<hr />
26+
<Outlet />
27+
<TanStackRouterDevtools />
28+
</>
29+
),
30+
});

src/renderer/react/routes/index.tsx

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { createFileRoute } from '@tanstack/react-router';
2+
3+
export const Route = createFileRoute('/')({
4+
component: Index,
5+
});
6+
7+
function Index() {
8+
return (
9+
<div className="p-2">
10+
<h3>Welcome Home!</h3>
11+
</div>
12+
);
13+
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { createFileRoute } from '@tanstack/react-router';
2+
3+
export const Route = createFileRoute('/projects')({
4+
component: About,
5+
loader: ({ context }) => context.core.projects.list(),
6+
});
7+
8+
function About() {
9+
const projects = Route.useLoaderData();
10+
11+
return (
12+
<div className="p-2">
13+
Hello from Projects page!{' '}
14+
<ul>
15+
{projects.list.map((project) => {
16+
return <li key={project.id}>{project.name}</li>;
17+
})}
18+
</ul>
19+
</div>
20+
);
21+
}

src/types.d.ts

+10
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,13 @@
33
// whether you're running in development or production).
44
declare const MAIN_WINDOW_VITE_DEV_SERVER_URL: string;
55
declare const MAIN_WINDOW_VITE_NAME: string;
6+
7+
// This file should augment the properties of the `Window` with the type of the
8+
// `ContextBridgeApi` from `Electron.contextBridge` declared in `./preload.ts`.
9+
import type { ContextBridgeApi } from './renderer/preload';
10+
11+
declare global {
12+
interface Window {
13+
ipc: ContextBridgeApi;
14+
}
15+
}

tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"baseUrl": ".",
1111
"outDir": "dist",
1212
"moduleResolution": "node",
13-
"resolveJsonModule": true
13+
"resolveJsonModule": true,
14+
"jsx": "react-jsx"
1415
},
1516
"include": ["src"]
1617
}

vite.renderer.config.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1+
import { TanStackRouterVite } from '@tanstack/router-vite-plugin';
12
import { defineConfig } from 'vite';
23

34
// https://vitejs.dev/config
4-
export default defineConfig({});
5+
export default defineConfig({
6+
plugins: [
7+
TanStackRouterVite({
8+
routesDirectory: './src/renderer/react/routes',
9+
generatedRouteTree: './src/renderer/react/routeTree.gen.ts',
10+
}),
11+
],
12+
});

window.d.ts

-9
This file was deleted.

0 commit comments

Comments
 (0)