@iyulab/router 0.1.0 → 0.3.0

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/README.md CHANGED
@@ -1,18 +1,19 @@
1
1
  # @iyulab/router
2
2
 
3
- A modern client-side router for web applications with support for Lit and React components.
3
+ A modern, lightweight client-side router for web applications with support for both Lit and React components.
4
4
 
5
5
  ## Features
6
6
 
7
- - 🚀 Modern URLPattern-based routing
8
- - 🔧 Support for both Lit and React components
9
- - 📱 Client-side navigation with history management
10
- - 🎯 Nested routing support
11
- - Async data loading with loaders
12
- - 🔗 Smart link component with external link detection
13
- - 📊 Route progress tracking
14
- - 🎨 Flexible outlet system for component rendering
15
- - 🌐 Global route information access via `window.route`
7
+ - 🚀 **Modern URLPattern-based routing** - Uses native URLPattern API for powerful path matching
8
+ - 🔧 **Unified Framework Support** - Works with both Lit and React components using render functions
9
+ - 📱 **Client-side Navigation** - History API integration with browser back/forward support
10
+ - 🎯 **Nested Routing** - Support for deeply nested route hierarchies with index and path routes
11
+ - 🔗 **Smart Link Component** - Automatic external link detection and handling
12
+ - 📊 **Route Events** - Track navigation progress with route-begin, route-done, and route-error events
13
+ - 🎨 **Flexible Outlet System** - Unified rendering with renderContent method
14
+ - 🌐 **Global Route Access** - Access current route information anywhere via `window.route`
15
+ - 🔄 **Force Re-rendering** - Control component re-rendering on route changes
16
+ - ⚠️ **Enhanced Error Handling** - Built-in ErrorPage component with improved styling
16
17
 
17
18
  ## Installation
18
19
 
@@ -20,43 +21,89 @@ A modern client-side router for web applications with support for Lit and React
20
21
  npm install @iyulab/router
21
22
  ```
22
23
 
23
- ## Usage
24
+ ## Quick Start
24
25
 
25
26
  ### Basic Setup
26
27
 
27
28
  ```typescript
28
29
  import { Router } from '@iyulab/router';
30
+ import { html } from 'lit';
29
31
 
30
32
  const router = new Router({
31
33
  root: document.getElementById('app')!,
32
34
  basepath: '/app',
33
35
  routes: [
34
36
  {
35
- path: '/',
36
- element: 'home-page'
37
+ index: true,
38
+ render: () => html`<home-page></home-page>`
37
39
  },
38
40
  {
39
41
  path: '/user/:id',
40
- component: UserComponent,
41
- loader: async (routeInfo) => {
42
- const response = await fetch(`/api/user/${routeInfo.params.id}`);
43
- return response.json();
44
- }
42
+ render: (routeInfo) => html`<user-page .userId=${routeInfo.params.id}></user-page>`
45
43
  }
46
- ],
47
- notfound: 'not-found-page'
44
+ ]
48
45
  });
49
46
 
50
- // Connect the router
51
- router.connect();
47
+ // Start routing
48
+ router.go(window.location.href);
49
+ ```
50
+
51
+ ### Nested Routes
52
+
53
+ ```typescript
54
+ const routes = [
55
+ {
56
+ path: '/dashboard',
57
+ render: () => html`<dashboard-layout><u-outlet></u-outlet></dashboard-layout>`,
58
+ children: [
59
+ {
60
+ index: true, // Matches /dashboard exactly
61
+ render: () => html`<dashboard-home></dashboard-home>`
62
+ },
63
+ {
64
+ path: 'settings',
65
+ render: () => html`<dashboard-settings></dashboard-settings>`
66
+ }
67
+ ]
68
+ }
69
+ ];
52
70
  ```
53
71
 
72
+ ### Mixed Framework Support
73
+
74
+ ```typescript
75
+ import React from 'react';
76
+
77
+ const routes = [
78
+ // Lit component
79
+ {
80
+ path: '/lit-page',
81
+ render: (routeInfo) => html`<my-lit-component .routeInfo=${routeInfo}></my-lit-component>`
82
+ },
83
+ // React component
84
+ {
85
+ path: '/react-page',
86
+ render: (routeInfo) => React.createElement(MyReactComponent, { routeInfo })
87
+ },
88
+ // HTML element
89
+ {
90
+ path: '/element-page',
91
+ render: (routeInfo) => {
92
+ const element = document.createElement('my-element');
93
+ element.data = routeInfo.params;
94
+ return element;
95
+ }
96
+ }
97
+ ];
98
+ ```
99
+
100
+ ## Usage Examples
101
+
54
102
  ### Using with Lit Components
55
103
 
56
104
  ```typescript
57
105
  import { LitElement, html } from 'lit';
58
106
  import { customElement } from 'lit/decorators.js';
59
- import { UOutlet, ULink } from '@iyulab/router';
60
107
 
61
108
  @customElement('app-root')
62
109
  export class AppRoot extends LitElement {
@@ -65,7 +112,7 @@ export class AppRoot extends LitElement {
65
112
  <nav>
66
113
  <u-link href="/">Home</u-link>
67
114
  <u-link href="/about">About</u-link>
68
- <u-link href="/user/123">User</u-link>
115
+ <u-link href="/user/123">User Profile</u-link>
69
116
  </nav>
70
117
  <main>
71
118
  <u-outlet></u-outlet>
@@ -87,7 +134,7 @@ export function AppRoot() {
87
134
  <nav>
88
135
  <Link href="/">Home</Link>
89
136
  <Link href="/about">About</Link>
90
- <Link href="/user/123">User</Link>
137
+ <Link href="/user/123">User Profile</Link>
91
138
  </nav>
92
139
  <main>
93
140
  <Outlet />
@@ -97,144 +144,20 @@ export function AppRoot() {
97
144
  }
98
145
  ```
99
146
 
100
- ### Nested Routes
101
-
102
- ```typescript
103
- const routes = [
104
- {
105
- path: '/dashboard',
106
- element: 'dashboard-layout',
107
- children: [
108
- {
109
- index: true,
110
- element: 'dashboard-home'
111
- },
112
- {
113
- path: 'settings',
114
- element: 'dashboard-settings'
115
- },
116
- {
117
- path: 'profile',
118
- component: ProfileComponent
119
- }
120
- ]
121
- }
122
- ];
123
- ```
124
-
125
- ### Route Information Access
126
-
127
- You can access current route information globally via `window.route`:
128
-
129
- ```typescript
130
- // In any component or script
131
- console.log('Current path:', window.route.pathname);
132
- console.log('Route params:', window.route.params);
133
- console.log('Query params:', window.route.search);
134
- console.log('Route data:', window.route.data);
135
-
136
- // For Lit components
137
- import { LitElement, html } from 'lit';
138
- import { customElement } from 'lit/decorators.js';
139
-
140
- @customElement('my-component')
141
- export class MyComponent extends LitElement {
142
- connectedCallback() {
143
- super.connectedCallback();
144
- // Listen for route changes
145
- document.addEventListener('route-change', this.onRouteChange);
146
- }
147
-
148
- disconnectedCallback() {
149
- document.removeEventListener('route-change', this.onRouteChange);
150
- super.disconnectedCallback();
151
- }
152
-
153
- private onRouteChange = () => {
154
- this.requestUpdate(); // Trigger re-render when route changes
155
- };
156
-
157
- render() {
158
- return html`
159
- <div>Current path: ${window.route?.pathname}</div>
160
- <div>Params: ${JSON.stringify(window.route?.params)}</div>
161
- `;
162
- }
163
- }
164
-
165
- // For React components
166
- import React, { useState, useEffect } from 'react';
167
-
168
- export function MyReactComponent() {
169
- const [routeInfo, setRouteInfo] = useState(window.route);
170
-
171
- useEffect(() => {
172
- const handleRouteChange = () => {
173
- setRouteInfo(window.route);
174
- };
175
-
176
- document.addEventListener('route-change', handleRouteChange);
177
- return () => document.removeEventListener('route-change', handleRouteChange);
178
- }, []);
179
-
180
- return (
181
- <div>
182
- <div>Current path: {routeInfo?.pathname}</div>
183
- <div>Params: {JSON.stringify(routeInfo?.params)}</div>
184
- </div>
185
- );
186
- }
187
- ```
188
-
189
- ## API Reference
190
-
191
- ### Router
192
-
193
- #### Constructor Options
194
-
195
- - `root`: HTMLElement - The root element where the router will render components
196
- - `basepath`: string - The base path for the router (optional, defaults to '/')
197
- - `routes`: Route[] - Array of route configurations
198
- - `notfound`: LitElement class or string - Component to render when no route matches
199
-
200
- #### Methods
201
-
202
- - `connect()`: Connect the router and start listening to navigation events
203
- - `disconnect()`: Disconnect the router and stop listening to events
204
- - `go(href: string)`: Navigate to a specific path
205
- - `goBase()`: Navigate to the base path
206
-
207
- ### Route Configuration
208
-
209
- ```typescript
210
- type Route = {
211
- path?: string; // URL pattern (URLPattern syntax)
212
- index?: boolean; // Index route (matches parent path exactly)
213
- element?: typeof LitElement | string; // Lit element to render
214
- component?: ComponentType; // React component to render
215
- loader?: (routeInfo: RouteInfo) => Promise<any>; // Data loader function
216
- title?: string; // Page title
217
- children?: Route[]; // Nested routes
218
- force?: boolean; // Force re-render on navigation
219
- };
220
- ```
221
-
222
- ### Components
223
-
224
- - `UOutlet` / `Outlet`: Outlet component for rendering route components
225
- - `ULink` / `Link`: Smart link component with client-side navigation
226
-
227
- ### Global Route Access
228
-
229
- - `window.route`: Global access to current route information (RouteInfo object)
147
+ ## Browser Support
230
148
 
231
- ## Events
149
+ - **URLPattern API**: Required for routing functionality
150
+ - **Modern browsers**: Chrome 95+, Firefox 106+, Safari 16.4+
151
+ - **Polyfill**: Consider using [urlpattern-polyfill](https://www.npmjs.com/package/urlpattern-polyfill) for older browsers
232
152
 
233
- The router dispatches the following events:
153
+ ## Contributing
234
154
 
235
- - `route-change`: Fired when the route changes (detail contains RouteInfo)
236
- - `route-progress`: Fired during navigation with progress value (0-1)
155
+ 1. Fork the repository
156
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
157
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
158
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
159
+ 5. Open a Pull Request
237
160
 
238
161
  ## License
239
162
 
240
- MIT
163
+ MIT License - see [LICENSE](LICENSE) file for details.