import { Label, requestRender, type TextField, ui } from '../../ui'; /** * What a form that can be refused shows about its last attempt – the sign-in screen and the * password dialog: the warning line under the fields, and whether an answer is still awaited. */ export class FormStatus { readonly message = new Label('', { style: 'warning' }); private waiting = false; /** `onChange` redoes what the form shows of it: its button while waiting, its layout after a message. */ constructor(private readonly onChange: (busy: boolean) => void) {} get busy(): boolean { return this.waiting; } /** What the check scripts read. */ info(): { message: string; busy: boolean } { return { message: this.message.text, busy: this.waiting }; } say(message: string): void { this.message.setText(message); this.changed(); } setBusy(busy: boolean): void { this.waiting = busy; this.changed(); } private changed(): void { this.onChange(this.waiting); requestRender(); } } /** * Puts the caret back into a field after a refused attempt. A field blurs itself once its Enter * has been handled, and that happens after this call returns – so the focus has to be set again * behind it, or the next thing typed goes nowhere. */ export function refocus(field: TextField): void { queueMicrotask(() => ui().focus.focus(field)); }