Simple Navbar
A logo, an inline link row and a CTA, collapsing to a hamburger menu below the md breakpoint.
6 फ्रेमवर्कमध्यम
A nav bar whose Products link opens a real keyboard-navigable submenu - click, arrows, Escape.
<!--
A dropdown that opens on hover only is a mouse-only control. This one is a
<button aria-haspopup="true" aria-expanded> that opens on click and on Enter,
moves through items with the arrow keys, and closes on Escape returning focus
to the trigger - the behaviour a native menu has on every platform.
The submenu is a <ul> of plain links, not role="menu": these navigate
somewhere, they are not commands, and role="menu" would make a screen reader
announce them as application menu items and swallow the arrow keys.
-->
<header class="navdrop">
<nav class="navdrop__inner" aria-label="Main">
<a class="navdrop__brand" href="/">Adysre</a>
<ul class="navdrop__links">
<li class="navdrop__item">
<button
class="navdrop__trigger"
type="button"
aria-haspopup="true"
aria-expanded="false"
aria-controls="navdrop-products"
>
Products
<svg class="navdrop__chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="m6 9 6 6 6-6" />
</svg>
</button>
<ul class="navdrop__panel" id="navdrop-products" hidden>
<li><a class="navdrop__option" href="/analytics">Analytics</a></li>
<li><a class="navdrop__option" href="/automation">Automation</a></li>
<li><a class="navdrop__option" href="/integrations">Integrations</a></li>
</ul>
</li>
<li><a class="navdrop__link" href="/pricing">Pricing</a></li>
<li><a class="navdrop__link" href="/docs">Docs</a></li>
</ul>
<a class="navdrop__cta" href="/login">Sign in</a>
</nav>
</header>
<script>
document.querySelectorAll('.navdrop__item').forEach(function (item) {
var trigger = item.querySelector('.navdrop__trigger');
var panel = item.querySelector('.navdrop__panel');
var options = Array.prototype.slice.call(item.querySelectorAll('.navdrop__option'));
function setOpen(open) {
panel.hidden = !open;
trigger.setAttribute('aria-expanded', String(open));
}
trigger.addEventListener('click', function () {
var open = trigger.getAttribute('aria-expanded') === 'true';
setOpen(!open);
if (!open && options[0]) options[0].focus();
});
item.addEventListener('keydown', function (event) {
if (event.key === 'Escape') {
setOpen(false);
trigger.focus();
return;
}
if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;
event.preventDefault();
if (document.activeElement === trigger && event.key === 'ArrowDown') {
setOpen(true);
if (options[0]) options[0].focus();
return;
}
var index = options.indexOf(document.activeElement);
if (index === -1) return;
var next = event.key === 'ArrowDown' ? index + 1 : index - 1;
options[(next + options.length) % options.length].focus();
});
document.addEventListener('click', function (event) {
if (!item.contains(event.target)) setOpen(false);
});
});
</script>| Prop | टाइप | डिफ़ॉल्ट | विवरण |
|---|---|---|---|
onSelect | (item: string) => void | - | यूज़र द्वारा चुने गए मेन्यू आइटम के साथ चलता है। |
ctaLabel | string | 'Sign in' | कॉल-टू-एक्शन बटन का टेक्स्ट। |
ctaHref | string | '/login' | कॉल-टू-एक्शन लिंक का डेस्टिनेशन। |
className | string | - | रूट एलिमेंट पर मर्ज होने वाली अतिरिक्त क्लासेज़। |
A dropdown that opens on `:hover` is a mouse-only control: there is no hover on a phone and no hover on a keyboard. This one opens on click and on Enter, moves between entries with the arrow keys, closes on Escape returning focus to the trigger, and dismisses on an outside click. The submenu is a plain `<ul>` of links, deliberately **not** `role="menu"` - these navigate somewhere, they are not commands, and `role="menu"` makes a screen reader announce them as application menu items and swallow the arrow keys you just wired up. The chevron rotation hangs off `aria-expanded`, so the arrow physically cannot point the wrong way. Replace `OPTIONS` with your own destinations. The bar row is `min-h-14` with `flex-wrap` rather than a fixed `h-14`: the links stay visible at every width, so on a 320px phone they wrap under the brand instead of forcing a horizontal scrollbar.