Skip to content

Commit fa96221

Browse files
committed
feat(landing): SDK tile grid — 27 @lthn/sdk-* flavours across 13 languages
Adds a four-tier SDK section to the splash landing page. Each tile links to its LetheanNetwork/sdk-<id> source repo; alt-flavour chips underneath link to siblings in the same language family. Tiers: Web & Node TypeScript (10) · JavaScript (4) Mobile & Desktop Swift · Kotlin · Objective-C · Dart (2) Native & systems C · C++ (2) · Rust Server & scripting C# / .NET · Python · PHP · Clojure Icons via cdn.simpleicons.org (MIT-licensed brand SVGs, served by CDN — no asset bundling, always-current artwork). Colours derived from each language's canonical brand palette. Tile hover lifts a 1px border in the language's brand colour via a CSS custom property (--icon-colour) so the visual feedback matches the icon rather than a generic accent. All links currently route to GitHub source — npm / pip / cargo / NuGet / CocoaPods registry uploads land next; this component will flip its hrefs to registry URLs once that's wired. Co-Authored-By: Virgil <virgil@lethean.io>
1 parent 4918653 commit fa96221

2 files changed

Lines changed: 339 additions & 0 deletions

File tree

src/components/SDKGrid.astro

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
---
2+
// SPDX-Licence-Identifier: EUPL-1.2
3+
4+
// SDKGrid — landing-page tile grid for the @lthn/sdk-* family.
5+
//
6+
// Renders one tile per language, each linking directly to its
7+
// LetheanNetwork/sdk-<id> repo. Languages with multiple flavours
8+
// (TS has 10, JS has 4, C++ has 2, Dart has 2) show a "+ N more"
9+
// chip under the title pointing at the other repos.
10+
//
11+
// Icons come from cdn.simpleicons.org — MIT-licensed brand SVGs
12+
// covering every language we ship. CDN means no asset bundling +
13+
// always-current artwork. Falls back to the language label if the
14+
// CDN is unreachable (the alt text carries it).
15+
//
16+
// Once the npm / cargo / pip / etc. registry uploads are wired,
17+
// flip `href` on each tile to its registry URL; for now everything
18+
// points at the source repo.
19+
20+
interface Flavour {
21+
id: string;
22+
label: string;
23+
}
24+
25+
interface SDK {
26+
/** Canonical sdk-<id> repo this tile links to. */
27+
id: string;
28+
/** Display label on the tile. */
29+
label: string;
30+
/** simple-icons slug (https://simpleicons.org). */
31+
iconSlug: string;
32+
/** Hex colour for the icon (no leading #). */
33+
colour: string;
34+
/** Other flavours in the same language — rendered as a chip. */
35+
alts?: Flavour[];
36+
/** Short caption shown under the language name. */
37+
blurb?: string;
38+
}
39+
40+
const tiers: { name: string; items: SDK[] }[] = [
41+
{
42+
name: 'Web & Node',
43+
items: [
44+
{
45+
id: 'typescript-fetch',
46+
label: 'TypeScript',
47+
iconSlug: 'typescript',
48+
colour: '3178C6',
49+
blurb: 'zero-dep fetch() · 10 flavours',
50+
alts: [
51+
{ id: 'typescript-axios', label: 'axios' },
52+
{ id: 'typescript', label: 'generic' },
53+
{ id: 'typescript-angular', label: 'angular' },
54+
{ id: 'typescript-rxjs', label: 'rxjs' },
55+
{ id: 'typescript-node', label: 'node' },
56+
{ id: 'typescript-redux-query', label: 'redux-query' },
57+
{ id: 'typescript-inversify', label: 'inversify' },
58+
{ id: 'typescript-aurelia', label: 'aurelia' },
59+
{ id: 'typescript-jquery', label: 'jquery' },
60+
],
61+
},
62+
{
63+
id: 'javascript',
64+
label: 'JavaScript',
65+
iconSlug: 'javascript',
66+
colour: 'F7DF1E',
67+
blurb: 'plain ES6 · 4 flavours',
68+
alts: [
69+
{ id: 'javascript-flowtyped', label: 'flow' },
70+
{ id: 'javascript-closure-angular', label: 'closure-angular' },
71+
{ id: 'javascript-apollo', label: 'apollo' },
72+
],
73+
},
74+
],
75+
},
76+
{
77+
name: 'Mobile & Desktop',
78+
items: [
79+
{
80+
id: 'swift5',
81+
label: 'Swift',
82+
iconSlug: 'swift',
83+
colour: 'F05138',
84+
blurb: 'iOS · macOS · SwiftUI',
85+
},
86+
{
87+
id: 'kotlin',
88+
label: 'Kotlin',
89+
iconSlug: 'kotlin',
90+
colour: '7F52FF',
91+
blurb: 'Android · JVM',
92+
},
93+
{
94+
id: 'objc',
95+
label: 'Objective-C',
96+
iconSlug: 'apple',
97+
colour: 'A2AAAD',
98+
blurb: 'Cocoa · iOS legacy',
99+
},
100+
{
101+
id: 'dart-dio',
102+
label: 'Dart',
103+
iconSlug: 'dart',
104+
colour: '0175C2',
105+
blurb: 'Flutter · Dio · 2 flavours',
106+
alts: [{ id: 'dart', label: 'basic' }],
107+
},
108+
],
109+
},
110+
{
111+
name: 'Native & systems',
112+
items: [
113+
{
114+
id: 'c',
115+
label: 'C',
116+
iconSlug: 'c',
117+
colour: 'A8B9CC',
118+
blurb: 'libcurl · ANSI C',
119+
},
120+
{
121+
id: 'cpp-restsdk',
122+
label: 'C++',
123+
iconSlug: 'cplusplus',
124+
colour: '00599C',
125+
blurb: 'cpprestsdk · 2 flavours',
126+
alts: [{ id: 'cpp-qt', label: 'qt' }],
127+
},
128+
{
129+
id: 'rust',
130+
label: 'Rust',
131+
iconSlug: 'rust',
132+
colour: '000000',
133+
blurb: 'reqwest async',
134+
},
135+
],
136+
},
137+
{
138+
name: 'Server & scripting',
139+
items: [
140+
{
141+
id: 'csharp',
142+
label: 'C# / .NET',
143+
iconSlug: 'dotnet',
144+
colour: '512BD4',
145+
blurb: 'net8 · net6 · net47 · net48',
146+
},
147+
{
148+
id: 'python',
149+
label: 'Python',
150+
iconSlug: 'python',
151+
colour: '3776AB',
152+
blurb: 'urllib3-based',
153+
},
154+
{
155+
id: 'php',
156+
label: 'PHP',
157+
iconSlug: 'php',
158+
colour: '777BB4',
159+
blurb: 'Guzzle-based',
160+
},
161+
{
162+
id: 'clojure',
163+
label: 'Clojure',
164+
iconSlug: 'clojure',
165+
colour: '5881D8',
166+
blurb: 'JVM functional',
167+
},
168+
],
169+
},
170+
];
171+
172+
const totalRepos = tiers.reduce(
173+
(sum, tier) => sum + tier.items.reduce((s, sdk) => s + 1 + (sdk.alts?.length ?? 0), 0),
174+
0,
175+
);
176+
const totalLanguages = tiers.reduce((sum, tier) => sum + tier.items.length, 0);
177+
---
178+
179+
<section class="sdk-grid">
180+
<header class="sdk-grid__header">
181+
<h2>SDKs — every language, one OpenAPI spec</h2>
182+
<p>
183+
{totalRepos} client flavours across {totalLanguages} languages, all
184+
generated from the same <code>build/sdk/openapi.yaml</code>. Each
185+
tile links to its <a href="https://github.com/LetheanNetwork">LetheanNetwork</a>
186+
source repo. npm / pip / cargo / NuGet / CocoaPods registry uploads
187+
land next.
188+
</p>
189+
</header>
190+
191+
{
192+
tiers.map((tier) => (
193+
<div class="sdk-grid__tier">
194+
<h3>{tier.name}</h3>
195+
<ul class="sdk-grid__tiles">
196+
{tier.items.map((sdk) => (
197+
<li>
198+
<a
199+
class="sdk-tile"
200+
href={`https://github.com/LetheanNetwork/sdk-${sdk.id}`}
201+
style={`--icon-colour:#${sdk.colour}`}
202+
>
203+
<span class="sdk-tile__icon">
204+
<img
205+
src={`https://cdn.simpleicons.org/${sdk.iconSlug}/${sdk.colour}`}
206+
alt={`${sdk.label} logo`}
207+
width="32"
208+
height="32"
209+
loading="lazy"
210+
/>
211+
</span>
212+
<span class="sdk-tile__body">
213+
<span class="sdk-tile__title">{sdk.label}</span>
214+
{sdk.blurb && <span class="sdk-tile__blurb">{sdk.blurb}</span>}
215+
{sdk.alts && sdk.alts.length > 0 && (
216+
<span class="sdk-tile__alts">
217+
{sdk.alts.map((alt, i) => (
218+
<>
219+
{i > 0 && <span class="sdk-tile__alts-sep"> · </span>}
220+
<a
221+
href={`https://github.com/LetheanNetwork/sdk-${alt.id}`}
222+
onclick="event.stopPropagation()"
223+
>
224+
{alt.label}
225+
</a>
226+
</>
227+
))}
228+
</span>
229+
)}
230+
</span>
231+
</a>
232+
</li>
233+
))}
234+
</ul>
235+
</div>
236+
))
237+
}
238+
</section>
239+
240+
<style>
241+
.sdk-grid {
242+
margin: 2.5rem 0;
243+
}
244+
.sdk-grid__header {
245+
margin-bottom: 1.5rem;
246+
}
247+
.sdk-grid__header h2 {
248+
margin-bottom: 0.5rem;
249+
}
250+
.sdk-grid__header p {
251+
color: var(--sl-color-gray-2);
252+
font-size: 0.95rem;
253+
max-width: 60ch;
254+
}
255+
.sdk-grid__tier {
256+
margin-top: 2rem;
257+
}
258+
.sdk-grid__tier h3 {
259+
font-size: 0.85rem;
260+
text-transform: uppercase;
261+
letter-spacing: 0.05em;
262+
color: var(--sl-color-gray-3);
263+
margin-bottom: 0.75rem;
264+
font-weight: 600;
265+
}
266+
.sdk-grid__tiles {
267+
display: grid;
268+
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
269+
gap: 0.75rem;
270+
padding: 0;
271+
margin: 0;
272+
list-style: none;
273+
}
274+
.sdk-tile {
275+
display: flex;
276+
align-items: center;
277+
gap: 0.875rem;
278+
padding: 0.875rem 1rem;
279+
background: var(--sl-color-bg-inline-code);
280+
border: 1px solid var(--sl-color-hairline);
281+
border-radius: 8px;
282+
text-decoration: none;
283+
color: inherit;
284+
transition: border-color 0.15s, transform 0.15s;
285+
}
286+
.sdk-tile:hover {
287+
border-color: var(--icon-colour, var(--sl-color-accent));
288+
transform: translateY(-1px);
289+
}
290+
.sdk-tile__icon {
291+
flex-shrink: 0;
292+
width: 32px;
293+
height: 32px;
294+
display: flex;
295+
align-items: center;
296+
justify-content: center;
297+
}
298+
.sdk-tile__icon img {
299+
width: 32px;
300+
height: 32px;
301+
}
302+
.sdk-tile__body {
303+
display: flex;
304+
flex-direction: column;
305+
gap: 2px;
306+
min-width: 0;
307+
}
308+
.sdk-tile__title {
309+
font-weight: 600;
310+
color: var(--sl-color-white);
311+
font-size: 0.95rem;
312+
}
313+
.sdk-tile__blurb {
314+
color: var(--sl-color-gray-2);
315+
font-size: 0.75rem;
316+
line-height: 1.4;
317+
}
318+
.sdk-tile__alts {
319+
display: flex;
320+
flex-wrap: wrap;
321+
align-items: center;
322+
margin-top: 4px;
323+
font-size: 0.72rem;
324+
color: var(--sl-color-gray-3);
325+
}
326+
.sdk-tile__alts a {
327+
color: var(--sl-color-text-accent);
328+
text-decoration: none;
329+
}
330+
.sdk-tile__alts a:hover {
331+
text-decoration: underline;
332+
}
333+
.sdk-tile__alts-sep {
334+
color: var(--sl-color-gray-4);
335+
}
336+
</style>

src/content/docs/index.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ hero:
1515
---
1616

1717
import { Card, CardGrid } from '@astrojs/starlight/components';
18+
import SDKGrid from '../../components/SDKGrid.astro';
1819

1920
## What ships today
2021

@@ -30,3 +31,5 @@ import { Card, CardGrid } from '@astrojs/starlight/components';
3031
human-facing docs surface lights up incrementally.
3132
</Card>
3233
</CardGrid>
34+
35+
<SDKGrid />

0 commit comments

Comments
 (0)