Repository navigation
Expand file tree
/
Copy pathHomeHero.astro
More file actions
107 lines (99 loc) · 4.34 KB
/
Copy pathHomeHero.astro
File metadata and controls
107 lines (99 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
---
// Living Terminal hero: code window + a terminal pane that types `curl`
// and shows the runnable example's response. Animation is client-side, with a
// static final-state fallback for reduced motion.
import { starsLabel } from '../data/github.ts';
import stable from '../generated/echo-source.json';
import { Code } from 'astro:components';
import helloWorldSource from '../../../cookbook/hello-world/server.go?raw';
import { sourceSnippet } from '../../plugins/remark-source-code.mjs';
const next = process.env.DOCS_CHANNEL === 'next';
const helloWorldCode = sourceSnippet(helloWorldSource, 'hero', 'cookbook/hello-world/server.go');
// The code window is aria-hidden, so Shiki's <pre> must not be a tab stop.
const notFocusable = { pre(node: { properties: Record<string, unknown> }) { delete node.properties.tabindex; } };
---
<section class="hh">
<div class="hh-left">
<span class="hh-eyebrow"><i class="ph ph-sparkle"></i> {next ? 'Echo next — preview documentation' : `Echo ${stable.release} — release documentation`}</span>
<h1>Build fast Go APIs.<br /><span class="g">Without the bloat.</span></h1>
<p class="hh-sub">
A high-performance, minimalist Go web framework — a zero-allocation
router, batteries-included middleware, and an expressive API. Ship
production services in minutes.
</p>
<div class="hh-cta">
<a class="hh-btn pri" href="/guide/quickstart/">Get Started <i class="ph ph-arrow-right"></i></a>
<a class="hh-btn sec" href="https://github.com/labstack/echo" target="_blank" rel="noopener noreferrer"><i class="ph ph-star"></i> {starsLabel} on GitHub</a>
</div>
<button class="hh-install" type="button" data-copy="go get github.com/labstack/echo/v5" aria-label="Copy install command">
<span class="p">$</span> go get github.com/labstack/echo/v5 <i class="ph ph-copy cp"></i>
</button>
</div>
<div class="hh-win" aria-hidden="true">
<div class="bar">
<i style="background:#ff5f57"></i><i style="background:#febc2e"></i><i style="background:#28c840"></i>
<span class="fn">server.go · excerpt</span>
</div>
<Code code={helloWorldCode} lang="go" style="background: transparent" transformers={[notFocusable]} />
<div class="hh-term" data-term>
<div><span class="pr">~/echo $</span> <span data-cmd></span><span class="hh-cur" data-cur></span></div>
<div data-out></div>
</div>
</div>
</section>
<script>
// --- install copy button ---
document.querySelectorAll<HTMLButtonElement>('.hh-install').forEach((btn) => {
btn.addEventListener('click', async () => {
const text = btn.dataset.copy || '';
try {
await navigator.clipboard.writeText(text);
const icon = btn.querySelector('.cp');
if (icon) {
icon.classList.remove('ph-copy');
icon.classList.add('ph-check');
setTimeout(() => {
icon.classList.remove('ph-check');
icon.classList.add('ph-copy');
}, 1400);
}
} catch {}
});
});
// --- terminal typing animation ---
const term = document.querySelector('[data-term]');
if (term) {
const cmdEl = term.querySelector('[data-cmd]') as HTMLElement;
const outEl = term.querySelector('[data-out]') as HTMLElement;
const curEl = term.querySelector('[data-cur]') as HTMLElement;
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const response =
'<span class="dim">HTTP/1.1 200 OK</span>\n' +
'<span class="json">Hello, World!</span>';
const cmd = 'curl localhost:1323';
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
async function run() {
while (true) {
cmdEl.textContent = '';
outEl.innerHTML = '';
curEl.style.display = 'inline-block';
await sleep(900);
for (const ch of cmd) {
cmdEl.textContent += ch;
await sleep(55);
}
await sleep(450);
curEl.style.display = 'none';
outEl.innerHTML = '<pre style="margin:6px 0 0;padding:0;background:none;font:inherit">' + response + '</pre>';
await sleep(3600);
}
}
if (reduce) {
cmdEl.textContent = cmd;
curEl.style.display = 'none';
outEl.innerHTML = '<pre style="margin:6px 0 0;padding:0;background:none;font:inherit">' + response + '</pre>';
} else {
run();
}
}
</script>