@xfe-repo/web-router 1.2.3 → 1.2.6
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/index.d.mts +62 -7
- package/dist/index.d.ts +62 -7
- package/dist/index.js +166 -75
- package/dist/index.mjs +151 -76
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { History } from 'history';
|
|
2
1
|
import { LoadableComponent, loadableReady } from '@loadable/component';
|
|
2
|
+
import { History } from 'history';
|
|
3
3
|
import { ParsedQuery } from '@xfe-repo/web-utils/tools';
|
|
4
4
|
import React, { ReactElement, PropsWithChildren, ComponentType } from 'react';
|
|
5
5
|
import { RegisterComponentStatic } from '@xfe-repo/web-register';
|
|
@@ -22,6 +22,12 @@ declare const routerIndexRegx: RegExp;
|
|
|
22
22
|
declare const routerDynamicRegx: RegExp;
|
|
23
23
|
declare const getRoutes: (config: GetRoutesConfig) => RouteConfig[];
|
|
24
24
|
|
|
25
|
+
type LinkProps = Omit<LinkProps$1, 'to'> & {
|
|
26
|
+
to: string;
|
|
27
|
+
preload?: boolean;
|
|
28
|
+
};
|
|
29
|
+
declare const Link: React.MemoExoticComponent<(props: LinkProps) => react_jsx_runtime.JSX.Element>;
|
|
30
|
+
|
|
25
31
|
type RouterProps = PropsWithChildren<{
|
|
26
32
|
navigator: NavigatorType;
|
|
27
33
|
routes: RouteConfig[];
|
|
@@ -30,11 +36,60 @@ type RouterProps = PropsWithChildren<{
|
|
|
30
36
|
}>;
|
|
31
37
|
declare const Router: React.MemoExoticComponent<(props: RouterProps) => react_jsx_runtime.JSX.Element>;
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
/**
|
|
40
|
+
* History API 拦截器
|
|
41
|
+
*
|
|
42
|
+
* 劫持 history.pushState 和 history.replaceState 方法,
|
|
43
|
+
* 在调用原始方法后触发标准化的 historychange 事件。
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* // 监听 URL 变化
|
|
47
|
+
* window.addEventListener('historychange', (event) => {
|
|
48
|
+
* console.log('URL changed:', event.detail.url)
|
|
49
|
+
* })
|
|
50
|
+
*/
|
|
51
|
+
/** 自定义事件名称 */
|
|
52
|
+
declare const HISTORY_CHANGE_EVENT = "historychange";
|
|
53
|
+
/** History 变化事件详情 */
|
|
54
|
+
interface HistoryChangeEventDetail {
|
|
55
|
+
/** 变化类型 */
|
|
56
|
+
type: 'pushState' | 'replaceState' | 'popstate';
|
|
57
|
+
/** 完整 URL */
|
|
58
|
+
url: string;
|
|
59
|
+
/** 路径部分 */
|
|
60
|
+
pathname: string;
|
|
61
|
+
/** 查询参数部分 */
|
|
62
|
+
search: string;
|
|
63
|
+
/** hash 部分 */
|
|
64
|
+
hash: string;
|
|
65
|
+
/** history state */
|
|
66
|
+
state: any;
|
|
67
|
+
/** 时间戳 */
|
|
68
|
+
timestamp: number;
|
|
69
|
+
}
|
|
70
|
+
/** History 变化事件类型 */
|
|
71
|
+
interface HistoryChangeEvent extends CustomEvent<HistoryChangeEventDetail> {
|
|
72
|
+
type: typeof HISTORY_CHANGE_EVENT;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 初始化 history 拦截器
|
|
76
|
+
*
|
|
77
|
+
* 劫持 history.pushState 和 history.replaceState 方法,
|
|
78
|
+
* 在调用原始方法后触发 historychange 事件。
|
|
79
|
+
* 同时监听原生 popstate 事件并转发为 historychange 事件。
|
|
80
|
+
*
|
|
81
|
+
* @returns 清理函数,用于恢复原始方法和移除监听器
|
|
82
|
+
*/
|
|
83
|
+
declare function initHistoryInterceptor(): () => void;
|
|
84
|
+
/** 检查拦截器是否已初始化 */
|
|
85
|
+
declare function isHistoryIntercepted(): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* 事件监听函数
|
|
88
|
+
*
|
|
89
|
+
* @param callback 回调函数
|
|
90
|
+
* @returns 取消监听的函数
|
|
91
|
+
*/
|
|
92
|
+
declare function onHistoryChange(callback: (detail: HistoryChangeEventDetail) => void): () => void;
|
|
38
93
|
|
|
39
94
|
interface NavigatorType extends History {
|
|
40
95
|
preload: (path: string, isReplace?: boolean, query?: ParsedQuery<string | number | boolean>) => Promise<void>;
|
|
@@ -50,4 +105,4 @@ declare function createNavigator(options: CreateNavigatorOptions): NavigatorType
|
|
|
50
105
|
declare const getClientNavigator: () => NavigatorType;
|
|
51
106
|
declare const routerReady: typeof loadableReady;
|
|
52
107
|
|
|
53
|
-
export { type CreateNavigatorOptions, type GetRoutesConfig, Link, type NavigatorType, type PageComponent, type RouteConfig, Router, createNavigator, getClientNavigator, getRoutes, routerDynamicRegx, routerIndexRegx, routerReady };
|
|
108
|
+
export { type CreateNavigatorOptions, type GetRoutesConfig, HISTORY_CHANGE_EVENT, type HistoryChangeEvent, type HistoryChangeEventDetail, Link, type NavigatorType, type PageComponent, type RouteConfig, Router, createNavigator, getClientNavigator, getRoutes, initHistoryInterceptor, isHistoryIntercepted, onHistoryChange, routerDynamicRegx, routerIndexRegx, routerReady };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { History } from 'history';
|
|
2
1
|
import { LoadableComponent, loadableReady } from '@loadable/component';
|
|
2
|
+
import { History } from 'history';
|
|
3
3
|
import { ParsedQuery } from '@xfe-repo/web-utils/tools';
|
|
4
4
|
import React, { ReactElement, PropsWithChildren, ComponentType } from 'react';
|
|
5
5
|
import { RegisterComponentStatic } from '@xfe-repo/web-register';
|
|
@@ -22,6 +22,12 @@ declare const routerIndexRegx: RegExp;
|
|
|
22
22
|
declare const routerDynamicRegx: RegExp;
|
|
23
23
|
declare const getRoutes: (config: GetRoutesConfig) => RouteConfig[];
|
|
24
24
|
|
|
25
|
+
type LinkProps = Omit<LinkProps$1, 'to'> & {
|
|
26
|
+
to: string;
|
|
27
|
+
preload?: boolean;
|
|
28
|
+
};
|
|
29
|
+
declare const Link: React.MemoExoticComponent<(props: LinkProps) => react_jsx_runtime.JSX.Element>;
|
|
30
|
+
|
|
25
31
|
type RouterProps = PropsWithChildren<{
|
|
26
32
|
navigator: NavigatorType;
|
|
27
33
|
routes: RouteConfig[];
|
|
@@ -30,11 +36,60 @@ type RouterProps = PropsWithChildren<{
|
|
|
30
36
|
}>;
|
|
31
37
|
declare const Router: React.MemoExoticComponent<(props: RouterProps) => react_jsx_runtime.JSX.Element>;
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
/**
|
|
40
|
+
* History API 拦截器
|
|
41
|
+
*
|
|
42
|
+
* 劫持 history.pushState 和 history.replaceState 方法,
|
|
43
|
+
* 在调用原始方法后触发标准化的 historychange 事件。
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* // 监听 URL 变化
|
|
47
|
+
* window.addEventListener('historychange', (event) => {
|
|
48
|
+
* console.log('URL changed:', event.detail.url)
|
|
49
|
+
* })
|
|
50
|
+
*/
|
|
51
|
+
/** 自定义事件名称 */
|
|
52
|
+
declare const HISTORY_CHANGE_EVENT = "historychange";
|
|
53
|
+
/** History 变化事件详情 */
|
|
54
|
+
interface HistoryChangeEventDetail {
|
|
55
|
+
/** 变化类型 */
|
|
56
|
+
type: 'pushState' | 'replaceState' | 'popstate';
|
|
57
|
+
/** 完整 URL */
|
|
58
|
+
url: string;
|
|
59
|
+
/** 路径部分 */
|
|
60
|
+
pathname: string;
|
|
61
|
+
/** 查询参数部分 */
|
|
62
|
+
search: string;
|
|
63
|
+
/** hash 部分 */
|
|
64
|
+
hash: string;
|
|
65
|
+
/** history state */
|
|
66
|
+
state: any;
|
|
67
|
+
/** 时间戳 */
|
|
68
|
+
timestamp: number;
|
|
69
|
+
}
|
|
70
|
+
/** History 变化事件类型 */
|
|
71
|
+
interface HistoryChangeEvent extends CustomEvent<HistoryChangeEventDetail> {
|
|
72
|
+
type: typeof HISTORY_CHANGE_EVENT;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 初始化 history 拦截器
|
|
76
|
+
*
|
|
77
|
+
* 劫持 history.pushState 和 history.replaceState 方法,
|
|
78
|
+
* 在调用原始方法后触发 historychange 事件。
|
|
79
|
+
* 同时监听原生 popstate 事件并转发为 historychange 事件。
|
|
80
|
+
*
|
|
81
|
+
* @returns 清理函数,用于恢复原始方法和移除监听器
|
|
82
|
+
*/
|
|
83
|
+
declare function initHistoryInterceptor(): () => void;
|
|
84
|
+
/** 检查拦截器是否已初始化 */
|
|
85
|
+
declare function isHistoryIntercepted(): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* 事件监听函数
|
|
88
|
+
*
|
|
89
|
+
* @param callback 回调函数
|
|
90
|
+
* @returns 取消监听的函数
|
|
91
|
+
*/
|
|
92
|
+
declare function onHistoryChange(callback: (detail: HistoryChangeEventDetail) => void): () => void;
|
|
38
93
|
|
|
39
94
|
interface NavigatorType extends History {
|
|
40
95
|
preload: (path: string, isReplace?: boolean, query?: ParsedQuery<string | number | boolean>) => Promise<void>;
|
|
@@ -50,4 +105,4 @@ declare function createNavigator(options: CreateNavigatorOptions): NavigatorType
|
|
|
50
105
|
declare const getClientNavigator: () => NavigatorType;
|
|
51
106
|
declare const routerReady: typeof loadableReady;
|
|
52
107
|
|
|
53
|
-
export { type CreateNavigatorOptions, type GetRoutesConfig, Link, type NavigatorType, type PageComponent, type RouteConfig, Router, createNavigator, getClientNavigator, getRoutes, routerDynamicRegx, routerIndexRegx, routerReady };
|
|
108
|
+
export { type CreateNavigatorOptions, type GetRoutesConfig, HISTORY_CHANGE_EVENT, type HistoryChangeEvent, type HistoryChangeEventDetail, Link, type NavigatorType, type PageComponent, type RouteConfig, Router, createNavigator, getClientNavigator, getRoutes, initHistoryInterceptor, isHistoryIntercepted, onHistoryChange, routerDynamicRegx, routerIndexRegx, routerReady };
|
package/dist/index.js
CHANGED
|
@@ -261,6 +261,9 @@ var __toCommonJS = function(mod) {
|
|
|
261
261
|
// src/index.ts
|
|
262
262
|
var src_exports = {};
|
|
263
263
|
__export(src_exports, {
|
|
264
|
+
HISTORY_CHANGE_EVENT: function() {
|
|
265
|
+
return HISTORY_CHANGE_EVENT;
|
|
266
|
+
},
|
|
264
267
|
Link: function() {
|
|
265
268
|
return Link;
|
|
266
269
|
},
|
|
@@ -276,6 +279,15 @@ __export(src_exports, {
|
|
|
276
279
|
getRoutes: function() {
|
|
277
280
|
return getRoutes;
|
|
278
281
|
},
|
|
282
|
+
initHistoryInterceptor: function() {
|
|
283
|
+
return initHistoryInterceptor;
|
|
284
|
+
},
|
|
285
|
+
isHistoryIntercepted: function() {
|
|
286
|
+
return isHistoryIntercepted;
|
|
287
|
+
},
|
|
288
|
+
onHistoryChange: function() {
|
|
289
|
+
return onHistoryChange;
|
|
290
|
+
},
|
|
279
291
|
routerDynamicRegx: function() {
|
|
280
292
|
return routerDynamicRegx;
|
|
281
293
|
},
|
|
@@ -287,90 +299,93 @@ __export(src_exports, {
|
|
|
287
299
|
}
|
|
288
300
|
});
|
|
289
301
|
module.exports = __toCommonJS(src_exports);
|
|
290
|
-
var import_history = require("history");
|
|
291
302
|
var import_component2 = require("@loadable/component");
|
|
303
|
+
var import_history = require("history");
|
|
292
304
|
var import_react_router_dom3 = require("react-router-dom");
|
|
293
305
|
var import_tools = require("@xfe-repo/web-utils/tools");
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
var
|
|
297
|
-
var
|
|
298
|
-
var
|
|
299
|
-
|
|
300
|
-
var
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
if (pageIndexPath.startsWith("./")) return;
|
|
305
|
-
var pageComponent = (0, import_component.default)(function() {
|
|
306
|
-
return getPageComponents(pageIndexPath);
|
|
307
|
-
}, {
|
|
308
|
-
fallback: fallback
|
|
309
|
-
});
|
|
310
|
-
var routerPath = getRoutePath ? getRoutePath(pageIndexPath) : pageIndexPath.replace(routerIndexRegx, "$1");
|
|
311
|
-
if (routerPath === "home" || routerPath === "index") routerPath = "/";
|
|
312
|
-
var dynamicRoute = ((_pageIndexPath_match = pageIndexPath.match(routerDynamicRegx)) === null || _pageIndexPath_match === void 0 ? void 0 : _pageIndexPath_match[1]) || "";
|
|
313
|
-
if (dynamicRoute) routerPath = "".concat(routerPath, "/").concat(dynamicRoute);
|
|
314
|
-
var config2 = {
|
|
315
|
-
path: routerPath,
|
|
316
|
-
Component: pageComponent
|
|
317
|
-
};
|
|
318
|
-
routes.push(config2);
|
|
306
|
+
// src/historyInterceptor.ts
|
|
307
|
+
var HISTORY_CHANGE_EVENT = "historychange";
|
|
308
|
+
var originalPushState = null;
|
|
309
|
+
var originalReplaceState = null;
|
|
310
|
+
var isIntercepted = false;
|
|
311
|
+
function dispatchHistoryChangeEvent(detail) {
|
|
312
|
+
var event = new CustomEvent(HISTORY_CHANGE_EVENT, {
|
|
313
|
+
detail: detail,
|
|
314
|
+
bubbles: false,
|
|
315
|
+
cancelable: false
|
|
319
316
|
});
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
|
|
317
|
+
window.dispatchEvent(event);
|
|
318
|
+
}
|
|
319
|
+
function createEventDetail(type, state) {
|
|
320
|
+
return {
|
|
321
|
+
type: type,
|
|
322
|
+
url: window.location.href,
|
|
323
|
+
pathname: window.location.pathname,
|
|
324
|
+
search: window.location.search,
|
|
325
|
+
hash: window.location.hash,
|
|
326
|
+
state: state,
|
|
327
|
+
timestamp: Date.now()
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function initHistoryInterceptor() {
|
|
331
|
+
if (isIntercepted) {
|
|
332
|
+
return function() {};
|
|
333
|
+
}
|
|
334
|
+
originalPushState = history.pushState;
|
|
335
|
+
originalReplaceState = history.replaceState;
|
|
336
|
+
history.pushState = function(state, unused, url) {
|
|
337
|
+
originalPushState.call(this, state, unused, url);
|
|
338
|
+
dispatchHistoryChangeEvent(createEventDetail("pushState", state));
|
|
339
|
+
};
|
|
340
|
+
history.replaceState = function(state, unused, url) {
|
|
341
|
+
originalReplaceState.call(this, state, unused, url);
|
|
342
|
+
dispatchHistoryChangeEvent(createEventDetail("replaceState", state));
|
|
343
|
+
};
|
|
344
|
+
var handlePopState = function() {
|
|
345
|
+
dispatchHistoryChangeEvent(createEventDetail("popstate", history.state));
|
|
346
|
+
};
|
|
347
|
+
window.addEventListener("popstate", handlePopState);
|
|
348
|
+
isIntercepted = true;
|
|
349
|
+
return function() {
|
|
350
|
+
if (originalPushState) {
|
|
351
|
+
history.pushState = originalPushState;
|
|
352
|
+
originalPushState = null;
|
|
353
|
+
}
|
|
354
|
+
if (originalReplaceState) {
|
|
355
|
+
history.replaceState = originalReplaceState;
|
|
356
|
+
originalReplaceState = null;
|
|
357
|
+
}
|
|
358
|
+
window.removeEventListener("popstate", handlePopState);
|
|
359
|
+
isIntercepted = false;
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function isHistoryIntercepted() {
|
|
363
|
+
return isIntercepted;
|
|
364
|
+
}
|
|
365
|
+
function onHistoryChange(callback) {
|
|
366
|
+
var handler = function(event) {
|
|
367
|
+
var customEvent = event;
|
|
368
|
+
callback(customEvent.detail);
|
|
369
|
+
};
|
|
370
|
+
window.addEventListener(HISTORY_CHANGE_EVENT, handler);
|
|
371
|
+
return function() {
|
|
372
|
+
window.removeEventListener(HISTORY_CHANGE_EVENT, handler);
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
// src/index.ts
|
|
376
|
+
__reExport(src_exports, require("react-router-dom"), module.exports);
|
|
377
|
+
// src/Link.tsx
|
|
323
378
|
var import_react = require("react");
|
|
324
379
|
var import_react_router_dom = require("react-router-dom");
|
|
325
380
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
326
|
-
var
|
|
327
|
-
var navigator = props.navigator, routes = props.routes, _props_basename = props.basename, basename = _props_basename === void 0 ? "/" : _props_basename, children = props.children, NotFoundPageComponent = props.NotFoundPageComponent;
|
|
328
|
-
var _ref = _sliced_to_array((0, import_react.useState)({
|
|
329
|
-
action: navigator.action,
|
|
330
|
-
location: navigator.location
|
|
331
|
-
}), 2), navigatorState = _ref[0], setNavigatorState = _ref[1];
|
|
332
|
-
(0, import_react.useEffect)(function() {
|
|
333
|
-
return navigator.listen(setNavigatorState);
|
|
334
|
-
}, [
|
|
335
|
-
navigator
|
|
336
|
-
]);
|
|
337
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Router, {
|
|
338
|
-
navigator: navigator,
|
|
339
|
-
navigationType: navigatorState.action,
|
|
340
|
-
location: navigatorState.location,
|
|
341
|
-
basename: basename,
|
|
342
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Routes, {
|
|
343
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_router_dom.Route, {
|
|
344
|
-
path: "/",
|
|
345
|
-
element: children,
|
|
346
|
-
children: [
|
|
347
|
-
routes.map(function(param) {
|
|
348
|
-
var path = param.path, Component = param.Component;
|
|
349
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Route, {
|
|
350
|
-
path: path,
|
|
351
|
-
Component: Component
|
|
352
|
-
}, path);
|
|
353
|
-
}),
|
|
354
|
-
NotFoundPageComponent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Route, {
|
|
355
|
-
path: "*",
|
|
356
|
-
Component: NotFoundPageComponent
|
|
357
|
-
})
|
|
358
|
-
]
|
|
359
|
-
})
|
|
360
|
-
})
|
|
361
|
-
});
|
|
362
|
-
});
|
|
363
|
-
// src/Link.tsx
|
|
364
|
-
var import_react2 = require("react");
|
|
365
|
-
var import_react_router_dom2 = require("react-router-dom");
|
|
366
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
367
|
-
var Link = (0, import_react2.memo)(function(props) {
|
|
381
|
+
var Link = (0, import_react.memo)(function(props) {
|
|
368
382
|
var to = props.to, children = props.children, preload = props.preload, replace = props.replace, className = props.className, target = props.target;
|
|
369
|
-
var _navigator2 = (0,
|
|
383
|
+
var _navigator2 = (0, import_react.useMemo)(function() {
|
|
370
384
|
return getClientNavigator();
|
|
371
385
|
}, []);
|
|
372
386
|
if (/http(s)?:\/{2}/.test(to)) {
|
|
373
387
|
var handleLink = function(e) {
|
|
388
|
+
if (e.ctrlKey || e.metaKey) return;
|
|
374
389
|
e.preventDefault();
|
|
375
390
|
if (target === "_blank") {
|
|
376
391
|
window.open(to);
|
|
@@ -378,7 +393,7 @@ var Link = (0, import_react2.memo)(function(props) {
|
|
|
378
393
|
window.location.href = to;
|
|
379
394
|
}
|
|
380
395
|
};
|
|
381
|
-
return /* @__PURE__ */ (0,
|
|
396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
|
|
382
397
|
href: to,
|
|
383
398
|
onClick: handleLink,
|
|
384
399
|
className: className,
|
|
@@ -392,6 +407,9 @@ var Link = (0, import_react2.memo)(function(props) {
|
|
|
392
407
|
return _ts_generator(this, function(_state) {
|
|
393
408
|
switch(_state.label){
|
|
394
409
|
case 0:
|
|
410
|
+
if (e.ctrlKey || e.metaKey) return [
|
|
411
|
+
2
|
|
412
|
+
];
|
|
395
413
|
e.preventDefault();
|
|
396
414
|
return [
|
|
397
415
|
4,
|
|
@@ -409,15 +427,83 @@ var Link = (0, import_react2.memo)(function(props) {
|
|
|
409
427
|
return _ref.apply(this, arguments);
|
|
410
428
|
};
|
|
411
429
|
}();
|
|
412
|
-
return /* @__PURE__ */ (0,
|
|
430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
|
|
413
431
|
href: to,
|
|
414
432
|
onClick: handleLink1,
|
|
415
433
|
className: className,
|
|
416
434
|
children: children
|
|
417
435
|
});
|
|
418
436
|
}
|
|
419
|
-
return /* @__PURE__ */ (0,
|
|
437
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_router_dom.Link, _object_spread({}, props));
|
|
438
|
+
});
|
|
439
|
+
// src/Router.tsx
|
|
440
|
+
var import_react2 = require("react");
|
|
441
|
+
var import_react_router_dom2 = require("react-router-dom");
|
|
442
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
443
|
+
var Router = (0, import_react2.memo)(function(props) {
|
|
444
|
+
var navigator = props.navigator, routes = props.routes, _props_basename = props.basename, basename = _props_basename === void 0 ? "/" : _props_basename, children = props.children, NotFoundPageComponent = props.NotFoundPageComponent;
|
|
445
|
+
var _ref = _sliced_to_array((0, import_react2.useState)({
|
|
446
|
+
action: navigator.action,
|
|
447
|
+
location: navigator.location
|
|
448
|
+
}), 2), navigatorState = _ref[0], setNavigatorState = _ref[1];
|
|
449
|
+
(0, import_react2.useEffect)(function() {
|
|
450
|
+
return navigator.listen(setNavigatorState);
|
|
451
|
+
}, [
|
|
452
|
+
navigator
|
|
453
|
+
]);
|
|
454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Router, {
|
|
455
|
+
navigator: navigator,
|
|
456
|
+
navigationType: navigatorState.action,
|
|
457
|
+
location: navigatorState.location,
|
|
458
|
+
basename: basename,
|
|
459
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Routes, {
|
|
460
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_router_dom2.Route, {
|
|
461
|
+
path: "/",
|
|
462
|
+
element: children,
|
|
463
|
+
children: [
|
|
464
|
+
routes.map(function(param) {
|
|
465
|
+
var path = param.path, Component = param.Component;
|
|
466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Route, {
|
|
467
|
+
path: path,
|
|
468
|
+
Component: Component
|
|
469
|
+
}, path);
|
|
470
|
+
}),
|
|
471
|
+
NotFoundPageComponent && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_router_dom2.Route, {
|
|
472
|
+
path: "*",
|
|
473
|
+
Component: NotFoundPageComponent
|
|
474
|
+
})
|
|
475
|
+
]
|
|
476
|
+
})
|
|
477
|
+
})
|
|
478
|
+
});
|
|
420
479
|
});
|
|
480
|
+
// src/routes.ts
|
|
481
|
+
var import_component = __toESM(require("@loadable/component"));
|
|
482
|
+
var routerIndexRegx = /^(?!.*component)(.*)?\/index(\[[^.]+])?\.(ts|js)x?$/;
|
|
483
|
+
var routerDynamicRegx = /\[([^.]+)]/;
|
|
484
|
+
var getRoutes = function(config) {
|
|
485
|
+
var pagesIndexPath = config.pagesIndexPath, getRoutePath = config.getRoutePath, getPageComponents = config.getPageComponents, fallback = config.fallback;
|
|
486
|
+
var routes = [];
|
|
487
|
+
pagesIndexPath.forEach(function(pageIndexPath) {
|
|
488
|
+
var _pageIndexPath_match;
|
|
489
|
+
if (pageIndexPath.startsWith("./")) return;
|
|
490
|
+
var pageComponent = (0, import_component.default)(function() {
|
|
491
|
+
return getPageComponents(pageIndexPath);
|
|
492
|
+
}, {
|
|
493
|
+
fallback: fallback
|
|
494
|
+
});
|
|
495
|
+
var routerPath = getRoutePath ? getRoutePath(pageIndexPath) : pageIndexPath.replace(routerIndexRegx, "$1");
|
|
496
|
+
if (routerPath === "home" || routerPath === "index") routerPath = "/";
|
|
497
|
+
var dynamicRoute = ((_pageIndexPath_match = pageIndexPath.match(routerDynamicRegx)) === null || _pageIndexPath_match === void 0 ? void 0 : _pageIndexPath_match[1]) || "";
|
|
498
|
+
if (dynamicRoute) routerPath = "".concat(routerPath, "/").concat(dynamicRoute);
|
|
499
|
+
var config2 = {
|
|
500
|
+
path: routerPath,
|
|
501
|
+
Component: pageComponent
|
|
502
|
+
};
|
|
503
|
+
routes.push(config2);
|
|
504
|
+
});
|
|
505
|
+
return routes;
|
|
506
|
+
};
|
|
421
507
|
// src/index.ts
|
|
422
508
|
var _navigator;
|
|
423
509
|
function createNavigator(options) {
|
|
@@ -504,13 +590,18 @@ var getClientNavigator = function() {
|
|
|
504
590
|
return _navigator;
|
|
505
591
|
};
|
|
506
592
|
var routerReady = import_component2.loadableReady;
|
|
593
|
+
initHistoryInterceptor();
|
|
507
594
|
// Annotate the CommonJS export names for ESM import in node:
|
|
508
595
|
0 && (module.exports = _object_spread({
|
|
596
|
+
HISTORY_CHANGE_EVENT: HISTORY_CHANGE_EVENT,
|
|
509
597
|
Link: Link,
|
|
510
598
|
Router: Router,
|
|
511
599
|
createNavigator: createNavigator,
|
|
512
600
|
getClientNavigator: getClientNavigator,
|
|
513
601
|
getRoutes: getRoutes,
|
|
602
|
+
initHistoryInterceptor: initHistoryInterceptor,
|
|
603
|
+
isHistoryIntercepted: isHistoryIntercepted,
|
|
604
|
+
onHistoryChange: onHistoryChange,
|
|
514
605
|
routerDynamicRegx: routerDynamicRegx,
|
|
515
606
|
routerIndexRegx: routerIndexRegx,
|
|
516
607
|
routerReady: routerReady
|
package/dist/index.mjs
CHANGED
|
@@ -197,90 +197,93 @@ function _ts_generator(thisArg, body) {
|
|
|
197
197
|
};
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
-
import { createHashHistory, createBrowserHistory, createMemoryHistory } from "history";
|
|
201
200
|
import { loadableReady } from "@loadable/component";
|
|
201
|
+
import { createBrowserHistory, createHashHistory, createMemoryHistory } from "history";
|
|
202
202
|
import { matchRoutes } from "react-router-dom";
|
|
203
203
|
import { queryString } from "@xfe-repo/web-utils/tools";
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
var
|
|
208
|
-
var
|
|
209
|
-
|
|
210
|
-
var
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
if (pageIndexPath.startsWith("./")) return;
|
|
215
|
-
var pageComponent = loadable(function() {
|
|
216
|
-
return getPageComponents(pageIndexPath);
|
|
217
|
-
}, {
|
|
218
|
-
fallback: fallback
|
|
219
|
-
});
|
|
220
|
-
var routerPath = getRoutePath ? getRoutePath(pageIndexPath) : pageIndexPath.replace(routerIndexRegx, "$1");
|
|
221
|
-
if (routerPath === "home" || routerPath === "index") routerPath = "/";
|
|
222
|
-
var dynamicRoute = ((_pageIndexPath_match = pageIndexPath.match(routerDynamicRegx)) === null || _pageIndexPath_match === void 0 ? void 0 : _pageIndexPath_match[1]) || "";
|
|
223
|
-
if (dynamicRoute) routerPath = "".concat(routerPath, "/").concat(dynamicRoute);
|
|
224
|
-
var config2 = {
|
|
225
|
-
path: routerPath,
|
|
226
|
-
Component: pageComponent
|
|
227
|
-
};
|
|
228
|
-
routes.push(config2);
|
|
229
|
-
});
|
|
230
|
-
return routes;
|
|
231
|
-
};
|
|
232
|
-
// src/Router.tsx
|
|
233
|
-
import { memo, useState, useEffect } from "react";
|
|
234
|
-
import { Router as OriginalRouter, Routes, Route } from "react-router-dom";
|
|
235
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
236
|
-
var Router = memo(function(props) {
|
|
237
|
-
var navigator = props.navigator, routes = props.routes, _props_basename = props.basename, basename = _props_basename === void 0 ? "/" : _props_basename, children = props.children, NotFoundPageComponent = props.NotFoundPageComponent;
|
|
238
|
-
var _useState = _sliced_to_array(useState({
|
|
239
|
-
action: navigator.action,
|
|
240
|
-
location: navigator.location
|
|
241
|
-
}), 2), navigatorState = _useState[0], setNavigatorState = _useState[1];
|
|
242
|
-
useEffect(function() {
|
|
243
|
-
return navigator.listen(setNavigatorState);
|
|
244
|
-
}, [
|
|
245
|
-
navigator
|
|
246
|
-
]);
|
|
247
|
-
return /* @__PURE__ */ jsx(OriginalRouter, {
|
|
248
|
-
navigator: navigator,
|
|
249
|
-
navigationType: navigatorState.action,
|
|
250
|
-
location: navigatorState.location,
|
|
251
|
-
basename: basename,
|
|
252
|
-
children: /* @__PURE__ */ jsx(Routes, {
|
|
253
|
-
children: /* @__PURE__ */ jsxs(Route, {
|
|
254
|
-
path: "/",
|
|
255
|
-
element: children,
|
|
256
|
-
children: [
|
|
257
|
-
routes.map(function(param) {
|
|
258
|
-
var path = param.path, Component = param.Component;
|
|
259
|
-
return /* @__PURE__ */ jsx(Route, {
|
|
260
|
-
path: path,
|
|
261
|
-
Component: Component
|
|
262
|
-
}, path);
|
|
263
|
-
}),
|
|
264
|
-
NotFoundPageComponent && /* @__PURE__ */ jsx(Route, {
|
|
265
|
-
path: "*",
|
|
266
|
-
Component: NotFoundPageComponent
|
|
267
|
-
})
|
|
268
|
-
]
|
|
269
|
-
})
|
|
270
|
-
})
|
|
204
|
+
// src/historyInterceptor.ts
|
|
205
|
+
var HISTORY_CHANGE_EVENT = "historychange";
|
|
206
|
+
var originalPushState = null;
|
|
207
|
+
var originalReplaceState = null;
|
|
208
|
+
var isIntercepted = false;
|
|
209
|
+
function dispatchHistoryChangeEvent(detail) {
|
|
210
|
+
var event = new CustomEvent(HISTORY_CHANGE_EVENT, {
|
|
211
|
+
detail: detail,
|
|
212
|
+
bubbles: false,
|
|
213
|
+
cancelable: false
|
|
271
214
|
});
|
|
272
|
-
|
|
215
|
+
window.dispatchEvent(event);
|
|
216
|
+
}
|
|
217
|
+
function createEventDetail(type, state) {
|
|
218
|
+
return {
|
|
219
|
+
type: type,
|
|
220
|
+
url: window.location.href,
|
|
221
|
+
pathname: window.location.pathname,
|
|
222
|
+
search: window.location.search,
|
|
223
|
+
hash: window.location.hash,
|
|
224
|
+
state: state,
|
|
225
|
+
timestamp: Date.now()
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function initHistoryInterceptor() {
|
|
229
|
+
if (isIntercepted) {
|
|
230
|
+
return function() {};
|
|
231
|
+
}
|
|
232
|
+
originalPushState = history.pushState;
|
|
233
|
+
originalReplaceState = history.replaceState;
|
|
234
|
+
history.pushState = function(state, unused, url) {
|
|
235
|
+
originalPushState.call(this, state, unused, url);
|
|
236
|
+
dispatchHistoryChangeEvent(createEventDetail("pushState", state));
|
|
237
|
+
};
|
|
238
|
+
history.replaceState = function(state, unused, url) {
|
|
239
|
+
originalReplaceState.call(this, state, unused, url);
|
|
240
|
+
dispatchHistoryChangeEvent(createEventDetail("replaceState", state));
|
|
241
|
+
};
|
|
242
|
+
var handlePopState = function() {
|
|
243
|
+
dispatchHistoryChangeEvent(createEventDetail("popstate", history.state));
|
|
244
|
+
};
|
|
245
|
+
window.addEventListener("popstate", handlePopState);
|
|
246
|
+
isIntercepted = true;
|
|
247
|
+
return function() {
|
|
248
|
+
if (originalPushState) {
|
|
249
|
+
history.pushState = originalPushState;
|
|
250
|
+
originalPushState = null;
|
|
251
|
+
}
|
|
252
|
+
if (originalReplaceState) {
|
|
253
|
+
history.replaceState = originalReplaceState;
|
|
254
|
+
originalReplaceState = null;
|
|
255
|
+
}
|
|
256
|
+
window.removeEventListener("popstate", handlePopState);
|
|
257
|
+
isIntercepted = false;
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
function isHistoryIntercepted() {
|
|
261
|
+
return isIntercepted;
|
|
262
|
+
}
|
|
263
|
+
function onHistoryChange(callback) {
|
|
264
|
+
var handler = function(event) {
|
|
265
|
+
var customEvent = event;
|
|
266
|
+
callback(customEvent.detail);
|
|
267
|
+
};
|
|
268
|
+
window.addEventListener(HISTORY_CHANGE_EVENT, handler);
|
|
269
|
+
return function() {
|
|
270
|
+
window.removeEventListener(HISTORY_CHANGE_EVENT, handler);
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
// src/index.ts
|
|
274
|
+
export * from "react-router-dom";
|
|
273
275
|
// src/Link.tsx
|
|
274
|
-
import { memo
|
|
276
|
+
import { memo, useMemo } from "react";
|
|
275
277
|
import { Link as OriginalLink } from "react-router-dom";
|
|
276
|
-
import { jsx
|
|
277
|
-
var Link =
|
|
278
|
+
import { jsx } from "react/jsx-runtime";
|
|
279
|
+
var Link = memo(function(props) {
|
|
278
280
|
var to = props.to, children = props.children, preload = props.preload, replace = props.replace, className = props.className, target = props.target;
|
|
279
281
|
var _navigator2 = useMemo(function() {
|
|
280
282
|
return getClientNavigator();
|
|
281
283
|
}, []);
|
|
282
284
|
if (/http(s)?:\/{2}/.test(to)) {
|
|
283
285
|
var handleLink = function(e) {
|
|
286
|
+
if (e.ctrlKey || e.metaKey) return;
|
|
284
287
|
e.preventDefault();
|
|
285
288
|
if (target === "_blank") {
|
|
286
289
|
window.open(to);
|
|
@@ -288,7 +291,7 @@ var Link = memo2(function(props) {
|
|
|
288
291
|
window.location.href = to;
|
|
289
292
|
}
|
|
290
293
|
};
|
|
291
|
-
return /* @__PURE__ */
|
|
294
|
+
return /* @__PURE__ */ jsx("a", {
|
|
292
295
|
href: to,
|
|
293
296
|
onClick: handleLink,
|
|
294
297
|
className: className,
|
|
@@ -302,6 +305,9 @@ var Link = memo2(function(props) {
|
|
|
302
305
|
return _ts_generator(this, function(_state) {
|
|
303
306
|
switch(_state.label){
|
|
304
307
|
case 0:
|
|
308
|
+
if (e.ctrlKey || e.metaKey) return [
|
|
309
|
+
2
|
|
310
|
+
];
|
|
305
311
|
e.preventDefault();
|
|
306
312
|
return [
|
|
307
313
|
4,
|
|
@@ -319,15 +325,83 @@ var Link = memo2(function(props) {
|
|
|
319
325
|
return _ref.apply(this, arguments);
|
|
320
326
|
};
|
|
321
327
|
}();
|
|
322
|
-
return /* @__PURE__ */
|
|
328
|
+
return /* @__PURE__ */ jsx("a", {
|
|
323
329
|
href: to,
|
|
324
330
|
onClick: handleLink1,
|
|
325
331
|
className: className,
|
|
326
332
|
children: children
|
|
327
333
|
});
|
|
328
334
|
}
|
|
329
|
-
return /* @__PURE__ */
|
|
335
|
+
return /* @__PURE__ */ jsx(OriginalLink, _object_spread({}, props));
|
|
330
336
|
});
|
|
337
|
+
// src/Router.tsx
|
|
338
|
+
import { memo as memo2, useState, useEffect } from "react";
|
|
339
|
+
import { Router as OriginalRouter, Routes, Route } from "react-router-dom";
|
|
340
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
341
|
+
var Router = memo2(function(props) {
|
|
342
|
+
var navigator = props.navigator, routes = props.routes, _props_basename = props.basename, basename = _props_basename === void 0 ? "/" : _props_basename, children = props.children, NotFoundPageComponent = props.NotFoundPageComponent;
|
|
343
|
+
var _useState = _sliced_to_array(useState({
|
|
344
|
+
action: navigator.action,
|
|
345
|
+
location: navigator.location
|
|
346
|
+
}), 2), navigatorState = _useState[0], setNavigatorState = _useState[1];
|
|
347
|
+
useEffect(function() {
|
|
348
|
+
return navigator.listen(setNavigatorState);
|
|
349
|
+
}, [
|
|
350
|
+
navigator
|
|
351
|
+
]);
|
|
352
|
+
return /* @__PURE__ */ jsx2(OriginalRouter, {
|
|
353
|
+
navigator: navigator,
|
|
354
|
+
navigationType: navigatorState.action,
|
|
355
|
+
location: navigatorState.location,
|
|
356
|
+
basename: basename,
|
|
357
|
+
children: /* @__PURE__ */ jsx2(Routes, {
|
|
358
|
+
children: /* @__PURE__ */ jsxs(Route, {
|
|
359
|
+
path: "/",
|
|
360
|
+
element: children,
|
|
361
|
+
children: [
|
|
362
|
+
routes.map(function(param) {
|
|
363
|
+
var path = param.path, Component = param.Component;
|
|
364
|
+
return /* @__PURE__ */ jsx2(Route, {
|
|
365
|
+
path: path,
|
|
366
|
+
Component: Component
|
|
367
|
+
}, path);
|
|
368
|
+
}),
|
|
369
|
+
NotFoundPageComponent && /* @__PURE__ */ jsx2(Route, {
|
|
370
|
+
path: "*",
|
|
371
|
+
Component: NotFoundPageComponent
|
|
372
|
+
})
|
|
373
|
+
]
|
|
374
|
+
})
|
|
375
|
+
})
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
// src/routes.ts
|
|
379
|
+
import loadable from "@loadable/component";
|
|
380
|
+
var routerIndexRegx = /^(?!.*component)(.*)?\/index(\[[^.]+])?\.(ts|js)x?$/;
|
|
381
|
+
var routerDynamicRegx = /\[([^.]+)]/;
|
|
382
|
+
var getRoutes = function(config) {
|
|
383
|
+
var pagesIndexPath = config.pagesIndexPath, getRoutePath = config.getRoutePath, getPageComponents = config.getPageComponents, fallback = config.fallback;
|
|
384
|
+
var routes = [];
|
|
385
|
+
pagesIndexPath.forEach(function(pageIndexPath) {
|
|
386
|
+
var _pageIndexPath_match;
|
|
387
|
+
if (pageIndexPath.startsWith("./")) return;
|
|
388
|
+
var pageComponent = loadable(function() {
|
|
389
|
+
return getPageComponents(pageIndexPath);
|
|
390
|
+
}, {
|
|
391
|
+
fallback: fallback
|
|
392
|
+
});
|
|
393
|
+
var routerPath = getRoutePath ? getRoutePath(pageIndexPath) : pageIndexPath.replace(routerIndexRegx, "$1");
|
|
394
|
+
if (routerPath === "home" || routerPath === "index") routerPath = "/";
|
|
395
|
+
var dynamicRoute = ((_pageIndexPath_match = pageIndexPath.match(routerDynamicRegx)) === null || _pageIndexPath_match === void 0 ? void 0 : _pageIndexPath_match[1]) || "";
|
|
396
|
+
if (dynamicRoute) routerPath = "".concat(routerPath, "/").concat(dynamicRoute);
|
|
397
|
+
var config2 = {
|
|
398
|
+
path: routerPath,
|
|
399
|
+
Component: pageComponent
|
|
400
|
+
};
|
|
401
|
+
routes.push(config2);
|
|
402
|
+
});
|
|
403
|
+
return routes;
|
|
404
|
+
};
|
|
331
405
|
// src/index.ts
|
|
332
406
|
var _navigator;
|
|
333
407
|
function createNavigator(options) {
|
|
@@ -414,4 +488,5 @@ var getClientNavigator = function() {
|
|
|
414
488
|
return _navigator;
|
|
415
489
|
};
|
|
416
490
|
var routerReady = loadableReady;
|
|
417
|
-
|
|
491
|
+
initHistoryInterceptor();
|
|
492
|
+
export { HISTORY_CHANGE_EVENT, Link, Router, createNavigator, getClientNavigator, getRoutes, initHistoryInterceptor, isHistoryIntercepted, onHistoryChange, routerDynamicRegx, routerIndexRegx, routerReady };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xfe-repo/web-router",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"@types/loadable__component": "^5.13.9",
|
|
29
29
|
"@types/node": "^20.16.5",
|
|
30
30
|
"@types/react": "^18",
|
|
31
|
-
"@xfe-repo/eslint-config": "0.0.5",
|
|
32
31
|
"@xfe-repo/typescript-config": "0.0.6",
|
|
32
|
+
"@xfe-repo/eslint-config": "0.0.5",
|
|
33
33
|
"@xfe-repo/web-register": "1.3.5"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@xfe-repo/web-utils": "1.3.
|
|
36
|
+
"@xfe-repo/web-utils": "1.3.8"
|
|
37
37
|
},
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"registry": "https://registry.npmjs.org/"
|