@nu-art/commando
Version:
146 lines (145 loc) • 4.96 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConsoleContainer = void 0;
const ts_common_1 = require("@nu-art/ts-common");
const types_1 = require("./types");
/**
* An abstract class representing a container for Blessed widgets with state management and key bindings.
*
* @template Type - The type of the Blessed widget.
* @template State - The type of the state object.
*/
class ConsoleContainer extends ts_common_1.Logger {
/**
* Creates an instance of ConsoleContainer.
*
* @param {Type} type - The type of the container widget.
* @param {BlessedWidgetOptions[Type]} [containerProps] - The properties to apply to the container widget.
* @param {KeyBinding[]} [keyBinding] - An array of key bindings for the container widget.
*/
constructor(type, containerProps, keyBinding = []) {
super(containerProps === null || containerProps === void 0 ? void 0 : containerProps.name);
this.enabled = false;
this.state = {};
this.widgets = [];
/**
* Resumes rendering and enables focus on the widgets.
*
* @returns {this} The current instance for method chaining.
*/
this.resume = () => {
this.enabled = true;
this.widgets.forEach(widget => {
widget.focusable = true;
});
this._render();
return this;
};
/**
* Pauses rendering and disables focus on the widgets.
*
* @returns {this} The current instance for method chaining.
*/
this.pause = () => {
this.enabled = false;
this.widgets.forEach(widget => {
widget.focusable = false;
});
return this;
};
/**
* Disposes of the container and its widgets.
*
* @returns {this} The current instance for method chaining.
*/
this.dispose = () => {
if (!this.container)
return this;
this.widgets.forEach(widget => widget.detach());
this.widgets.length = 0;
this._render();
if (this.enabled)
this.pause();
this.container.detach();
this.container.destroy();
// @ts-ignore
this.container = null;
return this;
};
this.type = type;
this.keyBinding = keyBinding;
this.containerProps = containerProps;
}
/**
* Sets the state of the container and triggers a re-render.
*
* @param {ResolvableContent<Partial<State>>} state - The new state to set.
* @returns {this} The current instance for method chaining.
*/
setState(state) {
this.state = (0, ts_common_1.mergeObject)(this.state, state);
this._render();
return this;
}
/**
* Creates a Blessed widget of the specified type and adds it to the container.
*
* @template WidgetType - The type of the widget to create.
* @param {WidgetType} type - The type of the widget to create.
* @param {BlessedWidgetOptions[WidgetType]} props - The properties to apply to the widget.
* @returns {BlessedWidget[WidgetType]} The created widget.
*/
createWidget(type, props) {
const widget = (0, types_1.createBlessedWidget)(type, props, this.container);
this.widgets.push(widget);
return widget;
}
/**
* Gets the currently focused widget within the container.
*
* @returns {Widgets.Node} The focused widget.
*/
getFocusedWidget() {
return this.container.screen.focused;
}
createContainer() {
if (this.container) {
return this.logWarning('Container already exists!');
}
try {
this.container = (0, types_1.createBlessedWidget)(this.type, this.containerProps, this.container);
this.keyBinding.forEach(keyBinding => {
this.container.key(keyBinding.keys, keyBinding.callback);
});
}
catch (error) {
this.logError('Failed to create container:', error);
}
}
_createWidgets() {
if (this.widgets.length > 0) {
this.logWarning(`Widgets already created (${this.widgets.length} widgets)!`);
return;
}
this.createContent();
}
/**
* Creates the container and its widgets, and resumes rendering if not already enabled.
*
* @returns {this} The current instance for method chaining.
*/
create() {
this.createContainer();
this._createWidgets();
if (!this.enabled)
this.resume();
return this;
}
_render() {
if (!this.enabled)
return;
this.render();
this.container.screen.render();
}
}
exports.ConsoleContainer = ConsoleContainer;