7
7
RubyGemsIcon ,
8
8
ChevronLeftIcon ,
9
9
} from "@/icons"
10
- import { Card , Tag } from "@/components"
10
+ import { Card } from "@/components"
11
11
import NextLink from "next/link"
12
12
import NextHead from "next/head"
13
13
import { useMounted } from "nextra/hooks"
@@ -30,6 +30,17 @@ import {
30
30
import { clsx } from "clsx"
31
31
import { getComponents } from "nextra-theme-docs"
32
32
import { RadioGroup , RadioGroupItem } from "@/components/radio"
33
+ import { Button } from "@/app/conf/_design-system/button"
34
+ import { Tag } from "@/app/conf/_design-system/tag"
35
+
36
+ type PackageInfo = {
37
+ name : string
38
+ description : string
39
+ url : string
40
+ github : string
41
+ npm : string
42
+ gem ?: string
43
+ }
33
44
34
45
type CodePageProps = {
35
46
allTags : {
@@ -39,14 +50,7 @@ type CodePageProps = {
39
50
} [ ]
40
51
data : {
41
52
tags : string [ ]
42
- frontMatter : {
43
- name : string
44
- description : string
45
- url : string
46
- github : string
47
- npm : string
48
- gem ?: string
49
- }
53
+ frontMatter : PackageInfo
50
54
stars ?: number
51
55
formattedStars ?: string
52
56
lastRelease ?: string
@@ -187,11 +191,9 @@ export function CodePage({ allTags, data }: CodePageProps) {
187
191
key = "meta-og-description"
188
192
/>
189
193
</ NextHead >
190
- < div className = "container py-10 md:py-20" >
191
- < h1 className = "text-4xl font-extrabold md:text-7xl" >
192
- Code Using GraphQL
193
- </ h1 >
194
- < div className = "my-10 flex max-w-[700px] items-center border-b border-current pb-2.5 text-2xl font-extrabold" >
194
+ < div className = "container py-8 md:pt-16" >
195
+ < h1 className = "typography-h1" > Code Using GraphQL</ h1 >
196
+ < div className = "typography-h3 my-10 flex max-w-[700px] items-center border-b border-current pb-2.5" >
195
197
< div
196
198
className = { clsx (
197
199
"flex shrink-0" ,
@@ -201,6 +203,7 @@ export function CodePage({ allTags, data }: CodePageProps) {
201
203
{ inputTags }
202
204
</ div >
203
205
< input
206
+ // TODO: This should also do a fuzzy full text search, not just search on tags.
204
207
value = { search }
205
208
onChange = { e => setSearch ( e . target . value ) }
206
209
onKeyDown = { handleKeyDown }
@@ -213,26 +216,27 @@ export function CodePage({ allTags, data }: CodePageProps) {
213
216
/>
214
217
< MagnifyingGlassIcon className = "shrink-0" />
215
218
</ div >
216
- < div className = "roboto-mono flex flex-wrap gap-3 md:gap-5 " >
219
+ < div className = "flex flex-wrap gap-2 " >
217
220
{ queryTags . map ( ( { tag, count, name } ) => {
218
221
const isTagMatchSearch =
219
222
! search || name . toLowerCase ( ) . includes ( search . toLowerCase ( ) )
220
223
if ( ! isTagMatchSearch ) return
224
+
221
225
return (
222
226
< NextLink
223
227
href = { `/community/tools-and-libraries/?tags=${ tag } ` }
224
228
key = { tag }
225
229
data-tag = { tag }
226
- className = { clsx (
227
- "tag" ,
228
- mounted &&
229
- ( queryParamsTags as string [ ] ) . includes ( tag ) &&
230
- "bg-primary" ,
231
- ) }
232
230
onClick = { handleQuery }
233
231
title = { `${ mounted && ( queryParamsTags as string [ ] ) . includes ( tag ) ? "Remove" : "Add" } tag "${ name } "` }
232
+ className = "flex"
234
233
>
235
- { name } ({ count } )
234
+ < Tag
235
+ className = "!capitalize lg:!text-sm [&:has(:hover)_.Tag--bg]:opacity-50"
236
+ color = "hsl(var(--color-neu-500)/.8)"
237
+ >
238
+ { name } ({ count } )
239
+ </ Tag >
236
240
</ NextLink >
237
241
)
238
242
} ) }
@@ -258,7 +262,8 @@ export function CodePage({ allTags, data }: CodePageProps) {
258
262
</ div >
259
263
</ RadioGroup >
260
264
261
- < div className = "container grid gap-10 py-20 md:grid-cols-2" >
265
+ { /* todo: add md:*:h-full when the readme opens in a modal */ }
266
+ < div className = "container grid gap-2 py-8 md:grid-cols-2 md:gap-4" >
262
267
{ ( sort === "alphabetical"
263
268
? [ ...newData ] . sort ( ( a , b ) =>
264
269
a . frontMatter . name . localeCompare ( b . frontMatter . name ) ,
@@ -273,75 +278,46 @@ export function CodePage({ allTags, data }: CodePageProps) {
273
278
license,
274
279
compiledSource,
275
280
} ) => {
276
- const { name, description, url , github , npm , gem } = frontMatter
281
+ const { name, description } = frontMatter
277
282
const hasMetadata = formattedStars || lastRelease || license
278
283
return (
279
284
< Card
280
285
key = { `${ name } ${ tags . toString ( ) } ` }
281
286
className = { clsx (
282
- "h-max !p-0" ,
287
+ "flex h-max flex-col !p-0" ,
283
288
"min-w-0" , // hack to avoid overflow when opening details
284
289
) }
285
290
>
286
- < div className = "flex grow flex-col gap-7 p-8 lg:p-12" >
287
- < div className = "flex items-center gap-6 [&_a:hover]:text-primary [&_a]:transition-colors" >
288
- < span className = "grow break-all text-3xl font-extrabold" >
289
- { name }
290
- </ span >
291
- { url && (
292
- < a href = { url } target = "_blank" rel = "noreferrer" >
293
- < GlobeIcon />
294
- </ a >
295
- ) }
296
- { github && (
297
- < a
298
- href = { `https://github.com/${ github } ` }
299
- target = "_blank"
300
- rel = "noreferrer"
301
- >
302
- < GitHubIcon />
303
- </ a >
304
- ) }
305
- { npm && (
306
- < a
307
- href = { `https://npmjs.com/package/${ npm } ` }
308
- target = "_blank"
309
- rel = "noreferrer"
310
- >
311
- < NPMIcon />
312
- </ a >
313
- ) }
314
- { gem && (
315
- < a
316
- href = { `https://rubygems.org/gems/${ gem } ` }
317
- target = "_blank"
318
- rel = "noreferrer"
319
- >
320
- < RubyGemsIcon />
321
- </ a >
322
- ) }
323
- </ div >
324
- < div className = "roboto-mono flex gap-2" >
291
+ < article className = "flex grow flex-col gap-7 p-4 lg:p-8" >
292
+ < header className = "flex items-center gap-2" >
293
+ < span className = "typography-h3 grow break-all" > { name } </ span >
294
+ < PackageLinks data = { frontMatter } />
295
+ </ header >
296
+ < div className = "flex gap-2" >
325
297
{ tags . map ( tag => (
326
- < Tag
298
+ < NextLink
327
299
key = { tag }
328
- // @ts -expect-error -- fixme
329
- as = { NextLink }
330
300
href = { `/community/tools-and-libraries/?tags=${ tag } ` }
331
- className = "cursor-pointer transition-colors hover:!bg-primary hover:text-white "
301
+ className = "flex [&:has(: hover)_.Tag--bg]:opacity-50 "
332
302
>
333
- { allTagsMap . get ( tag ) ! . name }
334
- </ Tag >
303
+ < Tag
304
+ className = "cursor-pointer !capitalize"
305
+ color = "hsl(var(--color-neu-400))" // todo: tags could be color coded like on the conference page
306
+ >
307
+ { allTagsMap . get ( tag ) ! . name }
308
+ </ Tag >
309
+ </ NextLink >
335
310
) ) }
336
311
</ div >
337
312
< Markdown className = "line-clamp-4 grow lg:text-lg [&_a]:text-primary" >
338
313
{ description }
339
314
</ Markdown >
315
+ < div className = "flex-1" />
340
316
{ hasMetadata && (
341
317
< div
342
318
className = { clsx (
343
319
"flex items-center gap-5 max-md:text-xs" ,
344
- "[&>:not(:last-child)]:border-r [&>:not(:last-child)]:border-gray -500 [&>:not(:last-child)]:pr-5" ,
320
+ "[&>:not(:last-child)]:border-r [&>:not(:last-child)]:border-neu -500 [&>:not(:last-child)]:pr-5" ,
345
321
) }
346
322
>
347
323
{ lastRelease && < span > Last release { lastRelease } </ span > }
@@ -354,14 +330,14 @@ export function CodePage({ allTags, data }: CodePageProps) {
354
330
{ license && < span > { license } </ span > }
355
331
</ div >
356
332
) }
357
- </ div >
333
+ </ article >
358
334
359
335
{ compiledSource && (
360
- < details className = "bg-[#f0f0f0] dark:bg-[#2f2f2f] " >
336
+ < details className = "bg-neu-100 " >
361
337
< summary
362
338
className = { clsx (
363
- "flex justify-between px-8 py-5 font-bold text-primary lg:px-12 dark:[[open]>&]:shadow-[-5px_10px_30px_20px_#1b1b1b4d]" ,
364
- "[[open]>&]:shadow-[0_6px_21px_0_#1b1b1b33] " ,
339
+ "flex justify-between px-8 py-5 text-primary lg:px-12 dark:[[open]>&]:shadow-[-5px_10px_30px_20px_#1b1b1b4d]" ,
340
+ "[[open]>&]:bg-neu-200 " ,
365
341
"cursor-pointer" ,
366
342
) }
367
343
>
@@ -405,3 +381,44 @@ const RemoteContent = memo(function RemoteContent({
405
381
} )
406
382
return < MDXContent components = { components } />
407
383
} )
384
+
385
+ function PackageLinks ( { data } : { data : PackageInfo } ) {
386
+ const { url, github, npm, gem } = data
387
+
388
+ return (
389
+ < >
390
+ { url && (
391
+ < Button href = { url } variant = "tertiary" isIconButton >
392
+ < GlobeIcon className = "size-5" />
393
+ </ Button >
394
+ ) }
395
+ { github && (
396
+ < Button
397
+ href = { `https://github.com/${ github } ` }
398
+ variant = "tertiary"
399
+ isIconButton
400
+ >
401
+ < GitHubIcon className = "size-5" />
402
+ </ Button >
403
+ ) }
404
+ { npm && (
405
+ < Button
406
+ href = { `https://npmjs.com/package/${ npm } ` }
407
+ variant = "tertiary"
408
+ isIconButton
409
+ >
410
+ < NPMIcon className = "size-5" viewBox = "0 0 30 30" />
411
+ </ Button >
412
+ ) }
413
+ { gem && (
414
+ < Button
415
+ href = { `https://rubygems.org/gems/${ gem } ` }
416
+ variant = "tertiary"
417
+ isIconButton
418
+ >
419
+ < RubyGemsIcon className = "size-5" />
420
+ </ Button >
421
+ ) }
422
+ </ >
423
+ )
424
+ }
0 commit comments