Initial commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Mount-on-open menu fixture</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { font-family: system-ui, sans-serif; }
|
||||
header { display: flex; align-items: center; gap: 24px; height: 56px; padding: 0 24px; border-bottom: 1px solid #eee; }
|
||||
.brand { font-weight: 700; }
|
||||
nav { display: flex; gap: 8px; }
|
||||
.trigger { background: none; border: 0; font: inherit; padding: 8px 12px; border-radius: 6px; cursor: pointer; color: #333; }
|
||||
.trigger[aria-expanded="true"] { background: #eef2fd; color: #2b50d6; }
|
||||
/* the panel is mounted into <body> on open (Radix-style portal) and removed on close */
|
||||
.menu-panel { position: absolute; background: #fff; border: 1px solid #e2e2e2; border-radius: 12px; box-shadow: 0 12px 32px rgba(0,0,0,0.12); padding: 16px; width: 320px; display: grid; gap: 8px; }
|
||||
.menu-panel a { display: block; padding: 10px 12px; border-radius: 8px; color: #222; text-decoration: none; }
|
||||
.menu-panel a:hover { background: #f4f6fe; }
|
||||
.menu-panel .label { font-size: 12px; color: #888; text-transform: uppercase; letter-spacing: .04em; padding: 4px 12px; }
|
||||
main { padding: 48px 24px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<span class="brand">Acme</span>
|
||||
<nav>
|
||||
<button class="trigger" id="t-product" aria-haspopup="menu" aria-expanded="false" aria-controls="panel-product">Product</button>
|
||||
<a class="trigger" href="/pricing">Pricing</a>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
<h1>Mount-on-open menu</h1>
|
||||
<p>The Product menu mounts its panel into <body> on open and removes it on close.</p>
|
||||
</main>
|
||||
<script>
|
||||
const t = document.getElementById('t-product');
|
||||
let panel = null;
|
||||
function open() {
|
||||
if (panel) return;
|
||||
panel = document.createElement('div');
|
||||
panel.className = 'menu-panel';
|
||||
panel.id = 'panel-product';
|
||||
panel.setAttribute('role', 'menu');
|
||||
const r = t.getBoundingClientRect();
|
||||
panel.style.left = (r.left + window.scrollX) + 'px';
|
||||
panel.style.top = (r.bottom + window.scrollY + 8) + 'px';
|
||||
panel.innerHTML = '<div class="label">Build</div>' +
|
||||
'<a href="/features">Features</a>' +
|
||||
'<a href="/integrations">Integrations</a>' +
|
||||
'<a href="/changelog">Changelog</a>' +
|
||||
'<div class="label">Learn</div>' +
|
||||
'<a href="/docs">Documentation</a>' +
|
||||
'<a href="/guides">Guides</a>';
|
||||
document.body.appendChild(panel);
|
||||
t.setAttribute('aria-expanded', 'true');
|
||||
}
|
||||
function close() {
|
||||
if (panel) { panel.remove(); panel = null; }
|
||||
t.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
t.addEventListener('click', () => (t.getAttribute('aria-expanded') === 'true' ? close() : open()));
|
||||
document.addEventListener('keydown', (e) => { if (e.key === 'Escape') close(); });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user