polen 0.8.0-next.4 → 0.8.0-next.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/build/api/vite/plugins/core.d.ts.map +1 -1
- package/build/api/vite/plugins/core.js +146 -52
- package/build/api/vite/plugins/core.js.map +1 -1
- package/build/lib/file-router/linter.d.ts.map +1 -1
- package/build/lib/file-router/linter.js +3 -3
- package/build/lib/file-router/linter.js.map +1 -1
- package/build/lib/file-router/route.d.ts +48 -10
- package/build/lib/file-router/route.d.ts.map +1 -1
- package/build/lib/file-router/route.js +68 -3
- package/build/lib/file-router/route.js.map +1 -1
- package/build/lib/file-router/scan.d.ts +2 -2
- package/build/lib/file-router/scan.d.ts.map +1 -1
- package/build/lib/file-router/scan.js +8 -8
- package/build/lib/file-router/scan.js.map +1 -1
- package/build/lib/file-router/sidebar.d.ts +2 -0
- package/build/lib/file-router/sidebar.d.ts.map +1 -0
- package/build/lib/file-router/sidebar.js +2 -0
- package/build/lib/file-router/sidebar.js.map +1 -0
- package/build/lib/kit-temp.d.ts +2 -0
- package/build/lib/kit-temp.d.ts.map +1 -0
- package/build/lib/kit-temp.js +23 -0
- package/build/lib/kit-temp.js.map +1 -0
- package/build/project-data.d.ts +21 -1
- package/build/project-data.d.ts.map +1 -1
- package/build/template/components/Sidebar.d.ts +7 -0
- package/build/template/components/Sidebar.d.ts.map +1 -0
- package/build/template/components/Sidebar.jsx +108 -0
- package/build/template/components/Sidebar.jsx.map +1 -0
- package/build/template/routes/root.d.ts.map +1 -1
- package/build/template/routes/root.jsx +28 -5
- package/build/template/routes/root.jsx.map +1 -1
- package/package.json +1 -1
- package/src/api/vite/plugins/core.ts +178 -54
- package/src/lib/file-router/index.test.ts +5 -5
- package/src/lib/file-router/linter.ts +3 -3
- package/src/lib/file-router/route.ts +147 -11
- package/src/lib/file-router/scan.ts +9 -9
- package/src/lib/file-router/sidebar.ts +0 -0
- package/src/lib/kit-temp.ts +21 -0
- package/src/project-data.ts +26 -1
- package/src/template/components/Sidebar.tsx +185 -0
- package/src/template/routes/root.tsx +35 -5
package/build/project-data.d.ts
CHANGED
@@ -4,6 +4,7 @@ import type { Schema } from './api/schema/index.js';
|
|
4
4
|
export interface ProjectData {
|
5
5
|
schema: null | Schema.Schema;
|
6
6
|
siteNavigationItems: SiteNavigationItem[];
|
7
|
+
sidebarIndex: SidebarIndex;
|
7
8
|
faviconPath: string;
|
8
9
|
paths: Configurator.Config[`paths`][`project`];
|
9
10
|
pagesScanResult: FileRouter.ScanResult;
|
@@ -16,6 +17,25 @@ export interface ProjectData {
|
|
16
17
|
}
|
17
18
|
export interface SiteNavigationItem {
|
18
19
|
title: string;
|
19
|
-
|
20
|
+
pathExp: string;
|
21
|
+
}
|
22
|
+
export interface SidebarIndex {
|
23
|
+
[pathExpression: string]: Sidebar;
|
24
|
+
}
|
25
|
+
export interface Sidebar {
|
26
|
+
items: SidebarItem[];
|
27
|
+
}
|
28
|
+
export type SidebarItem = SidebarNav | SidebarSection;
|
29
|
+
export interface SidebarNav {
|
30
|
+
type: `SidebarItem`;
|
31
|
+
title: string;
|
32
|
+
pathExp: string;
|
33
|
+
}
|
34
|
+
export interface SidebarSection {
|
35
|
+
type: `SidebarSection`;
|
36
|
+
title: string;
|
37
|
+
pathExp: string;
|
38
|
+
isNavToo: boolean;
|
39
|
+
navs: SidebarNav[];
|
20
40
|
}
|
21
41
|
//# sourceMappingURL=project-data.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"project-data.d.ts","sourceRoot":"","sources":["../src/project-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAEnD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,CAAA;IAC5B,mBAAmB,EAAE,kBAAkB,EAAE,CAAA;IACzC,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAA;IAC9C,eAAe,EAAE,UAAU,CAAC,UAAU,CAAA;IACtC,MAAM,EAAE;QACN,MAAM,EAAE;YACN,SAAS,EAAE,MAAM,CAAA;YACjB,KAAK,EAAE,MAAM,CAAA;SACd,CAAA;KACF,CAAA;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;
|
1
|
+
{"version":3,"file":"project-data.d.ts","sourceRoot":"","sources":["../src/project-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAEnD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,CAAA;IAC5B,mBAAmB,EAAE,kBAAkB,EAAE,CAAA;IACzC,YAAY,EAAE,YAAY,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAA;IAC9C,eAAe,EAAE,UAAU,CAAC,UAAU,CAAA;IACtC,MAAM,EAAE;QACN,MAAM,EAAE;YACN,SAAS,EAAE,MAAM,CAAA;YACjB,KAAK,EAAE,MAAM,CAAA;SACd,CAAA;KACF,CAAA;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAA;CAClC;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,WAAW,EAAE,CAAA;CACrB;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,cAAc,CAAA;AAErD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,aAAa,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,gBAAgB,CAAA;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,CAAA;IACjB,IAAI,EAAE,UAAU,EAAE,CAAA;CACnB"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../src/template/components/Sidebar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAA8B,MAAM,uBAAuB,CAAA;AAEpF,UAAU,YAAY;IACpB,KAAK,EAAE,WAAW,EAAE,CAAA;CACrB;AAED,eAAO,MAAM,OAAO,GAAI,WAAW,YAAY,gCAyB9C,CAAA"}
|
@@ -0,0 +1,108 @@
|
|
1
|
+
import { ChevronDownIcon, ChevronRightIcon } from '@radix-ui/react-icons';
|
2
|
+
import { Box, Flex, Text } from '@radix-ui/themes';
|
3
|
+
import { useState } from 'react';
|
4
|
+
import { Link, useLocation } from 'react-router';
|
5
|
+
export const Sidebar = ({ items }) => {
|
6
|
+
const location = useLocation();
|
7
|
+
return (<Box style={{
|
8
|
+
width: `240px`,
|
9
|
+
minWidth: `240px`,
|
10
|
+
flexShrink: 0,
|
11
|
+
borderRight: `1px solid var(--gray-3)`,
|
12
|
+
height: `100%`,
|
13
|
+
paddingRight: `var(--space-4)`,
|
14
|
+
}}>
|
15
|
+
<Flex direction='column' gap='1'>
|
16
|
+
{items.map((item) => (<SidebarItemComponent key={item.pathExp} item={item} currentPathExp={location.pathname}/>))}
|
17
|
+
</Flex>
|
18
|
+
</Box>);
|
19
|
+
};
|
20
|
+
const SidebarItemComponent = ({ item, currentPathExp, level = 0 }) => {
|
21
|
+
if (item.type === `SidebarItem`) {
|
22
|
+
return <SidebarNavItem nav={item} currentPathExp={currentPathExp} level={level}/>;
|
23
|
+
}
|
24
|
+
return <SidebarSectionItem section={item} currentPathExp={currentPathExp} level={level}/>;
|
25
|
+
};
|
26
|
+
const SidebarNavItem = ({ nav, currentPathExp, level }) => {
|
27
|
+
const isActive = currentPathExp === nav.pathExp;
|
28
|
+
return (<Link to={nav.pathExp} style={{
|
29
|
+
textDecoration: `none`,
|
30
|
+
color: isActive ? `var(--accent-11)` : `var(--gray-12)`,
|
31
|
+
padding: `var(--space-2) var(--space-3)`,
|
32
|
+
paddingLeft: `calc(var(--space-3) + ${(level * 16).toString()}px)`,
|
33
|
+
borderRadius: `var(--radius-2)`,
|
34
|
+
display: `block`,
|
35
|
+
backgroundColor: isActive ? `var(--accent-3)` : `transparent`,
|
36
|
+
transition: `background-color 0.2s ease, color 0.2s ease`,
|
37
|
+
}} onMouseEnter={(e) => {
|
38
|
+
if (!isActive) {
|
39
|
+
e.currentTarget.style.backgroundColor = `var(--gray-2)`;
|
40
|
+
}
|
41
|
+
}} onMouseLeave={(e) => {
|
42
|
+
if (!isActive) {
|
43
|
+
e.currentTarget.style.backgroundColor = `transparent`;
|
44
|
+
}
|
45
|
+
}}>
|
46
|
+
<Text size='2' weight={isActive ? `medium` : `regular`}>
|
47
|
+
{nav.title}
|
48
|
+
</Text>
|
49
|
+
</Link>);
|
50
|
+
};
|
51
|
+
const SidebarSectionItem = ({ section, currentPathExp, level }) => {
|
52
|
+
const [isExpanded, setIsExpanded] = useState(true);
|
53
|
+
const isDirectlyActive = currentPathExp === section.pathExp;
|
54
|
+
const hasActiveChild = section.navs.some(nav => currentPathExp === nav.pathExp);
|
55
|
+
const isActiveGroup = isDirectlyActive || hasActiveChild;
|
56
|
+
return (<>
|
57
|
+
<Flex align='center' style={{
|
58
|
+
padding: `var(--space-2) var(--space-3)`,
|
59
|
+
paddingLeft: `calc(var(--space-3) + ${(level * 16).toString()}px)`,
|
60
|
+
borderRadius: `var(--radius-2)`,
|
61
|
+
backgroundColor: isDirectlyActive ? `var(--accent-3)` : hasActiveChild ? `var(--accent-2)` : `transparent`,
|
62
|
+
transition: `background-color 0.2s ease`,
|
63
|
+
}} onMouseEnter={(e) => {
|
64
|
+
if (!isActiveGroup) {
|
65
|
+
e.currentTarget.style.backgroundColor = `var(--gray-2)`;
|
66
|
+
}
|
67
|
+
}} onMouseLeave={(e) => {
|
68
|
+
if (!isActiveGroup) {
|
69
|
+
e.currentTarget.style.backgroundColor = `transparent`;
|
70
|
+
}
|
71
|
+
}}>
|
72
|
+
<Box onClick={(e) => {
|
73
|
+
e.stopPropagation();
|
74
|
+
console.log(`Chevron clicked!`);
|
75
|
+
setIsExpanded(!isExpanded);
|
76
|
+
}} style={{
|
77
|
+
display: `flex`,
|
78
|
+
alignItems: `center`,
|
79
|
+
cursor: `pointer`,
|
80
|
+
padding: `4px`,
|
81
|
+
marginRight: `4px`,
|
82
|
+
marginLeft: `-4px`,
|
83
|
+
}}>
|
84
|
+
{isExpanded ? <ChevronDownIcon /> : <ChevronRightIcon />}
|
85
|
+
</Box>
|
86
|
+
{section.isNavToo
|
87
|
+
? (<Link to={section.pathExp} style={{
|
88
|
+
textDecoration: `none`,
|
89
|
+
color: isDirectlyActive ? `var(--accent-11)` : `var(--gray-12)`,
|
90
|
+
flex: 1,
|
91
|
+
}}>
|
92
|
+
<Text size='2' weight={isDirectlyActive ? `bold` : `medium`}>
|
93
|
+
{section.title}
|
94
|
+
</Text>
|
95
|
+
</Link>)
|
96
|
+
: (<Text size='2' weight={isDirectlyActive ? `bold` : `medium`} style={{
|
97
|
+
flex: 1,
|
98
|
+
color: isDirectlyActive ? `var(--accent-11)` : `var(--gray-12)`,
|
99
|
+
}}>
|
100
|
+
{section.title}
|
101
|
+
</Text>)}
|
102
|
+
</Flex>
|
103
|
+
{isExpanded && (<Flex direction='column' gap='1'>
|
104
|
+
{section.navs.map((nav) => (<SidebarNavItem key={nav.pathExp} nav={nav} currentPathExp={currentPathExp} level={level + 1}/>))}
|
105
|
+
</Flex>)}
|
106
|
+
</>);
|
107
|
+
};
|
108
|
+
//# sourceMappingURL=Sidebar.jsx.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"Sidebar.jsx","sourceRoot":"","sources":["../../../src/template/components/Sidebar.tsx"],"names":[],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../../src/template/routes/root.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../../src/template/routes/root.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AA0B7D,eAAO,MAAM,SAAS,mCA6BrB,CAAA;AAgJD,eAAO,MAAM,IAAI;;;;CAIf,CAAA"}
|
@@ -4,10 +4,11 @@ import { Box, Button, Heading, Text } from '@radix-ui/themes';
|
|
4
4
|
import { Flex, Theme } from '@radix-ui/themes';
|
5
5
|
import radixStylesUrl from '@radix-ui/themes/styles.css?url';
|
6
6
|
import { Link as LinkReactRouter } from 'react-router';
|
7
|
-
import { Outlet, ScrollRestoration } from 'react-router';
|
7
|
+
import { Outlet, ScrollRestoration, useLocation } from 'react-router';
|
8
8
|
import { PROJECT_DATA } from 'virtual:polen/project/data';
|
9
9
|
import { templateVariables } from 'virtual:polen/template/variables';
|
10
10
|
import { Link } from '../components/Link.jsx';
|
11
|
+
import { Sidebar } from '../components/Sidebar.jsx';
|
11
12
|
import entryClientUrl from '../entry.client.jsx?url';
|
12
13
|
import { changelog } from './changelog.jsx';
|
13
14
|
import { index } from './index.jsx';
|
@@ -40,6 +41,20 @@ export const Component = () => {
|
|
40
41
|
</html>);
|
41
42
|
};
|
42
43
|
const Layout = () => {
|
44
|
+
const location = useLocation();
|
45
|
+
// Determine if we should show sidebar based on current path
|
46
|
+
const getCurrentNavPathExp = () => {
|
47
|
+
// todo: general path manipulation lib because we are duplicating logic here found in FileRouter
|
48
|
+
// todo: kit: try a Str.split that returns [] | string[] so that our predicates can refine on it?
|
49
|
+
const segments = location.pathname.split(`/`).filter(Boolean);
|
50
|
+
if (Arr.isntEmpty(segments)) {
|
51
|
+
return `/${segments[0]}`;
|
52
|
+
}
|
53
|
+
return null;
|
54
|
+
};
|
55
|
+
const currentNavPathExp = getCurrentNavPathExp();
|
56
|
+
const sidebar = currentNavPathExp && PROJECT_DATA.sidebarIndex[currentNavPathExp];
|
57
|
+
const showSidebar = sidebar && sidebar.items.length > 0;
|
43
58
|
return (<Theme asChild>
|
44
59
|
<Box m='8'>
|
45
60
|
<Flex align='center' gap='8' pb='4' mb='8' style={{
|
@@ -54,14 +69,21 @@ const Layout = () => {
|
|
54
69
|
</Flex>
|
55
70
|
</LinkReactRouter>
|
56
71
|
<Flex direction='row' gap='4'>
|
57
|
-
{PROJECT_DATA.siteNavigationItems.map((item, key) => (<Link key={key} color='gray' to={item.
|
72
|
+
{PROJECT_DATA.siteNavigationItems.map((item, key) => (<Link key={key} color='gray' to={item.pathExp}>
|
58
73
|
{item.title}
|
59
74
|
</Link>))}
|
60
75
|
</Flex>
|
61
76
|
</Flex>
|
62
|
-
|
63
|
-
|
64
|
-
|
77
|
+
{showSidebar
|
78
|
+
? (<Flex gap='8'>
|
79
|
+
<Sidebar items={sidebar.items}/>
|
80
|
+
<Box style={{ flex: 1 }}>
|
81
|
+
<Outlet />
|
82
|
+
</Box>
|
83
|
+
</Flex>)
|
84
|
+
: (<Box>
|
85
|
+
<Outlet />
|
86
|
+
</Box>)}
|
65
87
|
</Box>
|
66
88
|
</Theme>);
|
67
89
|
};
|
@@ -127,6 +149,7 @@ children.push(notFoundRoute);
|
|
127
149
|
// ━━━━━━━━━━━━━━ • Root Route
|
128
150
|
//
|
129
151
|
//
|
152
|
+
import { Arr } from '@wollybeard/kit';
|
130
153
|
import { pages } from 'virtual:polen/project/pages.jsx';
|
131
154
|
export const root = createRoute({
|
132
155
|
path: `/`,
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"root.jsx","sourceRoot":"","sources":["../../../src/template/routes/root.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,cAAc,MAAM,iCAAiC,CAAA;AAC5D,OAAO,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,cAAc,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;
|
1
|
+
{"version":3,"file":"root.jsx","sourceRoot":"","sources":["../../../src/template/routes/root.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,13 +1,19 @@
|
|
1
|
-
import { Markdown } from '#api/singletons/markdown/index.js'
|
2
1
|
import type { ReactRouter } from '#dep/react-router/index.js'
|
3
2
|
import type { Vite } from '#dep/vite/index.js'
|
4
3
|
import { FileRouter } from '#lib/file-router/index.js'
|
5
4
|
import { ViteVirtual } from '#lib/vite-virtual/index.js'
|
6
5
|
import mdx from '@mdx-js/rollup'
|
7
|
-
import { Cache,
|
6
|
+
import { Cache, Idx, Json, Path, Str } from '@wollybeard/kit'
|
8
7
|
import jsesc from 'jsesc'
|
9
8
|
import remarkGfm from 'remark-gfm'
|
10
|
-
import type {
|
9
|
+
import type {
|
10
|
+
ProjectData,
|
11
|
+
Sidebar,
|
12
|
+
SidebarIndex,
|
13
|
+
SidebarNav,
|
14
|
+
SidebarSection,
|
15
|
+
SiteNavigationItem,
|
16
|
+
} from '../../../project-data.js'
|
11
17
|
import { superjson } from '../../../singletons/superjson.js'
|
12
18
|
import type { Configurator } from '../../configurator/index.js'
|
13
19
|
import { SchemaAugmentation } from '../../schema-augmentation/index.js'
|
@@ -53,27 +59,31 @@ export const Core = (config: Configurator.Config): Vite.PluginOption[] => {
|
|
53
59
|
],
|
54
60
|
}),
|
55
61
|
},
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
62
|
+
// TODO: We can remove, mdx subsumes this
|
63
|
+
// TODO: First we need to investigate how e can make our api singleton Markdown used by MDX.
|
64
|
+
// If we cannot, then we might want to ditch MDX instead and use our lower level solution here.
|
65
|
+
// It depends in part on how complex our Markdown singleton gets.
|
66
|
+
// {
|
67
|
+
// name: `polen:markdown`,
|
68
|
+
// enforce: `pre`,
|
69
|
+
// resolveId(id) {
|
70
|
+
// if (id.endsWith(`.md`)) {
|
71
|
+
// return id
|
72
|
+
// }
|
73
|
+
// return null
|
74
|
+
// },
|
75
|
+
// async load(id) {
|
76
|
+
// if (id.endsWith(`.md`)) {
|
77
|
+
// const markdownString = await Fs.read(id)
|
78
|
+
// if (!markdownString) return null
|
79
|
+
// const htmlString = await Markdown.parse(markdownString)
|
80
|
+
|
81
|
+
// const code = `export default ${JSON.stringify(htmlString)}`
|
82
|
+
// return code
|
83
|
+
// }
|
84
|
+
// return null
|
85
|
+
// },
|
86
|
+
// },
|
77
87
|
{
|
78
88
|
name: `polen:core:alias`,
|
79
89
|
resolveId(id, importer) {
|
@@ -136,35 +146,67 @@ export const Core = (config: Configurator.Config): Vite.PluginOption[] => {
|
|
136
146
|
async loader() {
|
137
147
|
// todo: parallel
|
138
148
|
const schema = await readSchema()
|
139
|
-
console.log({ schema })
|
140
149
|
const pagesScanResult = await scanPageRoutes()
|
141
150
|
|
142
151
|
const siteNavigationItems: SiteNavigationItem[] = []
|
143
152
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
.map(route => {
|
148
|
-
const path = FileRouter.routeToString(route)
|
149
|
-
const title = Str.titlizeSlug(path)
|
150
|
-
return {
|
151
|
-
path,
|
152
|
-
title,
|
153
|
-
}
|
154
|
-
})
|
153
|
+
//
|
154
|
+
// ━━ Build Navbar
|
155
|
+
//
|
155
156
|
|
156
|
-
|
157
|
+
// ━ Top pages become navigation items
|
158
|
+
const topPages = pagesScanResult.routes.filter(FileRouter.routeIsTopLevel)
|
159
|
+
|
160
|
+
for (const page of topPages) {
|
161
|
+
const path = FileRouter.routeToPathExpression(page)
|
162
|
+
const title = Str.titlizeSlug(path)
|
163
|
+
siteNavigationItems.push({ pathExp: path, title })
|
164
|
+
}
|
157
165
|
|
166
|
+
// ━ Top directories become navigation items
|
167
|
+
const topDirsPaths = pagesScanResult.routes
|
168
|
+
.filter(FileRouter.routeIsSubLevel)
|
169
|
+
// todo: kit, slice that understands non-empty
|
170
|
+
// Arr.slice(route.path.segments, 1)
|
171
|
+
.map(route => [route.logical.path[0]])
|
172
|
+
|
173
|
+
for (const dir of topDirsPaths) {
|
174
|
+
const pathExp = FileRouter.pathToExpression(dir)
|
175
|
+
const title = Str.titlizeSlug(pathExp)
|
176
|
+
// todo: this should never happen, if it does, swarn user
|
177
|
+
// Only add if not already added as a top page
|
178
|
+
if (!siteNavigationItems.some(item => item.pathExp === pathExp)) {
|
179
|
+
siteNavigationItems.push({ pathExp: pathExp, title })
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
// ━ Schema presence causes adding some navbar items
|
158
184
|
if (schema) {
|
159
|
-
siteNavigationItems.push({
|
185
|
+
siteNavigationItems.push({ pathExp: `/reference`, title: `Reference` })
|
160
186
|
if (schema.versions.length > 1) {
|
161
|
-
siteNavigationItems.push({
|
187
|
+
siteNavigationItems.push({ pathExp: `/changelog`, title: `Changelog` })
|
162
188
|
}
|
163
189
|
}
|
164
190
|
|
191
|
+
//
|
192
|
+
// ━━ Build Sidebar
|
193
|
+
//
|
194
|
+
|
195
|
+
const sidebarIndex: SidebarIndex = {}
|
196
|
+
|
197
|
+
for (const dirPath of topDirsPaths) {
|
198
|
+
const childPages = pagesScanResult.routes.filter(page => FileRouter.routeIsSubOf(page, dirPath))
|
199
|
+
sidebarIndex[FileRouter.pathToExpression(dirPath)] = buildSidebar(childPages, dirPath)
|
200
|
+
}
|
201
|
+
|
202
|
+
//
|
203
|
+
// ━━ Put It All together
|
204
|
+
//
|
205
|
+
|
165
206
|
const projectData: ProjectData = {
|
166
207
|
schema,
|
167
208
|
siteNavigationItems,
|
209
|
+
sidebarIndex,
|
168
210
|
faviconPath: `/logo.svg`,
|
169
211
|
pagesScanResult: pagesScanResult,
|
170
212
|
paths: config.paths.project,
|
@@ -204,25 +246,16 @@ export const Core = (config: Configurator.Config): Vite.PluginOption[] => {
|
|
204
246
|
|
205
247
|
// todo: kit fs should accept parsed file paths
|
206
248
|
for (const route of pagesScanResult.routes) {
|
207
|
-
const
|
208
|
-
const
|
209
|
-
const ident = Str.Case.camel(`page ` + Str.titlizeSlug(
|
249
|
+
const filePathExp = Path.format(route.file.path.absolute)
|
250
|
+
const pathExp = FileRouter.routeToPathExpression(route)
|
251
|
+
const ident = Str.Case.camel(`page ` + Str.titlizeSlug(pathExp))
|
210
252
|
|
211
253
|
s`
|
212
|
-
import ${ident} from '${
|
254
|
+
import ${ident} from '${filePathExp}'
|
213
255
|
|
214
256
|
${$.pages}.push({
|
215
|
-
path: '${
|
216
|
-
Component:
|
217
|
-
if (typeof ${ident} === 'function') {
|
218
|
-
// ━ MDX
|
219
|
-
const Component = ${ident}
|
220
|
-
return <Component />
|
221
|
-
} else {
|
222
|
-
// ━ MD
|
223
|
-
return <div dangerouslySetInnerHTML={{ __html: ${ident} }} />
|
224
|
-
}
|
225
|
-
}
|
257
|
+
path: '${pathExp}',
|
258
|
+
Component: ${ident}
|
226
259
|
})
|
227
260
|
`
|
228
261
|
}
|
@@ -234,3 +267,94 @@ export const Core = (config: Configurator.Config): Vite.PluginOption[] => {
|
|
234
267
|
},
|
235
268
|
]
|
236
269
|
}
|
270
|
+
|
271
|
+
/**
|
272
|
+
* Helper function to build sidebar items recursively
|
273
|
+
*/
|
274
|
+
const buildSidebar = (pages: FileRouter.Route[], basePath: FileRouter.Path): Sidebar => {
|
275
|
+
const navs: SidebarNav[] = []
|
276
|
+
const sections = Idx.create<SidebarSection, string>({ toKey: (item) => item.pathExp })
|
277
|
+
|
278
|
+
// Items
|
279
|
+
for (const page of pages) {
|
280
|
+
const pageRelative = FileRouter.makeRelativeUnsafe(page, basePath)
|
281
|
+
|
282
|
+
if (FileRouter.routeIsRootLevel(pageRelative)) {
|
283
|
+
continue
|
284
|
+
}
|
285
|
+
|
286
|
+
if (FileRouter.routeIsTopLevel(pageRelative)) {
|
287
|
+
// Section (index)
|
288
|
+
if (FileRouter.routeIsFromIndexFile(pageRelative)) {
|
289
|
+
const sectionPath = page.logical.path
|
290
|
+
const sectionPathExp = FileRouter.pathToExpression(sectionPath)
|
291
|
+
|
292
|
+
let section: SidebarSection | undefined
|
293
|
+
section = sections.getKey(sectionPathExp)
|
294
|
+
|
295
|
+
if (!section) {
|
296
|
+
const sectionTitle = Str.titlizeSlug(FileRouter.pathToExpression(pageRelative.logical.path))
|
297
|
+
section = {
|
298
|
+
type: `SidebarSection`,
|
299
|
+
title: sectionTitle,
|
300
|
+
pathExp: sectionPathExp,
|
301
|
+
isNavToo: false,
|
302
|
+
navs: [],
|
303
|
+
}
|
304
|
+
|
305
|
+
sections.set(section)
|
306
|
+
}
|
307
|
+
section.isNavToo = true
|
308
|
+
continue
|
309
|
+
}
|
310
|
+
|
311
|
+
// Nav
|
312
|
+
navs.push(pageToSidebarNav(page, basePath))
|
313
|
+
continue
|
314
|
+
}
|
315
|
+
|
316
|
+
// Section (sub-page)
|
317
|
+
if (FileRouter.routeIsSubLevel(pageRelative)) {
|
318
|
+
const sectionRelativePath = [pageRelative.logical.path[0]]
|
319
|
+
const sectionPath = [...basePath, ...sectionRelativePath]
|
320
|
+
const sectionPathExp = FileRouter.pathToExpression(sectionPath)
|
321
|
+
|
322
|
+
let section: SidebarSection | undefined
|
323
|
+
section = sections.getKey(sectionPathExp)
|
324
|
+
|
325
|
+
if (!section) {
|
326
|
+
const sectionTitle = Str.titlizeSlug(FileRouter.pathToExpression(sectionRelativePath))
|
327
|
+
section = {
|
328
|
+
type: `SidebarSection`,
|
329
|
+
title: sectionTitle,
|
330
|
+
pathExp: sectionPathExp,
|
331
|
+
isNavToo: false,
|
332
|
+
navs: [],
|
333
|
+
}
|
334
|
+
sections.set(section)
|
335
|
+
}
|
336
|
+
section.navs.push(pageToSidebarNav(page, sectionPath))
|
337
|
+
}
|
338
|
+
}
|
339
|
+
|
340
|
+
const items = [...navs, ...sections.data.array]
|
341
|
+
|
342
|
+
return {
|
343
|
+
items,
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
/**
|
348
|
+
* Helper function to build sidebar items recursively
|
349
|
+
*/
|
350
|
+
const pageToSidebarNav = (page: FileRouter.Route, basePath: FileRouter.Path): SidebarNav => {
|
351
|
+
const pagePathExp = FileRouter.routeToPathExpression(page)
|
352
|
+
const pageRelative = FileRouter.makeRelativeUnsafe(page, basePath)
|
353
|
+
const pageRelativePathExp = FileRouter.routeToPathExpression(pageRelative)
|
354
|
+
|
355
|
+
return {
|
356
|
+
type: `SidebarItem`,
|
357
|
+
pathExp: pagePathExp,
|
358
|
+
title: Str.titlizeSlug(pageRelativePathExp),
|
359
|
+
}
|
360
|
+
}
|
@@ -21,7 +21,7 @@ describe('.scan', () => {
|
|
21
21
|
const routes = await scan(project.dir)
|
22
22
|
expect(routes).toMatchObject($({
|
23
23
|
routes: [{
|
24
|
-
|
24
|
+
logical: { path: ['a'] },
|
25
25
|
file: { path: { relative: { dir: '', base: 'a.md' } } },
|
26
26
|
}],
|
27
27
|
}))
|
@@ -31,7 +31,7 @@ describe('.scan', () => {
|
|
31
31
|
const routes = await scan(project.dir)
|
32
32
|
expect(routes).toMatchObject($({
|
33
33
|
routes: [{
|
34
|
-
|
34
|
+
logical: { path: ['a', 'b'] },
|
35
35
|
file: { path: { relative: { dir: 'a', base: 'b.md' } } },
|
36
36
|
}],
|
37
37
|
}))
|
@@ -43,7 +43,7 @@ describe('.scan', () => {
|
|
43
43
|
const routes = await scan(project.dir)
|
44
44
|
expect(routes).toMatchObject($({
|
45
45
|
routes: [{
|
46
|
-
|
46
|
+
logical: { path: [] },
|
47
47
|
file: { path: { relative: { dir: '', base: 'index.md' } } },
|
48
48
|
}],
|
49
49
|
}))
|
@@ -53,7 +53,7 @@ describe('.scan', () => {
|
|
53
53
|
const routes = await scan(project.dir)
|
54
54
|
expect(routes).toMatchObject($({
|
55
55
|
routes: [{
|
56
|
-
|
56
|
+
logical: { path: ['a'] },
|
57
57
|
file: { path: { relative: { dir: 'a', base: 'index.md' } } },
|
58
58
|
}],
|
59
59
|
}))
|
@@ -66,7 +66,7 @@ describe('.scan', () => {
|
|
66
66
|
expect(routes).toMatchObject($({
|
67
67
|
diagnostics: [{}],
|
68
68
|
routes: [{
|
69
|
-
|
69
|
+
logical: { path: ['a'] },
|
70
70
|
file: { path: { relative: { dir: '', base: 'a.md' } } },
|
71
71
|
}],
|
72
72
|
}))
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Idx, Path } from '@wollybeard/kit'
|
2
|
-
import { type Route, type RouteFile,
|
2
|
+
import { type Route, type RouteFile, routeIsFromIndexFile, routeToPathExpression } from './route.js'
|
3
3
|
|
4
4
|
export type Diagnostic = DiagnosticIndexConflict
|
5
5
|
|
@@ -21,7 +21,7 @@ export interface LintResult {
|
|
21
21
|
export const lint = (routes: Route[]): LintResult => {
|
22
22
|
const diagnostics: Diagnostic[] = []
|
23
23
|
|
24
|
-
const seen = Idx.create({ toKey:
|
24
|
+
const seen = Idx.create({ toKey: routeToPathExpression })
|
25
25
|
|
26
26
|
// ━ Check for conflict between index and literal.
|
27
27
|
// Note: There is no other way for paths to conflict so we safely assuming the cause is index+literal.
|
@@ -31,7 +31,7 @@ export const lint = (routes: Route[]): LintResult => {
|
|
31
31
|
|
32
32
|
if (seenRoute) {
|
33
33
|
// Fix - ignore the index
|
34
|
-
const [index, literal] =
|
34
|
+
const [index, literal] = routeIsFromIndexFile(route) ? [route, seenRoute] : [seenRoute, route]
|
35
35
|
if (seenRoute === index) {
|
36
36
|
seen.set(route)
|
37
37
|
}
|