import { defineComponent, h, onBeforeUnmount, ref } from "vue";
import { cx, iconNode } from "../utils.js";
import GnButton from "./GnButton.js";
export default defineComponent({
name: "GnDropdown",
props: {
label: { type: String, default: "Actions" },
icon: { type: String, default: "ph-dots-three-outline" },
variant: { type: String, default: "secondary" },
items: { type: Array, default: () => [] }
},
emits: ["select"],
setup(props, { emit, slots }) {
const open = ref(false);
const root = ref(null);
const close = () => {
open.value = false;
document.removeEventListener("click", onOutsideClick);
document.removeEventListener("keydown", onKeydown);
};
const onOutsideClick = event => {
if(root.value && !root.value.contains(event.target)) {
close();
}
};
const onKeydown = event => {
if(event.key === "Escape") {
event.preventDefault();
close();
}
};
const toggle = () => {
open.value = !open.value;
if(open.value) {
setTimeout(() => document.addEventListener("click", onOutsideClick), 0);
document.addEventListener("keydown", onKeydown);
} else {
close();
}
};
const select = item => {
if(item.disabled) {
return;
}
item.onSelect?.(item);
emit("select", item);
close();
};
onBeforeUnmount(close);
return () => h("div", { ref: root, class: cx("dropdown", { "is-open": open.value }) }, [
slots.trigger?.({ open: open.value, toggle }) || h(GnButton, {
variant: props.variant,
icon: props.icon,
"aria-expanded": open.value ? "true" : "false",
onClick: toggle
}, () => props.label),
h("div", { class: "dropdown-menu", role: "menu" }, slots.default?.({ close }) || props.items.map(item => h("button", {
class: cx("dropdown-item", item.danger && "dropdown-item-danger"),
type: "button",
role: "menuitem",
disabled: item.disabled,
onClick: () => select(item)
}, [
iconNode(item.icon),
item.label
])))
]);
}
});