@teaui/core
Version:
A high-level terminal UI library for Node
118 lines • 4.33 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Button = void 0;
const sys_1 = require("../sys");
const Container_1 = require("../Container");
const Text_1 = require("./Text");
const geometry_1 = require("../geometry");
const events_1 = require("../events");
const UI_1 = require("../UI");
class Button extends Container_1.Container {
#hotKey;
#onClick;
#textView;
#border = 'default';
#align = 'center';
constructor(props) {
super(props);
this.#textView = new Text_1.Text({ alignment: 'center' });
this.add(this.#textView);
this.#update(props);
}
update(props) {
this.#update(props);
super.update(props);
}
childTheme(view) {
return (0, UI_1.childTheme)(super.childTheme(view), this.isPressed, this.isHover);
}
#update({ title, border, align, hotKey, onClick }) {
const styledText = hotKey ? (0, events_1.styleTextForHotKey)(title ?? '', hotKey) : title;
this.#textView.text = styledText ?? '';
this.#align = align ?? 'center';
this.#border = border ?? 'default';
this.#hotKey = hotKey;
this.#onClick = onClick;
}
naturalSize(available) {
const [left, right] = this.#borderSize();
return super.naturalSize(available).grow(left + right, 0);
}
get title() {
return this.#textView.text;
}
set title(value) {
const styledText = this.#hotKey
? (0, events_1.styleTextForHotKey)(value ?? '', this.#hotKey)
: (value ?? '');
this.#textView.text = styledText;
this.invalidateSize();
}
#borderSize() {
const [left, right] = BORDERS[this.#border];
return [sys_1.unicode.lineWidth(left), sys_1.unicode.lineWidth(right)];
}
receiveMouse(event, system) {
super.receiveMouse(event, system);
if ((0, events_1.isMouseClicked)(event)) {
this.#onClick?.();
}
}
receiveKey(_) {
this.#onClick?.();
}
render(viewport) {
if (viewport.isEmpty) {
return super.render(viewport);
}
viewport.registerMouse(['mouse.button.left', 'mouse.move']);
if (this.#hotKey) {
viewport.registerHotKey((0, events_1.toHotKeyDef)(this.#hotKey));
}
const textStyle = this.theme.ui({
isPressed: this.isPressed,
isHover: this.isHover,
});
const topsStyle = this.theme.ui({
isPressed: this.isPressed,
isHover: this.isHover,
isOrnament: true,
});
viewport.visibleRect.forEachPoint(pt => {
if (pt.y === 0 && viewport.contentSize.height > 2) {
viewport.write('▔', pt, topsStyle);
}
else if (pt.y === viewport.contentSize.height - 1 &&
viewport.contentSize.height > 2) {
viewport.write('▁', pt, topsStyle);
}
else {
viewport.write(' ', pt, textStyle);
}
});
const [leftWidth, rightWidth] = this.#borderSize();
const naturalSize = super.naturalSize(viewport.contentSize.shrink(leftWidth + rightWidth, 0));
const offsetLeft = this.#align === 'center'
? Math.round((viewport.contentSize.width - naturalSize.width) / 2)
: this.#align === 'left'
? 1
: viewport.contentSize.width - naturalSize.width - 1, offset = new geometry_1.Point(offsetLeft, Math.round((viewport.contentSize.height - naturalSize.height) / 2));
const [left, right] = BORDERS[this.#border], leftX = offset.x - leftWidth, rightX = offset.x + naturalSize.width;
for (let y = 0; y < naturalSize.height; y++) {
viewport.write(left, new geometry_1.Point(leftX, offset.y + y), textStyle);
viewport.write(right, new geometry_1.Point(rightX, offset.y + y), textStyle);
}
viewport.clipped(new geometry_1.Rect(offset, naturalSize), textStyle, inside => {
super.render(inside);
});
}
}
exports.Button = Button;
const BORDERS = {
default: ['[ ', ' ]'],
arrows: [' ', ' '],
none: [' ', ' '],
};
// E0A0
// E0B0
//# sourceMappingURL=Button.js.map