Skip to content

Commit 8faf458

Browse files
authored
feat(ai): refresh landing ecosystem animation (#940)
1 parent 0f79142 commit 8faf458

23 files changed

Lines changed: 747 additions & 715 deletions

src/components/AILibraryHero.tsx

Lines changed: 340 additions & 522 deletions
Large diffs are not rendered by default.

src/components/AILibraryHeroBox.tsx

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ type AILibraryHeroBoxProps = {
1515
strokeWidth?: number
1616
fill?: string
1717
showLogo?: boolean
18+
logoLight?: string
19+
logoDark?: string
20+
logo?: string
1821
logoSize?: number
1922
centerText?: boolean
2023
}
@@ -33,15 +36,21 @@ export function AILibraryHeroBox({
3336
opacity = 0.9,
3437
strokeWidth = 3,
3538
fill = 'url(#glassGradientLarge)',
39+
showLogo = true,
40+
logoLight,
41+
logoDark,
42+
logo,
3643
logoSize = 40,
44+
centerText = false,
3745
}: AILibraryHeroBoxProps) {
38-
// For centerText, align logo and text higher up; otherwise use normal center
39-
const textX = 25 + logoSize
40-
const textY = 15 + fontSize
46+
const hasCustomLogo = logo || logoLight || logoDark
47+
const hasSeparateLogos = !logo && logoLight && logoDark
48+
const textX = centerText ? width / 2 : 25 + logoSize
49+
const textY = height / 2 + fontSize * 0.35
4150

4251
// Position logo to the right of the text, centered vertically
4352
const logoX = 15
44-
const logoY = 15
53+
const logoY = height / 2 - logoSize / 2
4554

4655
return (
4756
<g transform={`translate(${x}, ${y})`}>
@@ -63,21 +72,69 @@ export function AILibraryHeroBox({
6372
fontFamily="Helvetica"
6473
fontSize={fontSize}
6574
fontWeight={fontWeight}
66-
textAnchor="start"
75+
textAnchor={centerText ? 'middle' : 'start'}
6776
opacity={opacity * 1.05}
6877
>
6978
{label}
7079
</text>
7180
)}
72-
<image
73-
href="/images/logos/logo-color-100.png"
74-
x={logoX}
75-
y={logoY}
76-
width={logoSize}
77-
height={logoSize}
78-
opacity={opacity}
79-
preserveAspectRatio="xMidYMid meet"
80-
/>
81+
{showLogo && logo ? (
82+
<image
83+
href={logo}
84+
x={logoX}
85+
y={logoY}
86+
width={logoSize}
87+
height={logoSize}
88+
opacity={opacity}
89+
preserveAspectRatio="xMidYMid meet"
90+
/>
91+
) : null}
92+
{showLogo && hasSeparateLogos ? (
93+
<>
94+
<image
95+
href={logoLight}
96+
x={logoX}
97+
y={logoY}
98+
width={logoSize}
99+
height={logoSize}
100+
opacity={opacity}
101+
preserveAspectRatio="xMidYMid meet"
102+
className="dark:hidden"
103+
/>
104+
<image
105+
href={logoDark}
106+
x={logoX}
107+
y={logoY}
108+
width={logoSize}
109+
height={logoSize}
110+
opacity={opacity}
111+
preserveAspectRatio="xMidYMid meet"
112+
className="hidden dark:block"
113+
/>
114+
</>
115+
) : null}
116+
{showLogo && !logo && !hasSeparateLogos && (logoLight || logoDark) ? (
117+
<image
118+
href={logoLight || logoDark}
119+
x={logoX}
120+
y={logoY}
121+
width={logoSize}
122+
height={logoSize}
123+
opacity={opacity}
124+
preserveAspectRatio="xMidYMid meet"
125+
/>
126+
) : null}
127+
{showLogo && !hasCustomLogo ? (
128+
<image
129+
href="/images/logos/logo-color-100.png"
130+
x={logoX}
131+
y={logoY}
132+
width={logoSize}
133+
height={logoSize}
134+
opacity={opacity}
135+
preserveAspectRatio="xMidYMid meet"
136+
/>
137+
) : null}
81138
</g>
82139
)
83140
}

src/components/FrameworkCard.tsx

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import { useCopyButton } from '~/components/CopyMarkdownButton'
66
import { useToast } from '~/components/ToastProvider'
77
import { Check, Copy } from 'lucide-react'
88
import { Card } from '~/components/Card'
9+
import {
10+
getFrameworkDocsHash,
11+
getFrameworkDocsPath,
12+
} from '~/libraries/frameworkSupport'
913

1014
export function FrameworkCard({
1115
framework,
@@ -35,16 +39,8 @@ export function FrameworkCard({
3539
)
3640
})
3741

38-
const hasCustomInstallPath = !!library.installPath
39-
const installationPath = library.installPath
40-
? library.installPath
41-
.replace('$framework', framework.value)
42-
.replace('$libraryId', libraryId)
43-
: 'installation'
44-
45-
// Add framework hash fragment only for default installation pages (when installPath is not defined)
46-
// Link component adds the # automatically, so we just pass the value without #
47-
const installationHash = !hasCustomInstallPath ? framework.value : undefined
42+
const installationPath = getFrameworkDocsPath(framework.value, library)
43+
const installationHash = getFrameworkDocsHash(framework.value, library)
4844

4945
return (
5046
<Card

src/components/landing/AiLanding.tsx

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,20 @@ export default function AiLanding() {
3030
className: 'bg-pink-500 border-pink-500 hover:bg-pink-600 text-white',
3131
}}
3232
/>
33-
<AILibraryHero
34-
project={aiProject}
35-
cta={{
36-
linkProps: {
37-
to: '/$libraryId/$version/docs',
38-
params: { libraryId: library.id, version },
39-
},
40-
label: 'Get Started',
41-
className: 'bg-pink-500 border-pink-500 hover:bg-pink-600 text-white',
42-
}}
43-
/>
33+
<div className="-mt-10 md:-mt-20">
34+
<AILibraryHero
35+
project={aiProject}
36+
cta={{
37+
linkProps: {
38+
to: '/$libraryId/$version/docs',
39+
params: { libraryId: library.id, version },
40+
},
41+
label: 'Get Started',
42+
className:
43+
'bg-pink-500 border-pink-500 hover:bg-pink-600 text-white',
44+
}}
45+
/>
46+
</div>
4447

4548
<LibraryStatsSection library={library} />
4649

@@ -54,68 +57,68 @@ export default function AiLanding() {
5457
A complete AI ecosystem, not a vendor platform
5558
</h3>
5659
<p className="mt-6 text-xl leading-7 opacity-75 max-w-[90vw] sm:max-w-[500px] lg:max-w-[800px]">
57-
TanStack AI is a pure open-source ecosystem of libraries and
58-
standards, not a service. We connect you directly to the AI
59-
providers you choose, with no middleman, no service fees, and no
60-
vendor lock-in. Just powerful, type-safe tools built by and for the
61-
community.
60+
TanStack AI is open-source libraries and AG-UI-compatible standards,
61+
not a hosted gateway. Bring your client framework, your server
62+
runtime, and the AI providers you trust. There is no middleman, no
63+
service fee, and no vendor lock-in, just composable tools built for
64+
teams that want to own their AI stack.
6265
</p>
6366
</div>
6467
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mx-auto max-w-[90vw] sm:max-w-[600px] lg:max-w-[1200px]">
6568
<div className="border border-gray-200 dark:border-gray-800 rounded-xl shadow-xs p-6 transition-all duration-300 ease-out bg-white dark:bg-gray-900 hover:shadow-sm hover:border-pink-500/50 hover:-translate-y-1">
66-
<h4 className="text-xl font-bold mb-3">Server Agnostic</h4>
69+
<h4 className="text-xl font-bold mb-3">Client Agnostic</h4>
6770
<p className="opacity-90 text-sm leading-relaxed">
68-
Use any backend server you want. Well-documented protocol with
69-
libraries for TypeScript, PHP, Python, and more.
71+
Use the headless client directly or framework bindings for React,
72+
Vue, Solid, Svelte, and Preact.
7073
</p>
7174
</div>
7275
<div className="border border-gray-200 dark:border-gray-800 rounded-xl shadow-xs p-6 transition-all duration-300 ease-out bg-white dark:bg-gray-900 hover:shadow-sm hover:border-pink-500/50 hover:-translate-y-1">
73-
<h4 className="text-xl font-bold mb-3">Client Agnostic</h4>
76+
<h4 className="text-xl font-bold mb-3">AG-UI Native</h4>
7477
<p className="opacity-90 text-sm leading-relaxed">
75-
Vanilla client library (@tanstack/ai-client) or framework
76-
integrations for React, Solid, and more coming soon.
78+
Client-to-server requests and server-to-client streams use AG-UI,
79+
so compatible clients and servers can interoperate.
7780
</p>
7881
</div>
7982
<div className="border border-gray-200 dark:border-gray-800 rounded-xl shadow-xs p-6 transition-all duration-300 ease-out bg-white dark:bg-gray-900 hover:shadow-sm hover:border-pink-500/50 hover:-translate-y-1">
80-
<h4 className="text-xl font-bold mb-3">Service Agnostic</h4>
83+
<h4 className="text-xl font-bold mb-3">Server Agnostic</h4>
8184
<p className="opacity-90 text-sm leading-relaxed">
82-
Connect to OpenAI, Anthropic, Gemini, and Ollama out of the box.
83-
Create custom adapters for any provider.
85+
Build endpoints in TypeScript, Python, or PHP with portable
86+
helpers for AG-UI events, SSE, and provider message formats.
8487
</p>
8588
</div>
8689
<div className="border border-gray-200 dark:border-gray-800 rounded-xl shadow-xs p-6 transition-all duration-300 ease-out bg-white dark:bg-gray-900 hover:shadow-sm hover:border-pink-500/50 hover:-translate-y-1">
87-
<h4 className="text-xl font-bold mb-3">Full Tooling Support</h4>
90+
<h4 className="text-xl font-bold mb-3">Provider Agnostic</h4>
8891
<p className="opacity-90 text-sm leading-relaxed">
89-
Complete support for client and server tools, including tool
90-
approvals and execution control.
92+
Official adapters cover OpenRouter, OpenAI, Anthropic, Gemini,
93+
Ollama, Groq, Grok/xAI, ElevenLabs, and fal.ai.
9194
</p>
9295
</div>
9396
<div className="border border-gray-200 dark:border-gray-800 rounded-xl shadow-xs p-6 transition-all duration-300 ease-out bg-white dark:bg-gray-900 hover:shadow-sm hover:border-pink-500/50 hover:-translate-y-1">
94-
<h4 className="text-xl font-bold mb-3">Thinking & Reasoning</h4>
97+
<h4 className="text-xl font-bold mb-3">Typed Tools</h4>
9598
<p className="opacity-90 text-sm leading-relaxed">
96-
Full support for thinking and reasoning models with
97-
thinking/reasoning tokens streamed to clients.
99+
Define isomorphic tools once, run them on the client or server,
100+
gate them with approvals, and use provider-native tools safely.
98101
</p>
99102
</div>
100103
<div className="border border-gray-200 dark:border-gray-800 rounded-xl shadow-xs p-6 transition-all duration-300 ease-out bg-white dark:bg-gray-900 hover:shadow-sm hover:border-pink-500/50 hover:-translate-y-1">
101-
<h4 className="text-xl font-bold mb-3">Fully Type-Safe</h4>
104+
<h4 className="text-xl font-bold mb-3">Model-Aware Types</h4>
102105
<p className="opacity-90 text-sm leading-relaxed">
103-
Complete type safety across providers, models, and model options
104-
from end to end.
106+
Provider and model choices narrow options, tools, modalities, and
107+
structured outputs at compile time.
105108
</p>
106109
</div>
107110
<div className="border border-gray-200 dark:border-gray-800 rounded-xl shadow-xs p-6 transition-all duration-300 ease-out bg-white dark:bg-gray-900 hover:shadow-sm hover:border-pink-500/50 hover:-translate-y-1">
108-
<h4 className="text-xl font-bold mb-3">Next-Gen DevTools</h4>
111+
<h4 className="text-xl font-bold mb-3">Media Generation</h4>
109112
<p className="opacity-90 text-sm leading-relaxed">
110-
Amazing developer tools that show you everything happening with
111-
your AI connections in real-time.
113+
Use stable APIs for image, video, speech, transcription, realtime
114+
voice, summarization, and generation hooks.
112115
</p>
113116
</div>
114117
<div className="border border-gray-200 dark:border-gray-800 rounded-xl shadow-xs p-6 transition-all duration-300 ease-out bg-white dark:bg-gray-900 hover:shadow-sm hover:border-pink-500/50 hover:-translate-y-1">
115-
<h4 className="text-xl font-bold mb-3">Pure Open Source</h4>
118+
<h4 className="text-xl font-bold mb-3">Observable Runtime</h4>
116119
<p className="opacity-90 text-sm leading-relaxed">
117-
No hidden service, no fees, no upsells. Community-supported
118-
software connecting you directly to your chosen providers.
120+
Devtools, debug logging, middleware, and observability hooks show
121+
what happened across your AI pipeline.
119122
</p>
120123
</div>
121124
</div>

0 commit comments

Comments
 (0)