@finsweet/webflow-apps-utils 1.0.4 → 1.0.5
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/dist/providers/GlobalProvider.stories.d.ts +5 -0
- package/dist/providers/GlobalProvider.stories.js +419 -0
- package/dist/providers/GlobalProviderDemo.svelte +266 -0
- package/dist/providers/GlobalProviderDemo.svelte.d.ts +3 -0
- package/dist/providers/configuratorUtils.d.ts +11 -14
- package/dist/providers/configuratorUtils.js +68 -115
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +1 -1
- package/dist/router/Router.stories.js +519 -2
- package/dist/stores/forms/Form.stories.d.ts +5 -0
- package/dist/stores/forms/Form.stories.js +342 -0
- package/dist/stores/forms/FormDemo.svelte +545 -0
- package/dist/stores/forms/FormDemo.svelte.d.ts +18 -0
- package/dist/ui/components/button/Button.svelte +1 -1
- package/dist/ui/components/copy-text/CopyText.stories.js +1 -1
- package/dist/ui/components/copy-text/CopyText.svelte +17 -19
- package/dist/ui/components/layout/Layout.svelte +38 -5
- package/dist/ui/components/layout/Layout.svelte.d.ts +24 -1
- package/dist/ui/components/layout/examples/ExampleLayout.svelte +12 -12
- package/dist/ui/components/section/Section.svelte +4 -2
- package/dist/ui/index.css +6 -2
- package/dist/utils/diff-mapper/DiffMapper.stories.d.ts +5 -0
- package/dist/utils/diff-mapper/DiffMapper.stories.js +185 -0
- package/dist/utils/diff-mapper/DiffMapperDemo.svelte +351 -0
- package/dist/utils/diff-mapper/DiffMapperDemo.svelte.d.ts +18 -0
- package/dist/utils/diff-mapper/deepDiffMapper.d.ts +31 -0
- package/dist/utils/diff-mapper/deepDiffMapper.js +264 -0
- package/dist/utils/diff-mapper/index.d.ts +1 -0
- package/dist/utils/diff-mapper/index.js +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/package.json +1 -1
- package/dist/providers/GlobalProvider.mdx +0 -322
- package/dist/router/Router.mdx +0 -958
- package/dist/stores/docs/Form.mdx +0 -542
|
@@ -1,9 +1,526 @@
|
|
|
1
1
|
import RouterExample from './examples/RouterExample.svelte';
|
|
2
2
|
const meta = {
|
|
3
|
-
title: '
|
|
3
|
+
title: 'Utils/Router',
|
|
4
4
|
component: RouterExample,
|
|
5
5
|
parameters: {
|
|
6
|
-
layout: 'fullscreen'
|
|
6
|
+
layout: 'fullscreen',
|
|
7
|
+
docs: {
|
|
8
|
+
description: {
|
|
9
|
+
component: `
|
|
10
|
+
# Router API Documentation
|
|
11
|
+
|
|
12
|
+
A comprehensive client-side router for Svelte 5 applications with support for reactive state management, dynamic routing, and app version persistence.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
\`\`\`typescript
|
|
17
|
+
import {
|
|
18
|
+
createRouter,
|
|
19
|
+
RouterProvider,
|
|
20
|
+
Route,
|
|
21
|
+
Link,
|
|
22
|
+
useRouter,
|
|
23
|
+
useLocation,
|
|
24
|
+
useNavigate
|
|
25
|
+
} from '@finsweet/webflow-apps-utils';
|
|
26
|
+
\`\`\`
|
|
27
|
+
|
|
28
|
+
## Core Classes
|
|
29
|
+
|
|
30
|
+
### Router
|
|
31
|
+
|
|
32
|
+
The main router class that handles navigation, route matching, and state management.
|
|
33
|
+
|
|
34
|
+
#### Constructor
|
|
35
|
+
|
|
36
|
+
\`\`\`typescript
|
|
37
|
+
new Router(config?: RouterConfig)
|
|
38
|
+
\`\`\`
|
|
39
|
+
|
|
40
|
+
#### Configuration Options
|
|
41
|
+
|
|
42
|
+
\`\`\`typescript
|
|
43
|
+
interface RouterConfig {
|
|
44
|
+
basePath?: string; // Base path for all routes (default: '')
|
|
45
|
+
hashMode?: boolean; // Use hash-based routing (default: false)
|
|
46
|
+
fallbackRoute?: string; // Fallback route when no match (default: '/')
|
|
47
|
+
autoInit?: boolean; // Auto-initialize on creation (default: true)
|
|
48
|
+
}
|
|
49
|
+
\`\`\`
|
|
50
|
+
|
|
51
|
+
#### Methods
|
|
52
|
+
|
|
53
|
+
##### Navigation Methods
|
|
54
|
+
|
|
55
|
+
\`\`\`typescript
|
|
56
|
+
// Navigate to a path
|
|
57
|
+
navigate(pathname: string, options?: { replace?: boolean; state?: any }): void
|
|
58
|
+
|
|
59
|
+
// Navigate back in history
|
|
60
|
+
back(): void
|
|
61
|
+
|
|
62
|
+
// Navigate forward in history
|
|
63
|
+
forward(): void
|
|
64
|
+
|
|
65
|
+
// Navigate to root path
|
|
66
|
+
gotoRootPath(): void
|
|
67
|
+
\`\`\`
|
|
68
|
+
|
|
69
|
+
##### Route Management
|
|
70
|
+
|
|
71
|
+
\`\`\`typescript
|
|
72
|
+
// Add a single route
|
|
73
|
+
addRoute(route: RouteConfig): void
|
|
74
|
+
|
|
75
|
+
// Add multiple routes
|
|
76
|
+
addRoutes(routes: RouteConfig[]): void
|
|
77
|
+
\`\`\`
|
|
78
|
+
|
|
79
|
+
##### State Access Methods
|
|
80
|
+
|
|
81
|
+
\`\`\`typescript
|
|
82
|
+
// Get reactive location information
|
|
83
|
+
useLocation(): LocationInfo
|
|
84
|
+
|
|
85
|
+
// Get reactive current route
|
|
86
|
+
useRoute(): RouteConfig | null
|
|
87
|
+
|
|
88
|
+
// Get reactive navigation state
|
|
89
|
+
useNavigating(): boolean
|
|
90
|
+
|
|
91
|
+
// Get reactive navigation history
|
|
92
|
+
useHistory(): HistoryEntry[]
|
|
93
|
+
|
|
94
|
+
// Check if path is active
|
|
95
|
+
isActive(path: string, exact?: boolean): boolean
|
|
96
|
+
|
|
97
|
+
// Get current route parameters
|
|
98
|
+
getParams(): RouteParams
|
|
99
|
+
|
|
100
|
+
// Get current query parameters
|
|
101
|
+
getQuery(): URLSearchParams
|
|
102
|
+
\`\`\`
|
|
103
|
+
|
|
104
|
+
##### App Version Methods
|
|
105
|
+
|
|
106
|
+
\`\`\`typescript
|
|
107
|
+
// Initialize app version path persistence
|
|
108
|
+
initAppVersion(appVersionPath: string): void
|
|
109
|
+
|
|
110
|
+
// Get current app version path
|
|
111
|
+
getAppVersionPath(): string
|
|
112
|
+
|
|
113
|
+
// Get full pathname including app version
|
|
114
|
+
getFullPathname(): string
|
|
115
|
+
|
|
116
|
+
// Get active path with app version
|
|
117
|
+
getActivePath(): string
|
|
118
|
+
\`\`\`
|
|
119
|
+
|
|
120
|
+
### createRouter()
|
|
121
|
+
|
|
122
|
+
Factory function to create a new router instance.
|
|
123
|
+
|
|
124
|
+
\`\`\`typescript
|
|
125
|
+
function createRouter(config?: RouterConfig): Router;
|
|
126
|
+
\`\`\`
|
|
127
|
+
|
|
128
|
+
## Components
|
|
129
|
+
|
|
130
|
+
### RouterProvider
|
|
131
|
+
|
|
132
|
+
Root component that provides router context to child components and manages router lifecycle.
|
|
133
|
+
|
|
134
|
+
\`\`\`typescript
|
|
135
|
+
interface RouterProviderProps {
|
|
136
|
+
router: Router; // Router instance
|
|
137
|
+
autoInit?: boolean; // Auto-initialize router (default: true)
|
|
138
|
+
loading?: boolean; // Show loading screen
|
|
139
|
+
loadingMessage?: string; // Loading message text
|
|
140
|
+
children?: Snippet<[RouterContext]>; // Children with router context
|
|
141
|
+
}
|
|
142
|
+
\`\`\`
|
|
143
|
+
|
|
144
|
+
### Route
|
|
145
|
+
|
|
146
|
+
Component for defining and rendering routes based on path patterns.
|
|
147
|
+
|
|
148
|
+
\`\`\`typescript
|
|
149
|
+
interface RouteProps {
|
|
150
|
+
path: string; // Path pattern (supports :params)
|
|
151
|
+
component?: any; // Component to render when active
|
|
152
|
+
meta?: Record<string, any>; // Route metadata
|
|
153
|
+
exact?: boolean; // Exact path matching (default: true)
|
|
154
|
+
children?: Snippet<[RouteContext]>; // Children with route context
|
|
155
|
+
}
|
|
156
|
+
\`\`\`
|
|
157
|
+
|
|
158
|
+
### Link
|
|
159
|
+
|
|
160
|
+
Navigation component that generates proper links with active state management.
|
|
161
|
+
|
|
162
|
+
\`\`\`typescript
|
|
163
|
+
interface LinkProps {
|
|
164
|
+
to: string; // Target path
|
|
165
|
+
replace?: boolean; // Replace history entry (default: false)
|
|
166
|
+
activeClass?: string; // CSS class when active
|
|
167
|
+
exact?: boolean; // Exact matching for active state
|
|
168
|
+
disabled?: boolean; // Disable the link
|
|
169
|
+
class?: string; // Additional CSS classes
|
|
170
|
+
state?: any; // State to pass with navigation
|
|
171
|
+
element?: 'a' | 'button'; // HTML element type (default: 'a')
|
|
172
|
+
children?: Snippet; // Link content
|
|
173
|
+
onclick?: (event: MouseEvent) => void; // Click handler
|
|
174
|
+
}
|
|
175
|
+
\`\`\`
|
|
176
|
+
|
|
177
|
+
## Hooks
|
|
178
|
+
|
|
179
|
+
### useRouter()
|
|
180
|
+
|
|
181
|
+
Get the router instance from context.
|
|
182
|
+
|
|
183
|
+
\`\`\`typescript
|
|
184
|
+
function useRouter(): Router;
|
|
185
|
+
\`\`\`
|
|
186
|
+
|
|
187
|
+
### useLocation()
|
|
188
|
+
|
|
189
|
+
Get reactive location information.
|
|
190
|
+
|
|
191
|
+
\`\`\`typescript
|
|
192
|
+
function useLocation(): LocationInfo;
|
|
193
|
+
\`\`\`
|
|
194
|
+
|
|
195
|
+
### useRoute()
|
|
196
|
+
|
|
197
|
+
Get reactive current route information.
|
|
198
|
+
|
|
199
|
+
\`\`\`typescript
|
|
200
|
+
function useRoute(): RouteConfig | null;
|
|
201
|
+
\`\`\`
|
|
202
|
+
|
|
203
|
+
### useParams()
|
|
204
|
+
|
|
205
|
+
Get reactive route parameters.
|
|
206
|
+
|
|
207
|
+
\`\`\`typescript
|
|
208
|
+
function useParams(): RouteParams;
|
|
209
|
+
\`\`\`
|
|
210
|
+
|
|
211
|
+
### useQuery()
|
|
212
|
+
|
|
213
|
+
Get reactive query parameters.
|
|
214
|
+
|
|
215
|
+
\`\`\`typescript
|
|
216
|
+
function useQuery(): URLSearchParams;
|
|
217
|
+
\`\`\`
|
|
218
|
+
|
|
219
|
+
### useNavigate()
|
|
220
|
+
|
|
221
|
+
Get a navigation function.
|
|
222
|
+
|
|
223
|
+
\`\`\`typescript
|
|
224
|
+
function useNavigate(): (pathname: string, options?: NavigateOptions) => void;
|
|
225
|
+
|
|
226
|
+
interface NavigateOptions {
|
|
227
|
+
replace?: boolean;
|
|
228
|
+
state?: any;
|
|
229
|
+
}
|
|
230
|
+
\`\`\`
|
|
231
|
+
|
|
232
|
+
### useNavigating()
|
|
233
|
+
|
|
234
|
+
Get reactive navigation state.
|
|
235
|
+
|
|
236
|
+
\`\`\`typescript
|
|
237
|
+
function useNavigating(): boolean;
|
|
238
|
+
\`\`\`
|
|
239
|
+
|
|
240
|
+
### useHistory()
|
|
241
|
+
|
|
242
|
+
Get reactive navigation history.
|
|
243
|
+
|
|
244
|
+
\`\`\`typescript
|
|
245
|
+
function useHistory(): HistoryEntry[];
|
|
246
|
+
\`\`\`
|
|
247
|
+
|
|
248
|
+
### useIsActiveRoute()
|
|
249
|
+
|
|
250
|
+
Get a function to check if routes are active.
|
|
251
|
+
|
|
252
|
+
\`\`\`typescript
|
|
253
|
+
function useIsActiveRoute(): (path: string, exact?: boolean) => boolean;
|
|
254
|
+
\`\`\`
|
|
255
|
+
|
|
256
|
+
### useRouteWatcher()
|
|
257
|
+
|
|
258
|
+
Watch for route changes and execute callbacks.
|
|
259
|
+
|
|
260
|
+
\`\`\`typescript
|
|
261
|
+
function useRouteWatcher(
|
|
262
|
+
callback: (location: LocationInfo, route: RouteConfig | null) => void,
|
|
263
|
+
immediate?: boolean
|
|
264
|
+
): void;
|
|
265
|
+
\`\`\`
|
|
266
|
+
|
|
267
|
+
### useSearchParams()
|
|
268
|
+
|
|
269
|
+
Get search params helper with reactive updates.
|
|
270
|
+
|
|
271
|
+
\`\`\`typescript
|
|
272
|
+
function useSearchParams(): SearchParamsHelper;
|
|
273
|
+
|
|
274
|
+
interface SearchParamsHelper {
|
|
275
|
+
get(key: string): string | null;
|
|
276
|
+
set(key: string, value: string): void;
|
|
277
|
+
delete(key: string): void;
|
|
278
|
+
has(key: string): boolean;
|
|
279
|
+
toString(): string;
|
|
280
|
+
getAll(): Record<string, string>;
|
|
281
|
+
}
|
|
282
|
+
\`\`\`
|
|
283
|
+
|
|
284
|
+
### useAppVersion()
|
|
285
|
+
|
|
286
|
+
Get the current app version path.
|
|
287
|
+
|
|
288
|
+
\`\`\`typescript
|
|
289
|
+
function useAppVersion(): string;
|
|
290
|
+
\`\`\`
|
|
291
|
+
|
|
292
|
+
### useFullPathname()
|
|
293
|
+
|
|
294
|
+
Get the full pathname including app version.
|
|
295
|
+
|
|
296
|
+
\`\`\`typescript
|
|
297
|
+
function useFullPathname(): string;
|
|
298
|
+
\`\`\`
|
|
299
|
+
|
|
300
|
+
## Interfaces
|
|
301
|
+
|
|
302
|
+
### RouteConfig
|
|
303
|
+
|
|
304
|
+
\`\`\`typescript
|
|
305
|
+
interface RouteConfig {
|
|
306
|
+
path: string; // Path pattern ('/users/:id')
|
|
307
|
+
component?: any; // Svelte component
|
|
308
|
+
meta?: Record<string, any>; // Route metadata
|
|
309
|
+
}
|
|
310
|
+
\`\`\`
|
|
311
|
+
|
|
312
|
+
### LocationInfo
|
|
313
|
+
|
|
314
|
+
\`\`\`typescript
|
|
315
|
+
interface LocationInfo {
|
|
316
|
+
pathname: string; // Current pathname
|
|
317
|
+
search: string; // Query string
|
|
318
|
+
hash: string; // URL hash
|
|
319
|
+
url: URL; // Complete URL object
|
|
320
|
+
params: RouteParams; // Route parameters
|
|
321
|
+
query: URLSearchParams; // Query parameters object
|
|
322
|
+
}
|
|
323
|
+
\`\`\`
|
|
324
|
+
|
|
325
|
+
### RouteParams
|
|
326
|
+
|
|
327
|
+
\`\`\`typescript
|
|
328
|
+
interface RouteParams {
|
|
329
|
+
[key: string]: string; // Parameter name to value mapping
|
|
330
|
+
}
|
|
331
|
+
\`\`\`
|
|
332
|
+
|
|
333
|
+
### HistoryEntry
|
|
334
|
+
|
|
335
|
+
\`\`\`typescript
|
|
336
|
+
interface HistoryEntry {
|
|
337
|
+
pathname: string; // Path of history entry
|
|
338
|
+
timestamp: number; // Entry creation time
|
|
339
|
+
state?: any; // Optional state data
|
|
340
|
+
}
|
|
341
|
+
\`\`\`
|
|
342
|
+
|
|
343
|
+
## Usage Examples
|
|
344
|
+
|
|
345
|
+
### Complete Application Setup
|
|
346
|
+
|
|
347
|
+
\`\`\`typescript
|
|
348
|
+
<!-- App.svelte -->
|
|
349
|
+
<script lang="ts">
|
|
350
|
+
import { onMount } from 'svelte';
|
|
351
|
+
import { createRouter, RouterProvider, Route, Link } from '@finsweet/webflow-apps-utils';
|
|
352
|
+
|
|
353
|
+
// Import page components
|
|
354
|
+
import HomePage from './pages/HomePage.svelte';
|
|
355
|
+
import AboutPage from './pages/AboutPage.svelte';
|
|
356
|
+
import UserPage from './pages/UserPage.svelte';
|
|
357
|
+
import NotFoundPage from './pages/NotFoundPage.svelte';
|
|
358
|
+
|
|
359
|
+
// Create router with configuration
|
|
360
|
+
const router = createRouter({
|
|
361
|
+
basePath: '',
|
|
362
|
+
fallbackRoute: '/'
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
// Define routes
|
|
366
|
+
router.addRoutes([
|
|
367
|
+
{ path: '/', component: HomePage, meta: { title: 'Home' } },
|
|
368
|
+
{ path: '/about', component: AboutPage, meta: { title: 'About' } },
|
|
369
|
+
{ path: '/users/:id', component: UserPage, meta: { title: 'User Profile' } },
|
|
370
|
+
{ path: '*', component: NotFoundPage, meta: { title: 'Not Found' } }
|
|
371
|
+
]);
|
|
372
|
+
|
|
373
|
+
onMount(() => {
|
|
374
|
+
// Initialize app version if needed
|
|
375
|
+
router.initAppVersion('/v1');
|
|
376
|
+
});
|
|
377
|
+
</script>
|
|
378
|
+
|
|
379
|
+
<RouterProvider {router}>
|
|
380
|
+
{#snippet children({ router, currentRoute, isNavigating })}
|
|
381
|
+
<div class="app">
|
|
382
|
+
<!-- Navigation -->
|
|
383
|
+
<nav class="navbar">
|
|
384
|
+
<div class="nav-brand">
|
|
385
|
+
<Link to="/">My App</Link>
|
|
386
|
+
</div>
|
|
387
|
+
<ul class="nav-links">
|
|
388
|
+
<li><Link to="/" exact activeClass="active">Home</Link></li>
|
|
389
|
+
<li><Link to="/about" activeClass="active">About</Link></li>
|
|
390
|
+
<li><Link to="/users/123" activeClass="active">Profile</Link></li>
|
|
391
|
+
</ul>
|
|
392
|
+
</nav>
|
|
393
|
+
|
|
394
|
+
<!-- Loading indicator -->
|
|
395
|
+
{#if isNavigating}
|
|
396
|
+
<div class="loading-bar"></div>
|
|
397
|
+
{/if}
|
|
398
|
+
|
|
399
|
+
<!-- Page title -->
|
|
400
|
+
<title>{currentRoute?.meta?.title || 'My App'}</title>
|
|
401
|
+
|
|
402
|
+
<!-- Main content -->
|
|
403
|
+
<main class="main-content">
|
|
404
|
+
<!-- Routes -->
|
|
405
|
+
<Route path="/" component={HomePage} />
|
|
406
|
+
<Route path="/about" component={AboutPage} />
|
|
407
|
+
<Route path="/users/:id">
|
|
408
|
+
{#snippet children({ params, isActive })}
|
|
409
|
+
{#if isActive}
|
|
410
|
+
<UserPage userId={params.id} />
|
|
411
|
+
{/if}
|
|
412
|
+
{/snippet}
|
|
413
|
+
</Route>
|
|
414
|
+
<Route path="*" exact={false} component={NotFoundPage} />
|
|
415
|
+
</main>
|
|
416
|
+
</div>
|
|
417
|
+
{/snippet}
|
|
418
|
+
</RouterProvider>
|
|
419
|
+
\`\`\`
|
|
420
|
+
|
|
421
|
+
### Using Hooks in Components
|
|
422
|
+
|
|
423
|
+
\`\`\`typescript
|
|
424
|
+
<!-- UserProfile.svelte -->
|
|
425
|
+
<script lang="ts">
|
|
426
|
+
import { useParams, useNavigate, useSearchParams } from '@finsweet/webflow-apps-utils';
|
|
427
|
+
|
|
428
|
+
const params = useParams();
|
|
429
|
+
const navigate = useNavigate();
|
|
430
|
+
const searchParams = useSearchParams();
|
|
431
|
+
|
|
432
|
+
// Reactive values
|
|
433
|
+
$: userId = params.id;
|
|
434
|
+
$: tab = searchParams.get('tab') || 'profile';
|
|
435
|
+
|
|
436
|
+
function switchTab(newTab: string) {
|
|
437
|
+
searchParams.set('tab', newTab);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function goBack() {
|
|
441
|
+
navigate('/users');
|
|
442
|
+
}
|
|
443
|
+
</script>
|
|
444
|
+
|
|
445
|
+
<div class="user-profile">
|
|
446
|
+
<header>
|
|
447
|
+
<button onclick={goBack}>← Back to Users</button>
|
|
448
|
+
<h1>User Profile: {userId}</h1>
|
|
449
|
+
</header>
|
|
450
|
+
|
|
451
|
+
<nav class="tabs">
|
|
452
|
+
<button
|
|
453
|
+
class:active={tab === 'profile'}
|
|
454
|
+
onclick={() => switchTab('profile')}
|
|
455
|
+
>
|
|
456
|
+
Profile
|
|
457
|
+
</button>
|
|
458
|
+
<button
|
|
459
|
+
class:active={tab === 'settings'}
|
|
460
|
+
onclick={() => switchTab('settings')}
|
|
461
|
+
>
|
|
462
|
+
Settings
|
|
463
|
+
</button>
|
|
464
|
+
</nav>
|
|
465
|
+
|
|
466
|
+
<main>
|
|
467
|
+
{#if tab === 'profile'}
|
|
468
|
+
<div>Profile content for user {userId}</div>
|
|
469
|
+
{:else if tab === 'settings'}
|
|
470
|
+
<div>Settings for user {userId}</div>
|
|
471
|
+
{/if}
|
|
472
|
+
</main>
|
|
473
|
+
</div>
|
|
474
|
+
\`\`\`
|
|
475
|
+
|
|
476
|
+
### Programmatic Navigation
|
|
477
|
+
|
|
478
|
+
\`\`\`typescript
|
|
479
|
+
<script lang="ts">
|
|
480
|
+
import { useRouter, useNavigate, useLocation } from '@finsweet/webflow-apps-utils';
|
|
481
|
+
|
|
482
|
+
const router = useRouter();
|
|
483
|
+
const navigate = useNavigate();
|
|
484
|
+
const location = useLocation();
|
|
485
|
+
|
|
486
|
+
async function handleLogin(userData: any) {
|
|
487
|
+
// Simulate login
|
|
488
|
+
await loginUser(userData);
|
|
489
|
+
|
|
490
|
+
// Navigate to dashboard after login
|
|
491
|
+
navigate('/dashboard', {
|
|
492
|
+
replace: true,
|
|
493
|
+
state: { loginTime: Date.now() }
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
function handleLogout() {
|
|
498
|
+
// Clear user data
|
|
499
|
+
clearUserSession();
|
|
500
|
+
|
|
501
|
+
// Navigate to home and replace history
|
|
502
|
+
router.navigate('/', { replace: true });
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function goToUserProfile(userId: string) {
|
|
506
|
+
navigate(\`/users/\${userId}?tab=profile\`);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
function navigateWithState() {
|
|
510
|
+
navigate('/results', {
|
|
511
|
+
state: {
|
|
512
|
+
searchQuery: 'example',
|
|
513
|
+
timestamp: Date.now()
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
</script>
|
|
518
|
+
\`\`\`
|
|
519
|
+
|
|
520
|
+
Explore the complete router implementation in the interactive demo below!
|
|
521
|
+
`
|
|
522
|
+
}
|
|
523
|
+
}
|
|
7
524
|
},
|
|
8
525
|
tags: ['autodocs'],
|
|
9
526
|
argTypes: {}
|