Files
advanced-camera-card/src/components-lib/editor/section-controller.ts
T

69 lines
2.0 KiB
TypeScript

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();
}
}