aprog 2.2.95 → 2.3.0
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/package.json +1 -1
- package/src/NotFound.js +16 -8
- package/src/router.js +87 -13
package/package.json
CHANGED
package/src/NotFound.js
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import {div} from "./general.js";
|
|
2
2
|
|
|
3
|
-
const NotFound = ({
|
|
3
|
+
const NotFound = ({ colors = {
|
|
4
|
+
numberColor: "#ff2800",
|
|
5
|
+
textColor: "#c3e4fc",
|
|
6
|
+
backgroundColor: "#043458",
|
|
7
|
+
}, message = "Page Not Found" }) => {
|
|
4
8
|
return div({
|
|
5
|
-
style:
|
|
9
|
+
style: {
|
|
10
|
+
...style,
|
|
11
|
+
color: colors.textColor,
|
|
12
|
+
backgroundColor: colors.backgroundColor
|
|
13
|
+
},
|
|
6
14
|
value: [
|
|
7
15
|
div({
|
|
8
|
-
style:
|
|
16
|
+
style: {
|
|
17
|
+
...style2,
|
|
18
|
+
color: colors.numberColor
|
|
19
|
+
},
|
|
9
20
|
value: "404"
|
|
10
21
|
}),
|
|
11
22
|
div({value: message})
|
|
@@ -20,15 +31,12 @@ const style = {
|
|
|
20
31
|
flexDirection: "column",
|
|
21
32
|
alignItems: "center",
|
|
22
33
|
justifyContent: "center",
|
|
23
|
-
fontSize: "1.875rem"
|
|
24
|
-
color: "#c3e4fc",
|
|
25
|
-
backgroundColor: "#043458"
|
|
34
|
+
fontSize: "1.875rem"
|
|
26
35
|
};
|
|
27
36
|
|
|
28
37
|
const style2 = {
|
|
29
38
|
fontSize: "3rem",
|
|
30
|
-
fontWeight: "bold"
|
|
31
|
-
color: "#ff2800"
|
|
39
|
+
fontWeight: "bold"
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
export default NotFound;
|
package/src/router.js
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import NotFound from "./NotFound.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Ініціалізація роутера.
|
|
5
|
+
*/
|
|
6
|
+
export const router = async ({routes, main, message = "", props = {}}) => {
|
|
4
7
|
const renderRoute = async () => {
|
|
5
|
-
const {
|
|
8
|
+
const {routeComponent, props: routeProps} = useRoutes(routes);
|
|
6
9
|
main.innerHTML = "";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
if (!routeComponent) {
|
|
12
|
+
return;
|
|
10
13
|
}
|
|
14
|
+
|
|
15
|
+
const component = await routeComponent({
|
|
16
|
+
...props,
|
|
17
|
+
...routeProps,
|
|
18
|
+
message,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
main.appendChild(component);
|
|
11
22
|
};
|
|
12
23
|
|
|
13
24
|
window.addEventListener('popstate', renderRoute);
|
|
@@ -16,21 +27,84 @@ export const router = async ({ routes, main }) => {
|
|
|
16
27
|
await renderRoute();
|
|
17
28
|
};
|
|
18
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Перехід без рендеру.
|
|
32
|
+
*/
|
|
19
33
|
export const navigateTo = (path, props = {}) => {
|
|
20
34
|
window.history.pushState(props, "", path);
|
|
21
35
|
};
|
|
22
36
|
|
|
23
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Перехід + рендер.
|
|
39
|
+
*/
|
|
40
|
+
export const navi = async (path, props = {}) => {
|
|
24
41
|
window.history.pushState(props, "", path);
|
|
25
|
-
|
|
42
|
+
|
|
43
|
+
await window.renderRoute();
|
|
26
44
|
};
|
|
27
45
|
|
|
28
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Порівнює URL з шаблоном route
|
|
48
|
+
* і повертає параметри.
|
|
49
|
+
*
|
|
50
|
+
* /category/{id}
|
|
51
|
+
* /category/15
|
|
52
|
+
*
|
|
53
|
+
* => { id: "15" }
|
|
54
|
+
*
|
|
55
|
+
* /category/{category_id}/product/{product_id}
|
|
56
|
+
* /category/15/product/128
|
|
57
|
+
*
|
|
58
|
+
* => {
|
|
59
|
+
* category_id: "15",
|
|
60
|
+
* product_id: "128"
|
|
61
|
+
* }
|
|
62
|
+
*/
|
|
63
|
+
const matchRoute = (routePath, path) => {
|
|
64
|
+
const keys = [];
|
|
65
|
+
|
|
66
|
+
const pattern = routePath.replace(/\{([^}]+)}/g, (_, key) => {
|
|
67
|
+
keys.push(key);
|
|
68
|
+
|
|
69
|
+
return '([^/]+)';
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const match = path.match(new RegExp(`^${pattern}$`));
|
|
73
|
+
|
|
74
|
+
if (!match) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return keys.reduce((params, key, index) => {
|
|
79
|
+
params[key] = decodeURIComponent(match[index + 1]);
|
|
80
|
+
|
|
81
|
+
return params;
|
|
82
|
+
}, {});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Знаходить поточний route.
|
|
87
|
+
*/
|
|
88
|
+
const useRoutes = (routes) => {
|
|
29
89
|
const path = window.location.pathname;
|
|
30
|
-
const matchingRoute = routes.find(route => route.path === path);
|
|
31
|
-
const props = window.history.state || {};
|
|
32
90
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
91
|
+
for (const route of routes) {
|
|
92
|
+
const params = matchRoute(route.path, path);
|
|
93
|
+
if (params !== null) {
|
|
94
|
+
return {
|
|
95
|
+
routeComponent: route.component,
|
|
96
|
+
props: {
|
|
97
|
+
...(window.history.state || {}),
|
|
98
|
+
...params,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
routeComponent: NotFound,
|
|
106
|
+
props: {
|
|
107
|
+
...(window.history.state || {}),
|
|
108
|
+
},
|
|
109
|
+
};
|
|
36
110
|
};
|