Skip to content

Instantly share code, notes, and snippets.

@janklan
Last active October 17, 2021 23:23
Show Gist options
  • Save janklan/7f592d1484b3e72d39a76a9516d115b4 to your computer and use it in GitHub Desktop.
Save janklan/7f592d1484b3e72d39a76a9516d115b4 to your computer and use it in GitHub Desktop.
Tailwind CSS Alpine dropdown
import Alpine from "alpinejs";
/**
* Dropdown component
*
* How to use:
*
* 1. Use any valid Dropdown component
* 2. Add `x-data="dropdown" x-bind="container"` to the container of both trigger buttons, and the dropdown menu
* 3. Add `x-bind="trigger"` to the element that should open the dropdown
* 4. Add `x-bind="menu"` to the container of the dropdown menu.
*
* Minimal code example (will work, but will not look good because all the other classes are missing):
*
* ```html
* <div x-data="dropdown" x-bind="container">
* <button x-bind="trigger">Open</button>
* <div x-bind="menu">
* <ul>
* <li>Menu item</li>
* </ul>
* </div>
* </div>
* ```
*
* @see https://localhost:8000/test/ui To see this in action
* @see https://alpinejs.dev/directives/cloak If you don't know what `x-cloak` is there for
* @see https://tailwindui.com/components/application-ui/elements/dropdowns For off-the-shelf dropdowns
*/
document.addEventListener('alpine:init', () => {
Alpine.data('dropdown', () => ({
isOpen: false,
open: function() {
if (!this.isOpen) {
this.isOpen = true;
}
},
close: function() {
if (this.isOpen) {
this.isOpen = false;
}
},
container: {
'x-on:keydown.escape'() { this.close() },
'x-on:click.outside'() { this.close() },
},
trigger: {
'x-on:click'() { this.isOpen = ! this.isOpen },
':aria-expanded'() { return this.isOpen },
},
menu: {
'x-show'() { return this.isOpen },
'x-transition:enter'() { return 'transition ease-out duration-100' },
'x-transition:enter-start'() { return 'transform opacity-0 scale-95' },
'x-transition:enter-end'() { return 'transform opacity-100 scale-100' },
'x-transition:leave'() { return 'transition ease-in duration-75' },
'x-transition:leave-start'() { return 'transform opacity-100 scale-100' },
'x-transition:leave-end'() { return 'transform opacity-0 scale-95' },
},
}))
})
@janklan
Copy link
Author

janklan commented Oct 17, 2021

The plan for the future is to add keyboard navigation, but this will at least handle hitting escape, and clicking outside the dropdown to close it. Also, x-cloak needs some prior setup unrelated to the Dropdown alone: https://alpinejs.dev/directives/cloak

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment