import GLib from "gi://GLib" import Pango from "gi://Pango" import Gtk from "gi://Gtk?version=3.0" import { bind, type Binding, type Variable } from "astal" // rotating arrow button: icon turns 90deg in small steps while the section // opens, ported from AlfheimOS; a single self-clearing chained timer drives // the animation so cancellation only ever touches provably live sources export function Arrow({ open, onToggle, }: { open: Variable onToggle: () => void }) { let deg = 0 let timer: number | undefined const icon = const animate = (target: number) => { if (timer !== undefined) { GLib.source_remove(timer) timer = undefined } const tick = () => { deg += Math.sign(target - deg) * 10 icon.css = `-gtk-icon-transform: rotate(${deg}deg);` if (deg !== target) { timer = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 15, tick) } else { timer = undefined } return GLib.SOURCE_REMOVE } if (deg !== target) tick() } open.subscribe((v) => animate(v ? 90 : 0)) return ( ) } type ArrowToggleButtonProps = { open: Variable icon: string | Binding label: string | Binding active: Binding onMainClick: () => void onArrowClick: () => void } // icon + label pill with a detached arrow: the pill toggles the feature, // the arrow rotates open its device menu export function ArrowToggleButton({ open, icon, label, active, onMainClick, onArrowClick, }: ArrowToggleButtonProps) { return ( (v ? "toggle-button active" : "toggle-button"))} hexpand > ) } type MenuProps = { open: Variable icon: string | Binding title: string children: Array } // revealer with a titled card header, shown while the section is open export function Menu({ open, icon, title, children }: MenuProps) { return ( {children} ) }