@esmx/router 3.0.0-rc.60 → 3.0.0-rc.62
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/router-link.mjs +28 -20
- package/dist/router.d.ts +1 -1
- package/dist/router.mjs +1 -1
- package/dist/types.d.ts +11 -4
- package/package.json +2 -2
- package/src/router-link.ts +36 -36
- package/src/router.ts +1 -1
- package/src/types.ts +13 -9
package/dist/router-link.mjs
CHANGED
|
@@ -17,15 +17,14 @@ function getEventTypeList(eventType) {
|
|
|
17
17
|
const validEvents = events.filter((type) => typeof type === "string").map((type) => type.trim()).filter(Boolean);
|
|
18
18
|
return validEvents.length ? validEvents : ["click"];
|
|
19
19
|
}
|
|
20
|
-
function
|
|
21
|
-
var _a
|
|
22
|
-
if (
|
|
23
|
-
if (e
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (e.preventDefault) e.preventDefault();
|
|
20
|
+
function shouldHandleNavigation(e) {
|
|
21
|
+
var _a;
|
|
22
|
+
if (e.defaultPrevented) return false;
|
|
23
|
+
if (e instanceof MouseEvent) {
|
|
24
|
+
if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return false;
|
|
25
|
+
if (e.button !== void 0 && e.button !== 0) return false;
|
|
26
|
+
}
|
|
27
|
+
(_a = e.preventDefault) == null ? void 0 : _a.call(e);
|
|
29
28
|
return true;
|
|
30
29
|
}
|
|
31
30
|
async function executeNavigation(router, props, linkType) {
|
|
@@ -54,10 +53,9 @@ async function executeNavigation(router, props, linkType) {
|
|
|
54
53
|
}
|
|
55
54
|
function createNavigateFunction(router, props, navigationType) {
|
|
56
55
|
return async (e) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
await executeNavigation(router, props, navigationType);
|
|
56
|
+
if (shouldHandleNavigation(e)) {
|
|
57
|
+
await executeNavigation(router, props, navigationType);
|
|
58
|
+
}
|
|
61
59
|
};
|
|
62
60
|
}
|
|
63
61
|
function computeAttributes(href, navigationType, isExternal, isActive, isExactActive, activeClass) {
|
|
@@ -88,13 +86,18 @@ function computeAttributes(href, navigationType, isExternal, isActive, isExactAc
|
|
|
88
86
|
}
|
|
89
87
|
return attributes;
|
|
90
88
|
}
|
|
91
|
-
function createEventHandlersGenerator(
|
|
92
|
-
return (
|
|
89
|
+
function createEventHandlersGenerator(router, props, navigationType, eventTypes) {
|
|
90
|
+
return (format) => {
|
|
93
91
|
const handlers = {};
|
|
92
|
+
const navigate = createNavigateFunction(router, props, navigationType);
|
|
94
93
|
eventTypes.forEach((eventType) => {
|
|
95
94
|
var _a;
|
|
96
|
-
const eventName = (_a =
|
|
97
|
-
handlers[eventName] =
|
|
95
|
+
const eventName = (_a = format == null ? void 0 : format(eventType)) != null ? _a : eventType.toLowerCase();
|
|
96
|
+
handlers[eventName] = (event) => {
|
|
97
|
+
var _a2;
|
|
98
|
+
(_a2 = props.beforeNavigate) == null ? void 0 : _a2.call(props, event, eventType);
|
|
99
|
+
return navigate(event);
|
|
100
|
+
};
|
|
98
101
|
});
|
|
99
102
|
return handlers;
|
|
100
103
|
};
|
|
@@ -106,7 +109,6 @@ export function createLinkResolver(router, props) {
|
|
|
106
109
|
const isActive = router.isRouteMatched(route, props.exact);
|
|
107
110
|
const isExactActive = router.isRouteMatched(route, "exact");
|
|
108
111
|
const isExternal = route.url.origin !== router.route.url.origin;
|
|
109
|
-
const navigate = createNavigateFunction(router, props, type);
|
|
110
112
|
const attributes = computeAttributes(
|
|
111
113
|
href,
|
|
112
114
|
type,
|
|
@@ -116,7 +118,13 @@ export function createLinkResolver(router, props) {
|
|
|
116
118
|
props.activeClass
|
|
117
119
|
);
|
|
118
120
|
const eventTypes = getEventTypeList(props.event || "click");
|
|
119
|
-
const
|
|
121
|
+
const createEventHandlers = createEventHandlersGenerator(
|
|
122
|
+
router,
|
|
123
|
+
props,
|
|
124
|
+
type,
|
|
125
|
+
eventTypes
|
|
126
|
+
);
|
|
127
|
+
const navigate = createNavigateFunction(router, props, type);
|
|
120
128
|
return {
|
|
121
129
|
route,
|
|
122
130
|
type,
|
|
@@ -126,6 +134,6 @@ export function createLinkResolver(router, props) {
|
|
|
126
134
|
tag: props.tag || "a",
|
|
127
135
|
attributes,
|
|
128
136
|
navigate,
|
|
129
|
-
|
|
137
|
+
createEventHandlers
|
|
130
138
|
};
|
|
131
139
|
}
|
package/dist/router.d.ts
CHANGED
|
@@ -103,7 +103,7 @@ export declare class Router {
|
|
|
103
103
|
* linkData.navigate(); // Programmatic navigation
|
|
104
104
|
*
|
|
105
105
|
* // Get event handlers for React
|
|
106
|
-
* const handlers = linkData.
|
|
106
|
+
* const handlers = linkData.createEventHandlers(name => `on${name.charAt(0).toUpperCase() + name.slice(1)}`);
|
|
107
107
|
* // handlers.onClick for React
|
|
108
108
|
* ```
|
|
109
109
|
*/
|
package/dist/router.mjs
CHANGED
|
@@ -200,7 +200,7 @@ export class Router {
|
|
|
200
200
|
* linkData.navigate(); // Programmatic navigation
|
|
201
201
|
*
|
|
202
202
|
* // Get event handlers for React
|
|
203
|
-
* const handlers = linkData.
|
|
203
|
+
* const handlers = linkData.createEventHandlers(name => `on${name.charAt(0).toUpperCase() + name.slice(1)}`);
|
|
204
204
|
* // handlers.onClick for React
|
|
205
205
|
* ```
|
|
206
206
|
*/
|
package/dist/types.d.ts
CHANGED
|
@@ -219,7 +219,6 @@ export interface RouterLinkAttributes {
|
|
|
219
219
|
target?: '_blank';
|
|
220
220
|
rel?: string;
|
|
221
221
|
}
|
|
222
|
-
export type RouterLinkEventHandler = <E extends Event = MouseEvent>(event: E) => boolean | void;
|
|
223
222
|
/**
|
|
224
223
|
* Framework-agnostic link configuration interface
|
|
225
224
|
*/
|
|
@@ -235,7 +234,15 @@ export interface RouterLinkProps {
|
|
|
235
234
|
event?: string | string[];
|
|
236
235
|
tag?: string;
|
|
237
236
|
layerOptions?: RouteLayerOptions;
|
|
238
|
-
|
|
237
|
+
/**
|
|
238
|
+
* Hook function called before navigation occurs
|
|
239
|
+
* @param event - The DOM event that triggered the navigation
|
|
240
|
+
* @param eventName - The name of the event that triggered navigation
|
|
241
|
+
*
|
|
242
|
+
* Can prevent default event to block the default navigation handling logic.
|
|
243
|
+
* Call event.preventDefault() to stop the navigation from proceeding.
|
|
244
|
+
*/
|
|
245
|
+
beforeNavigate?: (event: Event, eventName: string) => void;
|
|
239
246
|
}
|
|
240
247
|
/**
|
|
241
248
|
* Framework-agnostic link resolution result
|
|
@@ -248,6 +255,6 @@ export interface RouterLinkResolved {
|
|
|
248
255
|
isExternal: boolean;
|
|
249
256
|
tag: string;
|
|
250
257
|
attributes: RouterLinkAttributes;
|
|
251
|
-
navigate: (e
|
|
252
|
-
|
|
258
|
+
navigate: (e: Event) => Promise<void>;
|
|
259
|
+
createEventHandlers: (format?: (eventType: string) => string) => Record<string, (e: Event) => Promise<void>>;
|
|
253
260
|
}
|
package/package.json
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"unbuild": "3.6.0",
|
|
40
40
|
"vitest": "3.2.4"
|
|
41
41
|
},
|
|
42
|
-
"version": "3.0.0-rc.
|
|
42
|
+
"version": "3.0.0-rc.62",
|
|
43
43
|
"type": "module",
|
|
44
44
|
"private": false,
|
|
45
45
|
"exports": {
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"template",
|
|
59
59
|
"public"
|
|
60
60
|
],
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "e5a1e811403bf1db4437dff88c3ea8bc6b576f64"
|
|
62
62
|
}
|
package/src/router-link.ts
CHANGED
|
@@ -41,29 +41,22 @@ function getEventTypeList(eventType: unknown | unknown[]): string[] {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
44
|
+
* Navigation event handler called before navigation - determines if the router should handle the navigation
|
|
45
45
|
*
|
|
46
|
-
* Returns
|
|
47
|
-
* Returns
|
|
46
|
+
* Returns false: Let browser handle default behavior (normal link navigation)
|
|
47
|
+
* Returns true: Router takes over navigation, prevents default browser behavior
|
|
48
48
|
*
|
|
49
49
|
* This function intelligently decides when to let the browser handle clicks
|
|
50
50
|
* (like Ctrl+click for new tabs) vs when to use SPA routing
|
|
51
51
|
*/
|
|
52
|
-
function
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// don't redirect if `target="_blank"`
|
|
61
|
-
// @ts-expect-error getAttribute exists
|
|
62
|
-
const target = e.currentTarget?.getAttribute?.('target') ?? '';
|
|
63
|
-
if (/\b_blank\b/i.test(target)) return;
|
|
64
|
-
// Prevent default browser navigation to enable SPA routing
|
|
65
|
-
// Note: this may be a Weex event which doesn't have this method
|
|
66
|
-
if (e.preventDefault) e.preventDefault();
|
|
52
|
+
function shouldHandleNavigation(e: Event): boolean {
|
|
53
|
+
if (e.defaultPrevented) return false;
|
|
54
|
+
if (e instanceof MouseEvent) {
|
|
55
|
+
if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return false;
|
|
56
|
+
if (e.button !== undefined && e.button !== 0) return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
e.preventDefault?.();
|
|
67
60
|
|
|
68
61
|
return true;
|
|
69
62
|
}
|
|
@@ -112,12 +105,11 @@ function createNavigateFunction(
|
|
|
112
105
|
router: Router,
|
|
113
106
|
props: RouterLinkProps,
|
|
114
107
|
navigationType: RouterLinkType
|
|
115
|
-
):
|
|
116
|
-
return async (e
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
await executeNavigation(router, props, navigationType);
|
|
108
|
+
): RouterLinkResolved['navigate'] {
|
|
109
|
+
return async (e: Event): Promise<void> => {
|
|
110
|
+
if (shouldHandleNavigation(e)) {
|
|
111
|
+
await executeNavigation(router, props, navigationType);
|
|
112
|
+
}
|
|
121
113
|
};
|
|
122
114
|
}
|
|
123
115
|
|
|
@@ -173,18 +165,21 @@ function computeAttributes(
|
|
|
173
165
|
* Create event handlers generator function
|
|
174
166
|
*/
|
|
175
167
|
function createEventHandlersGenerator(
|
|
176
|
-
|
|
168
|
+
router: Router,
|
|
169
|
+
props: RouterLinkProps,
|
|
170
|
+
navigationType: RouterLinkType,
|
|
177
171
|
eventTypes: string[]
|
|
178
|
-
):
|
|
179
|
-
|
|
180
|
-
) => Record<string, (e: Event) => Promise<void>> {
|
|
181
|
-
return (nameTransform?: (eventType: string) => string) => {
|
|
172
|
+
): RouterLinkResolved['createEventHandlers'] {
|
|
173
|
+
return (format?: (eventType: string) => string) => {
|
|
182
174
|
const handlers: Record<string, (e: Event) => Promise<void>> = {};
|
|
175
|
+
const navigate = createNavigateFunction(router, props, navigationType);
|
|
183
176
|
|
|
184
177
|
eventTypes.forEach((eventType) => {
|
|
185
|
-
const eventName =
|
|
186
|
-
|
|
187
|
-
|
|
178
|
+
const eventName = format?.(eventType) ?? eventType.toLowerCase();
|
|
179
|
+
handlers[eventName] = (event) => {
|
|
180
|
+
props.beforeNavigate?.(event, eventType);
|
|
181
|
+
return navigate(event);
|
|
182
|
+
};
|
|
188
183
|
});
|
|
189
184
|
|
|
190
185
|
return handlers;
|
|
@@ -210,8 +205,6 @@ export function createLinkResolver(
|
|
|
210
205
|
const isExactActive = router.isRouteMatched(route, 'exact');
|
|
211
206
|
const isExternal = route.url.origin !== router.route.url.origin;
|
|
212
207
|
|
|
213
|
-
const navigate = createNavigateFunction(router, props, type);
|
|
214
|
-
|
|
215
208
|
const attributes = computeAttributes(
|
|
216
209
|
href,
|
|
217
210
|
type,
|
|
@@ -222,7 +215,14 @@ export function createLinkResolver(
|
|
|
222
215
|
);
|
|
223
216
|
|
|
224
217
|
const eventTypes = getEventTypeList(props.event || 'click');
|
|
225
|
-
const
|
|
218
|
+
const createEventHandlers = createEventHandlersGenerator(
|
|
219
|
+
router,
|
|
220
|
+
props,
|
|
221
|
+
type,
|
|
222
|
+
eventTypes
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
const navigate = createNavigateFunction(router, props, type);
|
|
226
226
|
|
|
227
227
|
return {
|
|
228
228
|
route,
|
|
@@ -233,6 +233,6 @@ export function createLinkResolver(
|
|
|
233
233
|
tag: props.tag || 'a',
|
|
234
234
|
attributes,
|
|
235
235
|
navigate,
|
|
236
|
-
|
|
236
|
+
createEventHandlers
|
|
237
237
|
};
|
|
238
238
|
}
|
package/src/router.ts
CHANGED
|
@@ -225,7 +225,7 @@ export class Router {
|
|
|
225
225
|
* linkData.navigate(); // Programmatic navigation
|
|
226
226
|
*
|
|
227
227
|
* // Get event handlers for React
|
|
228
|
-
* const handlers = linkData.
|
|
228
|
+
* const handlers = linkData.createEventHandlers(name => `on${name.charAt(0).toUpperCase() + name.slice(1)}`);
|
|
229
229
|
* // handlers.onClick for React
|
|
230
230
|
* ```
|
|
231
231
|
*/
|
package/src/types.ts
CHANGED
|
@@ -308,10 +308,6 @@ export interface RouterLinkAttributes {
|
|
|
308
308
|
rel?: string;
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
-
export type RouterLinkEventHandler = <E extends Event = MouseEvent>(
|
|
312
|
-
event: E
|
|
313
|
-
) => boolean | void;
|
|
314
|
-
|
|
315
311
|
/**
|
|
316
312
|
* Framework-agnostic link configuration interface
|
|
317
313
|
*/
|
|
@@ -327,7 +323,15 @@ export interface RouterLinkProps {
|
|
|
327
323
|
event?: string | string[];
|
|
328
324
|
tag?: string;
|
|
329
325
|
layerOptions?: RouteLayerOptions;
|
|
330
|
-
|
|
326
|
+
/**
|
|
327
|
+
* Hook function called before navigation occurs
|
|
328
|
+
* @param event - The DOM event that triggered the navigation
|
|
329
|
+
* @param eventName - The name of the event that triggered navigation
|
|
330
|
+
*
|
|
331
|
+
* Can prevent default event to block the default navigation handling logic.
|
|
332
|
+
* Call event.preventDefault() to stop the navigation from proceeding.
|
|
333
|
+
*/
|
|
334
|
+
beforeNavigate?: (event: Event, eventName: string) => void;
|
|
331
335
|
}
|
|
332
336
|
|
|
333
337
|
/**
|
|
@@ -346,10 +350,10 @@ export interface RouterLinkResolved {
|
|
|
346
350
|
attributes: RouterLinkAttributes;
|
|
347
351
|
|
|
348
352
|
// Navigation function
|
|
349
|
-
navigate: (e
|
|
353
|
+
navigate: (e: Event) => Promise<void>;
|
|
350
354
|
|
|
351
355
|
// Event handling
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
) => Record<string, (e: Event) => Promise<void
|
|
356
|
+
createEventHandlers: (
|
|
357
|
+
format?: (eventType: string) => string
|
|
358
|
+
) => Record<string, (e: Event) => Promise<void>>;
|
|
355
359
|
}
|