@tempots/ui 5.2.2 → 6.0.1
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/index.cjs +1 -1
- package/index.d.ts +1 -0
- package/index.js +753 -663
- package/package.json +1 -1
- package/renderables/router/router-context.d.ts +96 -0
- package/renderables/router/router.d.ts +58 -66
- package/renderables/size.d.ts +0 -9
package/package.json
CHANGED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Provider, Prop } from '@tempots/dom';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the context information for a router level in nested routing.
|
|
4
|
+
*
|
|
5
|
+
* Each router level (AppRouter or SubRouter) creates a RouterContext that contains
|
|
6
|
+
* information about the matched path, remaining path for child routers, and accumulated
|
|
7
|
+
* parameters from all parent router levels.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // For URL "/admin/users/123" with routes:
|
|
12
|
+
* // RootRouter: { '/admin/*': () => AdminRoutes() }
|
|
13
|
+
* // ChildRouter: { '/users/:id': (info) => UserDetail(info) }
|
|
14
|
+
*
|
|
15
|
+
* // RootRouter context:
|
|
16
|
+
* {
|
|
17
|
+
* matchedPath: '/admin',
|
|
18
|
+
* remainingPath: '/users/123',
|
|
19
|
+
* fullPath: '/admin/users/123',
|
|
20
|
+
* params: {}
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* // ChildRouter context:
|
|
24
|
+
* {
|
|
25
|
+
* matchedPath: '/users/123',
|
|
26
|
+
* remainingPath: '',
|
|
27
|
+
* fullPath: '/admin/users/123',
|
|
28
|
+
* params: { id: '123' }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
export interface RouterContext {
|
|
35
|
+
/**
|
|
36
|
+
* The portion of the path that was matched by this router level.
|
|
37
|
+
* For RootRouter, this is the matched portion of the full pathname.
|
|
38
|
+
* For ChildRouter, this is the matched portion of the remaining path from parent.
|
|
39
|
+
*/
|
|
40
|
+
readonly matchedPath: string;
|
|
41
|
+
/**
|
|
42
|
+
* The remaining path that should be processed by child routers.
|
|
43
|
+
* Empty string if no remaining path.
|
|
44
|
+
*/
|
|
45
|
+
readonly remainingPath: string;
|
|
46
|
+
/**
|
|
47
|
+
* The full original pathname from the browser location.
|
|
48
|
+
* This remains the same across all router levels.
|
|
49
|
+
*/
|
|
50
|
+
readonly fullPath: string;
|
|
51
|
+
/**
|
|
52
|
+
* Route parameters extracted at this router level.
|
|
53
|
+
* These are accumulated with parameters from parent router levels.
|
|
54
|
+
*/
|
|
55
|
+
readonly params: Record<string, string>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Provider for router context stack in nested routing scenarios.
|
|
59
|
+
*
|
|
60
|
+
* The RouterContextProvider maintains a stack of RouterContext objects,
|
|
61
|
+
* where each level represents a router in the nested hierarchy. Child
|
|
62
|
+
* routers can access the context stack to determine what path remains
|
|
63
|
+
* to be processed and what parameters have been accumulated from parent
|
|
64
|
+
* router levels.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* // RootRouter creates the initial context
|
|
69
|
+
* const RootRouter = <T extends Routes>(routes: T) =>
|
|
70
|
+
* Provide(
|
|
71
|
+
* RouterContextProvider,
|
|
72
|
+
* {},
|
|
73
|
+
* () => {
|
|
74
|
+
* // Router implementation that creates initial context
|
|
75
|
+
* return Use(Location, location => {
|
|
76
|
+
* // Match routes and create context...
|
|
77
|
+
* })
|
|
78
|
+
* }
|
|
79
|
+
* )
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* // ChildRouter reads parent context and adds its own
|
|
85
|
+
* const ChildRouter = <T extends Routes>(routes: T) =>
|
|
86
|
+
* Use(RouterContextProvider, contextStack => {
|
|
87
|
+
* const parentContext = contextStack.value[contextStack.value.length - 1]
|
|
88
|
+
* const remainingPath = parentContext?.remainingPath || ''
|
|
89
|
+
*
|
|
90
|
+
* // Match against remaining path and create new context...
|
|
91
|
+
* })
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @public
|
|
95
|
+
*/
|
|
96
|
+
export declare const RouterContextProvider: Provider<Prop<RouterContext[]>>;
|
|
@@ -1,100 +1,92 @@
|
|
|
1
1
|
import { TNode, Renderable, Signal } from '@tempots/dom';
|
|
2
2
|
import { ExtractParams, MakeParams, RouteInfo } from './route-info';
|
|
3
3
|
/**
|
|
4
|
-
* Creates
|
|
4
|
+
* Creates the root router for an application that provides routing context to child components.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* API and updates the UI when the URL changes.
|
|
6
|
+
* RootRouter is the top-level router that matches against the full browser pathname
|
|
7
|
+
* and creates the initial routing context. It provides the RouterContextProvider
|
|
8
|
+
* that child ChildRouter components can use for nested routing scenarios.
|
|
10
9
|
*
|
|
11
10
|
* @example
|
|
12
11
|
* ```typescript
|
|
13
|
-
* // Basic routing
|
|
14
|
-
* const
|
|
12
|
+
* // Basic app routing
|
|
13
|
+
* const App = RootRouter({
|
|
15
14
|
* '/': () => html.div('Home Page'),
|
|
16
15
|
* '/about': () => html.div('About Page'),
|
|
17
|
-
* '/
|
|
16
|
+
* '/admin/*': () => AdminSection(), // Passes remaining path to AdminSection
|
|
18
17
|
* '*': () => html.div('404 - Page Not Found')
|
|
19
18
|
* })
|
|
20
19
|
*
|
|
21
|
-
* render(
|
|
20
|
+
* render(App, document.body)
|
|
22
21
|
* ```
|
|
23
22
|
*
|
|
24
23
|
* @example
|
|
25
24
|
* ```typescript
|
|
26
|
-
* //
|
|
27
|
-
* const
|
|
28
|
-
* '/': () => html.div('
|
|
29
|
-
* '/
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* '/
|
|
37
|
-
* const userId = info.$.params.$.userId
|
|
38
|
-
* const postId = info.$.params.$.postId
|
|
39
|
-
* return html.div(
|
|
40
|
-
* html.h1('User ', userId, ' - Post ', postId),
|
|
41
|
-
* UserPost({ userId, postId })
|
|
42
|
-
* )
|
|
43
|
-
* },
|
|
44
|
-
* '*': () => html.div('Page not found')
|
|
25
|
+
* // Nested routing with RootRouter and ChildRouter
|
|
26
|
+
* const App = RootRouter({
|
|
27
|
+
* '/': () => html.div('Home'),
|
|
28
|
+
* '/admin/*': () => AdminRoutes(),
|
|
29
|
+
* '/blog/*': () => BlogRoutes()
|
|
30
|
+
* })
|
|
31
|
+
*
|
|
32
|
+
* const AdminRoutes = ChildRouter({
|
|
33
|
+
* '/users': () => html.div('User List'),
|
|
34
|
+
* '/users/:id': (info) => html.div('User: ', info.$.params.$.id),
|
|
35
|
+
* '/settings': () => html.div('Admin Settings')
|
|
45
36
|
* })
|
|
46
37
|
* ```
|
|
47
38
|
*
|
|
39
|
+
* @template T - The type of the routes configuration object
|
|
40
|
+
* @param routes - Object mapping route patterns to handler functions
|
|
41
|
+
* @returns A renderable router component that handles URL routing and provides context
|
|
42
|
+
* @throws {Error} When no matching route is found for the current URL
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export declare const RootRouter: <T extends { [K in keyof T]: (info: K extends string ? Signal<RouteInfo<MakeParams<ExtractParams<K>>, K>> : never) => TNode; }>(routes: T) => Renderable;
|
|
46
|
+
/**
|
|
47
|
+
* Creates a nested router that matches against the remaining path from parent routers.
|
|
48
|
+
*
|
|
49
|
+
* ChildRouter is used for nested routing scenarios where a parent router (RootRouter or
|
|
50
|
+
* another ChildRouter) has matched a portion of the path and passed the remaining path
|
|
51
|
+
* to child components. ChildRouter reads the parent routing context and matches its
|
|
52
|
+
* routes against the remaining path.
|
|
53
|
+
*
|
|
48
54
|
* @example
|
|
49
55
|
* ```typescript
|
|
50
|
-
* //
|
|
51
|
-
* const
|
|
52
|
-
* '/
|
|
53
|
-
* '/
|
|
54
|
-
*
|
|
55
|
-
* const searchParams = info.$.search
|
|
56
|
+
* // Parent RootRouter passes remaining path to AdminRoutes
|
|
57
|
+
* const App = RootRouter({
|
|
58
|
+
* '/admin/*': () => AdminRoutes(),
|
|
59
|
+
* '/blog/*': () => BlogRoutes()
|
|
60
|
+
* })
|
|
56
61
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* })
|
|
64
|
-
* )
|
|
65
|
-
* },
|
|
66
|
-
* '/products/:id/reviews': (info) => {
|
|
67
|
-
* const productId = info.$.params.$.id
|
|
68
|
-
* return ProductReviews({ productId })
|
|
69
|
-
* }
|
|
62
|
+
* // ChildRouter matches against remaining path
|
|
63
|
+
* const AdminRoutes = ChildRouter({
|
|
64
|
+
* '/users': () => html.div('User List'),
|
|
65
|
+
* '/users/:id': (info) => html.div('User: ', info.$.params.$.id),
|
|
66
|
+
* '/settings': () => html.div('Admin Settings'),
|
|
67
|
+
* '*': () => html.div('Admin 404')
|
|
70
68
|
* })
|
|
71
69
|
* ```
|
|
72
70
|
*
|
|
73
71
|
* @example
|
|
74
72
|
* ```typescript
|
|
75
|
-
* //
|
|
76
|
-
*
|
|
73
|
+
* // Multiple levels of nesting
|
|
74
|
+
* const BlogRoutes = ChildRouter({
|
|
75
|
+
* '/posts/*': () => PostRoutes(),
|
|
76
|
+
* '/categories': () => html.div('Categories')
|
|
77
|
+
* })
|
|
77
78
|
*
|
|
78
|
-
* const
|
|
79
|
-
* html.
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* html.button(
|
|
84
|
-
* on.click(() => Location.navigate('/about')),
|
|
85
|
-
* 'About'
|
|
86
|
-
* ),
|
|
87
|
-
* html.button(
|
|
88
|
-
* on.click(() => Location.navigate('/products/123')),
|
|
89
|
-
* 'Product 123'
|
|
90
|
-
* )
|
|
91
|
-
* )
|
|
79
|
+
* const PostRoutes = ChildRouter({
|
|
80
|
+
* '/': () => html.div('All Posts'),
|
|
81
|
+
* '/:id': (info) => html.div('Post: ', info.$.params.$.id),
|
|
82
|
+
* '/:id/comments': (info) => html.div('Comments for: ', info.$.params.$.id)
|
|
83
|
+
* })
|
|
92
84
|
* ```
|
|
93
85
|
*
|
|
94
86
|
* @template T - The type of the routes configuration object
|
|
95
87
|
* @param routes - Object mapping route patterns to handler functions
|
|
96
|
-
* @returns A renderable router component that handles URL routing
|
|
97
|
-
* @throws {Error} When no matching route is found for the
|
|
88
|
+
* @returns A renderable router component that handles nested URL routing
|
|
89
|
+
* @throws {Error} When no matching route is found for the remaining path
|
|
98
90
|
* @public
|
|
99
91
|
*/
|
|
100
|
-
export declare const
|
|
92
|
+
export declare const ChildRouter: <T extends { [K in keyof T]: (info: K extends string ? Signal<RouteInfo<MakeParams<ExtractParams<K>>, K>> : never) => TNode; }>(routes: T) => Renderable;
|
package/renderables/size.d.ts
CHANGED
|
@@ -204,15 +204,6 @@ export declare function getAbsoluteRect(el: Element): Rect;
|
|
|
204
204
|
* @public
|
|
205
205
|
*/
|
|
206
206
|
export declare const ElementRect: (fn: (rect: Signal<Rect>) => TNode) => import('@tempots/dom').Renderable;
|
|
207
|
-
/**
|
|
208
|
-
* Creates a renderable function that monitors the size of an element and provides it as a signal.
|
|
209
|
-
*
|
|
210
|
-
* @param fn - The renderable function that receives the size signal and returns a TNode.
|
|
211
|
-
* @returns A function that takes a DOMContext and returns a renderable function.
|
|
212
|
-
* @deprecated use ElementRect instead
|
|
213
|
-
* @public
|
|
214
|
-
*/
|
|
215
|
-
export declare const ElementSize: (fn: (size: Signal<Rect>) => TNode) => import('@tempots/dom').Renderable;
|
|
216
207
|
/**
|
|
217
208
|
* Creates a renderable function that monitors the window size and invokes the provided function with the current size.
|
|
218
209
|
* @param fn - The function to be invoked with the current window size.
|