@arcote.tech/platform 0.5.1 → 0.5.2
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 +4 -4
- package/src/layout/page-router.tsx +45 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcote.tech/platform",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.2",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Przemysław Krasiński [arcote.tech]",
|
|
7
7
|
"description": "Arc Platform — module system, router, layout, theme, i18n, platform app shell",
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
"type-check": "tsc --noEmit"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@arcote.tech/arc-ds": "^0.5.
|
|
22
|
-
"@arcote.tech/arc-react": "^0.5.
|
|
21
|
+
"@arcote.tech/arc-ds": "^0.5.2",
|
|
22
|
+
"@arcote.tech/arc-react": "^0.5.2"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"@arcote.tech/arc": "^0.5.
|
|
25
|
+
"@arcote.tech/arc": "^0.5.2",
|
|
26
26
|
"@lingui/core": "^5.0.0",
|
|
27
27
|
"@lingui/react": "^5.0.0",
|
|
28
28
|
"framer-motion": "^12.0.0",
|
|
@@ -9,6 +9,7 @@ import type { PageFragment } from "../types";
|
|
|
9
9
|
type MatchResult = {
|
|
10
10
|
page: PageFragment;
|
|
11
11
|
child?: PageFragment;
|
|
12
|
+
grandchild?: PageFragment;
|
|
12
13
|
params: Record<string, string>;
|
|
13
14
|
};
|
|
14
15
|
|
|
@@ -23,6 +24,26 @@ function matchPage(path: string, pages: PageFragment[]): MatchResult | undefined
|
|
|
23
24
|
if (p.children?.length) {
|
|
24
25
|
if (path === p.path) return { page: p, params: {} };
|
|
25
26
|
|
|
27
|
+
// Check grandchildren first (deeper match wins)
|
|
28
|
+
for (const c of p.children) {
|
|
29
|
+
if (c.children?.length) {
|
|
30
|
+
if (path === c.path) return { page: p, child: c, params: {} };
|
|
31
|
+
|
|
32
|
+
const exactGrandchild = c.children.find((gc) => gc.path === path);
|
|
33
|
+
if (exactGrandchild) return { page: p, child: c, grandchild: exactGrandchild, params: {} };
|
|
34
|
+
|
|
35
|
+
for (const gc of c.children) {
|
|
36
|
+
if (hasRouteParams(gc.path)) {
|
|
37
|
+
const params = matchRoutePath(gc.path, path);
|
|
38
|
+
if (params) return { page: p, child: c, grandchild: gc, params };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const prefixGrandchild = c.children.find((gc) => path.startsWith(gc.path));
|
|
43
|
+
if (prefixGrandchild) return { page: p, child: c, grandchild: prefixGrandchild, params: {} };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
26
47
|
// Try exact child match first
|
|
27
48
|
const exactChild = p.children.find((c) => c.path === path);
|
|
28
49
|
if (exactChild) return { page: p, child: exactChild, params: {} };
|
|
@@ -94,7 +115,7 @@ export function PageRouter() {
|
|
|
94
115
|
return null;
|
|
95
116
|
}
|
|
96
117
|
|
|
97
|
-
const { page, child } = match;
|
|
118
|
+
const { page, child, grandchild } = match;
|
|
98
119
|
const Layout = page.layout ?? DefaultLayout;
|
|
99
120
|
|
|
100
121
|
// Parent with children — redirect to first child if at parent path
|
|
@@ -103,6 +124,29 @@ export function PageRouter() {
|
|
|
103
124
|
return null;
|
|
104
125
|
}
|
|
105
126
|
|
|
127
|
+
// Grandchild — nested shell: OuterShell > InnerShell > GrandchildComponent
|
|
128
|
+
if (page.children?.length && child?.children?.length && grandchild) {
|
|
129
|
+
const OuterShell = page.component;
|
|
130
|
+
const InnerShell = child.component;
|
|
131
|
+
const GrandchildComponent = grandchild.component;
|
|
132
|
+
const content = (
|
|
133
|
+
<OuterShell tabs={page.children}>
|
|
134
|
+
<InnerShell tabs={child.children}>
|
|
135
|
+
<Suspense fallback={null}>
|
|
136
|
+
<GrandchildComponent />
|
|
137
|
+
</Suspense>
|
|
138
|
+
</InnerShell>
|
|
139
|
+
</OuterShell>
|
|
140
|
+
);
|
|
141
|
+
return Layout ? <Layout>{content}</Layout> : content;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Child with its own children — redirect to first grandchild
|
|
145
|
+
if (page.children?.length && child?.children?.length && !grandchild) {
|
|
146
|
+
navigate(child.children[0].path);
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
|
|
106
150
|
// Parent with active child — render shell with tabs
|
|
107
151
|
if (page.children?.length && child) {
|
|
108
152
|
const Shell = page.component;
|