@outfitter/tui 0.2.0
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/README.md +250 -0
- package/dist/borders/index.d.ts +3 -0
- package/dist/borders/index.js +13 -0
- package/dist/box/index.d.ts +4 -0
- package/dist/box/index.js +10 -0
- package/dist/confirm.d.ts +37 -0
- package/dist/confirm.js +36 -0
- package/dist/demo/index.d.ts +77 -0
- package/dist/demo/index.js +142 -0
- package/dist/demo/registry.d.ts +6 -0
- package/dist/demo/registry.js +28 -0
- package/dist/demo/renderers/borders.d.ts +7 -0
- package/dist/demo/renderers/borders.js +14 -0
- package/dist/demo/renderers/box.d.ts +7 -0
- package/dist/demo/renderers/box.js +15 -0
- package/dist/demo/renderers/colors.d.ts +7 -0
- package/dist/demo/renderers/colors.js +15 -0
- package/dist/demo/renderers/indicators.d.ts +7 -0
- package/dist/demo/renderers/indicators.js +14 -0
- package/dist/demo/renderers/list.d.ts +7 -0
- package/dist/demo/renderers/list.js +16 -0
- package/dist/demo/renderers/markdown.d.ts +7 -0
- package/dist/demo/renderers/markdown.js +15 -0
- package/dist/demo/renderers/progress.d.ts +7 -0
- package/dist/demo/renderers/progress.js +14 -0
- package/dist/demo/renderers/spinner.d.ts +7 -0
- package/dist/demo/renderers/spinner.js +16 -0
- package/dist/demo/renderers/table.d.ts +7 -0
- package/dist/demo/renderers/table.js +16 -0
- package/dist/demo/renderers/text.d.ts +7 -0
- package/dist/demo/renderers/text.js +13 -0
- package/dist/demo/renderers/tree.d.ts +7 -0
- package/dist/demo/renderers/tree.js +15 -0
- package/dist/demo/section.d.ts +4 -0
- package/dist/demo/section.js +20 -0
- package/dist/demo/templates.d.ts +3 -0
- package/dist/demo/templates.js +10 -0
- package/dist/demo/types.d.ts +2 -0
- package/dist/demo/types.js +8 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +77 -0
- package/dist/list/index.d.ts +3 -0
- package/dist/list/index.js +9 -0
- package/dist/preset/full.d.ts +12 -0
- package/dist/preset/full.js +37 -0
- package/dist/preset/standard.d.ts +9 -0
- package/dist/preset/standard.js +26 -0
- package/dist/prompt/confirm.d.ts +4 -0
- package/dist/prompt/confirm.js +9 -0
- package/dist/prompt/group.d.ts +4 -0
- package/dist/prompt/group.js +9 -0
- package/dist/prompt/index.d.ts +7 -0
- package/dist/prompt/index.js +32 -0
- package/dist/prompt/select.d.ts +4 -0
- package/dist/prompt/select.js +11 -0
- package/dist/prompt/text.d.ts +4 -0
- package/dist/prompt/text.js +11 -0
- package/dist/prompt/types.d.ts +3 -0
- package/dist/prompt/types.js +8 -0
- package/dist/prompt/validators.d.ts +2 -0
- package/dist/prompt/validators.js +8 -0
- package/dist/render/borders.d.ts +2 -0
- package/dist/render/borders.js +15 -0
- package/dist/render/box.d.ts +3 -0
- package/dist/render/box.js +20 -0
- package/dist/render/date.d.ts +2 -0
- package/dist/render/date.js +12 -0
- package/dist/render/format-relative.d.ts +2 -0
- package/dist/render/format-relative.js +8 -0
- package/dist/render/format.d.ts +2 -0
- package/dist/render/format.js +10 -0
- package/dist/render/heading.d.ts +3 -0
- package/dist/render/heading.js +11 -0
- package/dist/render/index.d.ts +31 -0
- package/dist/render/index.js +222 -0
- package/dist/render/indicators.d.ts +2 -0
- package/dist/render/indicators.js +16 -0
- package/dist/render/json.d.ts +2 -0
- package/dist/render/json.js +10 -0
- package/dist/render/layout.d.ts +5 -0
- package/dist/render/layout.js +22 -0
- package/dist/render/list.d.ts +2 -0
- package/dist/render/list.js +8 -0
- package/dist/render/markdown.d.ts +2 -0
- package/dist/render/markdown.js +8 -0
- package/dist/render/progress.d.ts +2 -0
- package/dist/render/progress.js +8 -0
- package/dist/render/separator.d.ts +3 -0
- package/dist/render/separator.js +11 -0
- package/dist/render/shapes.d.ts +2 -0
- package/dist/render/shapes.js +32 -0
- package/dist/render/spinner.d.ts +2 -0
- package/dist/render/spinner.js +12 -0
- package/dist/render/stack.d.ts +3 -0
- package/dist/render/stack.js +35 -0
- package/dist/render/table.d.ts +3 -0
- package/dist/render/table.js +9 -0
- package/dist/render/tree.d.ts +2 -0
- package/dist/render/tree.js +10 -0
- package/dist/render/types.d.ts +2 -0
- package/dist/render/types.js +1 -0
- package/dist/shared/@outfitter/tui-011579t8.d.ts +24 -0
- package/dist/shared/@outfitter/tui-06dntkse.js +146 -0
- package/dist/shared/@outfitter/tui-0awf316b.js +71 -0
- package/dist/shared/@outfitter/tui-0b85rht7.js +1 -0
- package/dist/shared/@outfitter/tui-0mpqnyc1.js +55 -0
- package/dist/shared/@outfitter/tui-1qh888th.d.ts +106 -0
- package/dist/shared/@outfitter/tui-1tk0kxa6.js +94 -0
- package/dist/shared/@outfitter/tui-1wggw2zj.d.ts +56 -0
- package/dist/shared/@outfitter/tui-2pwhzg55.js +123 -0
- package/dist/shared/@outfitter/tui-2tkva96b.d.ts +20 -0
- package/dist/shared/@outfitter/tui-2wfat6jb.js +22 -0
- package/dist/shared/@outfitter/tui-34q2aenf.d.ts +24 -0
- package/dist/shared/@outfitter/tui-37hjcqhb.d.ts +3 -0
- package/dist/shared/@outfitter/tui-3dyxg62j.d.ts +97 -0
- package/dist/shared/@outfitter/tui-3kza6p9k.d.ts +132 -0
- package/dist/shared/@outfitter/tui-43bnfxv9.js +30 -0
- package/dist/shared/@outfitter/tui-4yz7jcyq.js +214 -0
- package/dist/shared/@outfitter/tui-52ndmswq.js +23 -0
- package/dist/shared/@outfitter/tui-53ms1ba4.d.ts +41 -0
- package/dist/shared/@outfitter/tui-5dsn6d6d.js +86 -0
- package/dist/shared/@outfitter/tui-5pb72vf9.js +51 -0
- package/dist/shared/@outfitter/tui-6605wa2j.js +127 -0
- package/dist/shared/@outfitter/tui-6ptks7jj.js +19 -0
- package/dist/shared/@outfitter/tui-6svngg69.js +126 -0
- package/dist/shared/@outfitter/tui-733asbd8.js +37 -0
- package/dist/shared/@outfitter/tui-75bztyfp.d.ts +50 -0
- package/dist/shared/@outfitter/tui-83zaah9b.d.ts +17 -0
- package/dist/shared/@outfitter/tui-8ejx8gq5.d.ts +71 -0
- package/dist/shared/@outfitter/tui-8j1gbehy.d.ts +164 -0
- package/dist/shared/@outfitter/tui-8mypsnva.d.ts +74 -0
- package/dist/shared/@outfitter/tui-997aapz0.js +61 -0
- package/dist/shared/@outfitter/tui-9dbykt4g.d.ts +42 -0
- package/dist/shared/@outfitter/tui-9h1kdd98.d.ts +119 -0
- package/dist/shared/@outfitter/tui-9rj9yesd.js +118 -0
- package/dist/shared/@outfitter/tui-a65efhsk.d.ts +23 -0
- package/dist/shared/@outfitter/tui-a8nkrbds.js +1 -0
- package/dist/shared/@outfitter/tui-ajp1153q.d.ts +59 -0
- package/dist/shared/@outfitter/tui-ay1fv41j.d.ts +30 -0
- package/dist/shared/@outfitter/tui-azh1w4ak.js +67 -0
- package/dist/shared/@outfitter/tui-b14ry1j1.d.ts +53 -0
- package/dist/shared/@outfitter/tui-c56sxcm8.d.ts +87 -0
- package/dist/shared/@outfitter/tui-c6ft5w6q.d.ts +91 -0
- package/dist/shared/@outfitter/tui-cq7za0cz.js +62 -0
- package/dist/shared/@outfitter/tui-dh15zwg0.js +95 -0
- package/dist/shared/@outfitter/tui-esc46z2v.js +20 -0
- package/dist/shared/@outfitter/tui-f1mj6h6p.d.ts +2 -0
- package/dist/shared/@outfitter/tui-gcpz529w.js +122 -0
- package/dist/shared/@outfitter/tui-gqsdhmk9.d.ts +42 -0
- package/dist/shared/@outfitter/tui-hescagw2.js +32 -0
- package/dist/shared/@outfitter/tui-j2kd7eej.js +126 -0
- package/dist/shared/@outfitter/tui-j3bkjt2g.js +7 -0
- package/dist/shared/@outfitter/tui-jnn9d8cd.js +8 -0
- package/dist/shared/@outfitter/tui-jz5nws55.d.ts +51 -0
- package/dist/shared/@outfitter/tui-k3mby2kk.js +70 -0
- package/dist/shared/@outfitter/tui-kc4nxak0.js +20 -0
- package/dist/shared/@outfitter/tui-kcxv8txp.js +7 -0
- package/dist/shared/@outfitter/tui-kydbggmj.js +39 -0
- package/dist/shared/@outfitter/tui-mch672g9.js +30 -0
- package/dist/shared/@outfitter/tui-n9kxkdrh.js +82 -0
- package/dist/shared/@outfitter/tui-na4dnjpw.js +348 -0
- package/dist/shared/@outfitter/tui-ncaatp4j.js +25 -0
- package/dist/shared/@outfitter/tui-nce7fgtf.js +48 -0
- package/dist/shared/@outfitter/tui-ngz2fbdw.js +144 -0
- package/dist/shared/@outfitter/tui-nprd7g0d.js +52 -0
- package/dist/shared/@outfitter/tui-nr580mbv.js +272 -0
- package/dist/shared/@outfitter/tui-nr93tf31.d.ts +64 -0
- package/dist/shared/@outfitter/tui-pdwbbzwr.js +179 -0
- package/dist/shared/@outfitter/tui-qb07rtct.js +19 -0
- package/dist/shared/@outfitter/tui-qkyazctw.d.ts +36 -0
- package/dist/shared/@outfitter/tui-qn1rgz9v.d.ts +93 -0
- package/dist/shared/@outfitter/tui-qs3fhwp8.js +43 -0
- package/dist/shared/@outfitter/tui-r8hywf9m.d.ts +48 -0
- package/dist/shared/@outfitter/tui-rbbcc034.js +20 -0
- package/dist/shared/@outfitter/tui-rgkerz72.js +85 -0
- package/dist/shared/@outfitter/tui-rh52sycm.d.ts +45 -0
- package/dist/shared/@outfitter/tui-rr924x4z.d.ts +59 -0
- package/dist/shared/@outfitter/tui-rwpdjrt3.js +20 -0
- package/dist/shared/@outfitter/tui-rx9xq9s7.d.ts +26 -0
- package/dist/shared/@outfitter/tui-sk05ye6g.js +1 -0
- package/dist/shared/@outfitter/tui-sv2xmh3w.d.ts +26 -0
- package/dist/shared/@outfitter/tui-t1a9xgbd.js +111 -0
- package/dist/shared/@outfitter/tui-t9vd88jr.js +273 -0
- package/dist/shared/@outfitter/tui-tq1z78x0.js +11 -0
- package/dist/shared/@outfitter/tui-ts1f957s.d.ts +128 -0
- package/dist/shared/@outfitter/tui-ve0083wa.d.ts +61 -0
- package/dist/shared/@outfitter/tui-vt0wg6c4.js +54 -0
- package/dist/shared/@outfitter/tui-wfnnq0zq.d.ts +328 -0
- package/dist/shared/@outfitter/tui-x3yg0887.d.ts +223 -0
- package/dist/shared/@outfitter/tui-x9vvtfkk.js +20 -0
- package/dist/shared/@outfitter/tui-xbvz707j.js +20 -0
- package/dist/shared/@outfitter/tui-xbx6d4t7.js +1 -0
- package/dist/shared/@outfitter/tui-xph95b7h.js +67 -0
- package/dist/shared/@outfitter/tui-xqjx7d1f.js +135 -0
- package/dist/shared/@outfitter/tui-xrgrp99k.d.ts +112 -0
- package/dist/shared/@outfitter/tui-xzjv96ps.d.ts +300 -0
- package/dist/shared/@outfitter/tui-ykzs6v4v.d.ts +66 -0
- package/dist/shared/@outfitter/tui-yw9n5h6q.d.ts +54 -0
- package/dist/shared/@outfitter/tui-ywmakc6b.js +30 -0
- package/dist/shared/@outfitter/tui-z6nf9b9h.js +7 -0
- package/dist/shared/@outfitter/tui-zcspg6z6.d.ts +190 -0
- package/dist/shared/@outfitter/tui-zhbsnj7w.js +1 -0
- package/dist/streaming/ansi.d.ts +2 -0
- package/dist/streaming/ansi.js +8 -0
- package/dist/streaming/index.d.ts +4 -0
- package/dist/streaming/index.js +17 -0
- package/dist/streaming/spinner.d.ts +3 -0
- package/dist/streaming/spinner.js +10 -0
- package/dist/streaming/writer.d.ts +2 -0
- package/dist/streaming/writer.js +9 -0
- package/dist/table/index.d.ts +4 -0
- package/dist/table/index.js +10 -0
- package/dist/theme/context.d.ts +9 -0
- package/dist/theme/context.js +12 -0
- package/dist/theme/create.d.ts +8 -0
- package/dist/theme/create.js +10 -0
- package/dist/theme/index.d.ts +17 -0
- package/dist/theme/index.js +40 -0
- package/dist/theme/presets/bold.d.ts +8 -0
- package/dist/theme/presets/bold.js +10 -0
- package/dist/theme/presets/default.d.ts +8 -0
- package/dist/theme/presets/default.js +9 -0
- package/dist/theme/presets/index.d.ts +12 -0
- package/dist/theme/presets/index.js +22 -0
- package/dist/theme/presets/minimal.d.ts +8 -0
- package/dist/theme/presets/minimal.js +10 -0
- package/dist/theme/presets/rounded.d.ts +8 -0
- package/dist/theme/presets/rounded.js +10 -0
- package/dist/theme/resolve.d.ts +8 -0
- package/dist/theme/resolve.js +11 -0
- package/dist/theme/types.d.ts +7 -0
- package/dist/theme/types.js +1 -0
- package/dist/tree/index.d.ts +3 -0
- package/dist/tree/index.js +11 -0
- package/package.json +263 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
init_box,
|
|
4
|
+
normalizeBorders,
|
|
5
|
+
normalizePadding
|
|
6
|
+
} from "./tui-t9vd88jr.js";
|
|
7
|
+
|
|
8
|
+
// packages/tui/src/render/layout.ts
|
|
9
|
+
init_box();
|
|
10
|
+
function getTerminalWidth() {
|
|
11
|
+
return process.stdout.columns ?? 80;
|
|
12
|
+
}
|
|
13
|
+
function getBoxOverhead(options) {
|
|
14
|
+
const pad = normalizePadding(options.padding, 1);
|
|
15
|
+
const borders = normalizeBorders(options.borders);
|
|
16
|
+
return {
|
|
17
|
+
horizontal: (borders.left ? 1 : 0) + (borders.right ? 1 : 0) + pad.left + pad.right,
|
|
18
|
+
vertical: (borders.top ? 1 : 0) + (borders.bottom ? 1 : 0) + pad.top + pad.bottom
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function getContentWidth(options) {
|
|
22
|
+
const { horizontal } = getBoxOverhead(options);
|
|
23
|
+
if (options.width) {
|
|
24
|
+
const content = options.width - horizontal;
|
|
25
|
+
return Math.max(0, content);
|
|
26
|
+
}
|
|
27
|
+
return Math.max(0, getTerminalWidth() - horizontal);
|
|
28
|
+
}
|
|
29
|
+
function resolveWidth(mode, ctx) {
|
|
30
|
+
if (typeof mode === "number") {
|
|
31
|
+
return mode;
|
|
32
|
+
}
|
|
33
|
+
if (mode === "text") {
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
if (mode === "full") {
|
|
37
|
+
return getTerminalWidth();
|
|
38
|
+
}
|
|
39
|
+
if (mode === "container") {
|
|
40
|
+
if (!ctx) {
|
|
41
|
+
throw new Error("container width mode requires LayoutContext");
|
|
42
|
+
}
|
|
43
|
+
return ctx.width;
|
|
44
|
+
}
|
|
45
|
+
const percent = Number.parseInt(mode.slice(0, -1), 10);
|
|
46
|
+
const baseWidth = ctx?.width ?? getTerminalWidth();
|
|
47
|
+
return Math.floor(baseWidth * (percent / 100));
|
|
48
|
+
}
|
|
49
|
+
function createLayoutContext(options, parent) {
|
|
50
|
+
const effectiveOptions = { ...options };
|
|
51
|
+
if (effectiveOptions.width === undefined && parent) {
|
|
52
|
+
effectiveOptions.width = parent.width;
|
|
53
|
+
}
|
|
54
|
+
const width = getContentWidth(effectiveOptions);
|
|
55
|
+
return {
|
|
56
|
+
width,
|
|
57
|
+
...parent && { parent }
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function getWidth(text) {
|
|
61
|
+
return Bun.stringWidth(text);
|
|
62
|
+
}
|
|
63
|
+
function splitLines(block) {
|
|
64
|
+
return block.split(`
|
|
65
|
+
`);
|
|
66
|
+
}
|
|
67
|
+
function padToWidth(text, width) {
|
|
68
|
+
const currentWidth = getWidth(text);
|
|
69
|
+
if (currentWidth >= width)
|
|
70
|
+
return text;
|
|
71
|
+
return text + " ".repeat(width - currentWidth);
|
|
72
|
+
}
|
|
73
|
+
function createFilledArray(length, value) {
|
|
74
|
+
const result = [];
|
|
75
|
+
for (let i = 0;i < length; i++) {
|
|
76
|
+
result.push(value);
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
function joinHorizontal(blocks, options) {
|
|
81
|
+
if (blocks.length === 0)
|
|
82
|
+
return "";
|
|
83
|
+
const first = blocks[0];
|
|
84
|
+
if (first === undefined)
|
|
85
|
+
return "";
|
|
86
|
+
if (blocks.length === 1)
|
|
87
|
+
return first;
|
|
88
|
+
const gap = options?.gap ?? 0;
|
|
89
|
+
const align = options?.align ?? "top";
|
|
90
|
+
const gapString = " ".repeat(gap);
|
|
91
|
+
const blockLines = blocks.map(splitLines);
|
|
92
|
+
const maxHeight = Math.max(...blockLines.map((lines) => lines.length));
|
|
93
|
+
const blockWidths = blockLines.map((lines) => Math.max(...lines.map(getWidth)));
|
|
94
|
+
const paddedBlocks = blockLines.map((lines, blockIndex) => {
|
|
95
|
+
const width = blockWidths[blockIndex] ?? 0;
|
|
96
|
+
const height = lines.length;
|
|
97
|
+
const padding = maxHeight - height;
|
|
98
|
+
let topPadding;
|
|
99
|
+
switch (align) {
|
|
100
|
+
case "top":
|
|
101
|
+
topPadding = 0;
|
|
102
|
+
break;
|
|
103
|
+
case "center":
|
|
104
|
+
topPadding = Math.floor(padding / 2);
|
|
105
|
+
break;
|
|
106
|
+
case "bottom":
|
|
107
|
+
topPadding = padding;
|
|
108
|
+
break;
|
|
109
|
+
default: {
|
|
110
|
+
const _exhaustive = align;
|
|
111
|
+
topPadding = _exhaustive;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const bottomPadding = padding - topPadding;
|
|
115
|
+
const emptyLine = " ".repeat(width);
|
|
116
|
+
const paddedLines = [
|
|
117
|
+
...createFilledArray(topPadding, emptyLine),
|
|
118
|
+
...lines.map((line) => padToWidth(line, width)),
|
|
119
|
+
...createFilledArray(bottomPadding, emptyLine)
|
|
120
|
+
];
|
|
121
|
+
return paddedLines;
|
|
122
|
+
});
|
|
123
|
+
const resultLines = [];
|
|
124
|
+
for (let i = 0;i < maxHeight; i++) {
|
|
125
|
+
const lineSegments = paddedBlocks.map((block) => block[i] ?? "");
|
|
126
|
+
resultLines.push(lineSegments.join(gapString));
|
|
127
|
+
}
|
|
128
|
+
return resultLines.join(`
|
|
129
|
+
`);
|
|
130
|
+
}
|
|
131
|
+
function joinVertical(blocks, options) {
|
|
132
|
+
if (blocks.length === 0)
|
|
133
|
+
return "";
|
|
134
|
+
const first = blocks[0];
|
|
135
|
+
if (first === undefined)
|
|
136
|
+
return "";
|
|
137
|
+
if (blocks.length === 1)
|
|
138
|
+
return first;
|
|
139
|
+
const gap = options?.gap ?? 0;
|
|
140
|
+
const gapLines = gap > 0 ? `
|
|
141
|
+
`.repeat(gap) : "";
|
|
142
|
+
return blocks.join(`
|
|
143
|
+
${gapLines}`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export { getTerminalWidth, getBoxOverhead, getContentWidth, resolveWidth, createLayoutContext, joinHorizontal, joinVertical };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/tui/src/render/format-relative.ts
|
|
3
|
+
function formatRelative(date) {
|
|
4
|
+
let timestamp;
|
|
5
|
+
if (date instanceof Date) {
|
|
6
|
+
timestamp = date.getTime();
|
|
7
|
+
} else if (typeof date === "number") {
|
|
8
|
+
timestamp = date;
|
|
9
|
+
} else {
|
|
10
|
+
const parsed = Date.parse(date);
|
|
11
|
+
if (Number.isNaN(parsed)) {
|
|
12
|
+
return "invalid date";
|
|
13
|
+
}
|
|
14
|
+
timestamp = parsed;
|
|
15
|
+
}
|
|
16
|
+
if (!Number.isFinite(timestamp)) {
|
|
17
|
+
return "invalid date";
|
|
18
|
+
}
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
const diffMs = now - timestamp;
|
|
21
|
+
const absDiffMs = Math.abs(diffMs);
|
|
22
|
+
const isFuture = diffMs < 0;
|
|
23
|
+
const SECOND = 1000;
|
|
24
|
+
const MINUTE = 60 * SECOND;
|
|
25
|
+
const HOUR = 60 * MINUTE;
|
|
26
|
+
const DAY = 24 * HOUR;
|
|
27
|
+
const MONTH = 30 * DAY;
|
|
28
|
+
const YEAR = 365 * DAY;
|
|
29
|
+
if (absDiffMs < 10 * SECOND) {
|
|
30
|
+
return "just now";
|
|
31
|
+
}
|
|
32
|
+
if (absDiffMs < MINUTE) {
|
|
33
|
+
const seconds = Math.floor(absDiffMs / SECOND);
|
|
34
|
+
return isFuture ? `in ${seconds} seconds` : `${seconds} seconds ago`;
|
|
35
|
+
}
|
|
36
|
+
if (absDiffMs < HOUR) {
|
|
37
|
+
const minutes = Math.floor(absDiffMs / MINUTE);
|
|
38
|
+
if (minutes === 1) {
|
|
39
|
+
return isFuture ? "in 1 minute" : "1 minute ago";
|
|
40
|
+
}
|
|
41
|
+
return isFuture ? `in ${minutes} minutes` : `${minutes} minutes ago`;
|
|
42
|
+
}
|
|
43
|
+
if (absDiffMs < DAY) {
|
|
44
|
+
const hours = Math.floor(absDiffMs / HOUR);
|
|
45
|
+
if (hours === 1) {
|
|
46
|
+
return isFuture ? "in 1 hour" : "1 hour ago";
|
|
47
|
+
}
|
|
48
|
+
return isFuture ? `in ${hours} hours` : `${hours} hours ago`;
|
|
49
|
+
}
|
|
50
|
+
if (absDiffMs < 2 * DAY) {
|
|
51
|
+
return isFuture ? "tomorrow" : "yesterday";
|
|
52
|
+
}
|
|
53
|
+
if (absDiffMs < MONTH) {
|
|
54
|
+
const days = Math.floor(absDiffMs / DAY);
|
|
55
|
+
return isFuture ? `in ${days} days` : `${days} days ago`;
|
|
56
|
+
}
|
|
57
|
+
if (absDiffMs < YEAR) {
|
|
58
|
+
const months = Math.floor(absDiffMs / MONTH);
|
|
59
|
+
if (months === 1) {
|
|
60
|
+
return isFuture ? "in 1 month" : "1 month ago";
|
|
61
|
+
}
|
|
62
|
+
return isFuture ? `in ${months} months` : `${months} months ago`;
|
|
63
|
+
}
|
|
64
|
+
const years = Math.floor(absDiffMs / YEAR);
|
|
65
|
+
if (years === 1) {
|
|
66
|
+
return isFuture ? "in 1 year" : "1 year ago";
|
|
67
|
+
}
|
|
68
|
+
return isFuture ? `in ${years} years` : `${years} years ago`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { formatRelative };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// @bun
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
BORDERS,
|
|
4
|
+
init_borders
|
|
5
|
+
} from "./tui-2pwhzg55.js";
|
|
6
|
+
|
|
7
|
+
// packages/tui/src/theme/presets/default.ts
|
|
8
|
+
init_borders();
|
|
9
|
+
import { ANSI } from "@outfitter/cli/colors";
|
|
10
|
+
var defaultTheme = {
|
|
11
|
+
name: "default",
|
|
12
|
+
border: "single",
|
|
13
|
+
borderChars: BORDERS.single,
|
|
14
|
+
treeGuide: "single",
|
|
15
|
+
delimiter: "bullet",
|
|
16
|
+
markers: {
|
|
17
|
+
default: { type: "indicator", category: "marker", name: "circleOutline" },
|
|
18
|
+
current: { type: "indicator", category: "marker", name: "circleDot" },
|
|
19
|
+
focused: { type: "indicator", category: "marker", name: "pointer" },
|
|
20
|
+
checked: { type: "indicator", category: "marker", name: "checkboxChecked" },
|
|
21
|
+
disabled: { type: "indicator", category: "marker", name: "dash" },
|
|
22
|
+
success: { type: "indicator", category: "status", name: "success" },
|
|
23
|
+
warning: { type: "indicator", category: "status", name: "warning" },
|
|
24
|
+
error: { type: "indicator", category: "status", name: "error" },
|
|
25
|
+
info: { type: "indicator", category: "status", name: "info" }
|
|
26
|
+
},
|
|
27
|
+
listBullet: { unicode: "\u2022", fallback: "-" },
|
|
28
|
+
checkbox: {
|
|
29
|
+
checked: { unicode: "\u2611", fallback: "[x]" },
|
|
30
|
+
unchecked: { unicode: "\u2610", fallback: "[ ]" }
|
|
31
|
+
},
|
|
32
|
+
colors: {
|
|
33
|
+
success: ANSI.green,
|
|
34
|
+
warning: ANSI.yellow,
|
|
35
|
+
error: ANSI.red,
|
|
36
|
+
info: ANSI.blue,
|
|
37
|
+
primary: "",
|
|
38
|
+
secondary: ANSI.gray,
|
|
39
|
+
muted: ANSI.dim,
|
|
40
|
+
accent: ANSI.cyan,
|
|
41
|
+
highlight: ANSI.bold,
|
|
42
|
+
link: `${ANSI.cyan}${ANSI.underline}`,
|
|
43
|
+
destructive: ANSI.brightRed,
|
|
44
|
+
subtle: `${ANSI.dim}${ANSI.gray}`
|
|
45
|
+
},
|
|
46
|
+
spacing: {
|
|
47
|
+
boxPadding: 1,
|
|
48
|
+
listIndent: 2,
|
|
49
|
+
stackGap: 0,
|
|
50
|
+
horizontalGap: 1
|
|
51
|
+
},
|
|
52
|
+
spinner: "dots"
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export { defaultTheme };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Box-drawing border utilities.
|
|
3
|
+
*
|
|
4
|
+
* Provides border character sets and line drawing functions for tables, boxes, and panels.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Available border style presets.
|
|
10
|
+
*
|
|
11
|
+
* - `single`: Standard Unicode single-line borders (┌─┐)
|
|
12
|
+
* - `double`: Double-line borders (╔═╗)
|
|
13
|
+
* - `rounded`: Rounded corners with single lines (╭─╮)
|
|
14
|
+
* - `heavy`: Thick/heavy borders (┏━┓)
|
|
15
|
+
* - `ascii`: ASCII-only fallback (+, -, |)
|
|
16
|
+
* - `none`: No borders (empty strings)
|
|
17
|
+
*/
|
|
18
|
+
type BorderStyle = "single" | "double" | "rounded" | "heavy" | "ascii" | "none";
|
|
19
|
+
/**
|
|
20
|
+
* Complete set of box-drawing characters for a border style.
|
|
21
|
+
*
|
|
22
|
+
* Includes corners, edges, and intersection characters for building
|
|
23
|
+
* tables, boxes, and other bordered elements.
|
|
24
|
+
*/
|
|
25
|
+
interface BorderCharacters {
|
|
26
|
+
/** Top-left corner (e.g., ┌ ╔ ╭ ┏) */
|
|
27
|
+
topLeft: string;
|
|
28
|
+
/** Top-right corner (e.g., ┐ ╗ ╮ ┓) */
|
|
29
|
+
topRight: string;
|
|
30
|
+
/** Bottom-left corner (e.g., └ ╚ ╰ ┗) */
|
|
31
|
+
bottomLeft: string;
|
|
32
|
+
/** Bottom-right corner (e.g., ┘ ╝ ╯ ┛) */
|
|
33
|
+
bottomRight: string;
|
|
34
|
+
/** Horizontal line (e.g., ─ ═ ━) */
|
|
35
|
+
horizontal: string;
|
|
36
|
+
/** Vertical line (e.g., │ ║ ┃) */
|
|
37
|
+
vertical: string;
|
|
38
|
+
/** Top T-intersection for column separators (e.g., ┬ ╦ ┳) */
|
|
39
|
+
topT: string;
|
|
40
|
+
/** Bottom T-intersection for column separators (e.g., ┴ ╩ ┻) */
|
|
41
|
+
bottomT: string;
|
|
42
|
+
/** Left T-intersection for row separators (e.g., ├ ╠ ┣) */
|
|
43
|
+
leftT: string;
|
|
44
|
+
/** Right T-intersection for row separators (e.g., ┤ ╣ ┫) */
|
|
45
|
+
rightT: string;
|
|
46
|
+
/** Cross intersection for table cells (e.g., ┼ ╬ ╋) */
|
|
47
|
+
cross: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Preset border character sets for each style.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import { BORDERS } from "@outfitter/cli";
|
|
55
|
+
*
|
|
56
|
+
* const single = BORDERS.single;
|
|
57
|
+
* console.log(`${single.topLeft}${single.horizontal.repeat(10)}${single.topRight}`);
|
|
58
|
+
* // Output: ┌──────────┐
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
declare const BORDERS: Record<BorderStyle, BorderCharacters>;
|
|
62
|
+
/**
|
|
63
|
+
* Returns the border character set for the given style.
|
|
64
|
+
*
|
|
65
|
+
* @param style - The border style preset
|
|
66
|
+
* @returns The complete set of border characters
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const chars = getBorderCharacters("rounded");
|
|
71
|
+
* console.log(chars.topLeft); // ╭
|
|
72
|
+
* console.log(chars.topRight); // ╮
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
declare function getBorderCharacters(style: BorderStyle): BorderCharacters;
|
|
76
|
+
/**
|
|
77
|
+
* Position of a horizontal line within a bordered element.
|
|
78
|
+
*/
|
|
79
|
+
type LinePosition = "top" | "middle" | "bottom";
|
|
80
|
+
/**
|
|
81
|
+
* Draws a horizontal line with the appropriate corner/intersection characters.
|
|
82
|
+
*
|
|
83
|
+
* Used for building table borders and box edges. Handles column intersections
|
|
84
|
+
* when column widths are provided.
|
|
85
|
+
*
|
|
86
|
+
* @param width - Total width of the line content (excluding corners)
|
|
87
|
+
* @param chars - Border character set to use
|
|
88
|
+
* @param position - Position of line: "top", "middle", or "bottom"
|
|
89
|
+
* @param columnWidths - Optional array of column widths for intersection placement
|
|
90
|
+
* @returns The formatted horizontal line string
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* const chars = getBorderCharacters("single");
|
|
95
|
+
*
|
|
96
|
+
* // Simple line (no columns)
|
|
97
|
+
* drawHorizontalLine(10, chars, "top");
|
|
98
|
+
* // Returns: ┌──────────┐
|
|
99
|
+
*
|
|
100
|
+
* // Line with column intersections
|
|
101
|
+
* drawHorizontalLine(14, chars, "middle", [5, 7]);
|
|
102
|
+
* // Returns: ├─────┼───────┤
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
declare function drawHorizontalLine(width: number, chars: BorderCharacters, position: LinePosition, columnWidths?: number[]): string;
|
|
106
|
+
export { BorderStyle, BorderCharacters, BORDERS, getBorderCharacters, LinePosition, drawHorizontalLine };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
getExample
|
|
4
|
+
} from "./tui-nprd7g0d.js";
|
|
5
|
+
import {
|
|
6
|
+
demoSection
|
|
7
|
+
} from "./tui-733asbd8.js";
|
|
8
|
+
import {
|
|
9
|
+
BORDER_STYLE_META,
|
|
10
|
+
getBorderStyles
|
|
11
|
+
} from "./tui-nr580mbv.js";
|
|
12
|
+
import {
|
|
13
|
+
renderTable
|
|
14
|
+
} from "./tui-t1a9xgbd.js";
|
|
15
|
+
|
|
16
|
+
// packages/tui/src/demo/renderers/table.ts
|
|
17
|
+
function renderTableDemo(config, theme) {
|
|
18
|
+
const showCode = config.showCode ?? true;
|
|
19
|
+
const showDescriptions = config.showDescriptions ?? true;
|
|
20
|
+
const lines = [];
|
|
21
|
+
lines.push(demoSection("Basic Table"));
|
|
22
|
+
lines.push("");
|
|
23
|
+
if (showCode) {
|
|
24
|
+
lines.push('import { renderTable } from "@outfitter/tui/render";');
|
|
25
|
+
lines.push("");
|
|
26
|
+
lines.push("renderTable([");
|
|
27
|
+
lines.push(' { id: 1, name: "Alice", status: "Active" },');
|
|
28
|
+
lines.push(' { id: 2, name: "Bob", status: "Pending" },');
|
|
29
|
+
lines.push("])");
|
|
30
|
+
lines.push("");
|
|
31
|
+
}
|
|
32
|
+
const basicData = getExample("tableData", config.examples);
|
|
33
|
+
lines.push(renderTable(basicData));
|
|
34
|
+
lines.push("");
|
|
35
|
+
lines.push(demoSection("Custom Headers"));
|
|
36
|
+
lines.push("");
|
|
37
|
+
if (showCode) {
|
|
38
|
+
lines.push("renderTable(data, {");
|
|
39
|
+
lines.push(' headers: { id: "Task ID", name: "Assignee" }');
|
|
40
|
+
lines.push("})");
|
|
41
|
+
lines.push("");
|
|
42
|
+
}
|
|
43
|
+
lines.push(renderTable(basicData, {
|
|
44
|
+
headers: { id: "Task ID", name: "Assignee" }
|
|
45
|
+
}));
|
|
46
|
+
lines.push("");
|
|
47
|
+
lines.push(demoSection("Border Styles"));
|
|
48
|
+
lines.push("");
|
|
49
|
+
const styles = getBorderStyles().filter((s) => s !== "none");
|
|
50
|
+
const smallData = [
|
|
51
|
+
{ id: 1, name: "Alice" },
|
|
52
|
+
{ id: 2, name: "Bob" }
|
|
53
|
+
];
|
|
54
|
+
for (const style of styles) {
|
|
55
|
+
const meta = BORDER_STYLE_META[style];
|
|
56
|
+
lines.push(`${meta.label.toUpperCase()} (border: "${style}")`);
|
|
57
|
+
if (showDescriptions) {
|
|
58
|
+
lines.push(theme.muted(meta.description));
|
|
59
|
+
}
|
|
60
|
+
lines.push("");
|
|
61
|
+
lines.push(renderTable(smallData, { border: style }));
|
|
62
|
+
lines.push("");
|
|
63
|
+
}
|
|
64
|
+
lines.push(demoSection("Compact Mode"));
|
|
65
|
+
lines.push("");
|
|
66
|
+
if (showCode) {
|
|
67
|
+
lines.push("renderTable(data, { compact: true })");
|
|
68
|
+
lines.push("");
|
|
69
|
+
}
|
|
70
|
+
lines.push(renderTable(smallData, { compact: true }));
|
|
71
|
+
lines.push("");
|
|
72
|
+
lines.push(theme.muted("Compact mode removes borders and uses space separators."));
|
|
73
|
+
lines.push("");
|
|
74
|
+
lines.push(demoSection("Wide Characters (CJK/Emoji)"));
|
|
75
|
+
lines.push("");
|
|
76
|
+
if (showCode) {
|
|
77
|
+
lines.push("renderTable([");
|
|
78
|
+
lines.push(' { id: 1, name: "\u5C71\u7530\u592A\u90CE", status: "\u5B8C\u4E86" },');
|
|
79
|
+
lines.push(' { id: 2, name: "Party \uD83C\uDF89", status: "\uD83D\uDE80" },');
|
|
80
|
+
lines.push("])");
|
|
81
|
+
lines.push("");
|
|
82
|
+
}
|
|
83
|
+
const wideData = [
|
|
84
|
+
{ id: 1, name: "\u5C71\u7530\u592A\u90CE", status: "\u5B8C\u4E86" },
|
|
85
|
+
{ id: 2, name: "Party \uD83C\uDF89", status: "\uD83D\uDE80" }
|
|
86
|
+
];
|
|
87
|
+
lines.push(renderTable(wideData));
|
|
88
|
+
lines.push("");
|
|
89
|
+
lines.push(theme.muted("Uses Bun.stringWidth() for correct column alignment."));
|
|
90
|
+
return lines.join(`
|
|
91
|
+
`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { renderTableDemo };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { PrimitiveId, PrimitiveMeta, ThemeMethodMeta, VariantMeta } from "./tui-xrgrp99k";
|
|
2
|
+
import { ListStyle } from "./tui-3kza6p9k";
|
|
3
|
+
import { SpinnerStyle } from "./tui-c6ft5w6q";
|
|
4
|
+
import { BorderStyle } from "./tui-1qh888th";
|
|
5
|
+
import { Theme } from "@outfitter/cli/colors";
|
|
6
|
+
/**
|
|
7
|
+
* Type-safe metadata for all theme methods.
|
|
8
|
+
*
|
|
9
|
+
* Uses `keyof Theme` to ensure every theme method has metadata.
|
|
10
|
+
* Adding a new method to Theme without updating this causes a compile error.
|
|
11
|
+
*/
|
|
12
|
+
declare const THEME_METHOD_META: Record<keyof Theme, ThemeMethodMeta>;
|
|
13
|
+
/**
|
|
14
|
+
* Gets theme methods grouped by category.
|
|
15
|
+
*/
|
|
16
|
+
declare function getThemeMethodsByCategory(): {
|
|
17
|
+
semantic: Array<keyof Theme>;
|
|
18
|
+
utility: Array<keyof Theme>;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Type-safe metadata for all border styles.
|
|
22
|
+
*/
|
|
23
|
+
declare const BORDER_STYLE_META: Record<BorderStyle, VariantMeta<BorderStyle>>;
|
|
24
|
+
/**
|
|
25
|
+
* Gets all border styles as an array.
|
|
26
|
+
*/
|
|
27
|
+
declare function getBorderStyles(): BorderStyle[];
|
|
28
|
+
/**
|
|
29
|
+
* Type-safe metadata for all spinner styles.
|
|
30
|
+
*/
|
|
31
|
+
declare const SPINNER_STYLE_META: Record<SpinnerStyle, VariantMeta<SpinnerStyle>>;
|
|
32
|
+
/**
|
|
33
|
+
* Gets all spinner styles as an array.
|
|
34
|
+
*/
|
|
35
|
+
declare function getSpinnerStyles(): SpinnerStyle[];
|
|
36
|
+
/**
|
|
37
|
+
* Type-safe metadata for all list styles.
|
|
38
|
+
*/
|
|
39
|
+
declare const LIST_STYLE_META: Record<ListStyle, VariantMeta<ListStyle>>;
|
|
40
|
+
/**
|
|
41
|
+
* Gets all list styles as an array.
|
|
42
|
+
*/
|
|
43
|
+
declare function getListStyles(): ListStyle[];
|
|
44
|
+
/**
|
|
45
|
+
* Type-safe metadata for all primitives.
|
|
46
|
+
*/
|
|
47
|
+
declare const PRIMITIVE_META: Record<PrimitiveId, PrimitiveMeta>;
|
|
48
|
+
/**
|
|
49
|
+
* Gets all primitive IDs as an array.
|
|
50
|
+
*/
|
|
51
|
+
declare function getPrimitiveIds(): PrimitiveId[];
|
|
52
|
+
/**
|
|
53
|
+
* Gets metadata for a specific primitive.
|
|
54
|
+
*/
|
|
55
|
+
declare function getPrimitiveMeta(id: PrimitiveId): PrimitiveMeta;
|
|
56
|
+
export { THEME_METHOD_META, getThemeMethodsByCategory, BORDER_STYLE_META, getBorderStyles, SPINNER_STYLE_META, getSpinnerStyles, LIST_STYLE_META, getListStyles, PRIMITIVE_META, getPrimitiveIds, getPrimitiveMeta };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
__esm
|
|
4
|
+
} from "./tui-hescagw2.js";
|
|
5
|
+
|
|
6
|
+
// packages/tui/src/render/borders.ts
|
|
7
|
+
function getBorderCharacters(style) {
|
|
8
|
+
return BORDERS[style];
|
|
9
|
+
}
|
|
10
|
+
function drawHorizontalLine(width, chars, position, columnWidths) {
|
|
11
|
+
if (!chars.horizontal) {
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
const positionChars = {
|
|
15
|
+
top: { left: chars.topLeft, right: chars.topRight, cross: chars.topT },
|
|
16
|
+
middle: { left: chars.leftT, right: chars.rightT, cross: chars.cross },
|
|
17
|
+
bottom: {
|
|
18
|
+
left: chars.bottomLeft,
|
|
19
|
+
right: chars.bottomRight,
|
|
20
|
+
cross: chars.bottomT
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const { left, right, cross: intersection } = positionChars[position];
|
|
24
|
+
if (!columnWidths || columnWidths.length <= 1) {
|
|
25
|
+
return `${left}${chars.horizontal.repeat(width)}${right}`;
|
|
26
|
+
}
|
|
27
|
+
const columnsWidth = columnWidths.reduce((sum, w) => sum + w, 0);
|
|
28
|
+
const intersectionsWidth = columnWidths.length - 1;
|
|
29
|
+
const actualWidth = columnsWidth + intersectionsWidth;
|
|
30
|
+
const adjustedWidths = [...columnWidths];
|
|
31
|
+
if (actualWidth !== width && adjustedWidths.length > 0) {
|
|
32
|
+
const lastIndex = adjustedWidths.length - 1;
|
|
33
|
+
const lastWidth = adjustedWidths[lastIndex] ?? 0;
|
|
34
|
+
adjustedWidths[lastIndex] = Math.max(0, lastWidth + (width - actualWidth));
|
|
35
|
+
}
|
|
36
|
+
const segments = adjustedWidths.map((colWidth) => chars.horizontal.repeat(colWidth));
|
|
37
|
+
return `${left}${segments.join(intersection)}${right}`;
|
|
38
|
+
}
|
|
39
|
+
var BORDERS;
|
|
40
|
+
var init_borders = __esm(() => {
|
|
41
|
+
BORDERS = {
|
|
42
|
+
single: {
|
|
43
|
+
topLeft: "\u250C",
|
|
44
|
+
topRight: "\u2510",
|
|
45
|
+
bottomLeft: "\u2514",
|
|
46
|
+
bottomRight: "\u2518",
|
|
47
|
+
horizontal: "\u2500",
|
|
48
|
+
vertical: "\u2502",
|
|
49
|
+
topT: "\u252C",
|
|
50
|
+
bottomT: "\u2534",
|
|
51
|
+
leftT: "\u251C",
|
|
52
|
+
rightT: "\u2524",
|
|
53
|
+
cross: "\u253C"
|
|
54
|
+
},
|
|
55
|
+
double: {
|
|
56
|
+
topLeft: "\u2554",
|
|
57
|
+
topRight: "\u2557",
|
|
58
|
+
bottomLeft: "\u255A",
|
|
59
|
+
bottomRight: "\u255D",
|
|
60
|
+
horizontal: "\u2550",
|
|
61
|
+
vertical: "\u2551",
|
|
62
|
+
topT: "\u2566",
|
|
63
|
+
bottomT: "\u2569",
|
|
64
|
+
leftT: "\u2560",
|
|
65
|
+
rightT: "\u2563",
|
|
66
|
+
cross: "\u256C"
|
|
67
|
+
},
|
|
68
|
+
rounded: {
|
|
69
|
+
topLeft: "\u256D",
|
|
70
|
+
topRight: "\u256E",
|
|
71
|
+
bottomLeft: "\u2570",
|
|
72
|
+
bottomRight: "\u256F",
|
|
73
|
+
horizontal: "\u2500",
|
|
74
|
+
vertical: "\u2502",
|
|
75
|
+
topT: "\u252C",
|
|
76
|
+
bottomT: "\u2534",
|
|
77
|
+
leftT: "\u251C",
|
|
78
|
+
rightT: "\u2524",
|
|
79
|
+
cross: "\u253C"
|
|
80
|
+
},
|
|
81
|
+
heavy: {
|
|
82
|
+
topLeft: "\u250F",
|
|
83
|
+
topRight: "\u2513",
|
|
84
|
+
bottomLeft: "\u2517",
|
|
85
|
+
bottomRight: "\u251B",
|
|
86
|
+
horizontal: "\u2501",
|
|
87
|
+
vertical: "\u2503",
|
|
88
|
+
topT: "\u2533",
|
|
89
|
+
bottomT: "\u253B",
|
|
90
|
+
leftT: "\u2523",
|
|
91
|
+
rightT: "\u252B",
|
|
92
|
+
cross: "\u254B"
|
|
93
|
+
},
|
|
94
|
+
ascii: {
|
|
95
|
+
topLeft: "+",
|
|
96
|
+
topRight: "+",
|
|
97
|
+
bottomLeft: "+",
|
|
98
|
+
bottomRight: "+",
|
|
99
|
+
horizontal: "-",
|
|
100
|
+
vertical: "|",
|
|
101
|
+
topT: "+",
|
|
102
|
+
bottomT: "+",
|
|
103
|
+
leftT: "+",
|
|
104
|
+
rightT: "+",
|
|
105
|
+
cross: "+"
|
|
106
|
+
},
|
|
107
|
+
none: {
|
|
108
|
+
topLeft: "",
|
|
109
|
+
topRight: "",
|
|
110
|
+
bottomLeft: "",
|
|
111
|
+
bottomRight: "",
|
|
112
|
+
horizontal: "",
|
|
113
|
+
vertical: "",
|
|
114
|
+
topT: "",
|
|
115
|
+
bottomT: "",
|
|
116
|
+
leftT: "",
|
|
117
|
+
rightT: "",
|
|
118
|
+
cross: ""
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
export { BORDERS, getBorderCharacters, drawHorizontalLine, init_borders };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { VisualTheme } from "./tui-8j1gbehy";
|
|
2
|
+
/**
|
|
3
|
+
* Default visual theme.
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Single-line box-drawing borders (┌─┐)
|
|
7
|
+
* - Standard status indicators
|
|
8
|
+
* - Bullet delimiters
|
|
9
|
+
* - Dots spinner
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { defaultTheme } from "@outfitter/tui/theme/presets";
|
|
14
|
+
*
|
|
15
|
+
* // Use default styling
|
|
16
|
+
* const box = renderBox("Hello", { border: defaultTheme.border });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
declare const defaultTheme: VisualTheme;
|
|
20
|
+
export { defaultTheme };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/tui/src/streaming/ansi.ts
|
|
3
|
+
var ANSI = {
|
|
4
|
+
cursorUp: (n) => `\x1B[${n}A`,
|
|
5
|
+
cursorDown: (n) => `\x1B[${n}B`,
|
|
6
|
+
cursorRight: (n) => `\x1B[${n}C`,
|
|
7
|
+
cursorLeft: (n) => `\x1B[${n}D`,
|
|
8
|
+
cursorToStart: "\x1B[G",
|
|
9
|
+
clearLine: "\x1B[2K",
|
|
10
|
+
clearToEnd: "\x1B[0J",
|
|
11
|
+
clearToStart: "\x1B[1J",
|
|
12
|
+
clearScreen: "\x1B[2J",
|
|
13
|
+
hideCursor: "\x1B[?25l",
|
|
14
|
+
showCursor: "\x1B[?25h",
|
|
15
|
+
saveCursor: "\x1B[s",
|
|
16
|
+
restoreCursor: "\x1B[u",
|
|
17
|
+
carriageReturn: "\r",
|
|
18
|
+
newLine: `
|
|
19
|
+
`
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { ANSI };
|