Skip to content

Commit 8ce5441

Browse files
authored
Merge branch 'main' into feat/maintainer-card-linkedin-icon
2 parents 147c1bc + 21507c0 commit 8ce5441

24 files changed

+378
-347
lines changed

src/components/CookieConsent.tsx

Lines changed: 0 additions & 187 deletions
This file was deleted.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React from 'react'
2+
import type { Framework } from '~/libraries'
3+
import { useIntersectionObserver } from '~/hooks/useIntersectionObserver'
4+
5+
const LazyCodeExampleCardImpl = React.lazy(async () => {
6+
const mod = await import('./CodeExampleCard')
7+
8+
return { default: mod.CodeExampleCard }
9+
})
10+
11+
interface LazyCodeExampleCardProps {
12+
title?: string
13+
frameworks: Framework[]
14+
codeByFramework: Partial<Record<Framework, { lang: string; code: string }>>
15+
}
16+
17+
export function LazyCodeExampleCard(props: LazyCodeExampleCardProps) {
18+
const { ref, isIntersecting } = useIntersectionObserver({
19+
rootMargin: '25%',
20+
triggerOnce: true,
21+
})
22+
23+
return (
24+
<div ref={ref} className="px-4 space-y-4 flex flex-col items-center">
25+
{!isIntersecting ? (
26+
<div className="w-full max-w-5xl mx-auto space-y-4">
27+
<div className="h-10 w-56 mx-auto rounded bg-gray-200/70 dark:bg-gray-800/70 animate-pulse" />
28+
<div className="rounded-xl border border-gray-200 dark:border-gray-800 bg-white/70 dark:bg-gray-900/70 overflow-hidden">
29+
<div className="h-14 border-b border-gray-200 dark:border-gray-800 bg-gray-100/70 dark:bg-gray-800/70 animate-pulse" />
30+
<div className="p-4 space-y-3">
31+
<div className="h-4 w-11/12 rounded bg-gray-200/70 dark:bg-gray-800/70 animate-pulse" />
32+
<div className="h-4 w-10/12 rounded bg-gray-200/70 dark:bg-gray-800/70 animate-pulse" />
33+
<div className="h-4 w-8/12 rounded bg-gray-200/70 dark:bg-gray-800/70 animate-pulse" />
34+
<div className="h-4 w-9/12 rounded bg-gray-200/70 dark:bg-gray-800/70 animate-pulse" />
35+
<div className="h-4 w-7/12 rounded bg-gray-200/70 dark:bg-gray-800/70 animate-pulse" />
36+
<div className="h-48 rounded bg-gray-100/70 dark:bg-gray-800/50 animate-pulse" />
37+
</div>
38+
</div>
39+
</div>
40+
) : (
41+
<React.Suspense fallback={null}>
42+
<LazyCodeExampleCardImpl {...props} />
43+
</React.Suspense>
44+
)}
45+
</div>
46+
)
47+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import * as React from 'react'
2+
import type { LibraryId } from '~/libraries'
3+
import { useIntersectionObserver } from '~/hooks/useIntersectionObserver'
4+
5+
const LazyMaintainersSection = React.lazy(async () => {
6+
const mod = await import('./MaintainersSection')
7+
8+
return { default: mod.MaintainersSection }
9+
})
10+
11+
const LazyPartnersSection = React.lazy(async () => {
12+
const mod = await import('./PartnersSection')
13+
14+
return { default: mod.PartnersSection }
15+
})
16+
17+
const LazyLibraryShowcases = React.lazy(async () => {
18+
const mod = await import('./ShowcaseSection')
19+
20+
return { default: mod.LibraryShowcases }
21+
})
22+
23+
interface LazyLandingCommunitySectionProps {
24+
libraryId: LibraryId
25+
libraryName: string
26+
showShowcases?: boolean
27+
}
28+
29+
function SectionSkeleton({ title }: { title: string }) {
30+
return (
31+
<div className="px-4 w-full lg:max-w-(--breakpoint-lg) md:mx-auto">
32+
<div className="space-y-8">
33+
<div className="h-10 w-48 rounded bg-gray-200/70 dark:bg-gray-800/70 animate-pulse" />
34+
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-6">
35+
{Array.from({ length: 4 }).map((_, index) => (
36+
<div
37+
key={`${title}-${index}`}
38+
className="aspect-square rounded-lg bg-gray-200/70 dark:bg-gray-800/70 animate-pulse"
39+
/>
40+
))}
41+
</div>
42+
</div>
43+
</div>
44+
)
45+
}
46+
47+
function ShowcaseSkeleton() {
48+
return (
49+
<div className="px-4 lg:max-w-(--breakpoint-lg) md:mx-auto w-full">
50+
<div className="space-y-8 py-16">
51+
<div className="space-y-2">
52+
<div className="h-10 w-64 rounded bg-gray-200/70 dark:bg-gray-800/70 animate-pulse" />
53+
<div className="h-6 w-80 max-w-full rounded bg-gray-200/70 dark:bg-gray-800/70 animate-pulse" />
54+
</div>
55+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
56+
{Array.from({ length: 3 }).map((_, index) => (
57+
<div
58+
key={`showcase-${index}`}
59+
className="aspect-video rounded-xl bg-gray-200/70 dark:bg-gray-800/70 animate-pulse"
60+
/>
61+
))}
62+
</div>
63+
</div>
64+
</div>
65+
)
66+
}
67+
68+
export function LazyLandingCommunitySection({
69+
libraryId,
70+
libraryName,
71+
showShowcases = true,
72+
}: LazyLandingCommunitySectionProps) {
73+
const { ref, isIntersecting } = useIntersectionObserver({
74+
rootMargin: '25%',
75+
triggerOnce: true,
76+
})
77+
78+
return (
79+
<div ref={ref} className="flex flex-col gap-20 md:gap-24">
80+
{!isIntersecting ? (
81+
<>
82+
<SectionSkeleton title="Maintainers" />
83+
<SectionSkeleton title="Partners" />
84+
{showShowcases ? <ShowcaseSkeleton /> : null}
85+
</>
86+
) : (
87+
<React.Suspense
88+
fallback={
89+
<>
90+
<SectionSkeleton title="Maintainers" />
91+
<SectionSkeleton title="Partners" />
92+
{showShowcases ? <ShowcaseSkeleton /> : null}
93+
</>
94+
}
95+
>
96+
<LazyMaintainersSection libraryId={libraryId} />
97+
<LazyPartnersSection libraryId={libraryId} />
98+
{showShowcases ? (
99+
<div className="px-4 lg:max-w-(--breakpoint-lg) md:mx-auto">
100+
<LazyLibraryShowcases
101+
libraryId={libraryId}
102+
libraryName={libraryName}
103+
/>
104+
</div>
105+
) : null}
106+
</React.Suspense>
107+
)}
108+
</div>
109+
)
110+
}

src/components/MaintainerCard.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,14 @@ export function CompactMaintainerCard({
234234
aria-label={`View ${maintainer.name}'s GitHub profile`}
235235
className="group relative aspect-square block rounded-lg shadow-xs border border-gray-200 dark:border-gray-800 overflow-hidden"
236236
tabIndex={0}
237-
style={{
238-
backgroundImage: `url(${maintainer.avatar})`,
239-
backgroundSize: 'cover',
240-
backgroundPosition: 'center',
241-
}}
242237
>
238+
<img
239+
alt={`Avatar of ${maintainer.name}`}
240+
className="absolute inset-0 w-full h-full object-cover"
241+
src={maintainer.avatar}
242+
loading="lazy"
243+
decoding="async"
244+
/>
243245
<div className="absolute inset-0 bg-linear-to-t from-black/70 via-black/20 to-transparent" />
244246
<div className="absolute inset-0 p-3 flex flex-col justify-end">
245247
<div className="text-white">

src/components/landing/AiLanding.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { useParams } from '@tanstack/react-router'
22
import { Footer } from '~/components/Footer'
33
import { LazySponsorSection } from '~/components/LazySponsorSection'
4-
import { PartnersSection } from '~/components/PartnersSection'
5-
import { MaintainersSection } from '~/components/MaintainersSection'
64
import { BottomCTA } from '~/components/BottomCTA'
75
import { aiProject } from '~/libraries/ai'
86
import { AILibraryHero } from '~/components/AILibraryHero'
@@ -12,6 +10,7 @@ import LandingPageGad from '~/components/LandingPageGad'
1210
import { LibraryHero } from '~/components/LibraryHero'
1311
import { LibraryPageContainer } from '~/components/LibraryPageContainer'
1412
import { LibraryStatsSection } from '~/components/LibraryStatsSection'
13+
import { LazyLandingCommunitySection } from '~/components/LazyLandingCommunitySection'
1514

1615
const library = getLibrary('ai')
1716

@@ -122,8 +121,11 @@ export default function AiLanding() {
122121
</div>
123122
</div>
124123

125-
<MaintainersSection libraryId="ai" />
126-
<PartnersSection libraryId="ai" />
124+
<LazyLandingCommunitySection
125+
libraryId="ai"
126+
libraryName="TanStack AI"
127+
showShowcases={false}
128+
/>
127129
<LazySponsorSection />
128130
<LandingPageGad />
129131

0 commit comments

Comments
 (0)