@flowtty/core 1.0.0-alpha.11 → 1.0.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{backend-CT8SGLO5.d.ts → backend-DPFtzaxG.d.ts} +11 -0
- package/dist/host/index.d.ts +2 -2
- package/dist/host/index.js +46 -6
- package/dist/{host-C98WW3Ai.d.ts → host-DnKJiaQh.d.ts} +20 -2
- package/dist/index.d.ts +7 -3
- package/dist/index.js +4 -4
- package/dist/testing/index.d.ts +1 -1
- package/dist/{wrap-D5f0P1iA.js → wrap-DvO7jrLD.js} +13 -1
- package/package.json +1 -1
|
@@ -45,6 +45,17 @@ interface Key {
|
|
|
45
45
|
//#endregion
|
|
46
46
|
//#region src/backend.d.ts
|
|
47
47
|
interface Backend {
|
|
48
|
+
/**
|
|
49
|
+
* The render area, in cells.
|
|
50
|
+
*
|
|
51
|
+
* `height` may be `Infinity`: an unbounded surface — a report printed once
|
|
52
|
+
* rather than a screen to fit into. The renderer then lays the tree out with
|
|
53
|
+
* no height constraint (percent heights have nothing to resolve against and
|
|
54
|
+
* fall back to auto) and draws a buffer exactly as tall as the content, so a
|
|
55
|
+
* frame can be any number of rows. `useTerminalSize()` reports `Infinity`
|
|
56
|
+
* for the height too, which is what a component should branch on when it
|
|
57
|
+
* would otherwise size itself to the screen.
|
|
58
|
+
*/
|
|
48
59
|
size(): {
|
|
49
60
|
width: number;
|
|
50
61
|
height: number;
|
package/dist/host/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { D as
|
|
1
|
+
import { D as Yoga, O as YogaNode, _ as Rect, b as layoutOf, c as appendChild, d as createTextInstance, f as insertBefore, g as removeChild, h as refreshMeasure, i as Instance, k as getYoga, l as applyProps, m as ownText, n as Container, o as TextInstance, p as measureText, r as HostType, u as createInstance, v as computeLayout, x as BORDER_CHARS, y as contentHeight } from "../host-DnKJiaQh.js";
|
|
2
2
|
import { t as Buffer } from "../cells-C-GthybI.js";
|
|
3
3
|
//#region src/host/paint.d.ts
|
|
4
4
|
export declare function paint(container: Container, width: number, height: number): Buffer;
|
|
5
5
|
//#endregion
|
|
6
|
-
export { BORDER_CHARS, type Container, type HostType, type Instance, type Rect, type TextInstance, type Yoga, type YogaNode, appendChild, applyProps, computeLayout, createInstance, createTextInstance, getYoga, insertBefore, layoutOf, measureText, ownText, refreshMeasure, removeChild };
|
|
6
|
+
export { BORDER_CHARS, type Container, type HostType, type Instance, type Rect, type TextInstance, type Yoga, type YogaNode, appendChild, applyProps, computeLayout, contentHeight, createInstance, createTextInstance, getYoga, insertBefore, layoutOf, measureText, ownText, refreshMeasure, removeChild };
|
package/dist/host/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as noteWarning, n as BORDER_CHARS, s as Buffer, t as wrapText } from "../wrap-DvO7jrLD.js";
|
|
2
2
|
import { Align, Display, Edge, FlexDirection, Gutter, Justify, MeasureMode, PositionType, Wrap, loadYoga } from "yoga-layout/load";
|
|
3
3
|
//#region src/host/yoga.ts
|
|
4
4
|
let yogaPromise = null;
|
|
@@ -25,6 +25,7 @@ function createTextInstance(text, _Yoga) {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
function applyProps(inst, props, _Yoga) {
|
|
28
|
+
const hadRuns = inst.props?.runs !== void 0;
|
|
28
29
|
inst.props = props;
|
|
29
30
|
const n = inst.yogaNode;
|
|
30
31
|
if (typeof props.width === "number") n.setWidth(props.width);
|
|
@@ -80,6 +81,7 @@ function applyProps(inst, props, _Yoga) {
|
|
|
80
81
|
n.setAlignContent(acMap(props.alignContent));
|
|
81
82
|
n.setJustifyContent(jcMap(props.justifyContent));
|
|
82
83
|
n.setAlignItems(aiMap(props.alignItems));
|
|
84
|
+
if (hadRuns || props.runs !== void 0) refreshMeasure(inst, _Yoga);
|
|
83
85
|
}
|
|
84
86
|
function wrapMap(v) {
|
|
85
87
|
switch (v) {
|
|
@@ -125,11 +127,13 @@ function measureText(text) {
|
|
|
125
127
|
};
|
|
126
128
|
}
|
|
127
129
|
function ownText(inst) {
|
|
130
|
+
if (inst.props.runs !== void 0) return inst.props.runs.map((r) => r.text).join("");
|
|
128
131
|
return inst.children.filter((c) => c.type === "text").map((c) => c.text).join("");
|
|
129
132
|
}
|
|
130
133
|
function refreshMeasure(inst, _Yoga) {
|
|
131
|
-
const hasText = inst.children.some((c) => c.type === "text");
|
|
134
|
+
const hasText = inst.props.runs !== void 0 || inst.children.some((c) => c.type === "text");
|
|
132
135
|
const hasBox = inst.children.some((c) => c.type === "box");
|
|
136
|
+
if (hasText && hasBox) noteWarning("flowtty: a box has both text and child boxes (e.g. <Text>a <Text bold>b</Text></Text>). <Text> is a box, not an inline span, so they do not flow as one line. Use <Span> for styled pieces inside a <Text>, or put separate <Text>s in a <Box flexDirection=\"row\">.");
|
|
133
137
|
if (hasText && !hasBox) {
|
|
134
138
|
const text = ownText(inst);
|
|
135
139
|
const mode = inst.props.wrap ?? "none";
|
|
@@ -186,6 +190,15 @@ function insertBefore(parent, child, before, Yoga) {
|
|
|
186
190
|
function computeLayout(container, width, height) {
|
|
187
191
|
for (const root of container.children) root.yogaNode.calculateLayout(width, height);
|
|
188
192
|
}
|
|
193
|
+
function contentHeight(container) {
|
|
194
|
+
let bottom = 0;
|
|
195
|
+
for (const root of container.children) {
|
|
196
|
+
const { top, height } = layoutOf(root);
|
|
197
|
+
const edge = top + height;
|
|
198
|
+
if (Number.isFinite(edge) && edge > bottom) bottom = edge;
|
|
199
|
+
}
|
|
200
|
+
return Math.ceil(bottom);
|
|
201
|
+
}
|
|
189
202
|
function layoutOf(inst, offsetX = 0, offsetY = 0) {
|
|
190
203
|
const n = inst.yogaNode;
|
|
191
204
|
return {
|
|
@@ -215,6 +228,22 @@ function textStyleOf(inst) {
|
|
|
215
228
|
if (p.backgroundColor !== void 0) style.bg = p.backgroundColor;
|
|
216
229
|
return style;
|
|
217
230
|
}
|
|
231
|
+
function runStyles(runs, base) {
|
|
232
|
+
const out = [];
|
|
233
|
+
for (const run of runs) {
|
|
234
|
+
const style = { ...base };
|
|
235
|
+
if (run.color !== void 0) style.fg = run.color;
|
|
236
|
+
if (run.backgroundColor !== void 0) style.bg = run.backgroundColor;
|
|
237
|
+
if (run.bold !== void 0) style.bold = run.bold;
|
|
238
|
+
if (run.dim !== void 0) style.dim = run.dim;
|
|
239
|
+
if (run.underline !== void 0) style.underline = run.underline;
|
|
240
|
+
if (run.inverse !== void 0) style.inverse = run.inverse;
|
|
241
|
+
if (run.strikethrough !== void 0) style.strikethrough = run.strikethrough;
|
|
242
|
+
if (run.link !== void 0) style.link = run.link;
|
|
243
|
+
for (const _ch of run.text) out.push(style);
|
|
244
|
+
}
|
|
245
|
+
return out;
|
|
246
|
+
}
|
|
218
247
|
function setClipped(buffer, x, y, char, style, clip) {
|
|
219
248
|
if (clip !== null) {
|
|
220
249
|
if (x < clip.left || y < clip.top || x >= clip.left + clip.width || y >= clip.top + clip.height) return;
|
|
@@ -333,14 +362,25 @@ function paintInstance(inst, buffer, offsetX, offsetY, inheritedBg = void 0, cli
|
|
|
333
362
|
const lines = mode === "none" ? text.split("\n") : wrapText(text, content.width, mode);
|
|
334
363
|
const textStyle = textStyleOf(inst);
|
|
335
364
|
if (textStyle.bg === void 0 && effectiveBg !== void 0) textStyle.bg = effectiveBg;
|
|
365
|
+
const styles = inst.props.runs !== void 0 ? runStyles(inst.props.runs, textStyle) : null;
|
|
366
|
+
const source = styles ? [...text] : null;
|
|
367
|
+
let at = 0;
|
|
336
368
|
for (let row = 0; row < lines.length; row++) {
|
|
337
|
-
if (row >= content.height) break;
|
|
338
369
|
const chars = [...lines[row] ?? ""];
|
|
339
370
|
for (let col = 0; col < chars.length; col++) {
|
|
340
|
-
if (col >= content.width) break;
|
|
341
371
|
const ch = chars[col];
|
|
372
|
+
let style = textStyle;
|
|
373
|
+
if (styles && source) {
|
|
374
|
+
let found = at;
|
|
375
|
+
while (found < source.length && source[found] !== ch) found++;
|
|
376
|
+
if (found < source.length) {
|
|
377
|
+
style = styles[found];
|
|
378
|
+
at = found + 1;
|
|
379
|
+
} else style = styles[Math.min(at, styles.length - 1)] ?? textStyle;
|
|
380
|
+
}
|
|
381
|
+
if (row >= content.height || col >= content.width) continue;
|
|
342
382
|
const safe = ch.charCodeAt(0) < 32 ? " " : ch;
|
|
343
|
-
setClipped(buffer, content.left + col, content.top + row, safe,
|
|
383
|
+
setClipped(buffer, content.left + col, content.top + row, safe, style, clip);
|
|
344
384
|
}
|
|
345
385
|
}
|
|
346
386
|
}
|
|
@@ -380,4 +420,4 @@ function paintInstance(inst, buffer, offsetX, offsetY, inheritedBg = void 0, cli
|
|
|
380
420
|
for (const child of absolutes) paintInstance(child, buffer, box.left, box.top, effectiveBg, overlayClip);
|
|
381
421
|
}
|
|
382
422
|
//#endregion
|
|
383
|
-
export { BORDER_CHARS, appendChild, applyProps, computeLayout, createInstance, createTextInstance, getYoga, insertBefore, layoutOf, measureText, ownText, paint, refreshMeasure, removeChild };
|
|
423
|
+
export { BORDER_CHARS, appendChild, applyProps, computeLayout, contentHeight, createInstance, createTextInstance, getYoga, insertBefore, layoutOf, measureText, ownText, paint, refreshMeasure, removeChild };
|
|
@@ -35,7 +35,8 @@ interface Rect {
|
|
|
35
35
|
width: number;
|
|
36
36
|
height: number;
|
|
37
37
|
}
|
|
38
|
-
declare function computeLayout(container: Container, width: number, height: number): void;
|
|
38
|
+
declare function computeLayout(container: Container, width: number, height: number | undefined): void;
|
|
39
|
+
declare function contentHeight(container: Container): number;
|
|
39
40
|
declare function layoutOf(inst: Instance, offsetX?: number, offsetY?: number): Rect;
|
|
40
41
|
//#endregion
|
|
41
42
|
//#region src/host/host.d.ts
|
|
@@ -55,6 +56,11 @@ interface BoxProps {
|
|
|
55
56
|
justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
|
|
56
57
|
/** Cross-axis alignment of children. */
|
|
57
58
|
alignItems?: "flex-start" | "flex-end" | "center" | "stretch";
|
|
59
|
+
/** The box's text as styled pieces of ONE line of text: they are joined,
|
|
60
|
+
* measured and wrapped together as a single paragraph, and each piece paints
|
|
61
|
+
* with its own style on top of the box's text style. `<Text>` builds this from
|
|
62
|
+
* `<Span>` children. When set, it replaces the box's direct text children. */
|
|
63
|
+
runs?: TextRun[];
|
|
58
64
|
wrap?: "wrap" | "truncate" | "none";
|
|
59
65
|
color?: Color;
|
|
60
66
|
bold?: boolean;
|
|
@@ -147,6 +153,18 @@ interface ScrollMetrics {
|
|
|
147
153
|
scrollTop: number;
|
|
148
154
|
maxScrollTop: number;
|
|
149
155
|
}
|
|
156
|
+
/** One styled piece of a box's text — see `BoxProps.runs`. */
|
|
157
|
+
interface TextRun {
|
|
158
|
+
text: string;
|
|
159
|
+
color?: Color;
|
|
160
|
+
backgroundColor?: Color;
|
|
161
|
+
bold?: boolean;
|
|
162
|
+
dim?: boolean;
|
|
163
|
+
underline?: boolean;
|
|
164
|
+
inverse?: boolean;
|
|
165
|
+
strikethrough?: boolean;
|
|
166
|
+
link?: string;
|
|
167
|
+
}
|
|
150
168
|
interface Instance {
|
|
151
169
|
type: "box";
|
|
152
170
|
props: BoxProps;
|
|
@@ -181,4 +199,4 @@ declare function appendChild(parent: Instance, child: Instance | TextInstance, Y
|
|
|
181
199
|
declare function removeChild(parent: Instance, child: Instance | TextInstance, Yoga: Yoga): void;
|
|
182
200
|
declare function insertBefore(parent: Instance, child: Instance | TextInstance, before: Instance | TextInstance, Yoga: Yoga): void;
|
|
183
201
|
//#endregion
|
|
184
|
-
export {
|
|
202
|
+
export { BorderStyle as C, Yoga as D, GridChars as E, YogaNode as O, BorderChars as S, GRID_CHARS as T, Rect as _, ScrollMetrics as a, layoutOf as b, appendChild as c, createTextInstance as d, insertBefore as f, removeChild as g, refreshMeasure as h, Instance as i, getYoga as k, applyProps as l, ownText as m, Container as n, TextInstance as o, measureText as p, HostType as r, TextRun as s, BoxProps as t, createInstance as u, computeLayout as v, DEFAULT_BORDER_STYLE as w, BORDER_CHARS as x, contentHeight as y };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as BorderStyle, E as GridChars, S as BorderChars, T as GRID_CHARS, a as ScrollMetrics, s as TextRun, t as BoxProps, w as DEFAULT_BORDER_STYLE } from "./host-DnKJiaQh.js";
|
|
2
2
|
import { a as NAMED_COLORS, i as Color, n as Cell, o as NamedColor, r as Style, t as Buffer } from "./cells-C-GthybI.js";
|
|
3
|
-
import { a as NamedKey, i as NAMED_KEYS, n as Key, r as KeyName, t as Backend } from "./backend-
|
|
3
|
+
import { a as NamedKey, i as NAMED_KEYS, n as Key, r as KeyName, t as Backend } from "./backend-DPFtzaxG.js";
|
|
4
|
+
//#region src/warnings.d.ts
|
|
5
|
+
/** Warnings noted since the last call; clears the list. */
|
|
6
|
+
export declare function takeWarnings(): string[];
|
|
7
|
+
//#endregion
|
|
4
8
|
//#region src/wrap.d.ts
|
|
5
9
|
type WrapMode = "wrap" | "truncate" | "none";
|
|
6
10
|
/**
|
|
@@ -190,4 +194,4 @@ interface MultiSelectOptions {
|
|
|
190
194
|
}
|
|
191
195
|
declare function reduce$1<T>(items: SelectItem<T>[], state: MultiSelectState, key: Key, opts?: MultiSelectOptions): MultiSelectAction;
|
|
192
196
|
//#endregion
|
|
193
|
-
export { type Backend, type BorderChars, type BorderStyle, type BoxProps, Buffer, type Cell, type Color, DEFAULT_BORDER_STYLE, type EditorAction, type EditorOptions, type EditorState, GRID_CHARS, type GridChars, type InputRow, type Key, type KeyName, type MultiSelectAction, type MultiSelectOptions, type MultiSelectState, NAMED_COLORS, NAMED_KEYS, type NamedColor, type NamedKey, type ScrollMetrics, type SelectAction, type SelectItem, type SelectState, type Style, type VisualLine, type WrapMode, reduce as editorReducer, reduce$1 as multiSelectReducer, reduce$2 as selectReducer };
|
|
197
|
+
export { type Backend, type BorderChars, type BorderStyle, type BoxProps, Buffer, type Cell, type Color, DEFAULT_BORDER_STYLE, type EditorAction, type EditorOptions, type EditorState, GRID_CHARS, type GridChars, type InputRow, type Key, type KeyName, type MultiSelectAction, type MultiSelectOptions, type MultiSelectState, NAMED_COLORS, NAMED_KEYS, type NamedColor, type NamedKey, type ScrollMetrics, type SelectAction, type SelectItem, type SelectState, type Style, type TextRun, type VisualLine, type WrapMode, reduce as editorReducer, reduce$1 as multiSelectReducer, reduce$2 as selectReducer };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as GRID_CHARS, o as takeWarnings, r as DEFAULT_BORDER_STYLE, s as Buffer, t as wrapText } from "./wrap-DvO7jrLD.js";
|
|
2
2
|
import { t as NAMED_KEYS } from "./keys-Ck-RALk_.js";
|
|
3
3
|
//#region src/visualLines.ts
|
|
4
4
|
function splitVisualLines(text, mode, width) {
|
|
@@ -653,7 +653,7 @@ function reduce$2(items, state, key) {
|
|
|
653
653
|
index: visible[Math.min(state.cursor, n - 1)]
|
|
654
654
|
};
|
|
655
655
|
}
|
|
656
|
-
if (key.name === "down"
|
|
656
|
+
if (key.name === "down") {
|
|
657
657
|
if (n === 0) return { kind: "noop" };
|
|
658
658
|
return {
|
|
659
659
|
kind: "state",
|
|
@@ -663,7 +663,7 @@ function reduce$2(items, state, key) {
|
|
|
663
663
|
}
|
|
664
664
|
};
|
|
665
665
|
}
|
|
666
|
-
if (key.name === "up"
|
|
666
|
+
if (key.name === "up") {
|
|
667
667
|
if (n === 0) return { kind: "noop" };
|
|
668
668
|
return {
|
|
669
669
|
kind: "state",
|
|
@@ -718,4 +718,4 @@ function reduce$1(items, state, key, opts = {}) {
|
|
|
718
718
|
return { kind: "noop" };
|
|
719
719
|
}
|
|
720
720
|
//#endregion
|
|
721
|
-
export { Buffer, DEFAULT_BORDER_STYLE, GRID_CHARS, NAMED_COLORS, NAMED_KEYS, caretPosition, charWidth, reduce as editorReducer, inputRows, reduce$1 as multiSelectReducer, rowIndexAt, reduce$2 as selectReducer, splitVisualLines, stringWidth, visibleIndices, windowAround, wrapText };
|
|
721
|
+
export { Buffer, DEFAULT_BORDER_STYLE, GRID_CHARS, NAMED_COLORS, NAMED_KEYS, caretPosition, charWidth, reduce as editorReducer, inputRows, reduce$1 as multiSelectReducer, rowIndexAt, reduce$2 as selectReducer, splitVisualLines, stringWidth, takeWarnings, visibleIndices, windowAround, wrapText };
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as Buffer } from "../cells-C-GthybI.js";
|
|
2
|
-
import { n as Key, t as Backend } from "../backend-
|
|
2
|
+
import { n as Key, t as Backend } from "../backend-DPFtzaxG.js";
|
|
3
3
|
//#region src/testing/test-backend.d.ts
|
|
4
4
|
export declare class TestBackend implements Backend {
|
|
5
5
|
private readonly cols;
|
|
@@ -35,6 +35,18 @@ var Buffer = class {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
//#endregion
|
|
38
|
+
//#region src/warnings.ts
|
|
39
|
+
const pending = /* @__PURE__ */ new Set();
|
|
40
|
+
function noteWarning(message) {
|
|
41
|
+
pending.add(message);
|
|
42
|
+
}
|
|
43
|
+
/** Warnings noted since the last call; clears the list. */
|
|
44
|
+
function takeWarnings() {
|
|
45
|
+
const out = [...pending];
|
|
46
|
+
pending.clear();
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
38
50
|
//#region src/host/borders.ts
|
|
39
51
|
/** The library-wide default for components that draw a box-border chrome
|
|
40
52
|
* (DialogHost wrappers, Menu panels, Table grids). Declared once so the
|
|
@@ -177,4 +189,4 @@ function wrapLine(line, width, out) {
|
|
|
177
189
|
if (current) out.push(current);
|
|
178
190
|
}
|
|
179
191
|
//#endregion
|
|
180
|
-
export {
|
|
192
|
+
export { noteWarning as a, GRID_CHARS as i, BORDER_CHARS as n, takeWarnings as o, DEFAULT_BORDER_STYLE as r, Buffer as s, wrapText as t };
|