Skip to content

Commit e615125

Browse files
committed
feat: Docs Child Page List
1 parent 4335556 commit e615125

File tree

6 files changed

+200
-2
lines changed

6 files changed

+200
-2
lines changed

app/routes/docs/01-getting-started/01-basic.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Getting Started - Basic
33
nav_title: Basic
4-
description:
4+
description: Create a basic HonoX application using hono/jsx as a renderer.
55
---
66

77
Let's create a basic HonoX application using hono/jsx as a renderer. This application has no client JavaScript and renders JSX on the server side.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { useRequestContext } from 'hono/jsx-renderer'
2+
import type { Frontmatter } from '../../../../global'
3+
import { getDocsPagination } from '../DocsPagination/DocsPaginationUtil'
4+
import { getDocsChildPages } from './DocsChildPagesListUtil'
5+
6+
export const DocsChildPagesList = () => {
7+
const c = useRequestContext()
8+
9+
const docs = import.meta.glob<{
10+
frontmatter?: Frontmatter
11+
}>('../../**/*.mdx', {
12+
eager: true,
13+
})
14+
15+
const childDocs = getDocsChildPages(docs, c.req.path.replace('/docs', ''))
16+
17+
if (childDocs.length === 0) {
18+
return null
19+
}
20+
return (
21+
<div className='my-12 grid grid-cols-2 gap-6'>
22+
{childDocs.map((docs) => {
23+
if (!docs.frontmatter) {
24+
return null
25+
}
26+
return (
27+
<a
28+
href={`/docs${docs.path}`}
29+
className={
30+
'rounded-md border border-gray-300 p-4 text-lg text-gray-900 transition-colors hover:text-orange-700 dark:border-gray-700 dark:text-gray-100 dark:hover:text-orange-400'
31+
}
32+
>
33+
<p className={'font-semibold'}>
34+
{docs.frontmatter?.nav_title || docs.frontmatter?.title}
35+
</p>
36+
{docs.frontmatter?.description ? (
37+
<p class={'mt-2 text-sm text-gray-600 dark:text-gray-400'}>
38+
{docs.frontmatter?.description}
39+
</p>
40+
) : null}
41+
</a>
42+
)
43+
})}
44+
</div>
45+
)
46+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import type { Frontmatter } from '../../../../global'
2+
import { getDocsChildPages } from './DocsChildPagesListUtil'
3+
4+
describe('DocsPaginationutil', () => {
5+
const docs: Record<string, { frontmatter?: Frontmatter }> = {
6+
'../../index.mdx': {
7+
frontmatter: {
8+
title: 'Home',
9+
nav_title: 'Home',
10+
description: 'Welcome to HonoX documentation.',
11+
exclude_from_nav: true,
12+
},
13+
},
14+
'../../testing.mdx': {
15+
frontmatter: {
16+
title: 'Testing',
17+
nav_title: 'Testing',
18+
description: 'Testing description',
19+
exclude_from_nav: false,
20+
},
21+
},
22+
'../../01-getting-started/01-basic.mdx': {
23+
frontmatter: {
24+
title: 'Getting Started - Basic',
25+
nav_title: 'Basic',
26+
description: null,
27+
},
28+
},
29+
'../../01-getting-started/02-with-client.mdx': {
30+
frontmatter: {
31+
title: 'Get Started - with Client',
32+
nav_title: 'with Client',
33+
description: null,
34+
},
35+
},
36+
'../../01-getting-started/byor/index.mdx': {
37+
frontmatter: {
38+
title: 'BYOR - Bring Your Own Renderer',
39+
nav_title: 'Bring Your Own Renderer',
40+
description: null,
41+
},
42+
},
43+
'../../01-getting-started/byor/react.mdx': {
44+
frontmatter: {
45+
title: 'React Renderer',
46+
nav_title: 'React',
47+
description: null,
48+
},
49+
},
50+
'../../01-getting-started/index.mdx': {
51+
frontmatter: {
52+
title: 'Getting Started',
53+
nav_title: 'Getting Started',
54+
description: 'Learn how to create a basic HonoX application.',
55+
},
56+
},
57+
'../../02-guide/01-nested-layouts.mdx': {
58+
frontmatter: {
59+
title: 'Nexted Layouts',
60+
nav_title: 'Nested Layouts',
61+
description: null,
62+
},
63+
},
64+
'../../02-guide/index.mdx': {
65+
frontmatter: {
66+
title: 'Guide',
67+
nav_title: 'Guide',
68+
description: 'Guide to create a HonoX application.',
69+
},
70+
},
71+
}
72+
it('Should be get next and previous page at correct paths.', () => {
73+
const docsPagination = getDocsChildPages(docs, '/getting-started')
74+
expect(docsPagination).toStrictEqual([
75+
{
76+
path: '/getting-started/basic',
77+
frontmatter: {
78+
title: 'Getting Started - Basic',
79+
nav_title: 'Basic',
80+
description: null,
81+
},
82+
},
83+
{
84+
path: '/getting-started/with-client',
85+
frontmatter: {
86+
title: 'Get Started - with Client',
87+
nav_title: 'with Client',
88+
description: null,
89+
},
90+
},
91+
{
92+
path: '/getting-started/byor',
93+
frontmatter: {
94+
title: 'BYOR - Bring Your Own Renderer',
95+
nav_title: 'Bring Your Own Renderer',
96+
description: null,
97+
},
98+
},
99+
])
100+
})
101+
102+
it('Should be return empty array when incorrect paths.', () => {
103+
const docsPagination = getDocsChildPages(docs, '/incorrect-path')
104+
expect(docsPagination).toStrictEqual([])
105+
})
106+
it('Should be return empty array when child page is nothing.', () => {
107+
const docsPagination = getDocsChildPages(docs, '/getting-started/with-client')
108+
expect(docsPagination).toStrictEqual([])
109+
})
110+
})
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import type { Frontmatter } from '../../../../global'
2+
3+
export type Docs = {
4+
path: string
5+
frontmatter?: Frontmatter
6+
}
7+
8+
export const getDocsChildPages = (
9+
docs: Record<string, { frontmatter?: Frontmatter }>,
10+
currentPathName: string
11+
): Docs[] => {
12+
const childrenResult = Object.entries(docs)
13+
.map(([key, value]): [string, { frontmatter?: Frontmatter }] => {
14+
return [
15+
`/${key
16+
.replace(/\.\.\//g, '')
17+
.replace(/\.\//g, '')
18+
.replace(/index.mdx$/, '')
19+
.replace(/\.mdx$/, '')
20+
.replace(/\/$/, '')}`,
21+
value,
22+
]
23+
})
24+
.filter(([key]) => {
25+
return (
26+
key.replace(/\/\d+-/g, '/').startsWith(currentPathName) &&
27+
key
28+
.replace(/\/\d+-/g, '/')
29+
.replace(currentPathName, '')
30+
.split('/').length == 2
31+
)
32+
})
33+
.sort(([a], [b]) => a.localeCompare(b))
34+
.map(([key, value]) => ({
35+
path: key.replace(/\/\d+-/g, '/'),
36+
frontmatter: value.frontmatter,
37+
}))
38+
39+
return childrenResult
40+
}

app/routes/docs/_components/DocsPagination/DocsPagination.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const DocsPagination = () => {
1919
return (
2020
<nav
2121
className={
22-
'mt-8 flex items-center justify-between border-t border-gray-200 pt-8 pb-4 dark:border-gray-700'
22+
'my-12 flex items-center justify-between border-t border-gray-200 pt-8 pb-4 dark:border-gray-700'
2323
}
2424
>
2525
{groupedDocs.previous ? (

app/routes/docs/_renderer.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { jsxRenderer } from 'hono/jsx-renderer'
22
import { Link, Script } from 'honox/server'
33
import { Header } from '../_components/common/Header/Header'
4+
import { DocsChildPagesList } from './_components/DocsChildPagesList/DocsChildPagesList'
45
import { DocsPagination } from './_components/DocsPagination/DocsPagination'
56
import { SideNav } from './_components/SideNav/SideNav'
67

@@ -31,6 +32,7 @@ export default jsxRenderer(({ children, frontmatter }) => {
3132
<article className={'w-full min-w-0'}>
3233
{frontmatter ? <h1 class={'mb-6 text-4xl font-bold'}>{frontmatter.title}</h1> : null}
3334
{children}
35+
<DocsChildPagesList />
3436
<DocsPagination />
3537
</article>
3638
</main>

0 commit comments

Comments
 (0)