From 43fe18737711bc0dcf382517823c9880a6cfc65c Mon Sep 17 00:00:00 2001 From: brysonbw Date: Sun, 25 Jan 2026 18:51:30 -0700 Subject: [PATCH] refactor(router): migrate from @vaadin/router to @lit-labs/router --- package-lock.json | 103 ++++++------------ package.json | 3 +- src/app.ts | 14 +-- src/main.ts | 1 + src/{views/about-view.ts => pages/about.ts} | 6 +- src/{views/home-view.ts => pages/home.ts} | 6 +- .../not-found-view.ts => pages/not-found.ts} | 6 +- .../projects-view.ts => pages/projects.ts} | 6 +- src/routes.ts | 56 ++++------ 9 files changed, 74 insertions(+), 127 deletions(-) rename src/{views/about-view.ts => pages/about.ts} (95%) rename src/{views/home-view.ts => pages/home.ts} (97%) rename src/{views/not-found-view.ts => pages/not-found.ts} (93%) rename src/{views/projects-view.ts => pages/projects.ts} (97%) diff --git a/package-lock.json b/package-lock.json index 56bd8b2..b2f0afb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,13 +6,14 @@ "packages": { "": { "name": "codecause.dev", - "version": "1.0.1", + "version": "1.0.2", "dependencies": { + "@lit-labs/router": "^0.1.4", "@lit/task": "^1.0.3", - "@vaadin/router": "^2.0.1", "lit": "^3.3.2", "three": "^0.182.0", "three-stdlib": "^2.36.1", + "urlpattern-polyfill": "^10.1.0", "uuid": "^13.0.0" }, "devDependencies": { @@ -31,8 +32,8 @@ "vite-plugin-eslint": "^1.8.1" }, "engines": { - "node": ">=20", - "npm": ">=9.6.3" + "node": ">=24", + "npm": ">=11.6.2" } }, "node_modules/@babel/code-frame": { @@ -66,6 +67,7 @@ "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", @@ -2292,6 +2294,15 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@lit-labs/router": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@lit-labs/router/-/router-0.1.4.tgz", + "integrity": "sha512-xURH6fOPE0MYfXa1nyl+qTIhZRVWkFa2oggTRodKAI2q/HjA2Va7HEKe7fMm8DdnFE+zEI2aUGnStawKpVh3lQ==", + "license": "BSD-3-Clause", + "dependencies": { + "lit": "^2.0.0 || ^3.0.0" + } + }, "node_modules/@lit-labs/ssr-dom-shim": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.5.1.tgz", @@ -2770,6 +2781,7 @@ "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -2875,6 +2887,7 @@ "integrity": "sha512-nm3cvFN9SqZGXjmw5bZ6cGmvJSyJPn0wU9gHAZZHDnZl2wF9PhHv78Xf06E0MaNk4zLVHL8hb2/c32XvyJOLQg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.53.1", "@typescript-eslint/types": "8.53.1", @@ -3106,36 +3119,6 @@ "dev": true, "license": "ISC" }, - "node_modules/@vaadin/router": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@vaadin/router/-/router-2.0.1.tgz", - "integrity": "sha512-Rs3FQhc8CECrigF8dbaQk7Q3+/BXIjUMd5vapMIphW09WdDxZB88yQ1C/WXV08Z2skPqMP+6ooLde6ItjygleQ==", - "license": "Apache-2.0", - "dependencies": { - "@vaadin/vaadin-usage-statistics": "^2.1.3", - "path-to-regexp": "^6.3.0", - "type-fest": "^5.2.0" - } - }, - "node_modules/@vaadin/vaadin-development-mode-detector": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@vaadin/vaadin-development-mode-detector/-/vaadin-development-mode-detector-2.0.7.tgz", - "integrity": "sha512-9FhVhr0ynSR3X2ao+vaIEttcNU5XfzCbxtmYOV8uIRnUCtNgbvMOIcyGBvntsX9I5kvIP2dV3cFAOG9SILJzEA==", - "license": "Apache-2.0" - }, - "node_modules/@vaadin/vaadin-usage-statistics": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@vaadin/vaadin-usage-statistics/-/vaadin-usage-statistics-2.1.3.tgz", - "integrity": "sha512-8r4TNknD7OJQADe3VygeofFR7UNAXZ2/jjBFP5dgI8+2uMfnuGYgbuHivasKr9WSQ64sPej6m8rDoM1uSllXjQ==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@vaadin/vaadin-development-mode-detector": "^2.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, "node_modules/@vitejs/plugin-legacy": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-7.2.1.tgz", @@ -3180,6 +3163,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3360,6 +3344,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -3682,6 +3667,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3742,6 +3728,7 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -4832,12 +4819,6 @@ "dev": true, "license": "MIT" }, - "node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "license": "MIT" - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -4861,6 +4842,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -4919,6 +4901,7 @@ "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -5153,6 +5136,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5775,24 +5759,13 @@ "dev": true, "license": "MIT" }, - "node_modules/tagged-tag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", - "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/terser": { "version": "5.46.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", @@ -5817,7 +5790,8 @@ "version": "0.182.0", "resolved": "https://registry.npmjs.org/three/-/three-0.182.0.tgz", "integrity": "sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/three-stdlib": { "version": "2.36.1", @@ -5905,27 +5879,13 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.4.1.tgz", - "integrity": "sha512-xygQcmneDyzsEuKZrFbRMne5HDqMs++aFzefrJTgEIKjQ3rekM+RPfFCVq2Gp1VIDqddoYeppCj4Pcb+RZW0GQ==", - "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6043,6 +6003,12 @@ "punycode": "^2.1.0" } }, + "node_modules/urlpattern-polyfill": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz", + "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", + "license": "MIT" + }, "node_modules/uuid": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", @@ -6062,6 +6028,7 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", diff --git a/package.json b/package.json index 5713e9f..f097db8 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,12 @@ "format": "prettier --write ." }, "dependencies": { + "@lit-labs/router": "^0.1.4", "@lit/task": "^1.0.3", - "@vaadin/router": "^2.0.1", "lit": "^3.3.2", "three": "^0.182.0", "three-stdlib": "^2.36.1", + "urlpattern-polyfill": "^10.1.0", "uuid": "^13.0.0" }, "devDependencies": { diff --git a/src/app.ts b/src/app.ts index d2e9db8..28b1db1 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,26 +1,20 @@ import { LitElement, html, css, type TemplateResult } from 'lit'; -import { customElement, query } from 'lit/decorators.js'; -import { Router } from '@vaadin/router'; +import { customElement } from 'lit/decorators.js'; import { routes } from './routes'; import './components/header/header'; import './components/footer/footer'; +import { Router } from '@lit-labs/router'; @customElement('app-root') export class AppRoot extends LitElement { - @query('#outlet') - private _outlet!: HTMLElement | null; - - firstUpdated(): void { - const router = new Router(this._outlet); - router.setRoutes(routes); - } + private _router = new Router(this, routes); render(): TemplateResult { return html`
-
+
${this._router.outlet()}
`; diff --git a/src/main.ts b/src/main.ts index 36c3352..c6a4b34 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1 +1,2 @@ +import 'urlpattern-polyfill'; import './app'; diff --git a/src/views/about-view.ts b/src/pages/about.ts similarity index 95% rename from src/views/about-view.ts rename to src/pages/about.ts index 0019fbb..b9c8736 100644 --- a/src/views/about-view.ts +++ b/src/pages/about.ts @@ -1,8 +1,8 @@ import { LitElement, html, css, type TemplateResult } from 'lit'; import { customElement } from 'lit/decorators.js'; -@customElement('about-view') -export class AboutView extends LitElement { +@customElement('about-page') +export class AboutPage extends LitElement { render(): TemplateResult { return html`

About Us

@@ -84,6 +84,6 @@ export class AboutView extends LitElement { declare global { interface HTMLElementTagNameMap { - 'about-view': AboutView; + 'about-page': AboutPage; } } diff --git a/src/views/home-view.ts b/src/pages/home.ts similarity index 97% rename from src/views/home-view.ts rename to src/pages/home.ts index e65d998..06c8a6e 100644 --- a/src/views/home-view.ts +++ b/src/pages/home.ts @@ -19,8 +19,8 @@ const PERSON_IMAGES: readonly { { alt: 'person-4', path: person4, id: '4' }, ]; -@customElement('home-view') -export class HomeView extends LitElement { +@customElement('home-page') +export class HomePage extends LitElement { connectedCallback(): void { super.connectedCallback(); this.dispatchEvent( @@ -203,6 +203,6 @@ export class HomeView extends LitElement { declare global { interface HTMLElementTagNameMap { - 'home-view': HomeView; + 'home-page': HomePage; } } diff --git a/src/views/not-found-view.ts b/src/pages/not-found.ts similarity index 93% rename from src/views/not-found-view.ts rename to src/pages/not-found.ts index 21583c3..4274b4e 100644 --- a/src/views/not-found-view.ts +++ b/src/pages/not-found.ts @@ -1,8 +1,8 @@ import { LitElement, css, html, type TemplateResult } from 'lit'; import { customElement } from 'lit/decorators.js'; -@customElement('not-found-view') -export class NotFoundView extends LitElement { +@customElement('not-found-page') +export class NotFoundPage extends LitElement { connectedCallback(): void { super.connectedCallback(); this.dispatchEvent( @@ -78,6 +78,6 @@ export class NotFoundView extends LitElement { declare global { interface HTMLElementTagNameMap { - 'not-found-view': NotFoundView; + 'not-found-page': NotFoundPage; } } diff --git a/src/views/projects-view.ts b/src/pages/projects.ts similarity index 97% rename from src/views/projects-view.ts rename to src/pages/projects.ts index 2481e79..cd66a6b 100644 --- a/src/views/projects-view.ts +++ b/src/pages/projects.ts @@ -15,8 +15,8 @@ type Repo = { stargazers_count: number; }; -@customElement('projects-view') -export class ProjectsView extends LitElement { +@customElement('projects-page') +export class ProjectsPage extends LitElement { connectedCallback(): void { super.connectedCallback(); this._githubReposTask.run(); @@ -172,6 +172,6 @@ export class ProjectsView extends LitElement { declare global { interface HTMLElementTagNameMap { - 'projects-view': ProjectsView; + 'projects-page': ProjectsPage; } } diff --git a/src/routes.ts b/src/routes.ts index 46b7de5..dec8bd2 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -1,58 +1,42 @@ -import type { - ActionResult, - Route, - RouteContext, - Commands, -} from '@vaadin/router'; import { APP_TITLE } from './utils/constants'; +import { html } from 'lit'; +import type { RouteConfig } from '@lit-labs/router'; -export const routes: Route[] = [ +export const routes: RouteConfig[] = [ { path: '/', - async action( - this: Route, - _context: RouteContext, - commands: Commands - ): Promise { - await import('./views/home-view'); + render: () => html``, + enter: async (): Promise => { + await import('./pages/home.ts'); document.title = `${APP_TITLE} | Inspiring innovation, empowering collaboration, enabling progress, and driving impact through code`; - return commands.component('home-view'); + return true; }, }, { path: '/about', - async action( - this: Route, - _context: RouteContext, - commands: Commands - ): Promise { - await import('./views/about-view'); + render: () => html``, + enter: async (): Promise => { + await import('./pages/about.ts'); document.title = `${APP_TITLE} | About`; - return commands.component('about-view'); + return true; }, }, { path: '/projects', - async action( - this: Route, - _context: RouteContext, - commands: Commands - ): Promise { - await import('./views/projects-view'); + render: () => html``, + enter: async (): Promise => { + await import('./pages/projects.ts'); document.title = `${APP_TITLE} | Projects`; - return commands.component('projects-view'); + return true; }, }, { - path: '(.*)', - async action( - this: Route, - _context: RouteContext, - commands: Commands - ): Promise { - await import('./views/not-found-view'); + path: '/*', + render: () => html``, + enter: async (): Promise => { + await import('./pages/not-found.ts'); document.title = `${APP_TITLE} | Page not found`; - return commands.component('not-found-view'); + return true; }, }, ];