Menu
Add the component to your project
Run the following command in your terminal
bundle exec essence add dropdown
Copy and paste the following code into your project
# frozen_string_literal: true
class Components::Dropdown < Components::Essence
BASE = "relative inline-block"
TRIGGER_BASE = "cursor-pointer list-none"
CONTENT_BASE = "hidden absolute mt-2 z-10 rounded-md bg-white border border-b-2 border-gray-200/75 p-1.5 flex-col min-w-48 w-fit right-0"
ITEM_BASE = "flex items-center gap-2 p-1 w-full flex text-xs font-medium text-gray-700 group hover:bg-gray-50 transition duration-100 rounded-xs justify-start"
SEPARATOR_BASE = "border-t border-gray-200/75 my-2 -mx-1.5"
POSITIONS = {
top: "bottom-full",
right: "left-full",
bottom: "top-full",
left: "right-full"
}
attr_reader :attributes
def initialize(**attributes)
super(**attributes)
@attributes[:class] = merge_classes(BASE, attributes[:class])
end
def view_template(&)
div(**attributes, &)
end
def trigger(**mattributes, &)
mattributes[:class] = merge_classes(TRIGGER_BASE, mattributes[:class])
mattributes[:data] = { action: "click->dropdown#toggle click@window->dropdown#hide" }
render Button.new(**mattributes, &)
end
def content(**mattributes, &)
mattributes[:class] = merge_classes(CONTENT_BASE, mattributes[:class])
mattributes[:data] = { dropdown_target: "content" }
div(**mattributes, &)
end
def item(**mattributes, &)
mattributes[:size] = :xs
mattributes[:kind] = :ghost
mattributes[:class] = merge_classes(ITEM_BASE, mattributes[:class])
render Button.new(**mattributes, &)
end
def separator(**mattributes)
mattributes[:class] = merge_classes(SEPARATOR_BASE, mattributes[:class])
hr(**mattributes)
end
private
def initialize_default_attributes
{
data: {
controller: "dropdown"
}
}
end
end
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["content"];
connect() {}
toggle() {
this.contentTarget.classList.toggle("hidden");
}
hide(event) {
if (
!this.element.contains(event.target) &&
!this.contentTarget.classList.contains("hidden")
) {
this.contentTarget.classList.add("hidden");
}
}
}