import { App, Astal, Gdk, Gtk } from "astal/gtk3" const { TOP, RIGHT, BOTTOM, LEFT } = Astal.WindowAnchor type PopupProps = { child?: unknown marginBottom?: number marginTop?: number marginLeft?: number marginRight?: number halign?: Gtk.Align valign?: Gtk.Align } function Popup({ child, marginBottom, marginTop, marginLeft, marginRight, halign = Gtk.Align.CENTER, valign = Gtk.Align.CENTER, }: PopupProps) { return ( { const [, _x, _y] = event.get_coords() const { x, y, width, height } = self .get_child()! .get_allocation() const xOut = _x < x || _x > x + width const yOut = _y < y || _y > y + height // clicked outside if (xOut || yOut) self.hide() }} // close when hitting Escape onKeyPressEvent={(self, event: Gdk.Event) => { if (event.get_keyval()[1] === Gdk.KEY_Escape) { self.hide() } }} > true} // make sure click event does not bubble up // child can be positioned with `halign` `valign` and margins expand halign={halign} valign={valign} marginBottom={marginBottom} marginTop={marginTop} marginStart={marginLeft} marginEnd={marginRight} > {child} ) } App.start({ instanceName: "popup-example", css: ` .Popup { background-color: @theme_bg_color; box-shadow: 2px 3px 7px 0 rgba(0,0,0,0.4); border-radius: 12px; padding: 12px; } `, main() { const popup = ( ) return ( ) }, })