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.
Files changed (42) hide show
  1. package/build/api/vite/plugins/core.d.ts.map +1 -1
  2. package/build/api/vite/plugins/core.js +146 -52
  3. package/build/api/vite/plugins/core.js.map +1 -1
  4. package/build/lib/file-router/linter.d.ts.map +1 -1
  5. package/build/lib/file-router/linter.js +3 -3
  6. package/build/lib/file-router/linter.js.map +1 -1
  7. package/build/lib/file-router/route.d.ts +48 -10
  8. package/build/lib/file-router/route.d.ts.map +1 -1
  9. package/build/lib/file-router/route.js +68 -3
  10. package/build/lib/file-router/route.js.map +1 -1
  11. package/build/lib/file-router/scan.d.ts +2 -2
  12. package/build/lib/file-router/scan.d.ts.map +1 -1
  13. package/build/lib/file-router/scan.js +8 -8
  14. package/build/lib/file-router/scan.js.map +1 -1
  15. package/build/lib/file-router/sidebar.d.ts +2 -0
  16. package/build/lib/file-router/sidebar.d.ts.map +1 -0
  17. package/build/lib/file-router/sidebar.js +2 -0
  18. package/build/lib/file-router/sidebar.js.map +1 -0
  19. package/build/lib/kit-temp.d.ts +2 -0
  20. package/build/lib/kit-temp.d.ts.map +1 -0
  21. package/build/lib/kit-temp.js +23 -0
  22. package/build/lib/kit-temp.js.map +1 -0
  23. package/build/project-data.d.ts +21 -1
  24. package/build/project-data.d.ts.map +1 -1
  25. package/build/template/components/Sidebar.d.ts +7 -0
  26. package/build/template/components/Sidebar.d.ts.map +1 -0
  27. package/build/template/components/Sidebar.jsx +108 -0
  28. package/build/template/components/Sidebar.jsx.map +1 -0
  29. package/build/template/routes/root.d.ts.map +1 -1
  30. package/build/template/routes/root.jsx +28 -5
  31. package/build/template/routes/root.jsx.map +1 -1
  32. package/package.json +1 -1
  33. package/src/api/vite/plugins/core.ts +178 -54
  34. package/src/lib/file-router/index.test.ts +5 -5
  35. package/src/lib/file-router/linter.ts +3 -3
  36. package/src/lib/file-router/route.ts +147 -11
  37. package/src/lib/file-router/scan.ts +9 -9
  38. package/src/lib/file-router/sidebar.ts +0 -0
  39. package/src/lib/kit-temp.ts +21 -0
  40. package/src/project-data.ts +26 -1
  41. package/src/template/components/Sidebar.tsx +185 -0
  42. package/src/template/routes/root.tsx +35 -5
@@ -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
- path: string;
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;CACb"}
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,7 @@
1
+ import type { SidebarItem } from '../../project-data.js';
2
+ interface SidebarProps {
3
+ items: SidebarItem[];
4
+ }
5
+ export declare const Sidebar: ({ items }: SidebarProps) => import("react").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=Sidebar.d.ts.map
@@ -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;AAyB7D,eAAO,MAAM,SAAS,mCA6BrB,CAAA;AAmHD,eAAO,MAAM,IAAI;;;;CAIf,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.path}>
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
- <Box>
63
- <Outlet />
64
- </Box>
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":"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"}
1
+ {"version":3,"file":"root.jsx","sourceRoot":"","sources":["../../../src/template/routes/root.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polen",
3
- "version": "0.8.0-next.4",
3
+ "version": "0.8.0-next.6",
4
4
  "type": "module",
5
5
  "description": "A framework for delightful GraphQL developer portals",
6
6
  "author": {
@@ -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, Fs, Json, Path, Str } from '@wollybeard/kit'
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 { ProjectData, SiteNavigationItem } from '../../../project-data.js'
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
- name: `polen:markdown`,
58
- enforce: `pre`,
59
- resolveId(id) {
60
- if (id.endsWith(`.md`)) {
61
- return id
62
- }
63
- return null
64
- },
65
- async load(id) {
66
- if (id.endsWith(`.md`)) {
67
- const markdownString = await Fs.read(id)
68
- if (!markdownString) return null
69
- const htmlString = await Markdown.parse(markdownString)
70
-
71
- const code = `export default ${JSON.stringify(htmlString)}`
72
- return code
73
- }
74
- return null
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
- const siteNavigationItemsFromTopLevelPages = pagesScanResult.routes
145
- // We exclude home page
146
- .filter(route => route.path.segments.length === 1)
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
- siteNavigationItems.push(...siteNavigationItemsFromTopLevelPages)
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({ path: `/reference`, title: `Reference` })
185
+ siteNavigationItems.push({ pathExp: `/reference`, title: `Reference` })
160
186
  if (schema.versions.length > 1) {
161
- siteNavigationItems.push({ path: `/changelog`, title: `Changelog` })
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 filePath = Path.format(route.file.path.absolute)
208
- const path = FileRouter.routeToString(route)
209
- const ident = Str.Case.camel(`page ` + Str.titlizeSlug(path))
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 '${filePath}'
254
+ import ${ident} from '${filePathExp}'
213
255
 
214
256
  ${$.pages}.push({
215
- path: '${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
- path: { segments: ['a'] },
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
- path: { segments: ['a', 'b'] },
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
- path: { segments: [] },
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
- path: { segments: ['a'] },
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
- path: { segments: ['a'] },
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, routeIsIndex, routeToString } from './route.js'
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: routeToString })
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] = routeIsIndex(route) ? [route, seenRoute] : [seenRoute, route]
34
+ const [index, literal] = routeIsFromIndexFile(route) ? [route, seenRoute] : [seenRoute, route]
35
35
  if (seenRoute === index) {
36
36
  seen.set(route)
37
37
  }