Desktop UI APIs
Small helpers on __resuma: announce, measure, keyboard vs pointer, text zoom, presence, storage, online, and a focus queue.
__resuma.announce / measure
Accessibility.announce
js! {
await __resuma.action("save", []);
__resuma.announce("Saved");
}Every interactive page gets a polite #r-live region (role="status"). Prefer this over per-widget aria-live.
measure / keyboard / text zoom
js! {
const box = __resuma.measure(event.currentTarget); // { x, y, width, height }
const kb = __resuma.isNavigatingWithKeyboard(); // html[data-r-nav=keyboard]
const zoom = __resuma.contentSizeMultiplier(); // html font-size / 16
}Presence (idle vs active)
__resuma.presence() is { idle, hidden }. Idle after 60s without pointer/key/scroll, or when the tab is hidden. loader_poll skips ticks while idle so live dashboards do not burn the network. Listen for resuma:presence on document.
Online + Storage (SSR-safe)
js! {
if (!__resuma.online()) { /* offline PWA */ }
__resuma.storage.set("theme", "dark"); // no-op if localStorage throws
const t = __resuma.storage.get("theme");
}There is no Rust localStorage during SSR — keep reads/writes in js! / visible tasks. Pair with PWA. Document palettes (html[data-theme]) use HtmlTheme, not storage.set("theme").
RTL layout
FlowApp::new().with_dir("rtl")
// or per request in #[load] / page:
set_page_dir("rtl");
set_page_theme("slate"); // SSR html[data-theme] for this responseThis sets <html dir>. Use logical CSS (margin-inline-start, inset-inline-end) instead of left/right. Fluent strings in #[load] do not flip flex by themselves — see i18n.
Focus arbitrator
__resuma.focus(el) queues focus() for the next microtask so SPA swaps, popups, and dialogs do not steal focus from each other. focusMain() after navigation uses the same queue.