Skip to content

Commit 23e018a

Browse files
authored
feat: Entries index (#372)
1 parent 8dd8580 commit 23e018a

File tree

7 files changed

+258
-121
lines changed

7 files changed

+258
-121
lines changed

package-lock.json

Lines changed: 19 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"devDependencies": {
1010
"@savvywombat/tailwindcss-grid-areas": "^4.0.0",
1111
"@types/hast": "^3.0.4",
12+
"@types/lodash-es": "^4.17.12",
1213
"@types/minimist": "^1.2.5",
1314
"@types/node": "^18.19.50",
1415
"@types/react": "^18.3.5",
@@ -41,6 +42,7 @@
4142
"cmdk": "^1.0.0",
4243
"gray-matter": "^4.0.3",
4344
"image-size": "^1.1.1",
45+
"lodash-es": "^4.17.21",
4446
"match-sorter": "^6.3.4",
4547
"next": "^14.2.11",
4648
"next-mdx-remote": "^5.0.0",

src/components/mdx/Codesandbox/Codesandbox.tsx

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
import { Img } from '@/components/mdx'
22

33
import cn from '@/lib/cn'
4+
import { ComponentProps } from 'react'
5+
import { fetchCSB } from './fetchCSB'
46

57
export type CSB = {
68
id: string
7-
title: string
8-
screenshot_url: string
9-
description: string
10-
tags: string[]
9+
title?: string
10+
screenshot_url?: string
11+
description?: string
12+
tags?: string[]
1113
}
1214

13-
export function Codesandbox({
15+
type Codesandbox0Props = CSB & {
16+
hideTitle?: boolean
17+
embed?: boolean
18+
} & ComponentProps<'a'> & {
19+
imgProps?: ComponentProps<'img'>
20+
}
21+
22+
export function Codesandbox0({
1423
id,
1524
title = '',
1625
description = '',
@@ -19,10 +28,9 @@ export function Codesandbox({
1928
//
2029
hideTitle = false,
2130
embed = false,
22-
}: CSB & {
23-
hideTitle: boolean
24-
embed: boolean
25-
}) {
31+
className,
32+
imgProps: { className: imgClassName } = {},
33+
}: Codesandbox0Props) {
2634
return (
2735
<>
2836
{embed ? (
@@ -38,15 +46,15 @@ export function Codesandbox({
3846
href={`https://codesandbox.io/s/${id}`}
3947
target="_blank"
4048
rel="noreferrer"
41-
className="mb-2 block"
49+
className={cn('mb-2 block', className)}
4250
>
4351
{screenshot_url && (
4452
<Img
4553
src={screenshot_url}
4654
alt={title}
4755
width={1763}
4856
height={926}
49-
className="aspect-[16/9] object-cover"
57+
className={cn('aspect-[16/9] object-cover', imgClassName)}
5058
/>
5159
)}
5260
</a>
@@ -76,3 +84,20 @@ export function Codesandbox({
7684
</>
7785
)
7886
}
87+
88+
export async function Codesandbox1({ boxes, ...props }: { boxes: string[] } & Codesandbox0Props) {
89+
const ids = boxes // populated from 1.
90+
// console.log('ids', ids)
91+
92+
//
93+
// Batch fetch all CSBs of the page
94+
//
95+
const csbs = await fetchCSB(...ids)
96+
// console.log('boxes', boxes)
97+
const data = csbs[props.id]
98+
// console.log('data', data)
99+
100+
// Merge initial props with data
101+
const merged = { ...props, ...data }
102+
return <Codesandbox0 {...merged} />
103+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { ComponentProps } from 'react'
2+
3+
import { groupBy } from 'lodash-es'
4+
import { Codesandbox1 } from '../Codesandbox'
5+
6+
type Entry = {
7+
title: string
8+
url: string
9+
slug: string[]
10+
boxes: string[]
11+
}
12+
13+
export async function Entries({
14+
items,
15+
excludedGroups = ['getting-started'],
16+
...props
17+
}: { items: Entry[]; excludedGroups?: string[] } & ComponentProps<'div'>) {
18+
const groupedEntries = groupBy(items, ({ slug }) => slug[0])
19+
20+
return (
21+
<div className="my-8 columns-2 md:columns-3" {...props}>
22+
{Object.entries(groupedEntries)
23+
.filter(([group]) => !excludedGroups.includes(group))
24+
.map(([group, entries]) => {
25+
return (
26+
<>
27+
<h2 className="my-8 text-xl capitalize first-of-type:mt-0">{group}</h2>
28+
<ul className="text-sm">
29+
{entries?.map(({ title, url, boxes }) => (
30+
<li key={url} className="flex gap-1">
31+
<a href={url} className="text-primary">
32+
{title}
33+
</a>
34+
<ul className="inline-flex gap-1">
35+
{boxes.map((id) => (
36+
<li key={id}>
37+
<Codesandbox1
38+
key={id}
39+
id={id}
40+
boxes={[id]}
41+
hideTitle
42+
className="inline-block"
43+
imgProps={{ className: 'h-[1em] w-auto rounded-[1px]' }}
44+
/>
45+
</li>
46+
))}
47+
</ul>
48+
</li>
49+
))}
50+
</ul>
51+
</>
52+
)
53+
})}
54+
</div>
55+
)
56+
}

src/components/mdx/Entries/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './Entries'

src/components/mdx/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from './Code'
2-
export * from './Codesandbox'
2+
// export * from './Codesandbox'
33
export * from './Details'
4+
export * from './Entries'
45
export * from './Gha'
56
export * from './Grid'
67
export * from './Hint'

0 commit comments

Comments
 (0)