@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,24 @@
|
|
|
1
|
+
import { VisualTheme } from "./tui-8j1gbehy";
|
|
2
|
+
/**
|
|
3
|
+
* Rounded visual theme.
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Rounded box-drawing corners (╭─╮)
|
|
7
|
+
* - Rounded tree guide style
|
|
8
|
+
* - Softer visual aesthetic
|
|
9
|
+
*
|
|
10
|
+
* Inherits all other properties from {@link defaultTheme}.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { roundedTheme } from "@outfitter/tui/theme/presets";
|
|
15
|
+
*
|
|
16
|
+
* // Use rounded styling
|
|
17
|
+
* const box = renderBox("Hello", { border: roundedTheme.border });
|
|
18
|
+
* // ╭───────╮
|
|
19
|
+
* // │ Hello │
|
|
20
|
+
* // ╰───────╯
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare const roundedTheme: VisualTheme;
|
|
24
|
+
export { roundedTheme };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { ANSI, applyColor, ColorName, createTheme, createTokens, resolveTokenColorEnabled, Theme, TokenOptions, Tokens } from "@outfitter/cli/colors";
|
|
2
|
+
import { ANSI_REGEX, getStringWidth, padText, pluralize, slugify, stripAnsi, truncateText, wrapText } from "@outfitter/cli/text";
|
|
3
|
+
export { ANSI, applyColor, ColorName, createTheme, createTokens, resolveTokenColorEnabled, Theme, TokenOptions, Tokens, ANSI_REGEX, getStringWidth, padText, pluralize, slugify, stripAnsi, truncateText, wrapText };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree rendering utilities.
|
|
3
|
+
*
|
|
4
|
+
* Renders hierarchical data as ASCII trees with box-drawing characters.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Available tree guide styles.
|
|
10
|
+
*
|
|
11
|
+
* - `single`: Standard Unicode box-drawing (default)
|
|
12
|
+
* - `heavy`: Thick/bold box-drawing characters
|
|
13
|
+
* - `double`: Double-line box-drawing characters
|
|
14
|
+
* - `rounded`: Rounded corners (╰ instead of └)
|
|
15
|
+
*/
|
|
16
|
+
type TreeGuideStyle = "single" | "heavy" | "double" | "rounded";
|
|
17
|
+
/**
|
|
18
|
+
* Tree guide character sets for different visual styles.
|
|
19
|
+
*/
|
|
20
|
+
declare const TREE_GUIDES: Record<TreeGuideStyle, {
|
|
21
|
+
vertical: string;
|
|
22
|
+
fork: string;
|
|
23
|
+
end: string;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Options for customizing tree rendering.
|
|
27
|
+
*/
|
|
28
|
+
interface TreeOptions {
|
|
29
|
+
/**
|
|
30
|
+
* Guide style for tree branches.
|
|
31
|
+
* @default "single"
|
|
32
|
+
*/
|
|
33
|
+
guide?: TreeGuideStyle;
|
|
34
|
+
/**
|
|
35
|
+
* Maximum depth to render (1 = root children only).
|
|
36
|
+
* @default undefined (unlimited)
|
|
37
|
+
*/
|
|
38
|
+
maxDepth?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Custom function to render node labels.
|
|
41
|
+
* Receives the key, value, and current depth.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* renderLabel: (key, value, depth) => {
|
|
46
|
+
* if (value && typeof value === "object") {
|
|
47
|
+
* return `📁 ${key}/`;
|
|
48
|
+
* }
|
|
49
|
+
* return `📄 ${key}`;
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
renderLabel?: (key: string, value: unknown, depth: number) => string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Renders hierarchical data as a tree with unicode box-drawing characters.
|
|
57
|
+
*
|
|
58
|
+
* Uses unicode characters for tree structure.
|
|
59
|
+
* Nested objects are rendered as child nodes; leaf values (null, primitives)
|
|
60
|
+
* are rendered as terminal nodes.
|
|
61
|
+
*
|
|
62
|
+
* @param tree - Hierarchical object to render
|
|
63
|
+
* @param options - Customization options
|
|
64
|
+
* @returns Formatted tree string with box-drawing characters
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const tree = {
|
|
69
|
+
* src: {
|
|
70
|
+
* components: {
|
|
71
|
+
* Button: null,
|
|
72
|
+
* Input: null,
|
|
73
|
+
* },
|
|
74
|
+
* utils: null,
|
|
75
|
+
* },
|
|
76
|
+
* tests: null,
|
|
77
|
+
* };
|
|
78
|
+
*
|
|
79
|
+
* console.log(renderTree(tree));
|
|
80
|
+
* // ├── src
|
|
81
|
+
* // │ ├── components
|
|
82
|
+
* // │ │ ├── Button
|
|
83
|
+
* // │ │ └── Input
|
|
84
|
+
* // │ └── utils
|
|
85
|
+
* // └── tests
|
|
86
|
+
*
|
|
87
|
+
* console.log(renderTree(tree, { guide: "rounded" }));
|
|
88
|
+
* // ├── src
|
|
89
|
+
* // │ ├── components
|
|
90
|
+
* // │ │ ├── Button
|
|
91
|
+
* // │ │ ╰── Input
|
|
92
|
+
* // │ ╰── utils
|
|
93
|
+
* // ╰── tests
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
declare function renderTree(tree: Record<string, unknown>, options?: TreeOptions): string;
|
|
97
|
+
export { TreeGuideStyle, TREE_GUIDES, TreeOptions, renderTree };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List rendering utilities.
|
|
3
|
+
*
|
|
4
|
+
* Renders arrays as bullet lists with optional nesting and multiple styles.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Available list styles for {@link renderList}.
|
|
10
|
+
*
|
|
11
|
+
* - `dash`: Uses - character (default)
|
|
12
|
+
* - `bullet`: Uses • character
|
|
13
|
+
* - `number`: Uses 1. for top-level, a. for nested, i. for deeply nested
|
|
14
|
+
* - `checkbox`: Uses ☐ for unchecked, ☑ for checked
|
|
15
|
+
*/
|
|
16
|
+
type ListStyle = "dash" | "bullet" | "number" | "checkbox";
|
|
17
|
+
/**
|
|
18
|
+
* Options for customizing list rendering.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // Numbered list with custom indent
|
|
23
|
+
* renderList(items, { style: "number", indent: 4 });
|
|
24
|
+
*
|
|
25
|
+
* // Checkbox list with some items checked
|
|
26
|
+
* renderList(items, { style: "checkbox", checked: new Set([1, 3]) });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
interface ListOptions {
|
|
30
|
+
/**
|
|
31
|
+
* The list style to use.
|
|
32
|
+
* @default "dash"
|
|
33
|
+
*/
|
|
34
|
+
style?: ListStyle;
|
|
35
|
+
/**
|
|
36
|
+
* Indices of checked top-level items (0-indexed) for checkbox style.
|
|
37
|
+
* Only applies to top-level items. For nested items, use the
|
|
38
|
+
* `checked` property on {@link NestedListItem} instead.
|
|
39
|
+
*/
|
|
40
|
+
checked?: Set<number>;
|
|
41
|
+
/**
|
|
42
|
+
* Number of spaces per indentation level.
|
|
43
|
+
* @default 2
|
|
44
|
+
*/
|
|
45
|
+
indent?: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A list item with optional nested children for {@link renderList}.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const item: NestedListItem = {
|
|
53
|
+
* text: "Parent item",
|
|
54
|
+
* children: ["Child 1", "Child 2"],
|
|
55
|
+
* };
|
|
56
|
+
*
|
|
57
|
+
* // Checkbox item with checked state
|
|
58
|
+
* const checkboxItem: NestedListItem = {
|
|
59
|
+
* text: "Completed task",
|
|
60
|
+
* checked: true,
|
|
61
|
+
* };
|
|
62
|
+
*
|
|
63
|
+
* // Mixed styles: numbered parent with bullet children
|
|
64
|
+
* const mixedItem: NestedListItem = {
|
|
65
|
+
* text: "Section 1",
|
|
66
|
+
* childStyle: "bullet",
|
|
67
|
+
* children: ["Unordered item A", "Unordered item B"],
|
|
68
|
+
* };
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
interface NestedListItem {
|
|
72
|
+
/** The text content of this list item */
|
|
73
|
+
text: string;
|
|
74
|
+
/** Optional nested child items (strings or nested items) */
|
|
75
|
+
children?: Array<string | NestedListItem>;
|
|
76
|
+
/** Whether this item is checked (for checkbox style) */
|
|
77
|
+
checked?: boolean;
|
|
78
|
+
/** Override style for children (enables mixed numbered/bullet lists) */
|
|
79
|
+
childStyle?: ListStyle;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* A list item that can be either a simple string or a nested item with children.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const items: ListItem[] = [
|
|
87
|
+
* "Simple item",
|
|
88
|
+
* { text: "Parent", children: ["Child 1", "Child 2"] },
|
|
89
|
+
* ];
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
type ListItem = string | NestedListItem;
|
|
93
|
+
/**
|
|
94
|
+
* Renders items as a list with optional nesting and multiple styles.
|
|
95
|
+
*
|
|
96
|
+
* Supports both simple string items and nested items with children.
|
|
97
|
+
* The default style uses dash (-) characters.
|
|
98
|
+
*
|
|
99
|
+
* For numbered lists, child items are indented to align with the parent's
|
|
100
|
+
* content (after the marker), creating proper visual hierarchy.
|
|
101
|
+
*
|
|
102
|
+
* @param items - Array of list items (strings or nested items)
|
|
103
|
+
* @param options - Optional configuration for style, checked items, and indent
|
|
104
|
+
* @returns Formatted list string
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* // Simple dash list (default)
|
|
109
|
+
* console.log(renderList(["First", "Second", "Third"]));
|
|
110
|
+
* // - First
|
|
111
|
+
* // - Second
|
|
112
|
+
* // - Third
|
|
113
|
+
*
|
|
114
|
+
* // Numbered list with nesting
|
|
115
|
+
* console.log(renderList([
|
|
116
|
+
* { text: "First section", children: [
|
|
117
|
+
* { text: "Subsection A", children: ["Detail i", "Detail ii"] },
|
|
118
|
+
* ]},
|
|
119
|
+
* ], { style: "number" }));
|
|
120
|
+
* // 1. First section
|
|
121
|
+
* // a. Subsection A
|
|
122
|
+
* // i. Detail i
|
|
123
|
+
* // ii. Detail ii
|
|
124
|
+
*
|
|
125
|
+
* // Checkbox list
|
|
126
|
+
* console.log(renderList(["Todo 1", "Todo 2"], { style: "checkbox", checked: new Set([1]) }));
|
|
127
|
+
* // ☐ Todo 1
|
|
128
|
+
* // ☑ Todo 2
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
declare function renderList(items: ListItem[], options?: ListOptions): string;
|
|
132
|
+
export { ListStyle, ListOptions, NestedListItem, ListItem, renderList };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
init_box
|
|
4
|
+
} from "./tui-t9vd88jr.js";
|
|
5
|
+
import {
|
|
6
|
+
init_borders
|
|
7
|
+
} from "./tui-2pwhzg55.js";
|
|
8
|
+
|
|
9
|
+
// packages/tui/src/render/index.ts
|
|
10
|
+
init_borders();
|
|
11
|
+
init_box();
|
|
12
|
+
import {
|
|
13
|
+
ANSI,
|
|
14
|
+
applyColor,
|
|
15
|
+
createTheme,
|
|
16
|
+
createTokens,
|
|
17
|
+
resolveTokenColorEnabled
|
|
18
|
+
} from "@outfitter/cli/colors";
|
|
19
|
+
import {
|
|
20
|
+
ANSI_REGEX,
|
|
21
|
+
getStringWidth,
|
|
22
|
+
padText,
|
|
23
|
+
pluralize,
|
|
24
|
+
slugify,
|
|
25
|
+
stripAnsi,
|
|
26
|
+
truncateText,
|
|
27
|
+
wrapText
|
|
28
|
+
} from "@outfitter/cli/text";
|
|
29
|
+
|
|
30
|
+
export { ANSI, applyColor, createTheme, createTokens, resolveTokenColorEnabled, ANSI_REGEX, getStringWidth, padText, pluralize, slugify, stripAnsi, truncateText, wrapText };
|
|
@@ -0,0 +1,214 @@
|
|
|
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
|
+
createBox,
|
|
14
|
+
init_box,
|
|
15
|
+
renderBox
|
|
16
|
+
} from "./tui-t9vd88jr.js";
|
|
17
|
+
|
|
18
|
+
// packages/tui/src/demo/renderers/box.ts
|
|
19
|
+
init_box();
|
|
20
|
+
function renderBoxDemo(config, theme) {
|
|
21
|
+
const showCode = config.showCode ?? true;
|
|
22
|
+
const showDescriptions = config.showDescriptions ?? true;
|
|
23
|
+
const lines = [];
|
|
24
|
+
lines.push(demoSection("Basic Box"));
|
|
25
|
+
lines.push("");
|
|
26
|
+
if (showCode) {
|
|
27
|
+
lines.push('import { renderBox } from "@outfitter/tui/render";');
|
|
28
|
+
lines.push("");
|
|
29
|
+
}
|
|
30
|
+
const content = getExample("boxContent", config.examples);
|
|
31
|
+
if (showCode) {
|
|
32
|
+
lines.push(`renderBox("${content}")`);
|
|
33
|
+
lines.push("");
|
|
34
|
+
}
|
|
35
|
+
lines.push(renderBox(content));
|
|
36
|
+
lines.push("");
|
|
37
|
+
lines.push(demoSection("Box with Title"));
|
|
38
|
+
lines.push("");
|
|
39
|
+
const title = getExample("boxTitle", config.examples);
|
|
40
|
+
if (showCode) {
|
|
41
|
+
lines.push(`renderBox("${content}", { title: "${title}" })`);
|
|
42
|
+
lines.push("");
|
|
43
|
+
}
|
|
44
|
+
lines.push(renderBox(content, { title }));
|
|
45
|
+
lines.push("");
|
|
46
|
+
lines.push(demoSection("Border Styles"));
|
|
47
|
+
lines.push("");
|
|
48
|
+
const styles = getBorderStyles().filter((s) => s !== "none");
|
|
49
|
+
for (const style of styles) {
|
|
50
|
+
const meta = BORDER_STYLE_META[style];
|
|
51
|
+
lines.push(`${meta.label.toUpperCase()}`);
|
|
52
|
+
if (showDescriptions) {
|
|
53
|
+
lines.push(theme.muted(meta.description));
|
|
54
|
+
}
|
|
55
|
+
lines.push("");
|
|
56
|
+
lines.push(renderBox("Content", { border: style }));
|
|
57
|
+
lines.push("");
|
|
58
|
+
}
|
|
59
|
+
lines.push(demoSection("Alignment"));
|
|
60
|
+
lines.push("");
|
|
61
|
+
const alignments = [
|
|
62
|
+
"left",
|
|
63
|
+
"center",
|
|
64
|
+
"right"
|
|
65
|
+
];
|
|
66
|
+
for (const align of alignments) {
|
|
67
|
+
if (showCode) {
|
|
68
|
+
lines.push(`renderBox("${align}", { width: 30, align: "${align}" })`);
|
|
69
|
+
}
|
|
70
|
+
lines.push(renderBox(align, { width: 30, align }));
|
|
71
|
+
lines.push("");
|
|
72
|
+
}
|
|
73
|
+
lines.push(demoSection("Multi-Line Content"));
|
|
74
|
+
lines.push("");
|
|
75
|
+
const multiLine = ["Line one", "Line two", "Line three"];
|
|
76
|
+
if (showCode) {
|
|
77
|
+
lines.push('renderBox(["Line one", "Line two", "Line three"])');
|
|
78
|
+
lines.push("");
|
|
79
|
+
}
|
|
80
|
+
lines.push(renderBox(multiLine));
|
|
81
|
+
lines.push("");
|
|
82
|
+
lines.push(demoSection("Sections with Dividers"));
|
|
83
|
+
lines.push("");
|
|
84
|
+
if (showDescriptions) {
|
|
85
|
+
lines.push(theme.muted("Use sections to separate content with internal dividers."));
|
|
86
|
+
lines.push("");
|
|
87
|
+
}
|
|
88
|
+
if (showCode) {
|
|
89
|
+
lines.push('renderBox("", {');
|
|
90
|
+
lines.push(' sections: ["Header", ["Line 1", "Line 2"], "Footer"],');
|
|
91
|
+
lines.push(' border: "rounded",');
|
|
92
|
+
lines.push("})");
|
|
93
|
+
lines.push("");
|
|
94
|
+
}
|
|
95
|
+
lines.push(renderBox("", {
|
|
96
|
+
sections: ["Header", ["Line 1", "Line 2"], "Footer"],
|
|
97
|
+
border: "rounded"
|
|
98
|
+
}));
|
|
99
|
+
lines.push("");
|
|
100
|
+
if (showDescriptions) {
|
|
101
|
+
lines.push(theme.muted("Example: Status panel with sections"));
|
|
102
|
+
lines.push("");
|
|
103
|
+
}
|
|
104
|
+
if (showCode) {
|
|
105
|
+
lines.push('renderBox("", {');
|
|
106
|
+
lines.push(" sections: [");
|
|
107
|
+
lines.push(' "System Status",');
|
|
108
|
+
lines.push(' ["CPU: 45%", "Memory: 2.1 GB", "Disk: 120 GB free"],');
|
|
109
|
+
lines.push(' "Updated: 2 min ago"');
|
|
110
|
+
lines.push(" ],");
|
|
111
|
+
lines.push(' border: "single",');
|
|
112
|
+
lines.push(" width: 30,");
|
|
113
|
+
lines.push("})");
|
|
114
|
+
lines.push("");
|
|
115
|
+
}
|
|
116
|
+
lines.push(renderBox("", {
|
|
117
|
+
sections: [
|
|
118
|
+
"System Status",
|
|
119
|
+
["CPU: 45%", "Memory: 2.1 GB", "Disk: 120 GB free"],
|
|
120
|
+
"Updated: 2 min ago"
|
|
121
|
+
],
|
|
122
|
+
border: "single",
|
|
123
|
+
width: 30
|
|
124
|
+
}));
|
|
125
|
+
lines.push("");
|
|
126
|
+
lines.push(demoSection("Partial Borders"));
|
|
127
|
+
lines.push("");
|
|
128
|
+
if (showDescriptions) {
|
|
129
|
+
lines.push(theme.muted("Control which borders to render with the borders option."));
|
|
130
|
+
lines.push("");
|
|
131
|
+
}
|
|
132
|
+
if (showCode) {
|
|
133
|
+
lines.push('renderBox("Top and bottom only", {');
|
|
134
|
+
lines.push(" borders: { top: true, bottom: true, left: false, right: false }");
|
|
135
|
+
lines.push("})");
|
|
136
|
+
lines.push("");
|
|
137
|
+
}
|
|
138
|
+
lines.push(renderBox("Top and bottom only", {
|
|
139
|
+
borders: { top: true, bottom: true, left: false, right: false }
|
|
140
|
+
}));
|
|
141
|
+
lines.push("");
|
|
142
|
+
if (showCode) {
|
|
143
|
+
lines.push('renderBox("Left and right only", {');
|
|
144
|
+
lines.push(" borders: { top: false, bottom: false, left: true, right: true }");
|
|
145
|
+
lines.push("})");
|
|
146
|
+
lines.push("");
|
|
147
|
+
}
|
|
148
|
+
lines.push(renderBox("Left and right only", {
|
|
149
|
+
borders: { top: false, bottom: false, left: true, right: true }
|
|
150
|
+
}));
|
|
151
|
+
lines.push("");
|
|
152
|
+
lines.push(demoSection("Margin"));
|
|
153
|
+
lines.push("");
|
|
154
|
+
if (showDescriptions) {
|
|
155
|
+
lines.push(theme.muted("Add spacing outside the box with margin."));
|
|
156
|
+
lines.push("");
|
|
157
|
+
}
|
|
158
|
+
if (showCode) {
|
|
159
|
+
lines.push('renderBox("With margin", { margin: { left: 4 } })');
|
|
160
|
+
lines.push("");
|
|
161
|
+
}
|
|
162
|
+
lines.push(renderBox("With margin", { margin: { left: 4 } }));
|
|
163
|
+
lines.push("");
|
|
164
|
+
lines.push(demoSection("Individual Padding"));
|
|
165
|
+
lines.push("");
|
|
166
|
+
if (showDescriptions) {
|
|
167
|
+
lines.push(theme.muted("Control padding per side with an object."));
|
|
168
|
+
lines.push("");
|
|
169
|
+
}
|
|
170
|
+
if (showCode) {
|
|
171
|
+
lines.push('renderBox("Custom padding", {');
|
|
172
|
+
lines.push(" padding: { top: 1, bottom: 1, left: 3, right: 1 }");
|
|
173
|
+
lines.push("})");
|
|
174
|
+
lines.push("");
|
|
175
|
+
}
|
|
176
|
+
lines.push(renderBox("Custom padding", {
|
|
177
|
+
padding: { top: 1, bottom: 1, left: 3, right: 1 }
|
|
178
|
+
}));
|
|
179
|
+
lines.push("");
|
|
180
|
+
lines.push(demoSection("Nested Boxes"));
|
|
181
|
+
lines.push("");
|
|
182
|
+
if (showDescriptions) {
|
|
183
|
+
lines.push(theme.muted("Use createBox() to create composable boxes with metadata."));
|
|
184
|
+
lines.push("");
|
|
185
|
+
}
|
|
186
|
+
if (showCode) {
|
|
187
|
+
lines.push('const inner = createBox("Inner content", { border: "rounded" });');
|
|
188
|
+
lines.push('const outer = createBox(inner, { border: "double", title: "Container" });');
|
|
189
|
+
lines.push("console.log(outer.output);");
|
|
190
|
+
lines.push("");
|
|
191
|
+
}
|
|
192
|
+
const inner = createBox("Inner content", { border: "rounded" });
|
|
193
|
+
const outer = createBox(inner, { border: "double", title: "Container" });
|
|
194
|
+
lines.push(outer.output);
|
|
195
|
+
lines.push("");
|
|
196
|
+
if (showDescriptions) {
|
|
197
|
+
lines.push(theme.muted("Boxes can be nested to any depth."));
|
|
198
|
+
lines.push("");
|
|
199
|
+
}
|
|
200
|
+
if (showCode) {
|
|
201
|
+
lines.push('const level1 = createBox("Core", { border: "single" });');
|
|
202
|
+
lines.push('const level2 = createBox(level1, { border: "rounded", title: "Middle" });');
|
|
203
|
+
lines.push('const level3 = createBox(level2, { border: "double", title: "Outer" });');
|
|
204
|
+
lines.push("");
|
|
205
|
+
}
|
|
206
|
+
const level1 = createBox("Core", { border: "single" });
|
|
207
|
+
const level2 = createBox(level1, { border: "rounded", title: "Middle" });
|
|
208
|
+
const level3 = createBox(level2, { border: "double", title: "Outer" });
|
|
209
|
+
lines.push(level3.output);
|
|
210
|
+
return lines.join(`
|
|
211
|
+
`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export { renderBoxDemo };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
createCancelledError
|
|
4
|
+
} from "./tui-kcxv8txp.js";
|
|
5
|
+
|
|
6
|
+
// packages/tui/src/prompt/confirm.ts
|
|
7
|
+
import { confirm, isCancel } from "@clack/prompts";
|
|
8
|
+
import { Result } from "better-result";
|
|
9
|
+
async function promptConfirm(options) {
|
|
10
|
+
const confirmOptions = {
|
|
11
|
+
message: options.message
|
|
12
|
+
};
|
|
13
|
+
if (options.initialValue !== undefined) {
|
|
14
|
+
confirmOptions.initialValue = options.initialValue;
|
|
15
|
+
}
|
|
16
|
+
const result = await confirm(confirmOptions);
|
|
17
|
+
if (isCancel(result)) {
|
|
18
|
+
return Result.err(createCancelledError());
|
|
19
|
+
}
|
|
20
|
+
return Result.ok(result);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { promptConfirm };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { PasswordPromptOptions, PromptResult, TextPromptOptions } from "./tui-c56sxcm8";
|
|
2
|
+
/**
|
|
3
|
+
* Prompts for text input with Result wrapping.
|
|
4
|
+
*
|
|
5
|
+
* @param options - Text prompt options
|
|
6
|
+
* @returns Ok with value or Err with CancelledError
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { promptText } from "@outfitter/tui/prompt";
|
|
11
|
+
*
|
|
12
|
+
* const result = await promptText({
|
|
13
|
+
* message: "What is your name?",
|
|
14
|
+
* placeholder: "Enter your name",
|
|
15
|
+
* validate: (v) => v.length > 0 || "Name is required",
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* if (result.isOk()) {
|
|
19
|
+
* console.log(`Hello, ${result.value}!`);
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare function promptText(options: TextPromptOptions): PromptResult<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Prompts for password input with Result wrapping.
|
|
26
|
+
*
|
|
27
|
+
* @param options - Password prompt options
|
|
28
|
+
* @returns Ok with value or Err with CancelledError
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import { promptPassword } from "@outfitter/tui/prompt";
|
|
33
|
+
*
|
|
34
|
+
* const result = await promptPassword({
|
|
35
|
+
* message: "Enter your password:",
|
|
36
|
+
* validate: (v) => v.length >= 8 || "Password too short",
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare function promptPassword(options: PasswordPromptOptions): PromptResult<string>;
|
|
41
|
+
export { promptText, promptPassword };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/tui/src/render/list.ts
|
|
3
|
+
function toLetter(n) {
|
|
4
|
+
return String.fromCharCode(96 + n);
|
|
5
|
+
}
|
|
6
|
+
function toRoman(n) {
|
|
7
|
+
const numerals = [
|
|
8
|
+
[10, "x"],
|
|
9
|
+
[9, "ix"],
|
|
10
|
+
[5, "v"],
|
|
11
|
+
[4, "iv"],
|
|
12
|
+
[1, "i"]
|
|
13
|
+
];
|
|
14
|
+
let result = "";
|
|
15
|
+
let remaining = n;
|
|
16
|
+
for (const [value, symbol] of numerals) {
|
|
17
|
+
while (remaining >= value) {
|
|
18
|
+
result += symbol;
|
|
19
|
+
remaining -= value;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
function getMarker(style, depth, index, isChecked) {
|
|
25
|
+
switch (style) {
|
|
26
|
+
case "bullet":
|
|
27
|
+
return "\u2022";
|
|
28
|
+
case "dash":
|
|
29
|
+
return "-";
|
|
30
|
+
case "number":
|
|
31
|
+
if (depth === 0) {
|
|
32
|
+
return `${index + 1}.`;
|
|
33
|
+
}
|
|
34
|
+
if (depth === 1) {
|
|
35
|
+
return `${toLetter(index + 1)}.`;
|
|
36
|
+
}
|
|
37
|
+
return `${toRoman(index + 1)}.`;
|
|
38
|
+
case "checkbox":
|
|
39
|
+
return isChecked ? "\u2611" : "\u2610";
|
|
40
|
+
default: {
|
|
41
|
+
const _exhaustive = style;
|
|
42
|
+
return _exhaustive;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function renderList(items, options) {
|
|
47
|
+
const style = options?.style ?? "dash";
|
|
48
|
+
const checkedSet = options?.checked ?? new Set;
|
|
49
|
+
const baseIndent = options?.indent ?? 2;
|
|
50
|
+
const lines = [];
|
|
51
|
+
let _globalIndex = 0;
|
|
52
|
+
const renderItem = (item, currentIndent, depth, indexAtDepth, currentStyle) => {
|
|
53
|
+
const indentStr = " ".repeat(currentIndent);
|
|
54
|
+
const text = typeof item === "string" ? item : item.text;
|
|
55
|
+
let isChecked = false;
|
|
56
|
+
if (currentStyle === "checkbox") {
|
|
57
|
+
if (typeof item !== "string" && item.checked !== undefined) {
|
|
58
|
+
isChecked = item.checked;
|
|
59
|
+
} else if (depth === 0) {
|
|
60
|
+
isChecked = checkedSet.has(indexAtDepth);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const marker = getMarker(currentStyle, depth, indexAtDepth, isChecked);
|
|
64
|
+
lines.push(`${indentStr}${marker} ${text}`);
|
|
65
|
+
_globalIndex++;
|
|
66
|
+
if (typeof item !== "string" && item.children) {
|
|
67
|
+
const childStyle = typeof item !== "string" && item.childStyle ? item.childStyle : currentStyle;
|
|
68
|
+
const childIndent = currentStyle === "number" ? currentIndent + marker.length + 1 : currentIndent + baseIndent;
|
|
69
|
+
const childDepth = childStyle !== currentStyle ? 0 : depth + 1;
|
|
70
|
+
let childIndex = 0;
|
|
71
|
+
for (const child of item.children) {
|
|
72
|
+
renderItem(child, childIndent, childDepth, childIndex, childStyle);
|
|
73
|
+
childIndex++;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
let topIndex = 0;
|
|
78
|
+
for (const item of items) {
|
|
79
|
+
renderItem(item, 0, 0, topIndex, style);
|
|
80
|
+
topIndex++;
|
|
81
|
+
}
|
|
82
|
+
return lines.join(`
|
|
83
|
+
`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { renderList };
|