@yarso/astro-dropdown
v1.1.0
Published
Simple, customizable dropdown menu utility for Astro with only vanilla JS
Maintainers
Readme
Dropdown Menu for Astro 🚀
Simple, customizable dropdown menu utility for Astro with only vanilla JS.
I personally use UI libraries like ShadCN for web applications, but Astro was mainly designed for static sites. If I say "It's the best framework for building static sites like landing pages, portfolios, documentation pages, etc..." it's not just an opinion.
Initially, I used the Dropdown component that UI libraries provide, but most of the time I use it on headers so it gets loaded at the very beginning of the fetch. And believe me, it's more than 300KB, so I decided to build my own component just for my personal use with only vanilla JS.
Feel free to use it, modify it, report issues, or just complain about it.
[!NOTE]
The objective of this component is to reduce bundle size to improve the performance of Astro applications.
Installation
pnpm add @yarso/astro-dropdownUsage
Create a Dropdown Menu
Just add a <button> element as a child of the <Dropdown> component to set the trigger. Then add a <div> element also as a child of the <Dropdown> with a child <ul> element to set the content.
import { Dropdown } from "@yarso/astro-dropdown"<Dropdown>
<!-- Trigger element -->
<button>
🚀
</button>
<!-- Content element -->
<div>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</Dropdown>[!WARNING]
It's important to note that the content element must be a direct child of the dropdown element and have a<ul>element as a child. You can add any other elements inside the<ul>to create your dropdown menu.
Customization
You're free to style the <button> and <ul> elements as you wish using whatever attributes you want and whatever frameworks you prefer (e.g., Tailwind, Bootstrap, vanilla CSS, etc.).
[!NOTE]
I suggest you set a fixed width for the<ul>element to avoid the content splitting in the middle of the dropdown.
Custom Attributes
The <Dropdown> component has some optional custom attributes that you can use to customize its behavior:
container-gap: This attribute sets the gap in pixels between the trigger element and the content element (default is4).content-origin: This attribute sets the origin of the content element (default isbottom-right).content-z-index: This attribute sets the z-index of the content element (default is30).
import { Dropdown } from "@yarso/astro-dropdown"<Dropdown
container-gap={8}
content-origin="top-left"
content-z-index={10}
>
<!-- Trigger element -->
<button>
🚀
</button>
<!-- Content element -->
<div>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</Dropdown>How It Works
- Zero dependencies: Pure vanilla JavaScript
- Zero configuration: No setup needed
- Fully customizable: Total control over child elements
- Lightweight: ~6KB in production
- Multiple dropdowns: Now supported automatically!
Practical Example
<Dropdown>
<button class="rounded-xs bg-green-700 text-white hover:bg-green-500 transition-colors duration-200 py-1 px-3">
🚀
</button>
<div>
<ul class="bg-zinc-800 border-[1px] border-zinc-600 w-[200px]">
<li class="w-full">
href="/test-a"
class="hover:underline underline-offset-2 w-full block"
>Link to test A</a>
</li>
<li class="w-full">
href="/test-b"
class="hover:underline underline-offset-2 w-full block"
>Link to test B</a>
</li>
</ul>
</div>
</Dropdown>Known Limitations
This is a custom implementation designed to suit specific requirements, so yeah, there are plenty of areas for improvement.
Required Fixed Width on <ul> Element
If you don't set a fixed width for the <ul> element, the content might split awkwardly in the middle of the dropdown. You might be able to make it work using block elements as children of the <ul>, but it's easier to just set a fixed width.
No Custom Animations
For now, I don't allow custom animations, but I'll implement a fix once I get time. I honestly don't need it, but it could be useful for some people. Feel free to fork and create a PR if you want to add it—I'll be grateful for that.
License
MIT License.
