feat: Modernize the visual card editor. (#2586)

This commit is contained in:
Dermot Duffy
2026-07-20 20:44:16 -07:00
committed by GitHub
parent e204ec183f
commit b6e1de5999
146 changed files with 8487 additions and 5992 deletions
@@ -0,0 +1,68 @@
import type { ReactiveController, ReactiveControllerHost, TemplateResult } from 'lit';
import { FormsController, type FormContext, type FormsInput } from './forms-controller';
import { fireEditorIntent } from './intents';
import type { FormRequest } from './schema/registry';
import type { ConfigChange, ConfigPath } from './types';
type SectionEditorControllerHost = ReactiveControllerHost & EventTarget;
/**
* One top-level section of the editor: whether its panel is open, and the
* forms it shows. A section is given the whole configuration, because a
* dropdown in one section may list values set in another, but it never changes
* it: an edit is reported to the editor as an intent.
*/
export class SectionController implements ReactiveController {
private _host: SectionEditorControllerHost;
private _formsController: FormsController;
private _open = false;
// A section's body is built only once it has been opened, and is kept
// afterwards: closing animates, and a section the user never opens never
// builds its forms at all.
private _everOpened = false;
constructor(
host: SectionEditorControllerHost,
renderDocumentation: (path: ConfigPath) => TemplateResult | null,
) {
this._host = host;
this._formsController = new FormsController(
(changes: ConfigChange[]) =>
fireEditorIntent(this._host, { type: 'changes', changes }),
renderDocumentation,
);
host.addController(this);
}
public hostConnected(): void {
// No connection-time work.
}
public setInput(request: FormRequest, input: FormsInput): void {
this._formsController.setInput(request, input);
}
public getContexts(): FormContext[] {
return this._formsController.getContexts();
}
public isOpen(): boolean {
return this._open;
}
public wasEverOpened(): boolean {
return this._everOpened;
}
public setOpen(open: boolean): void {
if (open === this._open) {
return;
}
this._open = open;
this._everOpened = this._everOpened || open;
this._host.requestUpdate();
}
}