UNPKG

@teaui/core

Version:

A high-level terminal UI library for Node

113 lines 4.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CollapsibleText = void 0; const sys_1 = require("../sys"); const View_1 = require("../View"); const Style_1 = require("../Style"); const geometry_1 = require("../geometry"); const events_1 = require("../events"); class CollapsibleText extends View_1.View { #lines = []; #style; #isCollapsed = true; constructor(props) { super(props); this.#update(props); } update(props) { this.#update(props); super.update(props); } #update({ text, style }) { this.#style = style; this.#lines = text.split('\n'); } get text() { return this.#lines.join('\n'); } set text(value) { this.#lines = value.split('\n'); this.invalidateSize(); } naturalSize(available) { if (this.#lines.length === 0) { return geometry_1.Size.zero; } if (this.#lines.length === 1) { const { width: lineWidth, height: lineHeight } = sys_1.unicode.stringSize(this.#lines, available.width); if (lineWidth <= available.width && lineHeight === 1) { return new geometry_1.Size(lineWidth, 1); } if (this.#isCollapsed) { return new geometry_1.Size(lineWidth + 2, 1); } return new geometry_1.Size(lineWidth + 2, lineHeight); } if (this.#isCollapsed) { const lineWidth = sys_1.unicode.lineWidth(this.#lines[0]); return new geometry_1.Size(lineWidth + 2, 1); } return new geometry_1.Size(sys_1.unicode.stringSize(this.#lines, available.width)).grow(2, 0); } receiveMouse(event, system) { super.receiveMouse(event, system); if ((0, events_1.isMouseClicked)(event)) { this.#isCollapsed = !this.#isCollapsed; this.invalidateSize(); } } render(viewport) { if (viewport.isEmpty) { return; } const lines = this.#lines; if (!lines.length) { return; } const startingStyle = Style_1.Style.NONE; viewport.usingPen(this.#style, pen => { const { width, height } = sys_1.unicode.stringSize(lines, viewport.contentSize.width); const point = new geometry_1.Point(0, 0).mutableCopy(); let offsetX = 0; if (viewport.contentSize.width < width || height > 1) { viewport.registerMouse('mouse.button.left'); viewport.write(this.#isCollapsed ? '► ' : '▼ ', geometry_1.Point.zero, this.theme.text({ isPressed: this.isPressed })); offsetX = 2; } point.x = offsetX; for (const line of this.#lines) { let didWrap = false; for (const char of sys_1.unicode.printableChars(line)) { const width = sys_1.unicode.charWidth(char); if (width === 0) { pen.mergePen(Style_1.Style.fromSGR(char, startingStyle)); continue; } if (!this.#isCollapsed && point.x >= viewport.contentSize.width) { didWrap = true; point.x = offsetX; point.y += 1; } // don't print preceding whitespace after line wrap if (didWrap && char.match(/\s/)) { continue; } didWrap = false; if (point.x >= viewport.visibleRect.minX() && point.x + width - 1 < viewport.visibleRect.maxX() && point.y >= viewport.visibleRect.minY()) { viewport.write(char, point); } point.x += width; } point.y += 1; if (point.y >= viewport.visibleRect.maxY()) { break; } point.x = offsetX; } }); } } exports.CollapsibleText = CollapsibleText; //# sourceMappingURL=CollapsibleText.js.map