import { App, Astal, Gdk, Gtk } from "astal/gtk3" import { Variable, bind } from "astal" interface DropdownProps { gdkmonitor: Gdk.Monitor target: Gtk.Widget open: Variable width?: number vertical?: boolean className?: string children: Array } export default function Dropdown({ gdkmonitor, target, open, width = 260, vertical = true, className = "", children, }: DropdownProps) { const { TOP, BOTTOM, LEFT, RIGHT } = Astal.WindowAnchor const GAP = 8 const child = ( {children} ) function reposition() { const toplevel = target.get_toplevel() const [, tx, ty] = target.translate_coordinates(toplevel, 0, 0) const { width: bw, height: bh } = target.get_allocation() const { width: sw } = gdkmonitor.get_geometry() const x = Math.min(Math.max(tx + bw / 2 - width / 2, GAP), sw - width - GAP) const y = ty + bh + GAP child.marginStart = Math.round(x) child.marginTop = Math.round(y) } open.subscribe((v) => { if (v) reposition() }) return ( { if (!self.visible) open.set(false) }} onButtonPressEvent={(self, e) => { const event = e as unknown as Gdk.Event const [, px, py] = event.get_coords() const { x, y, width: w, height: h } = child.get_allocation() const xOut = px < x || px > x + w const yOut = py < y || py > y + h if (xOut || yOut) self.visible = false }} onKeyPressEvent={(self, e) => { const event = e as unknown as Gdk.Event if (event.get_keyval()[1] === Gdk.KEY_Escape) self.visible = false }} > {child} ) }