Skip to content

Commit 99de234

Browse files
committed
feat: add install command switcher
1 parent 8f97dc0 commit 99de234

File tree

3 files changed

+113
-2
lines changed

3 files changed

+113
-2
lines changed

src/components/InstallSwitcher.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { useMemo, useState } from 'react'
2+
3+
type PackageManager = 'npm' | 'pnpm' | 'bun'
4+
5+
type InstallSwitcherProps = {
6+
exampleSlug?: string
7+
}
8+
9+
const PACKAGE_MANAGERS: Array<{ id: PackageManager; label: string }> = [
10+
{ id: 'npm', label: 'npm' },
11+
{ id: 'pnpm', label: 'pnpm' },
12+
{ id: 'bun', label: 'bun' },
13+
]
14+
15+
export function InstallSwitcher({ exampleSlug = 'sonoscli' }: InstallSwitcherProps) {
16+
const [pm, setPm] = useState<PackageManager>('npm')
17+
18+
const command = useMemo(() => {
19+
switch (pm) {
20+
case 'npm':
21+
return `npx clawdhub@latest install ${exampleSlug}`
22+
case 'pnpm':
23+
return `pnpm dlx clawdhub@latest install ${exampleSlug}`
24+
case 'bun':
25+
return `bunx clawdhub@latest install ${exampleSlug}`
26+
}
27+
}, [exampleSlug, pm])
28+
29+
return (
30+
<div className="install-switcher">
31+
<div className="install-switcher-row">
32+
<div className="stat">Install any skill folder in one shot:</div>
33+
<div className="install-switcher-toggle" role="tablist" aria-label="Install command">
34+
{PACKAGE_MANAGERS.map((entry) => (
35+
<button
36+
key={entry.id}
37+
type="button"
38+
className={
39+
pm === entry.id ? 'install-switcher-pill is-active' : 'install-switcher-pill'
40+
}
41+
role="tab"
42+
aria-selected={pm === entry.id}
43+
onClick={() => setPm(entry.id)}
44+
>
45+
{entry.label}
46+
</button>
47+
))}
48+
</div>
49+
</div>
50+
<div className="hero-install-code mono">{command}</div>
51+
</div>
52+
)
53+
}

src/routes/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createFileRoute, Link } from '@tanstack/react-router'
22
import { useQuery } from 'convex/react'
33
import { api } from '../../convex/_generated/api'
44
import type { Doc } from '../../convex/_generated/dataModel'
5+
import { InstallSwitcher } from '../components/InstallSwitcher'
56
import { SkillCard } from '../components/SkillCard'
67

78
export const Route = createFileRoute('/')({
@@ -47,8 +48,7 @@ function Home() {
4748
</div>
4849
<div className="hero-install" style={{ marginTop: 18 }}>
4950
<div className="stat">Search skills. Versioned, rollback-ready.</div>
50-
<div className="stat">Install any skill folder in one shot:</div>
51-
<div className="hero-install-code mono">npx clawdhub@latest install sonoscli</div>
51+
<InstallSwitcher exampleSlug="sonoscli" />
5252
</div>
5353
</div>
5454
</div>

src/styles.css

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,64 @@ code {
657657
gap: 10px;
658658
}
659659

660+
.install-switcher {
661+
display: grid;
662+
gap: 10px;
663+
}
664+
665+
.install-switcher-row {
666+
display: flex;
667+
align-items: center;
668+
justify-content: space-between;
669+
gap: 14px;
670+
flex-wrap: wrap;
671+
}
672+
673+
.install-switcher-toggle {
674+
display: inline-flex;
675+
border-radius: 999px;
676+
padding: 4px;
677+
border: 1px solid rgba(255, 107, 74, 0.22);
678+
background: rgba(255, 107, 74, 0.06);
679+
}
680+
681+
[data-theme="dark"] .install-switcher-toggle {
682+
border-color: rgba(232, 106, 71, 0.32);
683+
background: rgba(232, 106, 71, 0.12);
684+
}
685+
686+
.install-switcher-pill {
687+
appearance: none;
688+
border: none;
689+
background: transparent;
690+
color: var(--ink-soft);
691+
font: inherit;
692+
font-weight: 650;
693+
font-size: 0.85rem;
694+
padding: 6px 10px;
695+
border-radius: 999px;
696+
cursor: pointer;
697+
transition:
698+
background 0.18s ease,
699+
color 0.18s ease,
700+
transform 0.18s ease;
701+
}
702+
703+
.install-switcher-pill:hover {
704+
color: var(--ink);
705+
transform: translateY(-1px);
706+
}
707+
708+
.install-switcher-pill.is-active {
709+
background: rgba(255, 107, 74, 0.18);
710+
color: var(--accent-deep);
711+
}
712+
713+
[data-theme="dark"] .install-switcher-pill.is-active {
714+
background: rgba(232, 106, 71, 0.22);
715+
color: #ffd0bf;
716+
}
717+
660718
.hero-install-code {
661719
border: 1px solid rgba(255, 107, 74, 0.2);
662720
background: rgba(255, 107, 74, 0.08);

0 commit comments

Comments
 (0)