@koordinates/xstate-tree 4.2.0 → 4.3.0-beta.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/lib/routing/Link.js
CHANGED
|
@@ -8,13 +8,37 @@ import { useHref } from "./useHref";
|
|
|
8
8
|
* The query/params/meta props are conditionally required based on the
|
|
9
9
|
* route passed as the To parameter
|
|
10
10
|
*/
|
|
11
|
-
export function Link({ to, children, testId, ...rest }) {
|
|
11
|
+
export function Link({ to, children, testId, preloadOnHoverMs, preloadOnInteraction, onMouseDown: _onMouseDown, onMouseEnter: _onMouseEnter, onMouseLeave: _onMouseLeave, ...rest }) {
|
|
12
12
|
// @ts-ignore, these fields _might_ exist, so typechecking doesn't believe they exist
|
|
13
13
|
// and everything that consumes params/query already checks for undefined
|
|
14
14
|
const { params, query, meta, ...props } = rest;
|
|
15
|
+
let timeout;
|
|
15
16
|
const href = useHref(to, params, query);
|
|
16
|
-
|
|
17
|
+
const onMouseDown = preloadOnInteraction
|
|
18
|
+
? (e) => {
|
|
19
|
+
_onMouseDown === null || _onMouseDown === void 0 ? void 0 : _onMouseDown(e);
|
|
20
|
+
to.preload({ params, query, meta });
|
|
21
|
+
}
|
|
22
|
+
: undefined;
|
|
23
|
+
const onMouseEnter = preloadOnHoverMs !== undefined
|
|
24
|
+
? (e) => {
|
|
25
|
+
_onMouseEnter === null || _onMouseEnter === void 0 ? void 0 : _onMouseEnter(e);
|
|
26
|
+
timeout = setTimeout(() => {
|
|
27
|
+
to.preload({ params, query, meta });
|
|
28
|
+
}, preloadOnHoverMs);
|
|
29
|
+
}
|
|
30
|
+
: undefined;
|
|
31
|
+
const onMouseLeave = preloadOnHoverMs !== undefined
|
|
32
|
+
? (e) => {
|
|
33
|
+
_onMouseLeave === null || _onMouseLeave === void 0 ? void 0 : _onMouseLeave(e);
|
|
34
|
+
if (timeout !== undefined) {
|
|
35
|
+
clearTimeout(timeout);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
: undefined;
|
|
39
|
+
return (React.createElement("a", { ...props, href: href, "data-testid": testId, onMouseDown: onMouseDown !== null && onMouseDown !== void 0 ? onMouseDown : _onMouseDown, onMouseEnter: onMouseEnter !== null && onMouseEnter !== void 0 ? onMouseEnter : _onMouseEnter, onMouseLeave: onMouseLeave !== null && onMouseLeave !== void 0 ? onMouseLeave : _onMouseLeave, onClick: (e) => {
|
|
17
40
|
var _a;
|
|
41
|
+
e.preventDefault();
|
|
18
42
|
if (((_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, e)) === false) {
|
|
19
43
|
return;
|
|
20
44
|
}
|
|
@@ -23,7 +47,6 @@ export function Link({ to, children, testId, ...rest }) {
|
|
|
23
47
|
if (e.metaKey || e.ctrlKey) {
|
|
24
48
|
return;
|
|
25
49
|
}
|
|
26
|
-
e.preventDefault();
|
|
27
50
|
to.navigate({ params, query, meta });
|
|
28
51
|
} }, children));
|
|
29
52
|
}
|
|
@@ -66,7 +66,7 @@ export function buildCreateRoute(history, basePath) {
|
|
|
66
66
|
}
|
|
67
67
|
return parentRoutes;
|
|
68
68
|
}
|
|
69
|
-
return ({ event, matcher, reverser, paramsSchema, querySchema, redirect, }) => {
|
|
69
|
+
return ({ event, matcher, reverser, paramsSchema, querySchema, redirect, preload, }) => {
|
|
70
70
|
let fullParamsSchema = paramsSchema;
|
|
71
71
|
let parentRoute = baseRoute;
|
|
72
72
|
while (fullParamsSchema && parentRoute) {
|
|
@@ -156,6 +156,14 @@ export function buildCreateRoute(history, basePath) {
|
|
|
156
156
|
history: this.history(),
|
|
157
157
|
});
|
|
158
158
|
},
|
|
159
|
+
// @ts-ignore :cry:
|
|
160
|
+
preload(args) {
|
|
161
|
+
const parentRoutes = getParentArray();
|
|
162
|
+
parentRoutes.forEach((route) => {
|
|
163
|
+
route === null || route === void 0 ? void 0 : route.preload(args);
|
|
164
|
+
});
|
|
165
|
+
preload === null || preload === void 0 ? void 0 : preload(args);
|
|
166
|
+
},
|
|
159
167
|
};
|
|
160
168
|
};
|
|
161
169
|
},
|
|
@@ -24,9 +24,10 @@ export function handleLocationChange(routes, basePath, path, search, meta) {
|
|
|
24
24
|
const matchedEvent = match.event;
|
|
25
25
|
matchedEvent.meta = { ...(meta !== null && meta !== void 0 ? meta : {}) };
|
|
26
26
|
matchedEvent.meta.indexEvent = true;
|
|
27
|
-
const { params } = match.event;
|
|
27
|
+
const { params, query } = match.event;
|
|
28
28
|
const routingEvents = [];
|
|
29
29
|
let route = match.route;
|
|
30
|
+
route.preload({ params, query, meta: matchedEvent.meta });
|
|
30
31
|
while (route.parent) {
|
|
31
32
|
routingEvents.push(route.parent.getEvent({ params, query: {}, meta: { ...(meta !== null && meta !== void 0 ? meta : {}) } }));
|
|
32
33
|
route = route.parent;
|
package/lib/xstate-tree.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ export declare type AnyRoute = {
|
|
|
51
51
|
navigate: any;
|
|
52
52
|
getEvent: any;
|
|
53
53
|
event: string;
|
|
54
|
+
preload: any;
|
|
54
55
|
basePath: string;
|
|
55
56
|
history: () => XstateTreeHistory;
|
|
56
57
|
parent?: AnyRoute;
|
|
@@ -127,6 +128,7 @@ export declare function buildCreateRoute(history: () => XstateTreeHistory, baseP
|
|
|
127
128
|
querySchema?: TQuerySchema | undefined;
|
|
128
129
|
meta?: TMeta | undefined;
|
|
129
130
|
redirect?: RouteRedirect<MergeRouteTypes<RouteParams<TBaseRoute>, ResolveZodType<TParamsSchema>>, ResolveZodType<TQuerySchema>, MergeRouteTypes<RouteMeta<TBaseRoute>, TMeta> & SharedMeta> | undefined;
|
|
131
|
+
preload?: RouteArgumentFunctions<void, MergeRouteTypes<RouteParams<TBaseRoute>, ResolveZodType<TParamsSchema>>, ResolveZodType<TQuerySchema>, MergeRouteTypes<RouteMeta<TBaseRoute>, TMeta>, RouteArguments<MergeRouteTypes<RouteParams<TBaseRoute>, ResolveZodType<TParamsSchema>>, ResolveZodType<TQuerySchema>, MergeRouteTypes<RouteMeta<TBaseRoute>, TMeta>>> | undefined;
|
|
130
132
|
}) => Route<MergeRouteTypes<RouteParams<TBaseRoute>, ResolveZodType<TParamsSchema>>, ResolveZodType<TQuerySchema>, TEvent, MergeRouteTypes<RouteMeta<TBaseRoute>, TMeta> & SharedMeta>;
|
|
131
133
|
route<TBaseRoute_1 extends AnyRoute>(baseRoute?: TBaseRoute_1 | undefined): <TEvent_1 extends string, TParamsSchema_1 extends Z.ZodObject<any, "strip", Z.ZodTypeAny, {
|
|
132
134
|
[x: string]: any;
|
|
@@ -136,7 +138,7 @@ export declare function buildCreateRoute(history: () => XstateTreeHistory, baseP
|
|
|
136
138
|
[x: string]: any;
|
|
137
139
|
}, {
|
|
138
140
|
[x: string]: any;
|
|
139
|
-
}> | undefined, TMeta_1 extends Record<string, unknown>>({ event, matcher, reverser, paramsSchema, querySchema, redirect, }: {
|
|
141
|
+
}> | undefined, TMeta_1 extends Record<string, unknown>>({ event, matcher, reverser, paramsSchema, querySchema, redirect, preload, }: {
|
|
140
142
|
event: TEvent_1;
|
|
141
143
|
paramsSchema?: TParamsSchema_1 | undefined;
|
|
142
144
|
querySchema?: TQuerySchema_1 | undefined;
|
|
@@ -157,6 +159,7 @@ export declare function buildCreateRoute(history: () => XstateTreeHistory, baseP
|
|
|
157
159
|
* Supplied with params/query objects and constructs the correct URL based on them
|
|
158
160
|
*/
|
|
159
161
|
reverser: RouteArgumentFunctions<string, MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1>, RouteArguments<MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1>>>;
|
|
162
|
+
preload?: RouteArgumentFunctions<void, MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1>, RouteArguments<MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1>>> | undefined;
|
|
160
163
|
}) => Route<MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, TEvent_1, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1> & SharedMeta>;
|
|
161
164
|
};
|
|
162
165
|
|
|
@@ -352,7 +355,7 @@ export declare function lazy<TMachine extends AnyStateMachine>(factory: () => Pr
|
|
|
352
355
|
* The query/params/meta props are conditionally required based on the
|
|
353
356
|
* route passed as the To parameter
|
|
354
357
|
*/
|
|
355
|
-
export declare function Link<TRoute extends AnyRoute>({ to, children, testId, ...rest }: LinkProps<TRoute>): JSX.Element;
|
|
358
|
+
export declare function Link<TRoute extends AnyRoute>({ to, children, testId, preloadOnHoverMs, preloadOnInteraction, onMouseDown: _onMouseDown, onMouseEnter: _onMouseEnter, onMouseLeave: _onMouseLeave, ...rest }: LinkProps<TRoute>): JSX.Element;
|
|
356
359
|
|
|
357
360
|
/**
|
|
358
361
|
* @public
|
|
@@ -365,6 +368,8 @@ export declare type LinkProps<TRoute extends AnyRoute, TRouteParams = TRoute ext
|
|
|
365
368
|
* onClick works as normal, but if you return false from it the navigation will not happen
|
|
366
369
|
*/
|
|
367
370
|
onClick?: (e: React_2.MouseEvent<HTMLAnchorElement>) => boolean | void;
|
|
371
|
+
preloadOnInteraction?: boolean;
|
|
372
|
+
preloadOnHoverMs?: number;
|
|
368
373
|
} & RouteArguments<TRouteParams, TRouteQuery, TRouteMeta> & Omit<React_2.AnchorHTMLAttributes<HTMLAnchorElement>, "href" | "onClick">;
|
|
369
374
|
|
|
370
375
|
/**
|
|
@@ -524,6 +529,17 @@ export declare type Route<TParams, TQuery, TEvent, TMeta> = {
|
|
|
524
529
|
* url via History.push
|
|
525
530
|
*/
|
|
526
531
|
navigate: RouteArgumentFunctions<void, TParams, TQuery, TMeta>;
|
|
532
|
+
/**
|
|
533
|
+
* Preloads data required by the route. Passed in query/params/meta objects as required by the route
|
|
534
|
+
*
|
|
535
|
+
* Must be idempotent as it may be called multiple times
|
|
536
|
+
*
|
|
537
|
+
* Can be called on
|
|
538
|
+
* * Mouse down on a Link
|
|
539
|
+
* * Hovering on a Link
|
|
540
|
+
* * When a route is matched
|
|
541
|
+
*/
|
|
542
|
+
preload: RouteArgumentFunctions<void, TParams, TQuery, TMeta>;
|
|
527
543
|
/**
|
|
528
544
|
* Returns an event object for this route based on the supplied params/query/meta
|
|
529
545
|
*
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@koordinates/xstate-tree",
|
|
3
3
|
"main": "lib/index.js",
|
|
4
4
|
"types": "lib/xstate-tree.d.ts",
|
|
5
|
-
"version": "4.
|
|
5
|
+
"version": "4.3.0-beta.1",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"description": "Build UIs with Actors using xstate and React",
|
|
8
8
|
"keywords": [
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@testing-library/dom": "^8.14.0",
|
|
35
35
|
"@testing-library/jest-dom": "^5.16.1",
|
|
36
36
|
"@testing-library/react": "^13.4.0",
|
|
37
|
-
"@testing-library/user-event": "^
|
|
37
|
+
"@testing-library/user-event": "^14.4.3",
|
|
38
38
|
"@types/history": "^4.7.7",
|
|
39
39
|
"@types/jest": "^28.1.4",
|
|
40
40
|
"@types/react": "^17.0.29",
|