Fix homepage install controls and split docs install sections
Move inline script inside Layout for proper View Transitions support, redesign install pills as connected tabs above the command bar, and split the combined pnpm/bun docs section into separate headings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,23 +25,33 @@ irm https://feynman.is/install.ps1 | iex
|
||||
|
||||
This installs the Windows runtime bundle under `%LOCALAPPDATA%\Programs\feynman`, adds its launcher to your user `PATH`, and lets you re-run the installer at any time to update.
|
||||
|
||||
## pnpm / bun
|
||||
## pnpm
|
||||
|
||||
If you already have Node.js 20.18.1+ installed, you can install Feynman globally via `pnpm` or `bun`:
|
||||
If you already have Node.js 20.18.1+ installed, you can install Feynman globally via `pnpm`:
|
||||
|
||||
```bash
|
||||
pnpm add -g @companion-ai/feynman
|
||||
bun add -g @companion-ai/feynman
|
||||
```
|
||||
|
||||
Or run it directly without installing:
|
||||
|
||||
```bash
|
||||
pnpm dlx @companion-ai/feynman
|
||||
```
|
||||
|
||||
## bun
|
||||
|
||||
```bash
|
||||
bun add -g @companion-ai/feynman
|
||||
```
|
||||
|
||||
Or run it directly without installing:
|
||||
|
||||
```bash
|
||||
bunx @companion-ai/feynman
|
||||
```
|
||||
|
||||
The package-manager distribution ships the same core application but depends on Node.js being present on your system. The standalone installer is preferred because it bundles its own Node runtime and works without a separate Node installation.
|
||||
Both package-manager distributions ship the same core application but depend on Node.js being present on your system. The standalone installer is preferred because it bundles its own Node runtime and works without a separate Node installation.
|
||||
|
||||
## Post-install setup
|
||||
|
||||
|
||||
@@ -57,14 +57,17 @@ const installCommands = [
|
||||
</div>
|
||||
|
||||
<div class="flex w-full max-w-3xl flex-col items-center gap-4">
|
||||
<div class="flex flex-wrap items-center justify-center gap-2">
|
||||
{installCommands.map((entry) => (
|
||||
<div class="flex w-full flex-col">
|
||||
<div class="flex self-start">
|
||||
{installCommands.map((entry, i) => (
|
||||
<button
|
||||
class:list={[
|
||||
"install-toggle rounded-full border px-3 py-1.5 text-sm font-medium transition-colors",
|
||||
"install-toggle px-4 py-2 text-sm font-medium transition-colors cursor-pointer",
|
||||
i === 0 ? "rounded-tl-lg" : "",
|
||||
i === installCommands.length - 1 ? "rounded-tr-lg" : "",
|
||||
entry.label === installCommands[0].label
|
||||
? "border-foreground bg-foreground text-background"
|
||||
: "border-border bg-background text-muted-foreground hover:text-foreground",
|
||||
? "bg-muted text-foreground"
|
||||
: "bg-muted/30 text-muted-foreground hover:text-foreground hover:bg-muted/50",
|
||||
]}
|
||||
data-command={entry.command}
|
||||
aria-label={`Show ${entry.label} install command`}
|
||||
@@ -73,10 +76,9 @@ const installCommands = [
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<button
|
||||
id="install-cmd"
|
||||
class="group flex w-full items-center justify-between gap-3 rounded-lg bg-muted px-4 py-3 text-left font-mono text-sm transition-colors hover:bg-muted/80 cursor-pointer"
|
||||
class="group flex w-full items-center justify-between gap-3 rounded-b-lg rounded-tr-lg bg-muted px-4 py-3 text-left font-mono text-sm transition-colors hover:bg-muted/80 cursor-pointer"
|
||||
data-command={installCommands[0].command}
|
||||
aria-label="Copy install command"
|
||||
>
|
||||
@@ -84,6 +86,7 @@ const installCommands = [
|
||||
<svg id="install-copy" class="size-4 shrink-0 text-muted-foreground transition-colors group-hover:text-foreground" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
<svg id="install-check" class="hidden size-4 shrink-0 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path d="M20 6L9 17l-5-5"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="/docs/getting-started/installation">
|
||||
@@ -214,50 +217,52 @@ const installCommands = [
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</Layout>
|
||||
|
||||
<script is:inline>
|
||||
function initCopyBtn() {
|
||||
(function () {
|
||||
function init() {
|
||||
var toggles = Array.from(document.querySelectorAll(".install-toggle"))
|
||||
var commandBtn = document.getElementById("install-cmd")
|
||||
var commandText = document.getElementById("install-command")
|
||||
var copyLabel = document.getElementById("install-copy")
|
||||
var checkLabel = document.getElementById("install-check")
|
||||
var btn = document.getElementById("install-cmd")
|
||||
var text = document.getElementById("install-command")
|
||||
var copyIcon = document.getElementById("install-copy")
|
||||
var checkIcon = document.getElementById("install-check")
|
||||
if (!btn || !text || !copyIcon || !checkIcon) return
|
||||
|
||||
toggles.forEach(function (toggle) {
|
||||
if (toggle._toggleBound) return
|
||||
toggle._toggleBound = true
|
||||
if (toggle._b) return
|
||||
toggle._b = true
|
||||
toggle.addEventListener("click", function () {
|
||||
var command = toggle.getAttribute("data-command")
|
||||
if (!commandBtn || !commandText || !command) return
|
||||
commandBtn.setAttribute("data-command", command)
|
||||
commandText.textContent = command
|
||||
toggles.forEach(function (item) {
|
||||
item.classList.remove("border-foreground", "bg-foreground", "text-background")
|
||||
item.classList.add("border-border", "bg-background", "text-muted-foreground")
|
||||
var cmd = toggle.getAttribute("data-command")
|
||||
if (!cmd) return
|
||||
btn.setAttribute("data-command", cmd)
|
||||
text.textContent = cmd
|
||||
toggles.forEach(function (t) {
|
||||
t.classList.remove("bg-muted", "text-foreground")
|
||||
t.classList.add("bg-muted/30", "text-muted-foreground", "hover:text-foreground", "hover:bg-muted/50")
|
||||
})
|
||||
toggle.classList.remove("border-border", "bg-background", "text-muted-foreground")
|
||||
toggle.classList.add("border-foreground", "bg-foreground", "text-background")
|
||||
toggle.classList.remove("bg-muted/30", "text-muted-foreground", "hover:text-foreground", "hover:bg-muted/50")
|
||||
toggle.classList.add("bg-muted", "text-foreground")
|
||||
})
|
||||
})
|
||||
|
||||
if (commandBtn && !commandBtn._copyBound) {
|
||||
commandBtn._copyBound = true
|
||||
commandBtn.addEventListener("click", function () {
|
||||
var command = commandBtn.getAttribute("data-command")
|
||||
if (!command) return
|
||||
navigator.clipboard.writeText(command).then(function () {
|
||||
if (!copyLabel || !checkLabel) return
|
||||
copyLabel.classList.add("hidden")
|
||||
checkLabel.classList.remove("hidden")
|
||||
if (!btn._b) {
|
||||
btn._b = true
|
||||
btn.addEventListener("click", function () {
|
||||
var cmd = btn.getAttribute("data-command")
|
||||
if (!cmd) return
|
||||
navigator.clipboard.writeText(cmd).then(function () {
|
||||
copyIcon.classList.add("hidden")
|
||||
checkIcon.classList.remove("hidden")
|
||||
setTimeout(function () {
|
||||
copyLabel.classList.remove("hidden")
|
||||
checkLabel.classList.add("hidden")
|
||||
copyIcon.classList.remove("hidden")
|
||||
checkIcon.classList.add("hidden")
|
||||
}, 2000)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
initCopyBtn()
|
||||
document.addEventListener("astro:after-swap", initCopyBtn)
|
||||
}
|
||||
init()
|
||||
document.addEventListener("astro:after-swap", init)
|
||||
})()
|
||||
</script>
|
||||
</Layout>
|
||||
|
||||
Reference in New Issue
Block a user