aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/bun-landing/index.css93
-rw-r--r--packages/bun-landing/page.tsx132
2 files changed, 139 insertions, 86 deletions
diff --git a/packages/bun-landing/index.css b/packages/bun-landing/index.css
index 6c2a6a9d7..3af3361b1 100644
--- a/packages/bun-landing/index.css
+++ b/packages/bun-landing/index.css
@@ -65,6 +65,7 @@ main {
max-width: var(--max-width);
display: grid;
grid-template-columns: auto auto;
+ overflow-y: hidden;
}
main,
@@ -226,15 +227,12 @@ header {
align-items: center;
border: 1px solid var(--orange);
margin-top: 1rem;
- display: grid;
+ display: flex;
+ justify-content: space-between;
align-content: center;
white-space: nowrap;
margin-bottom: 1rem;
-}
-
-#code-box {
font-family: var(--monospace-font);
- position: relative;
}
#curl:hover {
@@ -244,7 +242,7 @@ header {
#curl::before {
display: block;
- content: "$";
+ content: "$" / "";
color: var(--orange);
pointer-events: none;
width: 1ch;
@@ -267,21 +265,20 @@ header {
}
#code-box-copy {
- position: absolute;
- right: 16px;
- top: 0;
- bottom: 0;
height: 100%;
display: flex;
align-items: center;
- z-index: 5;
color: var(--orange-light);
transition: transform 0.05s linear;
transition-property: color, transform;
transform-origin: center center;
cursor: pointer;
+ background: transparent;
+ border: none;
+ font-size: inherit;
+ font-family: inherit;
}
#code-box-copy:hover {
@@ -302,6 +299,8 @@ header {
align-items: center;
width: min-content;
white-space: nowrap;
+ list-style-type: none;
+ padding: 0;
}
.Tab {
@@ -311,15 +310,25 @@ header {
padding-bottom: 8px;
border-bottom: 1px solid #ccc;
cursor: pointer;
+ padding: 0;
+}
+
+.TabButton {
+ background: transparent;
+ border: none;
padding: 16px 16px;
+ color: inherit;
+ font-size: inherit;
+ font-family: inherit;
+ cursor: inherit;
}
-.Tab[data-tab="react"]:hover,
-.Graphs--active-react .Tab[data-tab="react"],
-.Tab[data-tab="sqlite"]:hover,
-.Graphs--active-sqlite .Tab[data-tab="sqlite"],
-.Tab[data-tab="ffi"]:hover,
-.Graphs--active-ffi .Tab[data-tab="ffi"] {
+.TabButton[data-tab="react"]:hover,
+.Graphs--active-react .TabButton[data-tab="react"],
+.TabButton[data-tab="sqlite"]:hover,
+.Graphs--active-sqlite .TabButton[data-tab="sqlite"],
+.TabButton[data-tab="ffi"]:hover,
+.Graphs--active-ffi .TabButton[data-tab="ffi"] {
border-bottom-color: aquamarine;
background-color: rgba(130, 216, 247, 0.1);
border-right-color: aquamarine;
@@ -335,11 +344,14 @@ header {
.BarGraph-heading {
font-weight: 500;
font-size: 1.5rem;
+ margin: 0;
}
.BarGraphList {
flex: 1;
position: relative;
+ list-style-type: none;
+ padding: 0;
}
.BarGraph,
.ActiveTab,
@@ -350,6 +362,7 @@ header {
.BarGraph-subheading {
font-size: 0.9rem;
color: rgb(135, 134, 134);
+ margin: 0;
}
.BarGraphList {
@@ -390,15 +403,18 @@ header {
height: var(--opposite);
background-color: rgb(93, 89, 134);
- transform-origin: bottom center;
- transform: scaleY(var(--level));
position: relative;
+ height: calc(200px * var(--level));
}
.BarGraphItem {
border-right: 1px dashed var(--dark-border);
border-top: 1px dashed var(--dark-border);
border-bottom: 1px dashed var(--dark-border);
+ min-height: 200px;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
}
.BarGraphItem--deno {
@@ -406,7 +422,6 @@ header {
}
.BarGraph--horizontal .BarGraphBar {
- min-height: 200px;
}
.BarGraph--vertical .BarGraphBar {
@@ -434,8 +449,7 @@ header {
}
.BarGraph--horizontal .BarGraphBar-label {
- transform: scaleY(var(--inverse));
- top: calc(-20px * var(--inverse));
+ top: -22px;
}
.BarGraphItem--bun .BarGraphBar {
@@ -484,13 +498,13 @@ header {
}
.BarGraphKeyItem-value {
- color: #666;
+ color: #7a7a7a;
margin-top: 0.5rem;
}
.BarGraphKeyItem-viewSource {
margin-top: 0.5rem;
- color: #666;
+ color: #7a7a7a;
text-transform: lowercase;
font-weight: thin;
font-size: 0.8rem;
@@ -520,7 +534,7 @@ header {
}
.DemphasizedLabel {
- color: #666;
+ color: #7a7a7a;
font-weight: 300;
}
@@ -572,7 +586,7 @@ header {
}
.Tag--Command:before {
- content: "❯";
+ content: "❯" / "";
color: rgba(255, 255, 255, 0.35);
margin-top: auto;
margin-bottom: auto;
@@ -603,12 +617,12 @@ header {
.Tag--React:before {
color: rgba(130, 216, 247, 0.5);
- content: "<";
+ content: "<" / "";
}
.Tag--React:after {
color: rgba(130, 216, 247, 0.5);
- content: ">";
+ content: ">" / "";
}
.Tag--Bun {
@@ -852,16 +866,17 @@ li {
margin: 0;
gap: 0rem;
width: 100%;
+ border-top: 1px solid rgba(200, 200, 200, 0.1);
}
.Tab {
width: 100%;
- padding-top: 16px;
- padding-bottom: 16px;
+ border-bottom-color: #333;
}
- .Tab {
- border-bottom-color: #333;
+ .TabButton {
+ padding-top: 16px;
+ padding-bottom: 16px;
}
#pitch-content {
@@ -873,10 +888,6 @@ li {
.Graphs--active-ffi .Tab[data-tab="ffi"] {
background-color: rgba(100, 100, 100, 0.1);
}
-
- .Tabs {
- border-top: 1px solid rgba(200, 200, 200, 0.1);
- }
}
#explain p > code {
@@ -926,3 +937,13 @@ li {
img {
object-fit: contain;
}
+
+.visually-hidden {
+ clip: rect(0 0 0 0);
+ clip-path: inset(50%);
+ height: 1px;
+ overflow: hidden;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+} \ No newline at end of file
diff --git a/packages/bun-landing/page.tsx b/packages/bun-landing/page.tsx
index baefebe6d..56937f54f 100644
--- a/packages/bun-landing/page.tsx
+++ b/packages/bun-landing/page.tsx
@@ -64,14 +64,15 @@ const Label = ({ children, replace }) => {
};
const BarGraphItem = ({ type, amount = 0, label, max = 0 }) => (
- <div
+ <li
className={`BarGraphItem BarGraphItem--${type}`}
style={{ "--amount": amount, "--max": max }}
>
+ <div className="visually-hidden">{`${type}: ${fmt.format(amount)} ${label}`}</div>
<div
style={{ "--amount": amount, "--max": max }}
- title={`${amount} ${label}`}
className="BarGraphBar"
+ aria-hidden
>
<div
style={{ "--amount": amount, "--max": max }}
@@ -80,11 +81,11 @@ const BarGraphItem = ({ type, amount = 0, label, max = 0 }) => (
{fmt.format(amount)}
</div>
</div>
- </div>
+ </li>
);
const BarGraphLabel = ({ name, version, source }) => (
- <a href={source} target="_blank" className="BarGraphKeyItem">
+ <a href={source} target="_blank" className="BarGraphKeyItem" aria-label={`${name} benchmark source`}>
<div className="BarGraphKeyItem-label">{name}</div>
<div className="BarGraphKeyItem-value">{version}</div>
<div className="BarGraphKeyItem-viewSource">View source</div>
@@ -104,6 +105,7 @@ const Zig = () => (
className="Zig"
viewBox="0 0 400 140"
>
+ <title>Zig</title>
<g fill="#F7A41D">
<g>
<polygon points="46,22 28,44 19,30" />
@@ -187,9 +189,9 @@ const InstallBox = ({ desktop = false }) => (
</div>
<div id="code-box">
<div id="curl">curl https://bun.sh/install | bash</div>
- <div className="unselectable" id="code-box-copy">
+ <button className="unselectable" id="code-box-copy" aria-label="Copy installation script">
copy
- </div>
+ </button>
</div>
<a
className="unselectable"
@@ -240,11 +242,12 @@ export default ({ inlineCSS }) => (
<body>
<div id="header-wrap">
<header>
- <a href="/" id="logo-link">
- <img height="61px" src={`/logo@2x.png`} alt="Bun" id="logo" />
+ <a href="/" id="logo-link" aria-label="home">
+ <img height="61px" src="/logo.png" srcSet="/logo.png 1x, /logo@2x.png 2x" alt="Bun logo" id="logo" />
<img
height="31.65px"
- src={`/Bun@2x.png`}
+ src="/Bun.png"
+ srcSet="/Bun.png 1x, /Bun@2x.png 2x"
alt="Bun"
id="logo-text"
/>
@@ -288,27 +291,33 @@ export default ({ inlineCSS }) => (
</div>
<div className="Graphs Graphs--active-react">
- <div className="Tabs">
- <div data-tab="react" className="Tab">
- Bun.serve
- </div>
- <div data-tab="sqlite" className="Tab">
- bun:sqlite
- </div>
- <div data-tab="ffi" className="Tab">
- bun:ffi
- </div>
- </div>
+ <ul className="Tabs" role="tablist">
+ <li className="Tab">
+ <button data-tab="react" aria-controls="react-tab-content" className="TabButton" role="tab" aria-selected tabIndex={0}>
+ Bun.serve
+ </button>
+ </li>
+ <li className="Tab">
+ <button data-tab="sqlite" aria-controls="sqlite-tab-content" className="TabButton" role="tab" tabIndex={-1}>
+ bun:sqlite
+ </button>
+ </li>
+ <li className="Tab">
+ <button data-tab="ffi" aria-controls="ffi-tab-content" className="TabButton" role="tab" tabIndex={-1}>
+ bun:ffi
+ </button>
+ </li>
+ </ul>
<div id="active-tab" className="ActiveTab">
- <div className="BarGraph BarGraph--react BarGraph--horizontal BarGraph--dark">
- <div className="BarGraph-heading">
+ <div id="react-tab-content" className="BarGraph BarGraph--react BarGraph--horizontal BarGraph--dark">
+ <h2 className="BarGraph-heading">
Server-side rendering React
- </div>
- <div title="oha -z 5s" className="BarGraph-subheading">
+ </h2>
+ <p className="BarGraph-subheading">
HTTP requests per second (Linux AMD64)
- </div>
+ </p>
- <div style={{ "--count": 3 }} className="BarGraphList">
+ <ul style={{ "--count": 3 }} className="BarGraphList">
<BarGraphItem
type="bun"
amount={48936}
@@ -327,7 +336,7 @@ export default ({ inlineCSS }) => (
label="requests per second"
max={Math.max(48936, 16288, 12289) * 1.25}
/>
- </div>
+ </ul>
<div style={{ "--count": 3 }} className="BarGraphKey">
<BarGraphLabel
@@ -348,13 +357,13 @@ export default ({ inlineCSS }) => (
</div>
</div>
- <div className="BarGraph--sqlite BarGraph BarGraph--horizontal BarGraph--dark">
- <div className="BarGraph-heading">Load a huge table</div>
- <div className="BarGraph-subheading">
+ <div id="sqlite-tab-content" className="BarGraph--sqlite BarGraph BarGraph--horizontal BarGraph--dark">
+ <h2 className="BarGraph-heading">Load a huge table</h2>
+ <p className="BarGraph-subheading">
Average queries per second
- </div>
+ </p>
- <div style={{ "--count": 3 }} className="BarGraphList">
+ <ul style={{ "--count": 3 }} className="BarGraphList">
<BarGraphItem
type="bun"
amount={(1000 / 16.6).toFixed(2)}
@@ -379,7 +388,7 @@ export default ({ inlineCSS }) => (
Math.max(1000 / 16.6, 1000 / 42.96, 1000 / 104.69) * 1.25
)}
/>
- </div>
+ </ul>
<div style={{ "--count": 3 }} className="BarGraphKey">
<BarGraphLabel
@@ -400,11 +409,11 @@ export default ({ inlineCSS }) => (
</div>
</div>
- <div className="BarGraph BarGraph--ffi BarGraph--horizontal BarGraph--dark">
- <div className="BarGraph-heading">How fast can it get?</div>
- <div className="BarGraph-subheading">Operations per second</div>
+ <div id="ffi-tab-content" className="BarGraph BarGraph--ffi BarGraph--horizontal BarGraph--dark">
+ <h2 className="BarGraph-heading">How fast can it get?</h2>
+ <p className="BarGraph-subheading">Operations per second</p>
- <div style={{ "--count": 3 }} className="BarGraphList">
+ <ul style={{ "--count": 3 }} className="BarGraphList">
<BarGraphItem
type="bun"
amount={(115473441).toFixed(2)}
@@ -424,12 +433,12 @@ export default ({ inlineCSS }) => (
<BarGraphItem
type="deno"
amount={(2891761).toFixed(2)}
- label="oeprations per iteration"
+ label="operations per iteration"
max={Math.ceil(
Math.max(115473441, 43478261, 2891761) * 1.25
)}
/>
- </div>
+ </ul>
<div style={{ "--count": 3 }} className="BarGraphKey">
<BarGraphLabel
@@ -456,7 +465,7 @@ export default ({ inlineCSS }) => (
</div>
<section id="explain-section">
<div id="explain">
- <h1>Tell me more about Bun</h1>
+ <h2>Tell me more about Bun</h2>
<p>
Bun is a modern JavaScript runtime like Node or Deno. It was built
from scratch to focus on three main things:
@@ -487,7 +496,7 @@ export default ({ inlineCSS }) => (
future infrastructure, as well as developer productivity through
better, simpler tooling.
</p>
- <h1>Batteries included</h1>
+ <h2>Batteries included</h2>
<ul id="batteries">
<li>
Web APIs like{" "}
@@ -559,7 +568,7 @@ export default ({ inlineCSS }) => (
</li>
</ul>
- <h1>How does Bun work?</h1>
+ <h2>How does Bun work?</h2>
<p>
Bun.js uses the{" "}
<a href="https://github.com/WebKit/WebKit/tree/main/Source/JavaScriptCore">
@@ -584,7 +593,7 @@ export default ({ inlineCSS }) => (
transpiler, npm client, bundler, SQLite client, HTTP client,
WebSocket client and more.
</p>
- <h1>Why is Bun fast?</h1>
+ <h2>Why is Bun fast?</h2>
<p>
An enormous amount of time spent profiling, benchmarking and
optimizing things. The answer is different for every part of Bun,
@@ -598,7 +607,7 @@ export default ({ inlineCSS }) => (
Sponsor the Zig Software Foundation
</a>
</p>
- <h1>Getting started</h1>
+ <h2>Getting started</h2>
<p>
To install bun, run this{" "}
<a target="_blank" href="https://bun.sh/install">
@@ -654,8 +663,8 @@ export default {
<a href="https://bun.sh/discord">Bun's Discord</a>
</p>
- <h1>Bun CLI</h1>
- <Group title="npm takes 160ms to run a script that does nothing">
+ <h2>Bun CLI</h2>
+ <Group>
<Command>bun run</Command>
<p>
The same command for running JavaScript &amp; TypeScript files
@@ -675,7 +684,7 @@ export default {
</div>{" "}
</Group>
- <Group title="JavaScript package managers are not using the fastest system calls">
+ <Group>
<Command>bun install</Command>
<p>
bun install is an npm-compatible package manager. You probably
@@ -705,11 +714,11 @@ export default {
</Label>
</Group>
- <h1>What is the license?</h1>
+ <h2>What is the license?</h2>
<p>
MIT License, excluding dependencies which have various licenses.
</p>
- <h1>How do I see the source code?</h1>
+ <h2>How do I see the source code?</h2>
<p>
Bun is on <a href="https://github.com/Jarred-Sumner/bun">GitHub</a>
</p>
@@ -722,11 +731,34 @@ export default {
<script
dangerouslySetInnerHTML={{
__html: `
-[...document.querySelectorAll(".Tab")].map(el => el.addEventListener("click", function(e) {
+[...document.querySelectorAll(".TabButton")].map(el => el.addEventListener("click", function(e) {
var tab = e.srcElement.getAttribute("data-tab");
+ [...document.querySelectorAll(".TabButton")].map(el => {
+ var active = el.getAttribute("data-tab") === tab;
+ el.setAttribute("tabindex", active ? 0 : -1);
+ el.setAttribute("aria-selected", active);
+ });
document.querySelector(".Graphs").setAttribute("class", "Graphs Graphs--active-" + tab);
}));
+document.body.addEventListener("keydown", e => {
+ var tabs = [...document.querySelectorAll(".TabButton")];
+ var activeTabEl = document.querySelector(".TabButton[aria-selected='true']");
+ var activeTabIndex = tabs.indexOf(activeTabEl);
+ if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
+ e.preventDefault();
+ activeTabIndex = (activeTabIndex + 1) % tabs.length;
+ tabs[activeTabIndex].click();
+ tabs[activeTabIndex].focus();
+ }
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
+ e.preventDefault();
+ activeTabIndex = (activeTabIndex + tabs.length - 1) % tabs.length;
+ tabs[activeTabIndex].click();
+ tabs[activeTabIndex].focus();
+ }
+});
+
document.querySelector("#code-box-copy").addEventListener("click", async e => {
var el = document.querySelector("#code-box");
await navigator.clipboard.writeText("curl https://bun.sh/install | bash");